0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifdef CONFIG_NFS_USE_KERNEL_DNS
0011
0012 #include <linux/module.h>
0013 #include <linux/sunrpc/clnt.h>
0014 #include <linux/sunrpc/addr.h>
0015 #include <linux/dns_resolver.h>
0016 #include "dns_resolve.h"
0017
0018 ssize_t nfs_dns_resolve_name(struct net *net, char *name, size_t namelen,
0019 struct sockaddr *sa, size_t salen)
0020 {
0021 ssize_t ret;
0022 char *ip_addr = NULL;
0023 int ip_len;
0024
0025 ip_len = dns_query(net, NULL, name, namelen, NULL, &ip_addr, NULL,
0026 false);
0027 if (ip_len > 0)
0028 ret = rpc_pton(net, ip_addr, ip_len, sa, salen);
0029 else
0030 ret = -ESRCH;
0031 kfree(ip_addr);
0032 return ret;
0033 }
0034
0035 #else
0036
0037 #include <linux/module.h>
0038 #include <linux/hash.h>
0039 #include <linux/string.h>
0040 #include <linux/kmod.h>
0041 #include <linux/slab.h>
0042 #include <linux/socket.h>
0043 #include <linux/seq_file.h>
0044 #include <linux/inet.h>
0045 #include <linux/sunrpc/clnt.h>
0046 #include <linux/sunrpc/addr.h>
0047 #include <linux/sunrpc/cache.h>
0048 #include <linux/sunrpc/svcauth.h>
0049 #include <linux/sunrpc/rpc_pipe_fs.h>
0050 #include <linux/nfs_fs.h>
0051
0052 #include "nfs4_fs.h"
0053 #include "dns_resolve.h"
0054 #include "cache_lib.h"
0055 #include "netns.h"
0056
0057 #define NFS_DNS_HASHBITS 4
0058 #define NFS_DNS_HASHTBL_SIZE (1 << NFS_DNS_HASHBITS)
0059
0060 struct nfs_dns_ent {
0061 struct cache_head h;
0062
0063 char *hostname;
0064 size_t namelen;
0065
0066 struct sockaddr_storage addr;
0067 size_t addrlen;
0068 struct rcu_head rcu_head;
0069 };
0070
0071
0072 static void nfs_dns_ent_update(struct cache_head *cnew,
0073 struct cache_head *ckey)
0074 {
0075 struct nfs_dns_ent *new;
0076 struct nfs_dns_ent *key;
0077
0078 new = container_of(cnew, struct nfs_dns_ent, h);
0079 key = container_of(ckey, struct nfs_dns_ent, h);
0080
0081 memcpy(&new->addr, &key->addr, key->addrlen);
0082 new->addrlen = key->addrlen;
0083 }
0084
0085 static void nfs_dns_ent_init(struct cache_head *cnew,
0086 struct cache_head *ckey)
0087 {
0088 struct nfs_dns_ent *new;
0089 struct nfs_dns_ent *key;
0090
0091 new = container_of(cnew, struct nfs_dns_ent, h);
0092 key = container_of(ckey, struct nfs_dns_ent, h);
0093
0094 kfree(new->hostname);
0095 new->hostname = kmemdup_nul(key->hostname, key->namelen, GFP_KERNEL);
0096 if (new->hostname) {
0097 new->namelen = key->namelen;
0098 nfs_dns_ent_update(cnew, ckey);
0099 } else {
0100 new->namelen = 0;
0101 new->addrlen = 0;
0102 }
0103 }
0104
0105 static void nfs_dns_ent_free_rcu(struct rcu_head *head)
0106 {
0107 struct nfs_dns_ent *item;
0108
0109 item = container_of(head, struct nfs_dns_ent, rcu_head);
0110 kfree(item->hostname);
0111 kfree(item);
0112 }
0113
0114 static void nfs_dns_ent_put(struct kref *ref)
0115 {
0116 struct nfs_dns_ent *item;
0117
0118 item = container_of(ref, struct nfs_dns_ent, h.ref);
0119 call_rcu(&item->rcu_head, nfs_dns_ent_free_rcu);
0120 }
0121
0122 static struct cache_head *nfs_dns_ent_alloc(void)
0123 {
0124 struct nfs_dns_ent *item = kmalloc(sizeof(*item), GFP_KERNEL);
0125
0126 if (item != NULL) {
0127 item->hostname = NULL;
0128 item->namelen = 0;
0129 item->addrlen = 0;
0130 return &item->h;
0131 }
0132 return NULL;
0133 };
0134
0135 static unsigned int nfs_dns_hash(const struct nfs_dns_ent *key)
0136 {
0137 return hash_str(key->hostname, NFS_DNS_HASHBITS);
0138 }
0139
0140 static void nfs_dns_request(struct cache_detail *cd,
0141 struct cache_head *ch,
0142 char **bpp, int *blen)
0143 {
0144 struct nfs_dns_ent *key = container_of(ch, struct nfs_dns_ent, h);
0145
0146 qword_add(bpp, blen, key->hostname);
0147 (*bpp)[-1] = '\n';
0148 }
0149
0150 static int nfs_dns_upcall(struct cache_detail *cd,
0151 struct cache_head *ch)
0152 {
0153 struct nfs_dns_ent *key = container_of(ch, struct nfs_dns_ent, h);
0154
0155 if (test_and_set_bit(CACHE_PENDING, &ch->flags))
0156 return 0;
0157 if (!nfs_cache_upcall(cd, key->hostname))
0158 return 0;
0159 clear_bit(CACHE_PENDING, &ch->flags);
0160 return sunrpc_cache_pipe_upcall_timeout(cd, ch);
0161 }
0162
0163 static int nfs_dns_match(struct cache_head *ca,
0164 struct cache_head *cb)
0165 {
0166 struct nfs_dns_ent *a;
0167 struct nfs_dns_ent *b;
0168
0169 a = container_of(ca, struct nfs_dns_ent, h);
0170 b = container_of(cb, struct nfs_dns_ent, h);
0171
0172 if (a->namelen == 0 || a->namelen != b->namelen)
0173 return 0;
0174 return memcmp(a->hostname, b->hostname, a->namelen) == 0;
0175 }
0176
0177 static int nfs_dns_show(struct seq_file *m, struct cache_detail *cd,
0178 struct cache_head *h)
0179 {
0180 struct nfs_dns_ent *item;
0181 long ttl;
0182
0183 if (h == NULL) {
0184 seq_puts(m, "# ip address hostname ttl\n");
0185 return 0;
0186 }
0187 item = container_of(h, struct nfs_dns_ent, h);
0188 ttl = item->h.expiry_time - seconds_since_boot();
0189 if (ttl < 0)
0190 ttl = 0;
0191
0192 if (!test_bit(CACHE_NEGATIVE, &h->flags)) {
0193 char buf[INET6_ADDRSTRLEN+IPV6_SCOPE_ID_LEN+1];
0194
0195 rpc_ntop((struct sockaddr *)&item->addr, buf, sizeof(buf));
0196 seq_printf(m, "%15s ", buf);
0197 } else
0198 seq_puts(m, "<none> ");
0199 seq_printf(m, "%15s %ld\n", item->hostname, ttl);
0200 return 0;
0201 }
0202
0203 static struct nfs_dns_ent *nfs_dns_lookup(struct cache_detail *cd,
0204 struct nfs_dns_ent *key)
0205 {
0206 struct cache_head *ch;
0207
0208 ch = sunrpc_cache_lookup_rcu(cd,
0209 &key->h,
0210 nfs_dns_hash(key));
0211 if (!ch)
0212 return NULL;
0213 return container_of(ch, struct nfs_dns_ent, h);
0214 }
0215
0216 static struct nfs_dns_ent *nfs_dns_update(struct cache_detail *cd,
0217 struct nfs_dns_ent *new,
0218 struct nfs_dns_ent *key)
0219 {
0220 struct cache_head *ch;
0221
0222 ch = sunrpc_cache_update(cd,
0223 &new->h, &key->h,
0224 nfs_dns_hash(key));
0225 if (!ch)
0226 return NULL;
0227 return container_of(ch, struct nfs_dns_ent, h);
0228 }
0229
0230 static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen)
0231 {
0232 char buf1[NFS_DNS_HOSTNAME_MAXLEN+1];
0233 struct nfs_dns_ent key, *item;
0234 unsigned int ttl;
0235 ssize_t len;
0236 int ret = -EINVAL;
0237
0238 if (buf[buflen-1] != '\n')
0239 goto out;
0240 buf[buflen-1] = '\0';
0241
0242 len = qword_get(&buf, buf1, sizeof(buf1));
0243 if (len <= 0)
0244 goto out;
0245 key.addrlen = rpc_pton(cd->net, buf1, len,
0246 (struct sockaddr *)&key.addr,
0247 sizeof(key.addr));
0248
0249 len = qword_get(&buf, buf1, sizeof(buf1));
0250 if (len <= 0)
0251 goto out;
0252
0253 key.hostname = buf1;
0254 key.namelen = len;
0255 memset(&key.h, 0, sizeof(key.h));
0256
0257 if (get_uint(&buf, &ttl) < 0)
0258 goto out;
0259 if (ttl == 0)
0260 goto out;
0261 key.h.expiry_time = ttl + seconds_since_boot();
0262
0263 ret = -ENOMEM;
0264 item = nfs_dns_lookup(cd, &key);
0265 if (item == NULL)
0266 goto out;
0267
0268 if (key.addrlen == 0)
0269 set_bit(CACHE_NEGATIVE, &key.h.flags);
0270
0271 item = nfs_dns_update(cd, &key, item);
0272 if (item == NULL)
0273 goto out;
0274
0275 ret = 0;
0276 cache_put(&item->h, cd);
0277 out:
0278 return ret;
0279 }
0280
0281 static int do_cache_lookup(struct cache_detail *cd,
0282 struct nfs_dns_ent *key,
0283 struct nfs_dns_ent **item,
0284 struct nfs_cache_defer_req *dreq)
0285 {
0286 int ret = -ENOMEM;
0287
0288 *item = nfs_dns_lookup(cd, key);
0289 if (*item) {
0290 ret = cache_check(cd, &(*item)->h, &dreq->req);
0291 if (ret)
0292 *item = NULL;
0293 }
0294 return ret;
0295 }
0296
0297 static int do_cache_lookup_nowait(struct cache_detail *cd,
0298 struct nfs_dns_ent *key,
0299 struct nfs_dns_ent **item)
0300 {
0301 int ret = -ENOMEM;
0302
0303 *item = nfs_dns_lookup(cd, key);
0304 if (!*item)
0305 goto out_err;
0306 ret = -ETIMEDOUT;
0307 if (!test_bit(CACHE_VALID, &(*item)->h.flags)
0308 || (*item)->h.expiry_time < seconds_since_boot()
0309 || cd->flush_time > (*item)->h.last_refresh)
0310 goto out_put;
0311 ret = -ENOENT;
0312 if (test_bit(CACHE_NEGATIVE, &(*item)->h.flags))
0313 goto out_put;
0314 return 0;
0315 out_put:
0316 cache_put(&(*item)->h, cd);
0317 out_err:
0318 *item = NULL;
0319 return ret;
0320 }
0321
0322 static int do_cache_lookup_wait(struct cache_detail *cd,
0323 struct nfs_dns_ent *key,
0324 struct nfs_dns_ent **item)
0325 {
0326 struct nfs_cache_defer_req *dreq;
0327 int ret = -ENOMEM;
0328
0329 dreq = nfs_cache_defer_req_alloc();
0330 if (!dreq)
0331 goto out;
0332 ret = do_cache_lookup(cd, key, item, dreq);
0333 if (ret == -EAGAIN) {
0334 ret = nfs_cache_wait_for_upcall(dreq);
0335 if (!ret)
0336 ret = do_cache_lookup_nowait(cd, key, item);
0337 }
0338 nfs_cache_defer_req_put(dreq);
0339 out:
0340 return ret;
0341 }
0342
0343 ssize_t nfs_dns_resolve_name(struct net *net, char *name,
0344 size_t namelen, struct sockaddr *sa, size_t salen)
0345 {
0346 struct nfs_dns_ent key = {
0347 .hostname = name,
0348 .namelen = namelen,
0349 };
0350 struct nfs_dns_ent *item = NULL;
0351 ssize_t ret;
0352 struct nfs_net *nn = net_generic(net, nfs_net_id);
0353
0354 ret = do_cache_lookup_wait(nn->nfs_dns_resolve, &key, &item);
0355 if (ret == 0) {
0356 if (salen >= item->addrlen) {
0357 memcpy(sa, &item->addr, item->addrlen);
0358 ret = item->addrlen;
0359 } else
0360 ret = -EOVERFLOW;
0361 cache_put(&item->h, nn->nfs_dns_resolve);
0362 } else if (ret == -ENOENT)
0363 ret = -ESRCH;
0364 return ret;
0365 }
0366
0367 static struct cache_detail nfs_dns_resolve_template = {
0368 .owner = THIS_MODULE,
0369 .hash_size = NFS_DNS_HASHTBL_SIZE,
0370 .name = "dns_resolve",
0371 .cache_put = nfs_dns_ent_put,
0372 .cache_upcall = nfs_dns_upcall,
0373 .cache_request = nfs_dns_request,
0374 .cache_parse = nfs_dns_parse,
0375 .cache_show = nfs_dns_show,
0376 .match = nfs_dns_match,
0377 .init = nfs_dns_ent_init,
0378 .update = nfs_dns_ent_update,
0379 .alloc = nfs_dns_ent_alloc,
0380 };
0381
0382
0383 int nfs_dns_resolver_cache_init(struct net *net)
0384 {
0385 int err;
0386 struct nfs_net *nn = net_generic(net, nfs_net_id);
0387
0388 nn->nfs_dns_resolve = cache_create_net(&nfs_dns_resolve_template, net);
0389 if (IS_ERR(nn->nfs_dns_resolve))
0390 return PTR_ERR(nn->nfs_dns_resolve);
0391
0392 err = nfs_cache_register_net(net, nn->nfs_dns_resolve);
0393 if (err)
0394 goto err_reg;
0395 return 0;
0396
0397 err_reg:
0398 cache_destroy_net(nn->nfs_dns_resolve, net);
0399 return err;
0400 }
0401
0402 void nfs_dns_resolver_cache_destroy(struct net *net)
0403 {
0404 struct nfs_net *nn = net_generic(net, nfs_net_id);
0405
0406 nfs_cache_unregister_net(net, nn->nfs_dns_resolve);
0407 cache_destroy_net(nn->nfs_dns_resolve, net);
0408 }
0409
0410 static int nfs4_dns_net_init(struct net *net)
0411 {
0412 return nfs_dns_resolver_cache_init(net);
0413 }
0414
0415 static void nfs4_dns_net_exit(struct net *net)
0416 {
0417 nfs_dns_resolver_cache_destroy(net);
0418 }
0419
0420 static struct pernet_operations nfs4_dns_resolver_ops = {
0421 .init = nfs4_dns_net_init,
0422 .exit = nfs4_dns_net_exit,
0423 };
0424
0425 static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event,
0426 void *ptr)
0427 {
0428 struct super_block *sb = ptr;
0429 struct net *net = sb->s_fs_info;
0430 struct nfs_net *nn = net_generic(net, nfs_net_id);
0431 struct cache_detail *cd = nn->nfs_dns_resolve;
0432 int ret = 0;
0433
0434 if (cd == NULL)
0435 return 0;
0436
0437 if (!try_module_get(THIS_MODULE))
0438 return 0;
0439
0440 switch (event) {
0441 case RPC_PIPEFS_MOUNT:
0442 ret = nfs_cache_register_sb(sb, cd);
0443 break;
0444 case RPC_PIPEFS_UMOUNT:
0445 nfs_cache_unregister_sb(sb, cd);
0446 break;
0447 default:
0448 ret = -ENOTSUPP;
0449 break;
0450 }
0451 module_put(THIS_MODULE);
0452 return ret;
0453 }
0454
0455 static struct notifier_block nfs_dns_resolver_block = {
0456 .notifier_call = rpc_pipefs_event,
0457 };
0458
0459 int nfs_dns_resolver_init(void)
0460 {
0461 int err;
0462
0463 err = register_pernet_subsys(&nfs4_dns_resolver_ops);
0464 if (err < 0)
0465 goto out;
0466 err = rpc_pipefs_notifier_register(&nfs_dns_resolver_block);
0467 if (err < 0)
0468 goto out1;
0469 return 0;
0470 out1:
0471 unregister_pernet_subsys(&nfs4_dns_resolver_ops);
0472 out:
0473 return err;
0474 }
0475
0476 void nfs_dns_resolver_destroy(void)
0477 {
0478 rpc_pipefs_notifier_unregister(&nfs_dns_resolver_block);
0479 unregister_pernet_subsys(&nfs4_dns_resolver_ops);
0480 }
0481 #endif