From 8164f1b79731ad8ad9c713dc53d587a3b746f82f Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Sun, 16 Nov 2008 19:19:38 -0800 Subject: [PATCH] ipv4: Fix ARP behavior with many mac-vlans Ben Greear wrote: > I have 500 mac-vlans on a system talking to 500 other > mac-vlans. My problem is that the arp-table gets extremely > huge because every time an arp-request comes in on all mac-vlans, > a stale arp entry is added for each mac-vlan. I have filtering > turned on, but that doesn't help because the neigh_event_ns call > below will cause a stale neighbor entry to be created regardless > of whether a replay will be sent or not. > Maybe the neigh_event code should be below the checks for dont_send, > and only create check neigh_event_ns if we are !dont_send? The attached patch makes it work much better for me. The patch will cause the code to NOT create a stale neighbor entry if we are not going to respond to the ARP request. The old code *would* create a stale entry even if we are not going to respond. Signed-off-by: Ben Greear Signed-off-by: David S. Miller --- net/ipv4/arp.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 957c87dc8e16..29a74c01d8de 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -818,18 +818,18 @@ static int arp_process(struct sk_buff *skb) addr_type = rt->rt_type; if (addr_type == RTN_LOCAL) { - n = neigh_event_ns(&arp_tbl, sha, &sip, dev); - if (n) { - int dont_send = 0; + int dont_send = 0; - if (!dont_send) - dont_send |= arp_ignore(in_dev, sip, tip); - if (!dont_send && IN_DEV_ARPFILTER(in_dev)) - dont_send |= arp_filter(sip, tip, dev); - if (!dont_send) + if (!dont_send) + dont_send |= arp_ignore(in_dev,sip,tip); + if (!dont_send && IN_DEV_ARPFILTER(in_dev)) + dont_send |= arp_filter(sip,tip,dev); + if (!dont_send) { + 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); + neigh_release(n); + } } goto out; } else if (IN_DEV_FORWARD(in_dev)) {