]> git.neil.brown.name Git - history.git/commitdiff
Add new sysctl, medium_id, to devinet.
authorAlexey Kuznetsov <kuznet@ms2.inr.ac.ru>
Tue, 19 Mar 2002 12:22:04 +0000 (04:22 -0800)
committerDavid S. Miller <davem@nuts.ninka.net>
Tue, 19 Mar 2002 12:22:04 +0000 (04:22 -0800)
It is used to differentiate the devices by the medium
they are attached to.  It is used to change proxy_arp behavior:
the proxy arp feature is enabled for packets forwarded between
two devices attached to different media.

Documentation/networking/ip-sysctl.txt
include/linux/inetdevice.h
include/linux/sysctl.h
net/ipv4/arp.c
net/ipv4/devinet.c

index 2cc812d00611d4cc249c177b8481192273017b6d..bcaf30b2b5aea2b922c7e4a6d53f03e63e0ae01c 100644 (file)
@@ -355,6 +355,17 @@ mc_forwarding - BOOLEAN
        Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE
        and a multicast routing daemon is required.
 
+medium_id - INTEGER
+       Integer value used to differentiate the devices by the medium they
+       are attached to. Two devices can have different id values when
+       the broadcast packets are received only on one of them.
+       The default value 0 means that the device is the only interface
+       to its medium, value of -1 means that medium is not known.
+       
+       Currently, it is used to change the proxy_arp behavior:
+       the proxy_arp feature is enabled for packets forwarded between
+       two devices attached to different media.
+
 proxy_arp - BOOLEAN
        Do proxy arp.
 
index 47ee810f813c39ed72c2335cec9dfa9c07dc6c5c..ddd8e23c1ca5f6983cf9039c32358122b65890d9 100644 (file)
@@ -18,6 +18,7 @@ struct ipv4_devconf
        int     mc_forwarding;
        int     tag;
        int     arp_filter;
+       int     medium_id;
        void    *sysctl;
 };
 
@@ -48,6 +49,7 @@ struct in_device
 #define IN_DEV_TX_REDIRECTS(in_dev)    (ipv4_devconf.send_redirects || (in_dev)->cnf.send_redirects)
 #define IN_DEV_SEC_REDIRECTS(in_dev)   (ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects)
 #define IN_DEV_IDTAG(in_dev)           ((in_dev)->cnf.tag)
+#define IN_DEV_MEDIUM_ID(in_dev)       ((in_dev)->cnf.medium_id)
 
 #define IN_DEV_RX_REDIRECTS(in_dev) \
        ((IN_DEV_FORWARD(in_dev) && \
index 01829afb8e41bf9bc32495eaf8a12f225753a0ff..40ac6bbf359d21895fa49d03c6353f68cef3bce7 100644 (file)
@@ -333,7 +333,8 @@ enum
        NET_IPV4_CONF_BOOTP_RELAY=10,
        NET_IPV4_CONF_LOG_MARTIANS=11,
        NET_IPV4_CONF_TAG=12,
-       NET_IPV4_CONF_ARPFILTER=13
+       NET_IPV4_CONF_ARPFILTER=13,
+       NET_IPV4_CONF_MEDIUM_ID=14,
 };
 
 /* /proc/sys/net/ipv6 */
index 9e6a18144cbfb49b58725228a1c8995a88b33bc9..dd26ec77a82fd3158db52261184cb322c8355ea1 100644 (file)
@@ -449,6 +449,32 @@ int arp_bind_neighbour(struct dst_entry *dst)
        return 0;
 }
 
+/*
+ * Check if we can use proxy ARP for this path
+ */
+
+static inline int arp_fwd_proxy(struct in_device *in_dev, struct rtable *rt)
+{
+       struct in_device *out_dev;
+       int imi, omi = -1;
+
+       if (!IN_DEV_PROXY_ARP(in_dev))
+               return 0;
+
+       if ((imi = IN_DEV_MEDIUM_ID(in_dev)) == 0)
+               return 1;
+       if (imi == -1)
+               return 0;
+
+       /* place to check for proxy_arp for routes */
+
+       if ((out_dev = in_dev_get(rt->u.dst.dev)) != NULL) {
+               omi = IN_DEV_MEDIUM_ID(out_dev);
+               in_dev_put(out_dev);
+       }
+       return (omi != imi && omi != -1);
+}
+
 /*
  *     Interface to link layer: send routine and receive handler.
  */
@@ -755,7 +781,7 @@ int arp_process(struct sk_buff *skb)
                } else if (IN_DEV_FORWARD(in_dev)) {
                        if ((rt->rt_flags&RTCF_DNAT) ||
                            (addr_type == RTN_UNICAST  && rt->u.dst.dev != dev &&
-                            (IN_DEV_PROXY_ARP(in_dev) || pneigh_lookup(&arp_tbl, &tip, dev, 0)))) {
+                            (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, &tip, dev, 0)))) {
                                n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
                                if (n)
                                        neigh_release(n);
index 8acc73398857e48a4b266d509dcc4d7fa1db84fe..80d1031f0a72120dbca0c9cb2a49a3a2ac44efe6 100644 (file)
@@ -1032,7 +1032,7 @@ int devinet_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
 static struct devinet_sysctl_table
 {
        struct ctl_table_header *sysctl_header;
-       ctl_table devinet_vars[14];
+       ctl_table devinet_vars[15];
        ctl_table devinet_dev[2];
        ctl_table devinet_conf_dir[2];
        ctl_table devinet_proto_dir[2];
@@ -1066,6 +1066,9 @@ static struct devinet_sysctl_table
        {NET_IPV4_CONF_PROXY_ARP, "proxy_arp",
          &ipv4_devconf.proxy_arp, sizeof(int), 0644, NULL,
          &proc_dointvec},
+       {NET_IPV4_CONF_MEDIUM_ID, "medium_id",
+         &ipv4_devconf.medium_id, sizeof(int), 0644, NULL,
+         &proc_dointvec},
        {NET_IPV4_CONF_BOOTP_RELAY, "bootp_relay",
          &ipv4_devconf.bootp_relay, sizeof(int), 0644, NULL,
          &proc_dointvec},