diff options
-rw-r--r-- | Documentation/networking/ip-sysctl.txt | 3 | ||||
-rw-r--r-- | include/linux/ipv6.h | 2 | ||||
-rw-r--r-- | include/linux/sysctl.h | 1 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 11 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 4 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 8 |
6 files changed, 27 insertions, 2 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 307cd4ec8edd..935e298f674a 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
@@ -765,6 +765,9 @@ conf/all/forwarding - BOOLEAN | |||
765 | 765 | ||
766 | This referred to as global forwarding. | 766 | This referred to as global forwarding. |
767 | 767 | ||
768 | proxy_ndp - BOOLEAN | ||
769 | Do proxy ndp. | ||
770 | |||
768 | conf/interface/*: | 771 | conf/interface/*: |
769 | Change special settings per interface. | 772 | Change special settings per interface. |
770 | 773 | ||
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 1d6d3ccc9413..caca57df0d7d 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h | |||
@@ -176,6 +176,7 @@ struct ipv6_devconf { | |||
176 | __s32 accept_ra_rt_info_max_plen; | 176 | __s32 accept_ra_rt_info_max_plen; |
177 | #endif | 177 | #endif |
178 | #endif | 178 | #endif |
179 | __s32 proxy_ndp; | ||
179 | void *sysctl; | 180 | void *sysctl; |
180 | }; | 181 | }; |
181 | 182 | ||
@@ -203,6 +204,7 @@ enum { | |||
203 | DEVCONF_ACCEPT_RA_RTR_PREF, | 204 | DEVCONF_ACCEPT_RA_RTR_PREF, |
204 | DEVCONF_RTR_PROBE_INTERVAL, | 205 | DEVCONF_RTR_PROBE_INTERVAL, |
205 | DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, | 206 | DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, |
207 | DEVCONF_PROXY_NDP, | ||
206 | DEVCONF_MAX | 208 | DEVCONF_MAX |
207 | }; | 209 | }; |
208 | 210 | ||
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index af61d9235409..736ed917a4f8 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h | |||
@@ -556,6 +556,7 @@ enum { | |||
556 | NET_IPV6_ACCEPT_RA_RTR_PREF=20, | 556 | NET_IPV6_ACCEPT_RA_RTR_PREF=20, |
557 | NET_IPV6_RTR_PROBE_INTERVAL=21, | 557 | NET_IPV6_RTR_PROBE_INTERVAL=21, |
558 | NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, | 558 | NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, |
559 | NET_IPV6_PROXY_NDP=23, | ||
559 | __NET_IPV6_MAX | 560 | __NET_IPV6_MAX |
560 | }; | 561 | }; |
561 | 562 | ||
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 1e5a296d0a82..825a291d5aa5 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -175,6 +175,7 @@ struct ipv6_devconf ipv6_devconf __read_mostly = { | |||
175 | .accept_ra_rt_info_max_plen = 0, | 175 | .accept_ra_rt_info_max_plen = 0, |
176 | #endif | 176 | #endif |
177 | #endif | 177 | #endif |
178 | .proxy_ndp = 0, | ||
178 | }; | 179 | }; |
179 | 180 | ||
180 | static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { | 181 | static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { |
@@ -205,6 +206,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { | |||
205 | .accept_ra_rt_info_max_plen = 0, | 206 | .accept_ra_rt_info_max_plen = 0, |
206 | #endif | 207 | #endif |
207 | #endif | 208 | #endif |
209 | .proxy_ndp = 0, | ||
208 | }; | 210 | }; |
209 | 211 | ||
210 | /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ | 212 | /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ |
@@ -3337,6 +3339,7 @@ static void inline ipv6_store_devconf(struct ipv6_devconf *cnf, | |||
3337 | array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen; | 3339 | array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen; |
3338 | #endif | 3340 | #endif |
3339 | #endif | 3341 | #endif |
3342 | array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp; | ||
3340 | } | 3343 | } |
3341 | 3344 | ||
3342 | /* Maximum length of ifinfomsg attributes */ | 3345 | /* Maximum length of ifinfomsg attributes */ |
@@ -3860,6 +3863,14 @@ static struct addrconf_sysctl_table | |||
3860 | #endif | 3863 | #endif |
3861 | #endif | 3864 | #endif |
3862 | { | 3865 | { |
3866 | .ctl_name = NET_IPV6_PROXY_NDP, | ||
3867 | .procname = "proxy_ndp", | ||
3868 | .data = &ipv6_devconf.proxy_ndp, | ||
3869 | .maxlen = sizeof(int), | ||
3870 | .mode = 0644, | ||
3871 | .proc_handler = &proc_dointvec, | ||
3872 | }, | ||
3873 | { | ||
3863 | .ctl_name = 0, /* sentinel */ | 3874 | .ctl_name = 0, /* sentinel */ |
3864 | } | 3875 | } |
3865 | }, | 3876 | }, |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index b2be749d2217..66716911962e 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -412,7 +412,9 @@ int ip6_forward(struct sk_buff *skb) | |||
412 | return -ETIMEDOUT; | 412 | return -ETIMEDOUT; |
413 | } | 413 | } |
414 | 414 | ||
415 | if (pneigh_lookup(&nd_tbl, &hdr->daddr, skb->dev, 0)) { | 415 | /* XXX: idev->cnf.proxy_ndp? */ |
416 | if (ipv6_devconf.proxy_ndp && | ||
417 | pneigh_lookup(&nd_tbl, &hdr->daddr, skb->dev, 0)) { | ||
416 | int proxied = ip6_forward_proxy_check(skb); | 418 | int proxied = ip6_forward_proxy_check(skb); |
417 | if (proxied > 0) | 419 | if (proxied > 0) |
418 | return ip6_input(skb); | 420 | return ip6_input(skb); |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index ddf038636f01..76517a5f6576 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -824,6 +824,7 @@ static void ndisc_recv_ns(struct sk_buff *skb) | |||
824 | 824 | ||
825 | if (ipv6_chk_acast_addr(dev, &msg->target) || | 825 | if (ipv6_chk_acast_addr(dev, &msg->target) || |
826 | (idev->cnf.forwarding && | 826 | (idev->cnf.forwarding && |
827 | (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) && | ||
827 | (pneigh = pneigh_lookup(&nd_tbl, | 828 | (pneigh = pneigh_lookup(&nd_tbl, |
828 | &msg->target, dev, 0)) != NULL)) { | 829 | &msg->target, dev, 0)) != NULL)) { |
829 | if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) && | 830 | if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) && |
@@ -966,8 +967,13 @@ static void ndisc_recv_na(struct sk_buff *skb) | |||
966 | * has already sent a NA to us. | 967 | * has already sent a NA to us. |
967 | */ | 968 | */ |
968 | if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) && | 969 | if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) && |
969 | pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) | 970 | ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp && |
971 | pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) { | ||
972 | /* XXX: idev->cnf.prixy_ndp */ | ||
973 | WARN_ON(skb->dst != NULL && | ||
974 | ((struct rt6_info *)skb->dst)->rt6i_idev); | ||
970 | goto out; | 975 | goto out; |
976 | } | ||
971 | 977 | ||
972 | neigh_update(neigh, lladdr, | 978 | neigh_update(neigh, lladdr, |
973 | msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE, | 979 | msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE, |