AIR Wiki : LinkLocalARPMeasurements

HomePage :: Categories :: PageIndex :: RecentChanges :: RecentlyCommented :: Login/Register
Most recent edit on 2006-07-12 21:38:33 by FreekDijkstra

Additions:
Here is a short kernel patch, which makes a linux kernel broadcast ARP replies, if they concern link-local (zerconf IP addresses). The patch was written by David Daney for a 2.6.16.1 kernel, but also succesfully applied to a 2.6.8 and even a 2.4.27 kernel (apparently, the arp.c code doesn't change much these days). It was based on a earlier patch by FreekDijkstra.
# apply using cd linux-2.6.16.1 ; patch -p0 < ipv4ll.patch

net/ipv4/arp.c.orig 2006-03-31 13:44:50.000000000 -0800
+ net/ipv4/arp.c 2006-04-05 13:33:19.000000000 -0700
-690,6 +690,11
void arp_send(int type, int ptype, u32 d
if (dev->flags&IFF_NOARP)
return;
+ /* If link local address (169.254.0.0/16) we must broadcast
+ * the ARP packet. See RFC 3927 section 2.5 for details. */
+ if ((src_ip & htonl(0xFFFF0000UL))
htonl(0xA9FE0000UL)) + dest_hw = NULL;
+
skb = arp_create(type, ptype, dest_ip, dev, src_ip,
dest_hw, src_hw, target_hw);
if (skb
NULL) This patch was extensively discussed on the netdev mailing list for network related Linux kernel development, but so far not picked up upstream.


Deletions:
Here is a short kernel patch, which makes a linux kernel broadcast ARP replies, if they concern link-local (zerconf IP addresses). The patch was written by FreekDijkstra for a 2.6.13 kernel, but also succesfully applied to a 2.6.8 and even a 2.4.27 kernel (apparently, the arp.c code doesn't change much these days):
# apply using cd linux-2.6.13 ; patch -p0 < ipv4ll.patch

net/ipv4/arp.c 2005-08-29 01:41:01.000000000 +0200
+ net/ipv4/arp.c.new 2005-09-13 09:48:23.000000000 +0200
-851,8 +851,18
static int arp_process(struct sk_buff *s
dont_send |= arp_ignore(in_dev,dev,sip,tip);
if (!dont_send && IN_DEV_ARPFILTER(in_dev))
dont_send |= arp_filter(sip,tip,dev);
- if (!dont_send)
- arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha);
+ if (!dont_send) {
+ /* special case: broadcast ARP replies when sender ip is a IPv4 link-local address (RFC3927) */
+ sourcec ip (sip) is in network byte order. make sure so is llprefix, so memcmp() works correctly.
+ u16 llprefix = htons(0xA9FE);
169.254.0.0/16
+ if (!memcmp(&sip, &llprefix, 2)) {
+ printk(KERN_INFO "arp: source IP 0x%X is link-local. broadcast arp reply\n", ntohl(sip));
+ arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,NULL,dev->dev_addr,NULL);
+ } else {
+
printk(KERN_INFO "arp: source IP 0x%X is not link-local. unicast arp reply\n", ntohl(sip));
+ arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha);
+ }
+ }
neigh_release(n);
}
I'm sure this code could be more efficient (you could probably do a bitshift and a simple comparison as well). However, I'm slightly more certain this code will work on all platforms (big-endian and little-endian), so I leave the optimization to someone else.




Edited on 2005-09-30 02:35:30 by FreekDijkstra

Additions:

Measurements

machines:
Seperate network, give Mac same (fixed) IP as Linux. Join. Linux should reconfigure, but indeed the Mac complains and refuses to join the network.
Other problems include that computers are indeed reconfigured, but the reverse lookup still is to the older hosts, giving incorrect results from an end-user persepctive.




Edited on 2005-09-21 13:28:43 by FreekDijkstra

Additions:
I'm sure this code could be more efficient (you could probably do a bitshift and a simple comparison as well). However, I'm slightly more certain this code will work on all platforms (big-endian and little-endian), so I leave the optimization to someone else.



Edited on 2005-09-21 13:25:34 by FreekDijkstra

Additions:

Kernel Patch

