diff options
-rw-r--r-- | include/net/arp.h | 3 | ||||
-rw-r--r-- | net/ipv4/arp.c | 7 |
2 files changed, 9 insertions, 1 deletions
diff --git a/include/net/arp.h b/include/net/arp.h index 73c49864076b..174014585ade 100644 --- a/include/net/arp.h +++ b/include/net/arp.h @@ -37,6 +37,9 @@ static inline struct neighbour *__ipv4_neigh_lookup(struct net_device *dev, u32 { struct neighbour *n; + if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) + key = INADDR_ANY; + rcu_read_lock_bh(); n = __ipv4_neigh_lookup_noref(dev, key); if (n && !atomic_inc_not_zero(&n->refcnt)) diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 16acb59d665e..263729dea532 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -221,11 +221,16 @@ static u32 arp_hash(const void *pkey, static int arp_constructor(struct neighbour *neigh) { - __be32 addr = *(__be32 *)neigh->primary_key; + __be32 addr; struct net_device *dev = neigh->dev; struct in_device *in_dev; struct neigh_parms *parms; + u32 inaddr_any = INADDR_ANY; + if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) + memcpy(neigh->primary_key, &inaddr_any, arp_tbl.key_len); + + addr = *(__be32 *)neigh->primary_key; rcu_read_lock(); in_dev = __in_dev_get_rcu(dev); if (in_dev == NULL) { |