aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ndisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ndisc.c')
-rw-r--r--net/ipv6/ndisc.c237
1 files changed, 145 insertions, 92 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 452a2ac4eec8..2c74885f8355 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -84,13 +84,12 @@
84 84
85#include <net/flow.h> 85#include <net/flow.h>
86#include <net/ip6_checksum.h> 86#include <net/ip6_checksum.h>
87#include <net/inet_common.h>
87#include <linux/proc_fs.h> 88#include <linux/proc_fs.h>
88 89
89#include <linux/netfilter.h> 90#include <linux/netfilter.h>
90#include <linux/netfilter_ipv6.h> 91#include <linux/netfilter_ipv6.h>
91 92
92static struct socket *ndisc_socket;
93
94static u32 ndisc_hash(const void *pkey, const struct net_device *dev); 93static u32 ndisc_hash(const void *pkey, const struct net_device *dev);
95static int ndisc_constructor(struct neighbour *neigh); 94static int ndisc_constructor(struct neighbour *neigh);
96static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb); 95static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb);
@@ -270,7 +269,7 @@ static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
270 if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) { 269 if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
271 ND_PRINTK2(KERN_WARNING 270 ND_PRINTK2(KERN_WARNING
272 "%s(): duplicated ND6 option found: type=%d\n", 271 "%s(): duplicated ND6 option found: type=%d\n",
273 __FUNCTION__, 272 __func__,
274 nd_opt->nd_opt_type); 273 nd_opt->nd_opt_type);
275 } else { 274 } else {
276 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt; 275 ndopts->nd_opt_array[nd_opt->nd_opt_type] = nd_opt;
@@ -301,7 +300,7 @@ static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
301 */ 300 */
302 ND_PRINTK2(KERN_NOTICE 301 ND_PRINTK2(KERN_NOTICE
303 "%s(): ignored unsupported option; type=%d, len=%d\n", 302 "%s(): ignored unsupported option; type=%d, len=%d\n",
304 __FUNCTION__, 303 __func__,
305 nd_opt->nd_opt_type, nd_opt->nd_opt_len); 304 nd_opt->nd_opt_type, nd_opt->nd_opt_len);
306 } 305 }
307 } 306 }
@@ -441,30 +440,17 @@ static void pndisc_destructor(struct pneigh_entry *n)
441/* 440/*
442 * Send a Neighbour Advertisement 441 * Send a Neighbour Advertisement
443 */ 442 */
444
445static inline void ndisc_flow_init(struct flowi *fl, u8 type,
446 struct in6_addr *saddr, struct in6_addr *daddr,
447 int oif)
448{
449 memset(fl, 0, sizeof(*fl));
450 ipv6_addr_copy(&fl->fl6_src, saddr);
451 ipv6_addr_copy(&fl->fl6_dst, daddr);
452 fl->proto = IPPROTO_ICMPV6;
453 fl->fl_icmp_type = type;
454 fl->fl_icmp_code = 0;
455 fl->oif = oif;
456 security_sk_classify_flow(ndisc_socket->sk, fl);
457}
458
459static void __ndisc_send(struct net_device *dev, 443static void __ndisc_send(struct net_device *dev,
460 struct neighbour *neigh, 444 struct neighbour *neigh,
461 struct in6_addr *daddr, struct in6_addr *saddr, 445 const struct in6_addr *daddr,
462 struct icmp6hdr *icmp6h, struct in6_addr *target, 446 const struct in6_addr *saddr,
447 struct icmp6hdr *icmp6h, const struct in6_addr *target,
463 int llinfo) 448 int llinfo)
464{ 449{
465 struct flowi fl; 450 struct flowi fl;
466 struct dst_entry *dst; 451 struct dst_entry *dst;
467 struct sock *sk = ndisc_socket->sk; 452 struct net *net = dev_net(dev);
453 struct sock *sk = net->ipv6.ndisc_sk;
468 struct sk_buff *skb; 454 struct sk_buff *skb;
469 struct icmp6hdr *hdr; 455 struct icmp6hdr *hdr;
470 struct inet6_dev *idev; 456 struct inet6_dev *idev;
@@ -474,10 +460,9 @@ static void __ndisc_send(struct net_device *dev,
474 460
475 type = icmp6h->icmp6_type; 461 type = icmp6h->icmp6_type;
476 462
477 ndisc_flow_init(&fl, type, saddr, daddr, 463 icmpv6_flow_init(sk, &fl, type, saddr, daddr, dev->ifindex);
478 dev->ifindex);
479 464
480 dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output); 465 dst = icmp6_dst_alloc(dev, neigh, daddr);
481 if (!dst) 466 if (!dst)
482 return; 467 return;
483 468
@@ -499,7 +484,7 @@ static void __ndisc_send(struct net_device *dev,
499 if (!skb) { 484 if (!skb) {
500 ND_PRINTK0(KERN_ERR 485 ND_PRINTK0(KERN_ERR
501 "ICMPv6 ND: %s() failed to allocate an skb.\n", 486 "ICMPv6 ND: %s() failed to allocate an skb.\n",
502 __FUNCTION__); 487 __func__);
503 dst_release(dst); 488 dst_release(dst);
504 return; 489 return;
505 } 490 }
@@ -545,25 +530,28 @@ static void __ndisc_send(struct net_device *dev,
545} 530}
546 531
547static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, 532static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
548 struct in6_addr *daddr, struct in6_addr *solicited_addr, 533 const struct in6_addr *daddr,
549 int router, int solicited, int override, int inc_opt) 534 const struct in6_addr *solicited_addr,
535 int router, int solicited, int override, int inc_opt)
550{ 536{
551 struct in6_addr tmpaddr; 537 struct in6_addr tmpaddr;
552 struct inet6_ifaddr *ifp; 538 struct inet6_ifaddr *ifp;
553 struct in6_addr *src_addr; 539 const struct in6_addr *src_addr;
554 struct icmp6hdr icmp6h = { 540 struct icmp6hdr icmp6h = {
555 .icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT, 541 .icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT,
556 }; 542 };
557 543
558 /* for anycast or proxy, solicited_addr != src_addr */ 544 /* for anycast or proxy, solicited_addr != src_addr */
559 ifp = ipv6_get_ifaddr(&init_net, solicited_addr, dev, 1); 545 ifp = ipv6_get_ifaddr(dev_net(dev), solicited_addr, dev, 1);
560 if (ifp) { 546 if (ifp) {
561 src_addr = solicited_addr; 547 src_addr = solicited_addr;
562 if (ifp->flags & IFA_F_OPTIMISTIC) 548 if (ifp->flags & IFA_F_OPTIMISTIC)
563 override = 0; 549 override = 0;
564 in6_ifa_put(ifp); 550 in6_ifa_put(ifp);
565 } else { 551 } else {
566 if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr)) 552 if (ipv6_dev_get_saddr(dev, daddr,
553 inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs,
554 &tmpaddr))
567 return; 555 return;
568 src_addr = &tmpaddr; 556 src_addr = &tmpaddr;
569 } 557 }
@@ -578,8 +566,8 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
578} 566}
579 567
580void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh, 568void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
581 struct in6_addr *solicit, 569 const struct in6_addr *solicit,
582 struct in6_addr *daddr, struct in6_addr *saddr) 570 const struct in6_addr *daddr, const struct in6_addr *saddr)
583{ 571{
584 struct in6_addr addr_buf; 572 struct in6_addr addr_buf;
585 struct icmp6hdr icmp6h = { 573 struct icmp6hdr icmp6h = {
@@ -598,8 +586,8 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
598 !ipv6_addr_any(saddr) ? ND_OPT_SOURCE_LL_ADDR : 0); 586 !ipv6_addr_any(saddr) ? ND_OPT_SOURCE_LL_ADDR : 0);
599} 587}
600 588
601void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr, 589void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
602 struct in6_addr *daddr) 590 const struct in6_addr *daddr)
603{ 591{
604 struct icmp6hdr icmp6h = { 592 struct icmp6hdr icmp6h = {
605 .icmp6_type = NDISC_ROUTER_SOLICITATION, 593 .icmp6_type = NDISC_ROUTER_SOLICITATION,
@@ -616,7 +604,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
616 * suppress the inclusion of the sllao. 604 * suppress the inclusion of the sllao.
617 */ 605 */
618 if (send_sllao) { 606 if (send_sllao) {
619 struct inet6_ifaddr *ifp = ipv6_get_ifaddr(&init_net, saddr, 607 struct inet6_ifaddr *ifp = ipv6_get_ifaddr(dev_net(dev), saddr,
620 dev, 1); 608 dev, 1);
621 if (ifp) { 609 if (ifp) {
622 if (ifp->flags & IFA_F_OPTIMISTIC) { 610 if (ifp->flags & IFA_F_OPTIMISTIC) {
@@ -654,7 +642,7 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
654 struct in6_addr *target = (struct in6_addr *)&neigh->primary_key; 642 struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
655 int probes = atomic_read(&neigh->probes); 643 int probes = atomic_read(&neigh->probes);
656 644
657 if (skb && ipv6_chk_addr(&init_net, &ipv6_hdr(skb)->saddr, dev, 1)) 645 if (skb && ipv6_chk_addr(dev_net(dev), &ipv6_hdr(skb)->saddr, dev, 1))
658 saddr = &ipv6_hdr(skb)->saddr; 646 saddr = &ipv6_hdr(skb)->saddr;
659 647
660 if ((probes -= neigh->parms->ucast_probes) < 0) { 648 if ((probes -= neigh->parms->ucast_probes) < 0) {
@@ -662,7 +650,7 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
662 ND_PRINTK1(KERN_DEBUG 650 ND_PRINTK1(KERN_DEBUG
663 "%s(): trying to ucast probe in NUD_INVALID: " 651 "%s(): trying to ucast probe in NUD_INVALID: "
664 NIP6_FMT "\n", 652 NIP6_FMT "\n",
665 __FUNCTION__, 653 __func__,
666 NIP6(*target)); 654 NIP6(*target));
667 } 655 }
668 ndisc_send_ns(dev, neigh, target, target, saddr); 656 ndisc_send_ns(dev, neigh, target, target, saddr);
@@ -676,18 +664,19 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
676 } 664 }
677} 665}
678 666
679static struct pneigh_entry *pndisc_check_router(struct net_device *dev, 667static int pndisc_is_router(const void *pkey,
680 struct in6_addr *addr, int *is_router) 668 struct net_device *dev)
681{ 669{
682 struct pneigh_entry *n; 670 struct pneigh_entry *n;
671 int ret = -1;
683 672
684 read_lock_bh(&nd_tbl.lock); 673 read_lock_bh(&nd_tbl.lock);
685 n = __pneigh_lookup(&nd_tbl, &init_net, addr, dev); 674 n = __pneigh_lookup(&nd_tbl, dev_net(dev), pkey, dev);
686 if (n != NULL) 675 if (n)
687 *is_router = (n->flags & NTF_ROUTER); 676 ret = !!(n->flags & NTF_ROUTER);
688 read_unlock_bh(&nd_tbl.lock); 677 read_unlock_bh(&nd_tbl.lock);
689 678
690 return n; 679 return ret;
691} 680}
692 681
693static void ndisc_recv_ns(struct sk_buff *skb) 682static void ndisc_recv_ns(struct sk_buff *skb)
@@ -703,10 +692,9 @@ static void ndisc_recv_ns(struct sk_buff *skb)
703 struct inet6_ifaddr *ifp; 692 struct inet6_ifaddr *ifp;
704 struct inet6_dev *idev = NULL; 693 struct inet6_dev *idev = NULL;
705 struct neighbour *neigh; 694 struct neighbour *neigh;
706 struct pneigh_entry *pneigh = NULL;
707 int dad = ipv6_addr_any(saddr); 695 int dad = ipv6_addr_any(saddr);
708 int inc; 696 int inc;
709 int is_router = 0; 697 int is_router = -1;
710 698
711 if (ipv6_addr_is_multicast(&msg->target)) { 699 if (ipv6_addr_is_multicast(&msg->target)) {
712 ND_PRINTK2(KERN_WARNING 700 ND_PRINTK2(KERN_WARNING
@@ -756,7 +744,8 @@ static void ndisc_recv_ns(struct sk_buff *skb)
756 744
757 inc = ipv6_addr_is_multicast(daddr); 745 inc = ipv6_addr_is_multicast(daddr);
758 746
759 if ((ifp = ipv6_get_ifaddr(&init_net, &msg->target, dev, 1)) != NULL) { 747 ifp = ipv6_get_ifaddr(dev_net(dev), &msg->target, dev, 1);
748 if (ifp) {
760 749
761 if (ifp->flags & (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)) { 750 if (ifp->flags & (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)) {
762 if (dad) { 751 if (dad) {
@@ -801,11 +790,10 @@ static void ndisc_recv_ns(struct sk_buff *skb)
801 return; 790 return;
802 } 791 }
803 792
804 if (ipv6_chk_acast_addr(dev, &msg->target) || 793 if (ipv6_chk_acast_addr(dev_net(dev), dev, &msg->target) ||
805 (idev->cnf.forwarding && 794 (idev->cnf.forwarding &&
806 (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) && 795 (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) &&
807 (pneigh = pndisc_check_router(dev, &msg->target, 796 (is_router = pndisc_is_router(&msg->target, dev)) >= 0)) {
808 &is_router)) != NULL)) {
809 if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) && 797 if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
810 skb->pkt_type != PACKET_HOST && 798 skb->pkt_type != PACKET_HOST &&
811 inc != 0 && 799 inc != 0 &&
@@ -826,13 +814,11 @@ static void ndisc_recv_ns(struct sk_buff *skb)
826 goto out; 814 goto out;
827 } 815 }
828 816
829 is_router = !!(pneigh ? is_router : idev->cnf.forwarding); 817 if (is_router < 0)
818 is_router = !!idev->cnf.forwarding;
830 819
831 if (dad) { 820 if (dad) {
832 struct in6_addr maddr; 821 ndisc_send_na(dev, NULL, &in6addr_linklocal_allnodes, &msg->target,
833
834 ipv6_addr_all_nodes(&maddr);
835 ndisc_send_na(dev, NULL, &maddr, &msg->target,
836 is_router, 0, (ifp != NULL), 1); 822 is_router, 0, (ifp != NULL), 1);
837 goto out; 823 goto out;
838 } 824 }
@@ -914,7 +900,8 @@ static void ndisc_recv_na(struct sk_buff *skb)
914 return; 900 return;
915 } 901 }
916 } 902 }
917 if ((ifp = ipv6_get_ifaddr(&init_net, &msg->target, dev, 1))) { 903 ifp = ipv6_get_ifaddr(dev_net(dev), &msg->target, dev, 1);
904 if (ifp) {
918 if (ifp->flags & IFA_F_TENTATIVE) { 905 if (ifp->flags & IFA_F_TENTATIVE) {
919 addrconf_dad_failure(ifp); 906 addrconf_dad_failure(ifp);
920 return; 907 return;
@@ -945,7 +932,7 @@ static void ndisc_recv_na(struct sk_buff *skb)
945 */ 932 */
946 if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) && 933 if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
947 ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp && 934 ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp &&
948 pneigh_lookup(&nd_tbl, &init_net, &msg->target, dev, 0)) { 935 pneigh_lookup(&nd_tbl, dev_net(dev), &msg->target, dev, 0)) {
949 /* XXX: idev->cnf.prixy_ndp */ 936 /* XXX: idev->cnf.prixy_ndp */
950 goto out; 937 goto out;
951 } 938 }
@@ -1035,6 +1022,7 @@ static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt)
1035 struct sk_buff *skb; 1022 struct sk_buff *skb;
1036 struct nlmsghdr *nlh; 1023 struct nlmsghdr *nlh;
1037 struct nduseroptmsg *ndmsg; 1024 struct nduseroptmsg *ndmsg;
1025 struct net *net = dev_net(ra->dev);
1038 int err; 1026 int err;
1039 int base_size = NLMSG_ALIGN(sizeof(struct nduseroptmsg) 1027 int base_size = NLMSG_ALIGN(sizeof(struct nduseroptmsg)
1040 + (opt->nd_opt_len << 3)); 1028 + (opt->nd_opt_len << 3));
@@ -1064,7 +1052,7 @@ static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt)
1064 &ipv6_hdr(ra)->saddr); 1052 &ipv6_hdr(ra)->saddr);
1065 nlmsg_end(skb, nlh); 1053 nlmsg_end(skb, nlh);
1066 1054
1067 err = rtnl_notify(skb, &init_net, 0, RTNLGRP_ND_USEROPT, NULL, 1055 err = rtnl_notify(skb, net, 0, RTNLGRP_ND_USEROPT, NULL,
1068 GFP_ATOMIC); 1056 GFP_ATOMIC);
1069 if (err < 0) 1057 if (err < 0)
1070 goto errout; 1058 goto errout;
@@ -1075,7 +1063,7 @@ nla_put_failure:
1075 nlmsg_free(skb); 1063 nlmsg_free(skb);
1076 err = -EMSGSIZE; 1064 err = -EMSGSIZE;
1077errout: 1065errout:
1078 rtnl_set_sk_err(&init_net, RTNLGRP_ND_USEROPT, err); 1066 rtnl_set_sk_err(net, RTNLGRP_ND_USEROPT, err);
1079} 1067}
1080 1068
1081static void ndisc_router_discovery(struct sk_buff *skb) 1069static void ndisc_router_discovery(struct sk_buff *skb)
@@ -1104,6 +1092,14 @@ static void ndisc_router_discovery(struct sk_buff *skb)
1104 return; 1092 return;
1105 } 1093 }
1106 1094
1095#ifdef CONFIG_IPV6_NDISC_NODETYPE
1096 if (skb->ndisc_nodetype == NDISC_NODETYPE_HOST) {
1097 ND_PRINTK2(KERN_WARNING
1098 "ICMPv6 RA: from host or unauthorized router\n");
1099 return;
1100 }
1101#endif
1102
1107 /* 1103 /*
1108 * set the RA_RECV flag in the interface 1104 * set the RA_RECV flag in the interface
1109 */ 1105 */
@@ -1127,6 +1123,12 @@ static void ndisc_router_discovery(struct sk_buff *skb)
1127 return; 1123 return;
1128 } 1124 }
1129 1125
1126#ifdef CONFIG_IPV6_NDISC_NODETYPE
1127 /* skip link-specific parameters from interior routers */
1128 if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT)
1129 goto skip_linkparms;
1130#endif
1131
1130 if (in6_dev->if_flags & IF_RS_SENT) { 1132 if (in6_dev->if_flags & IF_RS_SENT) {
1131 /* 1133 /*
1132 * flag that an RA was received after an RS was sent 1134 * flag that an RA was received after an RS was sent
@@ -1178,7 +1180,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
1178 if (rt == NULL) { 1180 if (rt == NULL) {
1179 ND_PRINTK0(KERN_ERR 1181 ND_PRINTK0(KERN_ERR
1180 "ICMPv6 RA: %s() failed to add default route.\n", 1182 "ICMPv6 RA: %s() failed to add default route.\n",
1181 __FUNCTION__); 1183 __func__);
1182 in6_dev_put(in6_dev); 1184 in6_dev_put(in6_dev);
1183 return; 1185 return;
1184 } 1186 }
@@ -1187,7 +1189,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
1187 if (neigh == NULL) { 1189 if (neigh == NULL) {
1188 ND_PRINTK0(KERN_ERR 1190 ND_PRINTK0(KERN_ERR
1189 "ICMPv6 RA: %s() got default router without neighbour.\n", 1191 "ICMPv6 RA: %s() got default router without neighbour.\n",
1190 __FUNCTION__); 1192 __func__);
1191 dst_release(&rt->u.dst); 1193 dst_release(&rt->u.dst);
1192 in6_dev_put(in6_dev); 1194 in6_dev_put(in6_dev);
1193 return; 1195 return;
@@ -1241,6 +1243,10 @@ skip_defrtr:
1241 } 1243 }
1242 } 1244 }
1243 1245
1246#ifdef CONFIG_IPV6_NDISC_NODETYPE
1247skip_linkparms:
1248#endif
1249
1244 /* 1250 /*
1245 * Process options. 1251 * Process options.
1246 */ 1252 */
@@ -1272,7 +1278,13 @@ skip_defrtr:
1272 for (p = ndopts.nd_opts_ri; 1278 for (p = ndopts.nd_opts_ri;
1273 p; 1279 p;
1274 p = ndisc_next_option(p, ndopts.nd_opts_ri_end)) { 1280 p = ndisc_next_option(p, ndopts.nd_opts_ri_end)) {
1275 if (((struct route_info *)p)->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen) 1281 struct route_info *ri = (struct route_info *)p;
1282#ifdef CONFIG_IPV6_NDISC_NODETYPE
1283 if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT &&
1284 ri->prefix_len == 0)
1285 continue;
1286#endif
1287 if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen)
1276 continue; 1288 continue;
1277 rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3, 1289 rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3,
1278 &ipv6_hdr(skb)->saddr); 1290 &ipv6_hdr(skb)->saddr);
@@ -1280,6 +1292,12 @@ skip_defrtr:
1280 } 1292 }
1281#endif 1293#endif
1282 1294
1295#ifdef CONFIG_IPV6_NDISC_NODETYPE
1296 /* skip link-specific ndopts from interior routers */
1297 if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT)
1298 goto out;
1299#endif
1300
1283 if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) { 1301 if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) {
1284 struct nd_opt_hdr *p; 1302 struct nd_opt_hdr *p;
1285 for (p = ndopts.nd_opts_pi; 1303 for (p = ndopts.nd_opts_pi;
@@ -1343,6 +1361,16 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
1343 int optlen; 1361 int optlen;
1344 u8 *lladdr = NULL; 1362 u8 *lladdr = NULL;
1345 1363
1364#ifdef CONFIG_IPV6_NDISC_NODETYPE
1365 switch (skb->ndisc_nodetype) {
1366 case NDISC_NODETYPE_HOST:
1367 case NDISC_NODETYPE_NODEFAULT:
1368 ND_PRINTK2(KERN_WARNING
1369 "ICMPv6 Redirect: from host or unauthorized router\n");
1370 return;
1371 }
1372#endif
1373
1346 if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) { 1374 if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {
1347 ND_PRINTK2(KERN_WARNING 1375 ND_PRINTK2(KERN_WARNING
1348 "ICMPv6 Redirect: source address is not link-local.\n"); 1376 "ICMPv6 Redirect: source address is not link-local.\n");
@@ -1418,15 +1446,16 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
1418} 1446}
1419 1447
1420void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, 1448void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1421 struct in6_addr *target) 1449 const struct in6_addr *target)
1422{ 1450{
1423 struct sock *sk = ndisc_socket->sk; 1451 struct net_device *dev = skb->dev;
1452 struct net *net = dev_net(dev);
1453 struct sock *sk = net->ipv6.ndisc_sk;
1424 int len = sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr); 1454 int len = sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
1425 struct sk_buff *buff; 1455 struct sk_buff *buff;
1426 struct icmp6hdr *icmph; 1456 struct icmp6hdr *icmph;
1427 struct in6_addr saddr_buf; 1457 struct in6_addr saddr_buf;
1428 struct in6_addr *addrp; 1458 struct in6_addr *addrp;
1429 struct net_device *dev;
1430 struct rt6_info *rt; 1459 struct rt6_info *rt;
1431 struct dst_entry *dst; 1460 struct dst_entry *dst;
1432 struct inet6_dev *idev; 1461 struct inet6_dev *idev;
@@ -1436,8 +1465,6 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1436 int err; 1465 int err;
1437 u8 ha_buf[MAX_ADDR_LEN], *ha = NULL; 1466 u8 ha_buf[MAX_ADDR_LEN], *ha = NULL;
1438 1467
1439 dev = skb->dev;
1440
1441 if (ipv6_get_lladdr(dev, &saddr_buf, IFA_F_TENTATIVE)) { 1468 if (ipv6_get_lladdr(dev, &saddr_buf, IFA_F_TENTATIVE)) {
1442 ND_PRINTK2(KERN_WARNING 1469 ND_PRINTK2(KERN_WARNING
1443 "ICMPv6 Redirect: no link-local address on %s\n", 1470 "ICMPv6 Redirect: no link-local address on %s\n",
@@ -1452,10 +1479,10 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1452 return; 1479 return;
1453 } 1480 }
1454 1481
1455 ndisc_flow_init(&fl, NDISC_REDIRECT, &saddr_buf, &ipv6_hdr(skb)->saddr, 1482 icmpv6_flow_init(sk, &fl, NDISC_REDIRECT,
1456 dev->ifindex); 1483 &saddr_buf, &ipv6_hdr(skb)->saddr, dev->ifindex);
1457 1484
1458 dst = ip6_route_output(NULL, &fl); 1485 dst = ip6_route_output(net, NULL, &fl);
1459 if (dst == NULL) 1486 if (dst == NULL)
1460 return; 1487 return;
1461 1488
@@ -1499,12 +1526,11 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1499 if (buff == NULL) { 1526 if (buff == NULL) {
1500 ND_PRINTK0(KERN_ERR 1527 ND_PRINTK0(KERN_ERR
1501 "ICMPv6 Redirect: %s() failed to allocate an skb.\n", 1528 "ICMPv6 Redirect: %s() failed to allocate an skb.\n",
1502 __FUNCTION__); 1529 __func__);
1503 dst_release(dst); 1530 dst_release(dst);
1504 return; 1531 return;
1505 } 1532 }
1506 1533
1507
1508 skb_reserve(buff, LL_RESERVED_SPACE(dev)); 1534 skb_reserve(buff, LL_RESERVED_SPACE(dev));
1509 ip6_nd_hdr(sk, buff, dev, &saddr_buf, &ipv6_hdr(skb)->saddr, 1535 ip6_nd_hdr(sk, buff, dev, &saddr_buf, &ipv6_hdr(skb)->saddr,
1510 IPPROTO_ICMPV6, len); 1536 IPPROTO_ICMPV6, len);
@@ -1625,18 +1651,16 @@ int ndisc_rcv(struct sk_buff *skb)
1625static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr) 1651static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
1626{ 1652{
1627 struct net_device *dev = ptr; 1653 struct net_device *dev = ptr;
1628 1654 struct net *net = dev_net(dev);
1629 if (dev->nd_net != &init_net)
1630 return NOTIFY_DONE;
1631 1655
1632 switch (event) { 1656 switch (event) {
1633 case NETDEV_CHANGEADDR: 1657 case NETDEV_CHANGEADDR:
1634 neigh_changeaddr(&nd_tbl, dev); 1658 neigh_changeaddr(&nd_tbl, dev);
1635 fib6_run_gc(~0UL); 1659 fib6_run_gc(~0UL, net);
1636 break; 1660 break;
1637 case NETDEV_DOWN: 1661 case NETDEV_DOWN:
1638 neigh_ifdown(&nd_tbl, dev); 1662 neigh_ifdown(&nd_tbl, dev);
1639 fib6_run_gc(~0UL); 1663 fib6_run_gc(~0UL, net);
1640 break; 1664 break;
1641 default: 1665 default:
1642 break; 1666 break;
@@ -1745,44 +1769,74 @@ static int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name,
1745 1769
1746#endif 1770#endif
1747 1771
1748int __init ndisc_init(struct net_proto_family *ops) 1772static int ndisc_net_init(struct net *net)
1749{ 1773{
1750 struct ipv6_pinfo *np; 1774 struct ipv6_pinfo *np;
1751 struct sock *sk; 1775 struct sock *sk;
1752 int err; 1776 int err;
1753 1777
1754 err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &ndisc_socket); 1778 err = inet_ctl_sock_create(&sk, PF_INET6,
1779 SOCK_RAW, IPPROTO_ICMPV6, net);
1755 if (err < 0) { 1780 if (err < 0) {
1756 ND_PRINTK0(KERN_ERR 1781 ND_PRINTK0(KERN_ERR
1757 "ICMPv6 NDISC: Failed to initialize the control socket (err %d).\n", 1782 "ICMPv6 NDISC: Failed to initialize the control socket (err %d).\n",
1758 err); 1783 err);
1759 ndisc_socket = NULL; /* For safety. */
1760 return err; 1784 return err;
1761 } 1785 }
1762 1786
1763 sk = ndisc_socket->sk; 1787 net->ipv6.ndisc_sk = sk;
1788
1764 np = inet6_sk(sk); 1789 np = inet6_sk(sk);
1765 sk->sk_allocation = GFP_ATOMIC;
1766 np->hop_limit = 255; 1790 np->hop_limit = 255;
1767 /* Do not loopback ndisc messages */ 1791 /* Do not loopback ndisc messages */
1768 np->mc_loop = 0; 1792 np->mc_loop = 0;
1769 sk->sk_prot->unhash(sk);
1770 1793
1794 return 0;
1795}
1796
1797static void ndisc_net_exit(struct net *net)
1798{
1799 inet_ctl_sock_destroy(net->ipv6.ndisc_sk);
1800}
1801
1802static struct pernet_operations ndisc_net_ops = {
1803 .init = ndisc_net_init,
1804 .exit = ndisc_net_exit,
1805};
1806
1807int __init ndisc_init(void)
1808{
1809 int err;
1810
1811 err = register_pernet_subsys(&ndisc_net_ops);
1812 if (err)
1813 return err;
1771 /* 1814 /*
1772 * Initialize the neighbour table 1815 * Initialize the neighbour table
1773 */ 1816 */
1774
1775 neigh_table_init(&nd_tbl); 1817 neigh_table_init(&nd_tbl);
1776 1818
1777#ifdef CONFIG_SYSCTL 1819#ifdef CONFIG_SYSCTL
1778 neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, NET_IPV6_NEIGH, 1820 err = neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6,
1779 "ipv6", 1821 NET_IPV6_NEIGH, "ipv6",
1780 &ndisc_ifinfo_sysctl_change, 1822 &ndisc_ifinfo_sysctl_change,
1781 &ndisc_ifinfo_sysctl_strategy); 1823 &ndisc_ifinfo_sysctl_strategy);
1824 if (err)
1825 goto out_unregister_pernet;
1782#endif 1826#endif
1827 err = register_netdevice_notifier(&ndisc_netdev_notifier);
1828 if (err)
1829 goto out_unregister_sysctl;
1830out:
1831 return err;
1783 1832
1784 register_netdevice_notifier(&ndisc_netdev_notifier); 1833out_unregister_sysctl:
1785 return 0; 1834#ifdef CONFIG_SYSCTL
1835 neigh_sysctl_unregister(&nd_tbl.parms);
1836out_unregister_pernet:
1837#endif
1838 unregister_pernet_subsys(&ndisc_net_ops);
1839 goto out;
1786} 1840}
1787 1841
1788void ndisc_cleanup(void) 1842void ndisc_cleanup(void)
@@ -1792,6 +1846,5 @@ void ndisc_cleanup(void)
1792 neigh_sysctl_unregister(&nd_tbl.parms); 1846 neigh_sysctl_unregister(&nd_tbl.parms);
1793#endif 1847#endif
1794 neigh_table_clear(&nd_tbl); 1848 neigh_table_clear(&nd_tbl);
1795 sock_release(ndisc_socket); 1849 unregister_pernet_subsys(&ndisc_net_ops);
1796 ndisc_socket = NULL; /* For safety. */
1797} 1850}