1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * linux/fs/nfs/dns_resolve.c 4 * 5 * Copyright (c) 2009 Trond Myklebust <Trond.Myklebust@netapp.com> 6 * 7 * Resolves DNS hostnames into valid ip addresses 8 */ 9 10 #ifdef CONFIG_NFS_USE_KERNEL_DNS 11 12 #include <linux/module.h> 13 #include <linux/sunrpc/clnt.h> 14 #include <linux/sunrpc/addr.h> 15 #include <linux/dns_resolver.h> 16 #include "dns_resolve.h" 17 18 ssize_t nfs_dns_resolve_name(struct net *net, char *name, size_t namelen, 19 struct sockaddr *sa, size_t salen) 20 { 21 ssize_t ret; 22 char *ip_addr = NULL; 23 int ip_len; 24 25 ip_len = dns_query(NULL, name, namelen, NULL, &ip_addr, NULL); 26 if (ip_len > 0) 27 ret = rpc_pton(net, ip_addr, ip_len, sa, salen); 28 else 29 ret = -ESRCH; 30 kfree(ip_addr); 31 return ret; 32 } 33 34 #else 35 36 #include <linux/module.h> 37 #include <linux/hash.h> 38 #include <linux/string.h> 39 #include <linux/kmod.h> 40 #include <linux/slab.h> 41 #include <linux/module.h> 42 #include <linux/socket.h> 43 #include <linux/seq_file.h> 44 #include <linux/inet.h> 45 #include <linux/sunrpc/clnt.h> 46 #include <linux/sunrpc/addr.h> 47 #include <linux/sunrpc/cache.h> 48 #include <linux/sunrpc/svcauth.h> 49 #include <linux/sunrpc/rpc_pipe_fs.h> 50 #include <linux/nfs_fs.h> 51 52 #include "nfs4_fs.h" 53 #include "dns_resolve.h" 54 #include "cache_lib.h" 55 #include "netns.h" 56 57 #define NFS_DNS_HASHBITS 4 58 #define NFS_DNS_HASHTBL_SIZE (1 << NFS_DNS_HASHBITS) 59 60 struct nfs_dns_ent { 61 struct cache_head h; 62 63 char *hostname; 64 size_t namelen; 65 66 struct sockaddr_storage addr; 67 size_t addrlen; 68 struct rcu_head rcu_head; 69 }; 70 71 72 static void nfs_dns_ent_update(struct cache_head *cnew, 73 struct cache_head *ckey) 74 { 75 struct nfs_dns_ent *new; 76 struct nfs_dns_ent *key; 77 78 new = container_of(cnew, struct nfs_dns_ent, h); 79 key = container_of(ckey, struct nfs_dns_ent, h); 80 81 memcpy(&new->addr, &key->addr, key->addrlen); 82 new->addrlen = key->addrlen; 83 } 84 85 static void nfs_dns_ent_init(struct cache_head *cnew, 86 struct cache_head *ckey) 87 { 88 struct nfs_dns_ent *new; 89 struct nfs_dns_ent *key; 90 91 new = container_of(cnew, struct nfs_dns_ent, h); 92 key = container_of(ckey, struct nfs_dns_ent, h); 93 94 kfree(new->hostname); 95 new->hostname = kstrndup(key->hostname, key->namelen, GFP_KERNEL); 96 if (new->hostname) { 97 new->namelen = key->namelen; 98 nfs_dns_ent_update(cnew, ckey); 99 } else { 100 new->namelen = 0; 101 new->addrlen = 0; 102 } 103 } 104 105 static void nfs_dns_ent_free_rcu(struct rcu_head *head) 106 { 107 struct nfs_dns_ent *item; 108 109 item = container_of(head, struct nfs_dns_ent, rcu_head); 110 kfree(item->hostname); 111 kfree(item); 112 } 113 114 static void nfs_dns_ent_put(struct kref *ref) 115 { 116 struct nfs_dns_ent *item; 117 118 item = container_of(ref, struct nfs_dns_ent, h.ref); 119 call_rcu(&item->rcu_head, nfs_dns_ent_free_rcu); 120 } 121 122 static struct cache_head *nfs_dns_ent_alloc(void) 123 { 124 struct nfs_dns_ent *item = kmalloc(sizeof(*item), GFP_KERNEL); 125 126 if (item != NULL) { 127 item->hostname = NULL; 128 item->namelen = 0; 129 item->addrlen = 0; 130 return &item->h; 131 } 132 return NULL; 133 }; 134 135 static unsigned int nfs_dns_hash(const struct nfs_dns_ent *key) 136 { 137 return hash_str(key->hostname, NFS_DNS_HASHBITS); 138 } 139 140 static void nfs_dns_request(struct cache_detail *cd, 141 struct cache_head *ch, 142 char **bpp, int *blen) 143 { 144 struct nfs_dns_ent *key = container_of(ch, struct nfs_dns_ent, h); 145 146 qword_add(bpp, blen, key->hostname); 147 (*bpp)[-1] = '\n'; 148 } 149 150 static int nfs_dns_upcall(struct cache_detail *cd, 151 struct cache_head *ch) 152 { 153 struct nfs_dns_ent *key = container_of(ch, struct nfs_dns_ent, h); 154 int ret; 155 156 ret = nfs_cache_upcall(cd, key->hostname); 157 if (ret) 158 ret = sunrpc_cache_pipe_upcall(cd, ch); 159 return ret; 160 } 161 162 static int nfs_dns_match(struct cache_head *ca, 163 struct cache_head *cb) 164 { 165 struct nfs_dns_ent *a; 166 struct nfs_dns_ent *b; 167 168 a = container_of(ca, struct nfs_dns_ent, h); 169 b = container_of(cb, struct nfs_dns_ent, h); 170 171 if (a->namelen == 0 || a->namelen != b->namelen) 172 return 0; 173 return memcmp(a->hostname, b->hostname, a->namelen) == 0; 174 } 175 176 static int nfs_dns_show(struct seq_file *m, struct cache_detail *cd, 177 struct cache_head *h) 178 { 179 struct nfs_dns_ent *item; 180 long ttl; 181 182 if (h == NULL) { 183 seq_puts(m, "# ip address hostname ttl\n"); 184 return 0; 185 } 186 item = container_of(h, struct nfs_dns_ent, h); 187 ttl = item->h.expiry_time - seconds_since_boot(); 188 if (ttl < 0) 189 ttl = 0; 190 191 if (!test_bit(CACHE_NEGATIVE, &h->flags)) { 192 char buf[INET6_ADDRSTRLEN+IPV6_SCOPE_ID_LEN+1]; 193 194 rpc_ntop((struct sockaddr *)&item->addr, buf, sizeof(buf)); 195 seq_printf(m, "%15s ", buf); 196 } else 197 seq_puts(m, "<none> "); 198 seq_printf(m, "%15s %ld\n", item->hostname, ttl); 199 return 0; 200 } 201 202 static struct nfs_dns_ent *nfs_dns_lookup(struct cache_detail *cd, 203 struct nfs_dns_ent *key) 204 { 205 struct cache_head *ch; 206 207 ch = sunrpc_cache_lookup_rcu(cd, 208 &key->h, 209 nfs_dns_hash(key)); 210 if (!ch) 211 return NULL; 212 return container_of(ch, struct nfs_dns_ent, h); 213 } 214 215 static struct nfs_dns_ent *nfs_dns_update(struct cache_detail *cd, 216 struct nfs_dns_ent *new, 217 struct nfs_dns_ent *key) 218 { 219 struct cache_head *ch; 220 221 ch = sunrpc_cache_update(cd, 222 &new->h, &key->h, 223 nfs_dns_hash(key)); 224 if (!ch) 225 return NULL; 226 return container_of(ch, struct nfs_dns_ent, h); 227 } 228 229 static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen) 230 { 231 char buf1[NFS_DNS_HOSTNAME_MAXLEN+1]; 232 struct nfs_dns_ent key, *item; 233 unsigned int ttl; 234 ssize_t len; 235 int ret = -EINVAL; 236 237 if (buf[buflen-1] != '\n') 238 goto out; 239 buf[buflen-1] = '\0'; 240 241 len = qword_get(&buf, buf1, sizeof(buf1)); 242 if (len <= 0) 243 goto out; 244 key.addrlen = rpc_pton(cd->net, buf1, len, 245 (struct sockaddr *)&key.addr, 246 sizeof(key.addr)); 247 248 len = qword_get(&buf, buf1, sizeof(buf1)); 249 if (len <= 0) 250 goto out; 251 252 key.hostname = buf1; 253 key.namelen = len; 254 memset(&key.h, 0, sizeof(key.h)); 255 256 if (get_uint(&buf, &ttl) < 0) 257 goto out; 258 if (ttl == 0) 259 goto out; 260 key.h.expiry_time = ttl + seconds_since_boot(); 261 262 ret = -ENOMEM; 263 item = nfs_dns_lookup(cd, &key); 264 if (item == NULL) 265 goto out; 266 267 if (key.addrlen == 0) 268 set_bit(CACHE_NEGATIVE, &key.h.flags); 269 270 item = nfs_dns_update(cd, &key, item); 271 if (item == NULL) 272 goto out; 273 274 ret = 0; 275 cache_put(&item->h, cd); 276 out: 277 return ret; 278 } 279 280 static int do_cache_lookup(struct cache_detail *cd, 281 struct nfs_dns_ent *key, 282 struct nfs_dns_ent **item, 283 struct nfs_cache_defer_req *dreq) 284 { 285 int ret = -ENOMEM; 286 287 *item = nfs_dns_lookup(cd, key); 288 if (*item) { 289 ret = cache_check(cd, &(*item)->h, &dreq->req); 290 if (ret) 291 *item = NULL; 292 } 293 return ret; 294 } 295 296 static int do_cache_lookup_nowait(struct cache_detail *cd, 297 struct nfs_dns_ent *key, 298 struct nfs_dns_ent **item) 299 { 300 int ret = -ENOMEM; 301 302 *item = nfs_dns_lookup(cd, key); 303 if (!*item) 304 goto out_err; 305 ret = -ETIMEDOUT; 306 if (!test_bit(CACHE_VALID, &(*item)->h.flags) 307 || (*item)->h.expiry_time < seconds_since_boot() 308 || cd->flush_time > (*item)->h.last_refresh) 309 goto out_put; 310 ret = -ENOENT; 311 if (test_bit(CACHE_NEGATIVE, &(*item)->h.flags)) 312 goto out_put; 313 return 0; 314 out_put: 315 cache_put(&(*item)->h, cd); 316 out_err: 317 *item = NULL; 318 return ret; 319 } 320 321 static int do_cache_lookup_wait(struct cache_detail *cd, 322 struct nfs_dns_ent *key, 323 struct nfs_dns_ent **item) 324 { 325 struct nfs_cache_defer_req *dreq; 326 int ret = -ENOMEM; 327 328 dreq = nfs_cache_defer_req_alloc(); 329 if (!dreq) 330 goto out; 331 ret = do_cache_lookup(cd, key, item, dreq); 332 if (ret == -EAGAIN) { 333 ret = nfs_cache_wait_for_upcall(dreq); 334 if (!ret) 335 ret = do_cache_lookup_nowait(cd, key, item); 336 } 337 nfs_cache_defer_req_put(dreq); 338 out: 339 return ret; 340 } 341 342 ssize_t nfs_dns_resolve_name(struct net *net, char *name, 343 size_t namelen, struct sockaddr *sa, size_t salen) 344 { 345 struct nfs_dns_ent key = { 346 .hostname = name, 347 .namelen = namelen, 348 }; 349 struct nfs_dns_ent *item = NULL; 350 ssize_t ret; 351 struct nfs_net *nn = net_generic(net, nfs_net_id); 352 353 ret = do_cache_lookup_wait(nn->nfs_dns_resolve, &key, &item); 354 if (ret == 0) { 355 if (salen >= item->addrlen) { 356 memcpy(sa, &item->addr, item->addrlen); 357 ret = item->addrlen; 358 } else 359 ret = -EOVERFLOW; 360 cache_put(&item->h, nn->nfs_dns_resolve); 361 } else if (ret == -ENOENT) 362 ret = -ESRCH; 363 return ret; 364 } 365 366 static struct cache_detail nfs_dns_resolve_template = { 367 .owner = THIS_MODULE, 368 .hash_size = NFS_DNS_HASHTBL_SIZE, 369 .name = "dns_resolve", 370 .cache_put = nfs_dns_ent_put, 371 .cache_upcall = nfs_dns_upcall, 372 .cache_request = nfs_dns_request, 373 .cache_parse = nfs_dns_parse, 374 .cache_show = nfs_dns_show, 375 .match = nfs_dns_match, 376 .init = nfs_dns_ent_init, 377 .update = nfs_dns_ent_update, 378 .alloc = nfs_dns_ent_alloc, 379 }; 380 381 382 int nfs_dns_resolver_cache_init(struct net *net) 383 { 384 int err; 385 struct nfs_net *nn = net_generic(net, nfs_net_id); 386 387 nn->nfs_dns_resolve = cache_create_net(&nfs_dns_resolve_template, net); 388 if (IS_ERR(nn->nfs_dns_resolve)) 389 return PTR_ERR(nn->nfs_dns_resolve); 390 391 err = nfs_cache_register_net(net, nn->nfs_dns_resolve); 392 if (err) 393 goto err_reg; 394 return 0; 395 396 err_reg: 397 cache_destroy_net(nn->nfs_dns_resolve, net); 398 return err; 399 } 400 401 void nfs_dns_resolver_cache_destroy(struct net *net) 402 { 403 struct nfs_net *nn = net_generic(net, nfs_net_id); 404 405 nfs_cache_unregister_net(net, nn->nfs_dns_resolve); 406 cache_destroy_net(nn->nfs_dns_resolve, net); 407 } 408 409 static int nfs4_dns_net_init(struct net *net) 410 { 411 return nfs_dns_resolver_cache_init(net); 412 } 413 414 static void nfs4_dns_net_exit(struct net *net) 415 { 416 nfs_dns_resolver_cache_destroy(net); 417 } 418 419 static struct pernet_operations nfs4_dns_resolver_ops = { 420 .init = nfs4_dns_net_init, 421 .exit = nfs4_dns_net_exit, 422 }; 423 424 static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event, 425 void *ptr) 426 { 427 struct super_block *sb = ptr; 428 struct net *net = sb->s_fs_info; 429 struct nfs_net *nn = net_generic(net, nfs_net_id); 430 struct cache_detail *cd = nn->nfs_dns_resolve; 431 int ret = 0; 432 433 if (cd == NULL) 434 return 0; 435 436 if (!try_module_get(THIS_MODULE)) 437 return 0; 438 439 switch (event) { 440 case RPC_PIPEFS_MOUNT: 441 ret = nfs_cache_register_sb(sb, cd); 442 break; 443 case RPC_PIPEFS_UMOUNT: 444 nfs_cache_unregister_sb(sb, cd); 445 break; 446 default: 447 ret = -ENOTSUPP; 448 break; 449 } 450 module_put(THIS_MODULE); 451 return ret; 452 } 453 454 static struct notifier_block nfs_dns_resolver_block = { 455 .notifier_call = rpc_pipefs_event, 456 }; 457 458 int nfs_dns_resolver_init(void) 459 { 460 int err; 461 462 err = register_pernet_subsys(&nfs4_dns_resolver_ops); 463 if (err < 0) 464 goto out; 465 err = rpc_pipefs_notifier_register(&nfs_dns_resolver_block); 466 if (err < 0) 467 goto out1; 468 return 0; 469 out1: 470 unregister_pernet_subsys(&nfs4_dns_resolver_ops); 471 out: 472 return err; 473 } 474 475 void nfs_dns_resolver_destroy(void) 476 { 477 rpc_pipefs_notifier_unregister(&nfs_dns_resolver_block); 478 unregister_pernet_subsys(&nfs4_dns_resolver_ops); 479 } 480 #endif 481