Messages in this thread Patch in this message | | | Date | Thu, 30 Sep 1999 11:10:01 +0100 (BST) | From | Tom Yates <> | Subject | patch - arp responding overenthusastically? |
| |
ladies, gentlemen:
i'm posting this on behalf of a colleague here, dr. david robinson, to whom replies should be directed.
the odd behaviour we've found is that when an arp request is received with a target IP address of a local interface, the response contains the MAC address of the receiving interface rather than the target interface.
the fix in this this patch ensures that arp responses for a local interface are only replied to using that interface. the patch is against arp.c as it appeared in 2.2.11, btw.
david also adds that "It also provides a performance improvement; currently ip_route_input() is called for every arp request on the network where the target machine is not the local machine. With this patch, routing is only tried if IP forwarding is enabled on the interface."
thanks to clayton weaver <cgweav@eskimo.com> for the pointer here.
Tom Yates T: 01223 727 400 E*TRADE UK Ltd. www.etrade.co.uk
The contents of this message should be read in conjunction with the document found at http://www.etrade.co.uk/public/signature.html
--- linux/net/ipv4/arp.c.orig Mon Aug 9 20:04:41 1999 +++ linux/net/ipv4/arp.c Thu Aug 26 09:56:02 1999 @@ -649,25 +649,23 @@ /* 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) + ip_dev_find(tip) == dev) arp_send(ARPOP_REPLY,ETH_P_ARP,tip,dev,tip,sha,dev->dev_addr,dev->dev_addr); goto out; } - if (arp->ar_op == __constant_htons(ARPOP_REQUEST) && - ip_route_input(skb, tip, sip, 0, dev) == 0) { - - rt = (struct rtable*)skb->dst; - addr_type = rt->rt_type; - - if (addr_type == RTN_LOCAL) { + if (arp->ar_op == __constant_htons(ARPOP_REQUEST)) { + if (ip_dev_find(tip) == dev) { n = neigh_event_ns(&arp_tbl, sha, &sip, dev); if (n) { arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha); neigh_release(n); } goto out; - } else if (IN_DEV_FORWARD(in_dev)) { + } else if (IN_DEV_FORWARD(in_dev) && + ip_route_input(skb, tip, sip, 0, dev) == 0) { + rt = (struct rtable*)skb->dst; + addr_type = rt->rt_type; 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)))) { | |