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(net, NULL, name, namelen, NULL, &ip_addr, NULL, 26 false); 27 if (ip_len > 0) 28 ret = rpc_pton(net, ip_addr, ip_len, sa, salen); 29 else 30 ret = -ESRCH; 31 kfree(ip_addr); 32 return ret; 33 } 34 35 #else 36 37 #include <linux/module.h> 38 #include <linux/hash.h> 39 #include <linux/string.h> 40 #include <linux/kmod.h> 41 #include <linux/slab.h> 42 #include <linux/module.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 = kstrndup(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 int ret; 156 157 ret = nfs_cache_upcall(cd, key->hostname); 158 if (ret) 159 ret = sunrpc_cache_pipe_upcall(cd, ch); 160 return ret; 161 } 162 163 static int nfs_dns_match(struct cache_head *ca, 164 struct cache_head *cb) 165 { 166 struct nfs_dns_ent *a; 167 struct nfs_dns_ent *b; 168 169 a = container_of(ca, struct nfs_dns_ent, h); 170 b = container_of(cb, struct nfs_dns_ent, h); 171 172 if (a->namelen == 0 || a->namelen != b->namelen) 173 return 0; 174 return memcmp(a->hostname, b->hostname, a->namelen) == 0; 175 } 176 177 static int nfs_dns_show(struct seq_file *m, struct cache_detail *cd, 178 struct cache_head *h) 179 { 180 struct nfs_dns_ent *item; 181 long ttl; 182 183 if (h == NULL) { 184 seq_puts(m, "# ip address hostname ttl\n"); 185 return 0; 186 } 187 item = container_of(h, struct nfs_dns_ent, h); 188 ttl = item->h.expiry_time - seconds_since_boot(); 189 if (ttl < 0) 190 ttl = 0; 191 192 if (!test_bit(CACHE_NEGATIVE, &h->flags)) { 193 char buf[INET6_ADDRSTRLEN+IPV6_SCOPE_ID_LEN+1]; 194 195 rpc_ntop((struct sockaddr *)&item->addr, buf, sizeof(buf)); 196 seq_printf(m, "%15s ", buf); 197 } else 198 seq_puts(m, "<none> "); 199 seq_printf(m, "%15s %ld\n", item->hostname, ttl); 200 return 0; 201 } 202 203 static struct nfs_dns_ent *nfs_dns_lookup(struct cache_detail *cd, 204 struct nfs_dns_ent *key) 205 { 206 struct cache_head *ch; 207 208 ch = sunrpc_cache_lookup_rcu(cd, 209 &key->h, 210 nfs_dns_hash(key)); 211 if (!ch) 212 return NULL; 213 return container_of(ch, struct nfs_dns_ent, h); 214 } 215 216 static struct nfs_dns_ent *nfs_dns_update(struct cache_detail *cd, 217 struct nfs_dns_ent *new, 218 struct nfs_dns_ent *key) 219 { 220 struct cache_head *ch; 221 222 ch = sunrpc_cache_update(cd, 223 &new->h, &key->h, 224 nfs_dns_hash(key)); 225 if (!ch) 226 return NULL; 227 return container_of(ch, struct nfs_dns_ent, h); 228 } 229 230 static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen) 231 { 232 char buf1[NFS_DNS_HOSTNAME_MAXLEN+1]; 233 struct nfs_dns_ent key, *item; 234 unsigned int ttl; 235 ssize_t len; 236 int ret = -EINVAL; 237 238 if (buf[buflen-1] != '\n') 239 goto out; 240 buf[buflen-1] = '\0'; 241 242 len = qword_get(&buf, buf1, sizeof(buf1)); 243 if (len <= 0) 244 goto out; 245 key.addrlen = rpc_pton(cd->net, buf1, len, 246 (struct sockaddr *)&key.addr, 247 sizeof(key.addr)); 248 249 len = qword_get(&buf, buf1, sizeof(buf1)); 250 if (len <= 0) 251 goto out; 252 253 key.hostname = buf1; 254 key.namelen = len; 255 memset(&key.h, 0, sizeof(key.h)); 256 257 if (get_uint(&buf, &ttl) < 0) 258 goto out; 259 if (ttl == 0) 260 goto out; 261 key.h.expiry_time = ttl + seconds_since_boot(); 262 263 ret = -ENOMEM; 264 item = nfs_dns_lookup(cd, &key); 265 if (item == NULL) 266 goto out; 267 268 if (key.addrlen == 0) 269 set_bit(CACHE_NEGATIVE, &key.h.flags); 270 271 item = nfs_dns_update(cd, &key, item); 272 if (item == NULL) 273 goto out; 274 275 ret = 0; 276 cache_put(&item->h, cd); 277 out: 278 return ret; 279 } 280 281 static int do_cache_lookup(struct cache_detail *cd, 282 struct nfs_dns_ent *key, 283 struct nfs_dns_ent **item, 284 struct nfs_cache_defer_req *dreq) 285 { 286 int ret = -ENOMEM; 287 288 *item = nfs_dns_lookup(cd, key); 289 if (*item) { 290 ret = cache_check(cd, &(*item)->h, &dreq->req); 291 if (ret) 292 *item = NULL; 293 } 294 return ret; 295 } 296 297 static int do_cache_lookup_nowait(struct cache_detail *cd, 298 struct nfs_dns_ent *key, 299 struct nfs_dns_ent **item) 300 { 301 int ret = -ENOMEM; 302 303 *item = nfs_dns_lookup(cd, key); 304 if (!*item) 305 goto out_err; 306 ret = -ETIMEDOUT; 307 if (!test_bit(CACHE_VALID, &(*item)->h.flags) 308 || (*item)->h.expiry_time < seconds_since_boot() 309 || cd->flush_time > (*item)->h.last_refresh) 310 goto out_put; 311 ret = -ENOENT; 312 if (test_bit(CACHE_NEGATIVE, &(*item)->h.flags)) 313 goto out_put; 314 return 0; 315 out_put: 316 cache_put(&(*item)->h, cd); 317 out_err: 318 *item = NULL; 319 return ret; 320 } 321 322 static int do_cache_lookup_wait(struct cache_detail *cd, 323 struct nfs_dns_ent *key, 324 struct nfs_dns_ent **item) 325 { 326 struct nfs_cache_defer_req *dreq; 327 int ret = -ENOMEM; 328 329 dreq = nfs_cache_defer_req_alloc(); 330 if (!dreq) 331 goto out; 332 ret = do_cache_lookup(cd, key, item, dreq); 333 if (ret == -EAGAIN) { 334 ret = nfs_cache_wait_for_upcall(dreq); 335 if (!ret) 336 ret = do_cache_lookup_nowait(cd, key, item); 337 } 338 nfs_cache_defer_req_put(dreq); 339 out: 340 return ret; 341 } 342 343 ssize_t nfs_dns_resolve_name(struct net *net, char *name, 344 size_t namelen, struct sockaddr *sa, size_t salen) 345 { 346 struct nfs_dns_ent key = { 347 .hostname = name, 348 .namelen = namelen, 349 }; 350 struct nfs_dns_ent *item = NULL; 351 ssize_t ret; 352 struct nfs_net *nn = net_generic(net, nfs_net_id); 353 354 ret = do_cache_lookup_wait(nn->nfs_dns_resolve, &key, &item); 355 if (ret == 0) { 356 if (salen >= item->addrlen) { 357 memcpy(sa, &item->addr, item->addrlen); 358 ret = item->addrlen; 359 } else 360 ret = -EOVERFLOW; 361 cache_put(&item->h, nn->nfs_dns_resolve); 362 } else if (ret == -ENOENT) 363 ret = -ESRCH; 364 return ret; 365 } 366 367 static struct cache_detail nfs_dns_resolve_template = { 368 .owner = THIS_MODULE, 369 .hash_size = NFS_DNS_HASHTBL_SIZE, 370 .name = "dns_resolve", 371 .cache_put = nfs_dns_ent_put, 372 .cache_upcall = nfs_dns_upcall, 373 .cache_request = nfs_dns_request, 374 .cache_parse = nfs_dns_parse, 375 .cache_show = nfs_dns_show, 376 .match = nfs_dns_match, 377 .init = nfs_dns_ent_init, 378 .update = nfs_dns_ent_update, 379 .alloc = nfs_dns_ent_alloc, 380 }; 381 382 383 int nfs_dns_resolver_cache_init(struct net *net) 384 { 385 int err; 386 struct nfs_net *nn = net_generic(net, nfs_net_id); 387 388 nn->nfs_dns_resolve = cache_create_net(&nfs_dns_resolve_template, net); 389 if (IS_ERR(nn->nfs_dns_resolve)) 390 return PTR_ERR(nn->nfs_dns_resolve); 391 392 err = nfs_cache_register_net(net, nn->nfs_dns_resolve); 393 if (err) 394 goto err_reg; 395 return 0; 396 397 err_reg: 398 cache_destroy_net(nn->nfs_dns_resolve, net); 399 return err; 400 } 401 402 void nfs_dns_resolver_cache_destroy(struct net *net) 403 { 404 struct nfs_net *nn = net_generic(net, nfs_net_id); 405 406 nfs_cache_unregister_net(net, nn->nfs_dns_resolve); 407 cache_destroy_net(nn->nfs_dns_resolve, net); 408 } 409 410 static int nfs4_dns_net_init(struct net *net) 411 { 412 return nfs_dns_resolver_cache_init(net); 413 } 414 415 static void nfs4_dns_net_exit(struct net *net) 416 { 417 nfs_dns_resolver_cache_destroy(net); 418 } 419 420 static struct pernet_operations nfs4_dns_resolver_ops = { 421 .init = nfs4_dns_net_init, 422 .exit = nfs4_dns_net_exit, 423 }; 424 425 static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event, 426 void *ptr) 427 { 428 struct super_block *sb = ptr; 429 struct net *net = sb->s_fs_info; 430 struct nfs_net *nn = net_generic(net, nfs_net_id); 431 struct cache_detail *cd = nn->nfs_dns_resolve; 432 int ret = 0; 433 434 if (cd == NULL) 435 return 0; 436 437 if (!try_module_get(THIS_MODULE)) 438 return 0; 439 440 switch (event) { 441 case RPC_PIPEFS_MOUNT: 442 ret = nfs_cache_register_sb(sb, cd); 443 break; 444 case RPC_PIPEFS_UMOUNT: 445 nfs_cache_unregister_sb(sb, cd); 446 break; 447 default: 448 ret = -ENOTSUPP; 449 break; 450 } 451 module_put(THIS_MODULE); 452 return ret; 453 } 454 455 static struct notifier_block nfs_dns_resolver_block = { 456 .notifier_call = rpc_pipefs_event, 457 }; 458 459 int nfs_dns_resolver_init(void) 460 { 461 int err; 462 463 err = register_pernet_subsys(&nfs4_dns_resolver_ops); 464 if (err < 0) 465 goto out; 466 err = rpc_pipefs_notifier_register(&nfs_dns_resolver_block); 467 if (err < 0) 468 goto out1; 469 return 0; 470 out1: 471 unregister_pernet_subsys(&nfs4_dns_resolver_ops); 472 out: 473 return err; 474 } 475 476 void nfs_dns_resolver_destroy(void) 477 { 478 rpc_pipefs_notifier_unregister(&nfs_dns_resolver_block); 479 unregister_pernet_subsys(&nfs4_dns_resolver_ops); 480 } 481 #endif 482