@@ -19,8 +19,10 @@ static inline u32 arp_hashfn(const void *pkey, const struct net_device *dev, u32
}
#ifdef CONFIG_INET
-static inline struct neighbour *__ipv4_neigh_lookup_noref(struct net_device *dev, u32 key)
+static inline struct neighbour *__ipv4_neigh_lookup_noref(struct net_device *dev, const void *pkey)
{
+ u32 key = *(const u32 *)pkey;
+
if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))
key = INADDR_ANY;
@@ -28,7 +30,7 @@ static inline struct neighbour *__ipv4_neigh_lookup_noref(struct net_device *dev
}
#else
static inline
-struct neighbour *__ipv4_neigh_lookup_noref(struct net_device *dev, u32 key)
+struct neighbour *__ipv4_neigh_lookup_noref(struct net_device *dev, const void *pkey)
{
return NULL;
}
@@ -39,7 +41,7 @@ static inline struct neighbour *__ipv4_neigh_lookup(struct net_device *dev, u32
struct neighbour *n;
rcu_read_lock_bh();
- n = __ipv4_neigh_lookup_noref(dev, key);
+ n = __ipv4_neigh_lookup_noref(dev, &key);
if (n && !refcount_inc_not_zero(&n->refcnt))
n = NULL;
rcu_read_unlock_bh();
@@ -49,18 +51,7 @@ static inline struct neighbour *__ipv4_neigh_lookup(struct net_device *dev, u32
static inline void __ipv4_confirm_neigh(struct net_device *dev, u32 key)
{
- struct neighbour *n;
-
- rcu_read_lock_bh();
- n = __ipv4_neigh_lookup_noref(dev, key);
- if (n) {
- unsigned long now = jiffies;
-
- /* avoid dirtying neighbour */
- if (READ_ONCE(n->confirmed) != now)
- WRITE_ONCE(n->confirmed, now);
- }
- rcu_read_unlock_bh();
+ __neigh_confirm(dev, &key, __ipv4_neigh_lookup_noref);
}
void arp_init(void);
@@ -407,35 +407,13 @@ static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, cons
static inline void __ipv6_confirm_neigh(struct net_device *dev,
const void *pkey)
{
- struct neighbour *n;
-
- rcu_read_lock_bh();
- n = __ipv6_neigh_lookup_noref(dev, pkey);
- if (n) {
- unsigned long now = jiffies;
-
- /* avoid dirtying neighbour */
- if (READ_ONCE(n->confirmed) != now)
- WRITE_ONCE(n->confirmed, now);
- }
- rcu_read_unlock_bh();
+ __neigh_confirm(dev, pkey, __ipv6_neigh_lookup_noref);
}
static inline void __ipv6_confirm_neigh_stub(struct net_device *dev,
const void *pkey)
{
- struct neighbour *n;
-
- rcu_read_lock_bh();
- n = __ipv6_neigh_lookup_noref_stub(dev, pkey);
- if (n) {
- unsigned long now = jiffies;
-
- /* avoid dirtying neighbour */
- if (READ_ONCE(n->confirmed) != now)
- WRITE_ONCE(n->confirmed, now);
- }
- rcu_read_unlock_bh();
+ __neigh_confirm(dev, pkey, __ipv6_neigh_lookup_noref_stub);
}
/* uses ipv6_stub and is meant for use outside of IPv6 core */
@@ -335,6 +335,25 @@ static inline struct neighbour *neigh_create(struct neigh_table *tbl,
{
return __neigh_create(tbl, pkey, dev, true);
}
+
+static inline void __neigh_confirm(struct net_device *dev, const void *pkey,
+ struct neighbour *(*neigh_lookup_noref)(
+ struct net_device *, const void *))
+{
+ struct neighbour *n;
+
+ rcu_read_lock_bh();
+ n = neigh_lookup_noref(dev, pkey);
+ if (n) {
+ unsigned long now = jiffies;
+
+ /* avoid dirtying neighbour */
+ if (READ_ONCE(n->confirmed) != now)
+ WRITE_ONCE(n->confirmed, now);
+ }
+ rcu_read_unlock_bh();
+}
+
void neigh_destroy(struct neighbour *neigh);
int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb);
int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, u32 flags,
@@ -369,7 +369,7 @@ static inline struct neighbour *ip_neigh_gw4(struct net_device *dev,
{
struct neighbour *neigh;
- neigh = __ipv4_neigh_lookup_noref(dev, daddr);
+ neigh = __ipv4_neigh_lookup_noref(dev, &daddr);
if (unlikely(!neigh))
neigh = __neigh_create(&arp_tbl, &daddr, dev, false);
@@ -5478,8 +5478,7 @@ static int bpf_ipv4_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
if (nhc->nhc_gw_family)
params->ipv4_dst = nhc->nhc_gw.ipv4;
- neigh = __ipv4_neigh_lookup_noref(dev,
- (__force u32)params->ipv4_dst);
+ neigh = __ipv4_neigh_lookup_noref(dev, ¶ms->ipv4_dst);
} else {
struct in6_addr *dst = (struct in6_addr *)params->ipv6_dst;
@@ -3091,9 +3091,7 @@ int neigh_xmit(int index, struct net_device *dev,
goto out;
rcu_read_lock_bh();
if (index == NEIGH_ARP_TABLE) {
- u32 key = *((u32 *)addr);
-
- neigh = __ipv4_neigh_lookup_noref(dev, key);
+ neigh = __ipv4_neigh_lookup_noref(dev, addr);
} else {
neigh = __neigh_lookup_noref(tbl, addr, dev);
}
@@ -2161,7 +2161,7 @@ static bool fib_good_nh(const struct fib_nh *nh)
if (likely(nh->fib_nh_gw_family == AF_INET))
n = __ipv4_neigh_lookup_noref(nh->fib_nh_dev,
- (__force u32)nh->fib_nh_gw4);
+ &nh->fib_nh_gw4);
else if (nh->fib_nh_gw_family == AF_INET6)
n = __ipv6_neigh_lookup_noref_stub(nh->fib_nh_dev,
&nh->fib_nh_gw6);
@@ -1141,8 +1141,7 @@ static bool ipv4_good_nh(const struct fib_nh *nh)
rcu_read_lock_bh();
- n = __ipv4_neigh_lookup_noref(nh->fib_nh_dev,
- (__force u32)nh->fib_nh_gw4);
+ n = __ipv4_neigh_lookup_noref(nh->fib_nh_dev, &nh->fib_nh_gw4);
if (n)
state = n->nud_state;
Those __ipv4_confirm_neigh(), __ipv6_confirm_neigh() and __ipv6_confirm_neigh_stub() functions have similar code. introduce __neigh_confirm() for it. Signed-off-by: Yajun Deng <yajun.deng@linux.dev> --- include/net/arp.h | 21 ++++++--------------- include/net/ndisc.h | 26 ++------------------------ include/net/neighbour.h | 19 +++++++++++++++++++ include/net/route.h | 2 +- net/core/filter.c | 3 +-- net/core/neighbour.c | 4 +--- net/ipv4/fib_semantics.c | 2 +- net/ipv4/nexthop.c | 3 +-- 8 files changed, 32 insertions(+), 48 deletions(-)