Re: Restrict local IP announcements in ARP requests

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



	Hello,

On Fri, 13 Feb 2004, David S. Miller wrote:

> > http://www.ssi.bg/~ja/arp_announce-2.6.2-4.diff
>
> Ok, I eat this, please make a 2.4.x version against Marcelo's current tree.

	Attached, against rc2 which looks enough.

> The 2.6.x variant will go into 2.6.4-pre1 and the 2.4.x will go into 2.4.26-pre1

	very good

Regards

--
Julian Anastasov <ja@ssi.bg>
diff -ur v2.4.25-rc2/linux/Documentation/networking/ip-sysctl.txt linux/Documentation/networking/ip-sysctl.txt
--- v2.4.25-rc2/linux/Documentation/networking/ip-sysctl.txt	2003-06-14 08:41:59.000000000 +0300
+++ linux/Documentation/networking/ip-sysctl.txt	2004-02-14 11:00:31.528798088 +0200
@@ -481,6 +481,37 @@
 	conf/{all,interface}/arp_filter is set to TRUE,
 	it will be disabled otherwise
 
+arp_announce - INTEGER
+	Define different restriction levels for announcing the local
+	source IP address from IP packets in ARP requests sent on
+	interface:
+	0 - (default) Use any local address, configured on any interface
+	1 - Try to avoid local addresses that are not in the target's
+	subnet for this interface. This mode is useful when target
+	hosts reachable via this interface require the source IP
+	address in ARP requests to be part of their logical network
+	configured on the receiving interface. When we generate the
+	request we will check all our subnets that include the
+	target IP and will preserve the source address if it is from
+	such subnet. If there is no such subnet we select source
+	address according to the rules for level 2.
+	2 - Always use the best local address for this target.
+	In this mode we ignore the source address in the IP packet
+	and try to select local address that we prefer for talks with
+	the target host. Such local address is selected by looking
+	for primary IP addresses on all our subnets on the outgoing
+	interface that include the target IP address. If no suitable
+	local address is found we select the first local address
+	we have on the outgoing interface or on all other interfaces,
+	with the hope we will receive reply for our request and
+	even sometimes no matter the source IP address we announce.
+
+	The max value from conf/{all,interface}/arp_announce is used.
+
+	Increasing the restriction level gives more chance for
+	receiving answer from the resolved target while decreasing
+	the level announces more valid sender's information.
+
 tag - INTEGER
 	Allows you to write a number, which can be used as required.
 	Default value is 0.
diff -ur v2.4.25-rc2/linux/include/linux/inetdevice.h linux/include/linux/inetdevice.h
--- v2.4.25-rc2/linux/include/linux/inetdevice.h	2004-02-14 10:37:06.000000000 +0200
+++ linux/include/linux/inetdevice.h	2004-02-14 11:00:31.549794896 +0200
@@ -18,6 +18,7 @@
 	int	mc_forwarding;
 	int	tag;
 	int     arp_filter;
+	int	arp_announce;
 	int	medium_id;
 	int	force_igmp_version;
 	void	*sysctl;
@@ -69,6 +70,7 @@
 	  (ipv4_devconf.accept_redirects || (in_dev)->cnf.accept_redirects)))
 
 #define IN_DEV_ARPFILTER(in_dev)	(ipv4_devconf.arp_filter || (in_dev)->cnf.arp_filter)
+#define IN_DEV_ARP_ANNOUNCE(in_dev)	(max(ipv4_devconf.arp_announce, (in_dev)->cnf.arp_announce))
 
 struct in_ifaddr
 {
diff -ur v2.4.25-rc2/linux/include/linux/sysctl.h linux/include/linux/sysctl.h
--- v2.4.25-rc2/linux/include/linux/sysctl.h	2004-02-14 10:37:06.000000000 +0200
+++ linux/include/linux/sysctl.h	2004-02-14 11:00:31.550794744 +0200
@@ -360,6 +360,7 @@
 	NET_IPV4_CONF_ARPFILTER=13,
 	NET_IPV4_CONF_MEDIUM_ID=14,
 	NET_IPV4_CONF_FORCE_IGMP_VERSION=17,
+	NET_IPV4_CONF_ARP_ANNOUNCE=18,
 };
 
 /* /proc/sys/net/ipv4/netfilter */
diff -ur v2.4.25-rc2/linux/net/ipv4/arp.c linux/net/ipv4/arp.c
--- v2.4.25-rc2/linux/net/ipv4/arp.c	2003-11-28 22:04:14.000000000 +0200
+++ linux/net/ipv4/arp.c	2004-02-14 11:00:31.551794592 +0200
@@ -317,15 +317,40 @@
 
 static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
 {
-	u32 saddr;
+	u32 saddr = 0;
 	u8  *dst_ha = NULL;
 	struct net_device *dev = neigh->dev;
 	u32 target = *(u32*)neigh->primary_key;
 	int probes = atomic_read(&neigh->probes);
+	struct in_device *in_dev = in_dev_get(dev);
+
+	if (!in_dev)
+		return;
 
-	if (skb && inet_addr_type(skb->nh.iph->saddr) == RTN_LOCAL)
+	switch (IN_DEV_ARP_ANNOUNCE(in_dev)) {
+	default:
+	case 0:		/* By default announce any local IP */
+		if (skb && inet_addr_type(skb->nh.iph->saddr) == RTN_LOCAL)
+			saddr = skb->nh.iph->saddr;
+		break;
+	case 1:		/* Restrict announcements of saddr in same subnet */
+		if (!skb)
+			break;
 		saddr = skb->nh.iph->saddr;
-	else
+		if (inet_addr_type(saddr) == RTN_LOCAL) {
+			/* saddr should be known to target */
+			if (inet_addr_onlink(in_dev, target, saddr))
+				break;
+		}
+		saddr = 0;
+		break;
+	case 2:		/* Avoid secondary IPs, get a primary/preferred one */
+		break;
+	}
+
+	if (in_dev)
+		in_dev_put(in_dev);
+	if (!saddr)
 		saddr = inet_select_addr(dev, target, RT_SCOPE_LINK);
 
 	if ((probes -= neigh->parms->ucast_probes) < 0) {
diff -ur v2.4.25-rc2/linux/net/ipv4/devinet.c linux/net/ipv4/devinet.c
--- v2.4.25-rc2/linux/net/ipv4/devinet.c	2004-02-14 10:37:06.000000000 +0200
+++ linux/net/ipv4/devinet.c	2004-02-14 11:01:37.845716384 +0200
@@ -1057,7 +1057,7 @@
 static struct devinet_sysctl_table
 {
 	struct ctl_table_header *sysctl_header;
-	ctl_table devinet_vars[18];
+	ctl_table devinet_vars[19];
 	ctl_table devinet_dev[2];
 	ctl_table devinet_conf_dir[2];
 	ctl_table devinet_proto_dir[2];
@@ -1106,6 +1106,9 @@
 	{NET_IPV4_CONF_ARPFILTER, "arp_filter",
 	 &ipv4_devconf.arp_filter, sizeof(int), 0644, NULL,
 	 &proc_dointvec},
+	{NET_IPV4_CONF_ARP_ANNOUNCE, "arp_announce",
+	 &ipv4_devconf.arp_announce, sizeof(int), 0644, NULL,
+	 &proc_dointvec},
 	{NET_IPV4_CONF_FORCE_IGMP_VERSION, "force_igmp_version",
 	 &ipv4_devconf.force_igmp_version, sizeof(int), 0644, NULL,
 	 &proc_dointvec},

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux