aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/networking/ip-sysctl.txt3
-rw-r--r--include/linux/ipv6.h2
-rw-r--r--include/linux/sysctl.h1
-rw-r--r--net/ipv6/addrconf.c11
-rw-r--r--net/ipv6/ip6_output.c4
-rw-r--r--net/ipv6/ndisc.c8
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
768proxy_ndp - BOOLEAN
769 Do proxy ndp.
770
768conf/interface/*: 771conf/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
180static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { 181static 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,