The attached patch (against 2.4.4-ac10) adds the
/proc/sys/net/ipv4/conf/*/hidden option which is present in 2.2.x series.
This is somewhat similar to the arp-filter functionality which was added in
~2.4.4-ac10.  The difference is that this is not dependent upon the routing
table, it is simply configured using proc fs.

This is particularly useful in load-balanced server farms where loopback
addresses are configured for direct client-server traffic.  Without this
patch, Linux will respond to arp requests for the virtual IPs, making
effective load balancing difficult.

-Phil Oester


diff -r -u -x *~ -x *.rej
linux-2.4.4-ac10/Documentation/filesystems/proc.txt
linux-2.4.4-ac10-hidden/Documentation/filesystems/proc.txt
--- linux-2.4.4-ac10/Documentation/filesystems/proc.txt Fri Apr  6 13:42:48
2001
+++ linux-2.4.4-ac10-hidden/Documentation/filesystems/proc.txt  Thu May 17
15:01:45 2001
@@ -1578,6 +1578,17 @@

 Determines whether to send ICMP redirects to other hosts.

+hidden
+------
+
+Hide addresses attached to this device from other devices.
+Such addresses will never be selected by source address autoselection
+mechanism.  Also, host will not answer broadcast ARP requests for them and
+will not announce it as source address of ARP requests.  The addresses are,
+however, still reachable via IP.  This is primarily useful in
load-balancing
+environments.  This flag is activated only if it is enabled both in
specific
+device section and in "all" section.
+
 Routing settings
 ----------------

diff -r -u -x *~ -x *.rej
linux-2.4.4-ac10/Documentation/networking/ip-sysctl.txt
linux-2.4.4-ac10-hidden/Documentation/networking/ip-sysctl.txt
--- linux-2.4.4-ac10/Documentation/networking/ip-sysctl.txt     Thu May 17
14:53:02 2001
+++ linux-2.4.4-ac10-hidden/Documentation/networking/ip-sysctl.txt      Thu May
17 15:02:47 2001
@@ -392,6 +392,15 @@
        Default value is 0. Note that some distributions enable it
        in startip scripts.

+hidden - BOOLEAN
+       Hide addresses attached to this device from other devices.
+       Such addresses will never be selected by source address autoselection
+       mechanism.  Also, host will not answer broadcast ARP requests for them and
+       will not announce it as source address of ARP requests.  The addresses
are,
+       however, still reachable via IP.  This is primarily useful in
load-balancing
+       environments.  This flag is activated only if it is enabled both in
specific
+       device section and in "all" section.
+
 Alexey Kuznetsov.
 [EMAIL PROTECTED]

diff -r -u -x *~ -x *.rej linux-2.4.4-ac10/include/linux/inetdevice.h
linux-2.4.4-ac10-hidden/include/linux/inetdevice.h
--- linux-2.4.4-ac10/include/linux/inetdevice.h Thu May 17 14:53:07 2001
+++ linux-2.4.4-ac10-hidden/include/linux/inetdevice.h  Thu May 17 14:30:25
2001
@@ -18,6 +18,7 @@
        int     mc_forwarding;
        int     tag;
        int     arp_filter;
+       int     hidden;
        void    *sysctl;
 };

@@ -44,6 +45,7 @@

 #define IN_DEV_LOG_MARTIANS(in_dev)    (ipv4_devconf.log_martians ||
(in_dev)->cnf.log_martians)
 #define IN_DEV_PROXY_ARP(in_dev)       (ipv4_devconf.proxy_arp ||
(in_dev)->cnf.proxy_arp)
+#define IN_DEV_HIDDEN(in_dev)          ((in_dev)->cnf.hidden &&
ipv4_devconf.hidden)
 #define IN_DEV_SHARED_MEDIA(in_dev)    (ipv4_devconf.shared_media ||
(in_dev)->cnf.shared_media)
 #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)
diff -r -u -x *~ -x *.rej linux-2.4.4-ac10/include/linux/sysctl.h
linux-2.4.4-ac10-hidden/include/linux/sysctl.h
--- linux-2.4.4-ac10/include/linux/sysctl.h     Thu May 17 14:53:07 2001
+++ linux-2.4.4-ac10-hidden/include/linux/sysctl.h      Thu May 17 14:32:40 2001
@@ -326,7 +326,8 @@
        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_HIDDEN=14
 };

 /* /proc/sys/net/ipv6 */
diff -r -u -x *~ -x *.rej linux-2.4.4-ac10/net/ipv4/arp.c
linux-2.4.4-ac10-hidden/net/ipv4/arp.c
--- linux-2.4.4-ac10/net/ipv4/arp.c     Thu May 17 14:53:07 2001
+++ linux-2.4.4-ac10-hidden/net/ipv4/arp.c      Thu May 17 14:47:44 2001
@@ -66,7 +66,9 @@
  *             Alexey Kuznetsov:       new arp state machine;
  *                                     now it is in net/core/neighbour.c.
  *             Krzysztof Halasa:       Added Frame Relay ARP support.
