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