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