[IPV6] NDISC: Add proxy_ndp sysctl.
YOSHIFUJI Hideaki [Fri, 22 Sep 2006 21:43:49 +0000 (14:43 -0700)]
We do not always need proxy NDP functionality even we
enable forwarding.

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

Documentation/networking/ip-sysctl.txt
include/linux/ipv6.h
include/linux/sysctl.h
net/ipv6/addrconf.c
net/ipv6/ip6_output.c
net/ipv6/ndisc.c

index 307cd4e..935e298 100644 (file)
@@ -765,6 +765,9 @@ conf/all/forwarding - BOOLEAN
 
        This referred to as global forwarding.
 
+proxy_ndp - BOOLEAN
+       Do proxy ndp.
+
 conf/interface/*:
        Change special settings per interface.
 
index 1d6d3cc..caca57d 100644 (file)
@@ -176,6 +176,7 @@ struct ipv6_devconf {
        __s32           accept_ra_rt_info_max_plen;
 #endif
 #endif
+       __s32           proxy_ndp;
        void            *sysctl;
 };
 
@@ -203,6 +204,7 @@ enum {
        DEVCONF_ACCEPT_RA_RTR_PREF,
        DEVCONF_RTR_PROBE_INTERVAL,
        DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN,
+       DEVCONF_PROXY_NDP,
        DEVCONF_MAX
 };
 
index af61d92..736ed91 100644 (file)
@@ -556,6 +556,7 @@ enum {
        NET_IPV6_ACCEPT_RA_RTR_PREF=20,
        NET_IPV6_RTR_PROBE_INTERVAL=21,
        NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22,
+       NET_IPV6_PROXY_NDP=23,
        __NET_IPV6_MAX
 };
 
index 1e5a296..825a291 100644 (file)
@@ -175,6 +175,7 @@ struct ipv6_devconf ipv6_devconf __read_mostly = {
        .accept_ra_rt_info_max_plen = 0,
 #endif
 #endif
+       .proxy_ndp              = 0,
 };
 
 static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
@@ -205,6 +206,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
        .accept_ra_rt_info_max_plen = 0,
 #endif
 #endif
+       .proxy_ndp              = 0,
 };
 
 /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
@@ -3337,6 +3339,7 @@ static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
        array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen;
 #endif
 #endif
+       array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp;
 }
 
 /* Maximum length of ifinfomsg attributes */
@@ -3860,6 +3863,14 @@ static struct addrconf_sysctl_table
 #endif
 #endif
                {
+                       .ctl_name       =       NET_IPV6_PROXY_NDP,
+                       .procname       =       "proxy_ndp",
+                       .data           =       &ipv6_devconf.proxy_ndp,
+                       .maxlen         =       sizeof(int),
+                       .mode           =       0644,
+                       .proc_handler   =       &proc_dointvec,
+               },
+               {
                        .ctl_name       =       0,      /* sentinel */
                }
        },
index b2be749..6671691 100644 (file)
@@ -412,7 +412,9 @@ int ip6_forward(struct sk_buff *skb)
                return -ETIMEDOUT;
        }
 
-       if (pneigh_lookup(&nd_tbl, &hdr->daddr, skb->dev, 0)) {
+       /* XXX: idev->cnf.proxy_ndp? */
+       if (ipv6_devconf.proxy_ndp &&
+           pneigh_lookup(&nd_tbl, &hdr->daddr, skb->dev, 0)) {
                int proxied = ip6_forward_proxy_check(skb);
                if (proxied > 0)
                        return ip6_input(skb);
index ddf0386..76517a5 100644 (file)
@@ -824,6 +824,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
 
                if (ipv6_chk_acast_addr(dev, &msg->target) ||
                    (idev->cnf.forwarding && 
+                    (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) &&
                     (pneigh = pneigh_lookup(&nd_tbl,
                                             &msg->target, dev, 0)) != NULL)) {
                        if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
@@ -966,8 +967,13 @@ static void ndisc_recv_na(struct sk_buff *skb)
                 * has already sent a NA to us.
                 */
                if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
-                   pneigh_lookup(&nd_tbl, &msg->target, dev, 0))
+                   ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp &&
+                   pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) {
+                       /* XXX: idev->cnf.prixy_ndp */
+                       WARN_ON(skb->dst != NULL &&
+                               ((struct rt6_info *)skb->dst)->rt6i_idev);
                        goto out;
+               }
 
                neigh_update(neigh, lladdr,
                             msg->icmph.icmp6_solicited ? NUD_REACHABLE : NUD_STALE,