diff options
author | Jim Westfall <jwestfall@surrealistic.net> | 2018-01-14 07:18:51 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-01-15 14:53:43 -0500 |
commit | cd9ff4de0107c65d69d02253bb25d6db93c3dbc1 (patch) | |
tree | 84e0e11399bdb5eb0f479497026f16d5a7259a8f | |
parent | 096b9854c04df86f03b38a97d40b6506e5730919 (diff) |
ipv4: Make neigh lookup keys for loopback/point-to-point devices be INADDR_ANY
Map all lookup neigh keys to INADDR_ANY for loopback/point-to-point devices
to avoid making an entry for every remote ip the device needs to talk to.
This used the be the old behavior but became broken in a263b3093641f
(ipv4: Make neigh lookups directly in output packet path) and later removed
in 0bb4087cbec0 (ipv4: Fix neigh lookup keying over loopback/point-to-point
devices) because it was broken.
Signed-off-by: Jim Westfall <jwestfall@surrealistic.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-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 dc8cd47f883b..977aabfcdc03 100644 --- a/include/net/arp.h +++ b/include/net/arp.h | |||
@@ -20,6 +20,9 @@ static inline u32 arp_hashfn(const void *pkey, const struct net_device *dev, u32 | |||
20 | 20 | ||
21 | static inline struct neighbour *__ipv4_neigh_lookup_noref(struct net_device *dev, u32 key) | 21 | static inline struct neighbour *__ipv4_neigh_lookup_noref(struct net_device *dev, u32 key) |
22 | { | 22 | { |
23 | if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) | ||
24 | key = INADDR_ANY; | ||
25 | |||
23 | return ___neigh_lookup_noref(&arp_tbl, neigh_key_eq32, arp_hashfn, &key, dev); | 26 | return ___neigh_lookup_noref(&arp_tbl, neigh_key_eq32, arp_hashfn, &key, dev); |
24 | } | 27 | } |
25 | 28 | ||
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index a8d7c5a9fb05..6c231b43974d 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -223,11 +223,16 @@ static bool arp_key_eq(const struct neighbour *neigh, const void *pkey) | |||
223 | 223 | ||
224 | static int arp_constructor(struct neighbour *neigh) | 224 | static int arp_constructor(struct neighbour *neigh) |
225 | { | 225 | { |
226 | __be32 addr = *(__be32 *)neigh->primary_key; | 226 | __be32 addr; |
227 | struct net_device *dev = neigh->dev; | 227 | struct net_device *dev = neigh->dev; |
228 | struct in_device *in_dev; | 228 | struct in_device *in_dev; |
229 | struct neigh_parms *parms; | 229 | struct neigh_parms *parms; |
230 | u32 inaddr_any = INADDR_ANY; | ||
230 | 231 | ||
232 | if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) | ||
233 | memcpy(neigh->primary_key, &inaddr_any, arp_tbl.key_len); | ||
234 | |||
235 | addr = *(__be32 *)neigh->primary_key; | ||
231 | rcu_read_lock(); | 236 | rcu_read_lock(); |
232 | in_dev = __in_dev_get_rcu(dev); | 237 | in_dev = __in_dev_get_rcu(dev); |
233 | if (!in_dev) { | 238 | if (!in_dev) { |