- */
+ *             Julian Anastasov:       "hidden" flag: hide the
+ *                                     interface and don't reply for it
+*/

 #include <linux/types.h>
 #include <linux/string.h>
@@ -317,12 +319,23 @@
 static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
 {
        u32 saddr;
+       int from_skb;
+       struct in_device *in_dev2 = NULL;
+       struct net_device *dev2 = NULL;
        u8  *dst_ha = NULL;
        struct net_device *dev = neigh->dev;
        u32 target = *(u32*)neigh->primary_key;
        int probes = atomic_read(&neigh->probes);

-       if (skb && inet_addr_type(skb->nh.iph->saddr) == RTN_LOCAL)
+       from_skb = (skb &&
+               (dev2 = ip_dev_find(skb->nh.iph->saddr)) != NULL &&
+               (in_dev2 = in_dev_get(dev2)) != NULL &&
+               !IN_DEV_HIDDEN(in_dev2));
+       if (dev2) {
+               if (in_dev2) in_dev_put(in_dev2);
+               dev_put(dev2);
+       }
+       if (from_skb)
                saddr = skb->nh.iph->saddr;
        else
                saddr = inet_select_addr(dev, target, RT_SCOPE_LINK);
@@ -742,9 +755,22 @@

        /* Special case: IPv4 duplicate address detection packet (RFC2131) */
        if (sip == 0) {
-               if (arp->ar_op == __constant_htons(ARPOP_REQUEST) &&
-                   inet_addr_type(tip) == RTN_LOCAL)
+               int reply;
+               struct net_device *dev2 = NULL;
+               struct in_device *in_dev2 = NULL;
+
+               reply =
+                   (arp->ar_op == __constant_htons(ARPOP_REQUEST) &&
+                   (dev2 = ip_dev_find(tip)) != NULL &&
+                   (dev2 == dev ||
+                   ((in_dev2 = in_dev_get(dev2)) != NULL &&
+                   !IN_DEV_HIDDEN(in_dev2))));
+               if (dev2) {
+                   if (in_dev2) in_dev_put(in_dev2);
+                   dev_put(dev2);
+                   if (reply)

arp_send(ARPOP_REPLY,ETH_P_ARP,tip,dev,tip,sha,dev->dev_addr,dev->dev_addr);
+               }
                goto out;
        }

@@ -760,10 +786,29 @@
                                int dont_send = 0;
                                if (IN_DEV_ARPFILTER(in_dev))
                                        dont_send |= arp_filter(sip,tip,dev);
-                               if (!dont_send)
+                               if (!dont_send) {
+                                       if (ipv4_devconf.hidden && skb->pkt_type != 
+PACKET_HOST) {
+                                               int skip;
+                                               struct net_device *dev2 = NULL;
+                                               struct in_device *in_dev2 = NULL;
+
+                                               skip =
+                                               ((dev2 = ip_dev_find(tip)) != NULL &&
+                                                       dev2 != dev &&
+                                               (in_dev2=in_dev_get(dev2)) != NULL &&
+                                                       IN_DEV_HIDDEN(in_dev2));
+                                               if (dev2) {
+                                                       if (in_dev2) 
+in_dev_put(in_dev2);
+                                                       dev_put(dev2);
+                                                       if (skip) {
+                                                               neigh_release(n);
+                                                               goto out;
+                                                       }
+                                               }
+                                       }
                                        
arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha);
-
-                               neigh_release(n);
+                                       neigh_release(n);
+                               }
                        }
                        goto out;
                } else if (IN_DEV_FORWARD(in_dev)) {
diff -r -u -x *~ -x *.rej linux-2.4.4-ac10/net/ipv4/devinet.c
linux-2.4.4-ac10-hidden/net/ipv4/devinet.c
--- linux-2.4.4-ac10/net/ipv4/devinet.c Thu May 17 14:53:07 2001
+++ linux-2.4.4-ac10-hidden/net/ipv4/devinet.c  Thu May 17 14:51:44 2001
@@ -736,7 +736,8 @@

                read_lock(&in_dev->lock);
                for_primary_ifa(in_dev) {
-                       if (ifa->ifa_scope != RT_SCOPE_LINK &&
+                       if (!IN_DEV_HIDDEN(in_dev) &&
+                           ifa->ifa_scope != RT_SCOPE_LINK &&
                            ifa->ifa_scope <= scope) {
                                read_unlock(&in_dev->lock);
                                read_unlock(&inetdev_lock);
@@ -1016,7 +1017,7 @@
 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];
@@ -1061,6 +1062,9 @@
         &proc_dointvec},
        {NET_IPV4_CONF_ARPFILTER, "arp_filter",
         &ipv4_devconf.arp_filter, sizeof(int), 0644, NULL,
+        &proc_dointvec},
+       {NET_IPV4_CONF_HIDDEN, "hidden",
+        &ipv4_devconf.hidden, sizeof(int), 0644, NULL,
         &proc_dointvec},
         {0}},


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to