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