]> Pileus Git - ~andy/linux/blobdiff - net/ipv4/arp.c
Merge tag 'for-linus' of git://linux-c6x.org/git/projects/linux-c6x-upstreaming
[~andy/linux] / net / ipv4 / arp.c
index b67cf805910e1f962755cbc26f793be6a01a4c6a..1a9b99e04465a1eb7f8a197bdc7ca6f1bd6978f0 100644 (file)
@@ -732,6 +732,7 @@ static int arp_process(struct sk_buff *skb)
        int addr_type;
        struct neighbour *n;
        struct net *net = dev_net(dev);
+       bool is_garp = false;
 
        /* arp_rcv below verifies the ARP header and verifies the device
         * is ARP'able.
@@ -898,10 +899,12 @@ static int arp_process(struct sk_buff *skb)
                   It is possible, that this option should be enabled for some
                   devices (strip is candidate)
                 */
+               is_garp = arp->ar_op == htons(ARPOP_REQUEST) && tip == sip &&
+                         inet_addr_type(net, sip) == RTN_UNICAST;
+
                if (n == NULL &&
-                   (arp->ar_op == htons(ARPOP_REPLY) ||
-                    (arp->ar_op == htons(ARPOP_REQUEST) && tip == sip)) &&
-                   inet_addr_type(net, sip) == RTN_UNICAST)
+                   ((arp->ar_op == htons(ARPOP_REPLY)  &&
+                     inet_addr_type(net, sip) == RTN_UNICAST) || is_garp))
                        n = __neigh_lookup(&arp_tbl, &sip, dev, 1);
        }
 
@@ -914,8 +917,10 @@ static int arp_process(struct sk_buff *skb)
                   agents are active. Taking the first reply prevents
                   arp trashing and chooses the fastest router.
                 */
-               override = time_after(jiffies, n->updated +
-                                              NEIGH_VAR(n->parms, LOCKTIME));
+               override = time_after(jiffies,
+                                     n->updated +
+                                     NEIGH_VAR(n->parms, LOCKTIME)) ||
+                          is_garp;
 
                /* Broadcast replies and request packets
                   do not assert neighbour reachability.
@@ -1112,7 +1117,7 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
        return err;
 }
 
-int arp_invalidate(struct net_device *dev, __be32 ip)
+static int arp_invalidate(struct net_device *dev, __be32 ip)
 {
        struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev);
        int err = -ENXIO;
@@ -1127,7 +1132,6 @@ int arp_invalidate(struct net_device *dev, __be32 ip)
 
        return err;
 }
-EXPORT_SYMBOL(arp_invalidate);
 
 static int arp_req_delete_public(struct net *net, struct arpreq *r,
                struct net_device *dev)