summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/net/arp.h3
-rw-r--r--net/ipv4/arp.c7
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) {