Here is a short kernel patch, which makes a linux kernel broadcast ARP replies, if they concern link-local (zerconf IP addresses). The patch was written by FreekDijkstra for a 2.6.13 kernel, but also succesfully applied to a 2.6.8 and even a 2.4.27 kernel (apparently, the arp.c code doesn't change much these days):
# apply using cd linux-2.6.13 ; patch -p0 < ipv4ll.patch
--- net/ipv4/arp.c    2005-08-29 01:41:01.000000000 +0200
+++ net/ipv4/arp.c.new    2005-09-13 09:48:23.000000000 +0200
@@ -851,8 +851,18 @@ static int arp_process(struct sk_buff *s
                     dont_send |= arp_ignore(in_dev,dev,sip,tip);
                 if (!dont_send && IN_DEV_ARPFILTER(in_dev))
                     dont_send |= arp_filter(sip,tip,dev);
-                if (!dont_send)
-                    arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha);
+                if (!dont_send) {
+                    /* special case: broadcast ARP replies when sender ip is a IPv4 link-local address (RFC3927) */
+                    // sourcec ip (sip) is in network byte order. make sure so is llprefix, so memcmp() works correctly.
+                    u16 llprefix = htons(0xA9FE); // 169.254.0.0/16
+                    if (!memcmp(&sip, &llprefix, 2)) {
+                        // printk(KERN_INFO "arp: source IP 0x%X is link-local. broadcast arp reply\n", ntohl(sip));
+                        arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,NULL,dev->dev_addr,NULL);
+                    } else {
+                        // printk(KERN_INFO "arp: source IP 0x%X is not link-local. unicast arp reply\n", ntohl(sip));
+                        arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha);
+                    }
+                }
 
                 neigh_release(n);
             }




Edited on 2005-09-21 13:19:15 by FreekDijkstra

Additions:
Categories
CategoryZeroconf




Edited on 2005-06-09 16:48:55 by FreekDijkstra [results for 2.6 kernel]

Additions:
With statically configured link-local addresses: unicasted

Linux 2.6.6 and 2.6.8 kernels

With statically configured link-local addresses: unicasted


Deletions:

Linux 2.6 kernel





Edited on 2005-04-27 18:56:39 by FreekDijkstra [First results]

Additions:

Mac OS 10.3.9



Deletions:

Mac OS 10.3





Edited on 2005-04-27 18:56:20 by FreekDijkstra

Additions:
Setup
Take three nodes, and put them in a LAN, without external connectivity.
Configure either link-local (169.254/16) or private (10/8) IP addresses on the hosts.
Make sure the ARP cache is empty (for example do arp -d -a -n), check with arp -a -n (the -n makes sure no resolving is done, since that may generate an ARP request).
Do a single connection request, for example using ping -c 1 <IP of host 2> and check with ethereal or tcpdump arp if the ARP replies are unicasted or broadcasted. You can check by either decoding the ARP packet with ethereal or by just checking if host 3 sees the packet or not.

Linux 2.4.26 kernel

With private addresses: unicasted
With private addresses: unicasted
With statically configured link-local addresses: broadcasted
With bootpd automatically configured link-local addresses: broadcasted


Deletions:

Linux 2.4 kernel





Oldest known version of this page was edited on 2005-04-27 08:32:49 by FreekDijkstra [preliminary page]
Page view:

Link-Local ARP Measurements


RFC 3927 (IPv4 Link-Local Adressing) specifies that not just ARP requests, but also ARP replies must be broadcasted. This helps in identifying duplicate IP addresses, which is particularly usefull in LAN which use link-local IP addresses (169.254/16). These test are meant to measure normal ARP behaviour, identify when that normal behaviour is indeed a problem, and which kernels support broadcasting ARP replies, and if they broadcast all ARP replies or just those with link-local IP addresses in the body.

Generic ARP Behaviour Tests


describe set-up (with three hosts)

Description of Problem Scenario's


Link-Local ARP Behaviour Tests


Linux 2.4 kernel


Linux 2.6 kernel


Mac OS 10.3

Valid XHTML 1.0 Transitional :: Valid CSS :: Powered by Wikka Wakka Wiki 1.1.6.0
Page was generated in 0.1526 seconds