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