All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kuniyuki Iwashima <kuniyu@google.com>
To: Andrew Lunn <andrew+netdev@lunn.ch>,
	"David S . Miller" <davem@davemloft.net>,
	 Eric Dumazet <edumazet@kernel.org>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	 David Ahern <dsahern@kernel.org>,
	Ido Schimmel <idosch@nvidia.com>
Cc: Simon Horman <horms@kernel.org>,
	Kuniyuki Iwashima <kuniyu@google.com>,
	 Kuniyuki Iwashima <kuni1840@gmail.com>,
	netdev@vger.kernel.org,  Petr Machata <petrm@nvidia.com>
Subject: [PATCH v1 net-next 5/8] mlxsw: spectrum: Resolve neigh_table right before neigh_lookup().
Date: Wed, 30 Sep 2026 20:03:13 +0000	[thread overview]
Message-ID: <20260930200326.718459-6-kuniyu@google.com> (raw)
In-Reply-To: <20260930200326.718459-1-kuniyu@google.com>

We will replace neigh_lookup() and neigh_create() with
IPv4/IPv6-specific helpers.

mlxsw has two paths where neigh_table is fetched in advance
and passed down to a function which calls neigh_lookup() and
neigh_create().

To keep the changes simple, let's prepare them beforehand
by delaying the neigh_table resolution until right before
neigh_lookup().

struct mlxsw_sp_nexthop caches neigh_tbl, so it is replaced with
family, and a new helper, mlxsw_sp_nexthop_neigh_lookup(),
resolves neigh_table and calls neigh_lookup() and neigh_create().

Similarly, mlxsw_sp_span_entry_gretap[46]_parms() now pass family
to mlxsw_sp_span_dmac() to resolve neigh_table there just before
neigh_lookup() and neigh_create().

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
Cc: Petr Machata <petrm@nvidia.com>
---
 .../ethernet/mellanox/mlxsw/spectrum_router.c | 65 ++++++++++++-------
 .../ethernet/mellanox/mlxsw/spectrum_span.c   | 31 +++++----
 2 files changed, 58 insertions(+), 38 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index f4a435885ba4..ba8a7a44ce9e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -3072,9 +3072,9 @@ struct mlxsw_sp_nexthop {
 						   * this nexthop belongs to
 						   */
 	struct rhash_head ht_node;
-	struct neigh_table *neigh_tbl;
 	struct mlxsw_sp_nexthop_key key;
 	unsigned char gw_addr[sizeof(struct in6_addr)];
+	int family;
 	int ifindex;
 	int nh_weight;
 	int norm_nh_weight;
@@ -4300,28 +4300,49 @@ static void __mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp_nexthop *nh,
 	nh->update = 1;
 }
 
+static struct neighbour *
+mlxsw_sp_nexthop_neigh_lookup(struct mlxsw_sp_nexthop *nh)
+{
+	struct neigh_table *tbl;
+	struct net_device *dev;
+	struct neighbour *n;
+	struct net *net;
+
+	dev = mlxsw_sp_nexthop_dev(nh);
+	net = dev_net(dev);
+
+#if IS_ENABLED(CONFIG_IPV6)
+	if (nh->family == AF_INET6)
+		tbl = nd_table(net);
+	else
+#endif
+		tbl = arp_table(net);
+
+	n = neigh_lookup(tbl, &nh->gw_addr, dev);
+	if (!n) {
+		n = neigh_create(tbl, &nh->gw_addr, dev);
+		if (!IS_ERR(n))
+			neigh_event_send(n, NULL);
+	}
+
+	return n;
+}
+
 static int
 mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
 				    struct mlxsw_sp_neigh_entry *neigh_entry)
 {
 	struct neighbour *n, *old_n = neigh_entry->key.n;
 	struct mlxsw_sp_nexthop *nh;
-	struct net_device *dev;
 	bool entry_connected;
 	u8 nud_state, dead;
 	int err;
 
 	nh = list_first_entry(&neigh_entry->nexthop_list,
 			      struct mlxsw_sp_nexthop, neigh_list_node);
-	dev = mlxsw_sp_nexthop_dev(nh);
-
-	n = neigh_lookup(nh->neigh_tbl, &nh->gw_addr, dev);
-	if (!n) {
-		n = neigh_create(nh->neigh_tbl, &nh->gw_addr, dev);
-		if (IS_ERR(n))
-			return PTR_ERR(n);
-		neigh_event_send(n, NULL);
-	}
+	n = mlxsw_sp_nexthop_neigh_lookup(nh);
+	if (IS_ERR(n))
+		return PTR_ERR(n);
 
 	mlxsw_sp_neigh_entry_remove(mlxsw_sp, neigh_entry);
 	neigh_entry->key.n = n;
@@ -4402,7 +4423,6 @@ static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp,
 				       struct mlxsw_sp_nexthop *nh)
 {
 	struct mlxsw_sp_neigh_entry *neigh_entry;
-	struct net_device *dev;
 	struct neighbour *n;
 	u8 nud_state, dead;
 	int err;
@@ -4412,20 +4432,16 @@ static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp,
 
 	if (!nh->nhgi->gateway || nh->neigh_entry)
 		return 0;
-	dev = mlxsw_sp_nexthop_dev(nh);
 
 	/* Take a reference of neigh here ensuring that neigh would
 	 * not be destructed before the nexthop entry is finished.
 	 * The reference is taken either in neigh_lookup() or
 	 * in neigh_create() in case n is not found.
 	 */
-	n = neigh_lookup(nh->neigh_tbl, &nh->gw_addr, dev);
-	if (!n) {
-		n = neigh_create(nh->neigh_tbl, &nh->gw_addr, dev);
-		if (IS_ERR(n))
-			return PTR_ERR(n);
-		neigh_event_send(n, NULL);
-	}
+	n = mlxsw_sp_nexthop_neigh_lookup(nh);
+	if (IS_ERR(n))
+		return PTR_ERR(n);
+
 	neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, n);
 	if (!neigh_entry) {
 		neigh_entry = mlxsw_sp_neigh_entry_create(mlxsw_sp, n);
@@ -4630,7 +4646,7 @@ static int mlxsw_sp_nexthop4_init(struct mlxsw_sp *mlxsw_sp,
 	nh->nh_weight = 1;
 #endif
 	memcpy(&nh->gw_addr, &fib_nh->fib_nh_gw4, sizeof(fib_nh->fib_nh_gw4));
-	nh->neigh_tbl = arp_table(mlxsw_sp_net(mlxsw_sp));
+	nh->family = AF_INET;
 	err = mlxsw_sp_nexthop_insert(mlxsw_sp, nh);
 	if (err)
 		return err;
@@ -5120,7 +5136,6 @@ mlxsw_sp_nexthop_obj_init(struct mlxsw_sp *mlxsw_sp,
 			  struct nh_notifier_single_info *nh_obj, int weight)
 {
 	struct net_device *dev = nh_obj->dev;
-	struct net *net = dev_net(dev);
 	int err;
 
 	nh->nhgi = nh_grp->nhgi;
@@ -5129,12 +5144,12 @@ mlxsw_sp_nexthop_obj_init(struct mlxsw_sp *mlxsw_sp,
 	switch (nh_obj->gw_family) {
 	case AF_INET:
 		memcpy(&nh->gw_addr, &nh_obj->ipv4, sizeof(nh_obj->ipv4));
-		nh->neigh_tbl = arp_table(net);
+		nh->family = AF_INET;
 		break;
 	case AF_INET6:
 		memcpy(&nh->gw_addr, &nh_obj->ipv6, sizeof(nh_obj->ipv6));
 #if IS_ENABLED(CONFIG_IPV6)
-		nh->neigh_tbl = nd_table(net);
+		nh->family = AF_INET6;
 #endif
 		break;
 	}
@@ -6990,7 +7005,7 @@ static int mlxsw_sp_nexthop6_init(struct mlxsw_sp *mlxsw_sp,
 	nh->nh_weight = rt->fib6_nh->fib_nh_weight;
 	memcpy(&nh->gw_addr, &rt->fib6_nh->fib_nh_gw6, sizeof(nh->gw_addr));
 #if IS_ENABLED(CONFIG_IPV6)
-	nh->neigh_tbl = nd_table(mlxsw_sp_net(mlxsw_sp));
+	nh->family = AF_INET6;
 #endif
 
 	err = mlxsw_sp_nexthop_counter_enable(mlxsw_sp, nh);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
index 1cd8347c274d..d34d2040177b 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
@@ -224,14 +224,24 @@ struct mlxsw_sp_span_entry_ops mlxsw_sp_span_entry_ops_phys = {
 	.deconfigure = mlxsw_sp_span_entry_phys_deconfigure,
 };
 
-static int mlxsw_sp_span_dmac(struct neigh_table *tbl,
+static int mlxsw_sp_span_dmac(int family,
 			      const void *pkey,
 			      struct net_device *dev,
 			      unsigned char dmac[ETH_ALEN])
 {
-	struct neighbour *neigh = neigh_lookup(tbl, pkey, dev);
+	struct net *net = dev_net(dev);
+	struct neigh_table *tbl;
+	struct neighbour *neigh;
 	int err = 0;
 
+#if IS_ENABLED(CONFIG_IPV6_GRE)
+	if (family == AF_INET6)
+		tbl = nd_table(net);
+	else
+#endif
+		tbl = arp_table(net);
+
+	neigh = neigh_lookup(tbl, pkey, dev);
 	if (!neigh) {
 		neigh = neigh_create(tbl, pkey, dev);
 		if (IS_ERR(neigh))
@@ -355,8 +365,7 @@ mlxsw_sp_span_entry_tunnel_parms_common(struct net_device *edev,
 					union mlxsw_sp_l3addr saddr,
 					union mlxsw_sp_l3addr daddr,
 					union mlxsw_sp_l3addr gw,
-					__u8 ttl,
-					struct neigh_table *tbl,
+					__u8 ttl, int family,
 					struct mlxsw_sp_span_parms *sparmsp)
 {
 	unsigned char dmac[ETH_ALEN];
@@ -365,7 +374,7 @@ mlxsw_sp_span_entry_tunnel_parms_common(struct net_device *edev,
 	if (mlxsw_sp_l3addr_is_zero(gw))
 		gw = daddr;
 
-	if (!edev || mlxsw_sp_span_dmac(tbl, &gw, edev, dmac))
+	if (!edev || mlxsw_sp_span_dmac(family, &gw, edev, dmac))
 		goto unoffloadable;
 
 	if (is_vlan_dev(edev))
@@ -456,7 +465,6 @@ mlxsw_sp_span_entry_gretap4_parms(struct mlxsw_sp *mlxsw_sp,
 	bool inherit_tos = tparm.iph.tos & 0x1;
 	bool inherit_ttl = !tparm.iph.ttl;
 	union mlxsw_sp_l3addr gw = daddr;
-	struct neigh_table *tbl = NULL;
 	struct net_device *l3edev;
 
 	if (!(to_dev->flags & IFF_UP) ||
@@ -470,11 +478,10 @@ mlxsw_sp_span_entry_gretap4_parms(struct mlxsw_sp *mlxsw_sp,
 		return mlxsw_sp_span_entry_unoffloadable(sparmsp);
 
 	l3edev = mlxsw_sp_span_gretap4_route(to_dev, &saddr.addr4, &gw.addr4);
-	if (l3edev)
-		tbl = arp_table(dev_net(l3edev));
+
 	return mlxsw_sp_span_entry_tunnel_parms_common(l3edev, saddr, daddr, gw,
 						       tparm.iph.ttl,
-						       tbl, sparmsp);
+						       AF_INET, sparmsp);
 }
 
 static int
@@ -564,7 +571,6 @@ mlxsw_sp_span_entry_gretap6_parms(struct mlxsw_sp *mlxsw_sp,
 	union mlxsw_sp_l3addr daddr = { .addr6 = tparm.raddr };
 	bool inherit_ttl = !tparm.hop_limit;
 	union mlxsw_sp_l3addr gw = daddr;
-	struct neigh_table *tbl = NULL;
 	struct net_device *l3edev;
 
 	if (!(to_dev->flags & IFF_UP) ||
@@ -578,11 +584,10 @@ mlxsw_sp_span_entry_gretap6_parms(struct mlxsw_sp *mlxsw_sp,
 		return mlxsw_sp_span_entry_unoffloadable(sparmsp);
 
 	l3edev = mlxsw_sp_span_gretap6_route(to_dev, &saddr.addr6, &gw.addr6);
-	if (l3edev)
-		tbl = nd_table(dev_net(l3edev));
+
 	return mlxsw_sp_span_entry_tunnel_parms_common(l3edev, saddr, daddr, gw,
 						       tparm.hop_limit,
-						       tbl, sparmsp);
+						       AF_INET6, sparmsp);
 }
 
 static int
-- 
2.56.0.rc1.315.gc6ed9934b7-goog


  parent reply	other threads:[~2026-09-30 20:03 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-30 20:03 [PATCH v1 net-next 0/8] neighbour: Add IPv4/IPv6-specific wrappers for neigh_lookup() and friends Kuniyuki Iwashima
2026-09-30 20:03 ` [PATCH v1 net-next 1/8] ipv4: Rename ipv4_neigh_lookup() to ipv4_dst_neigh_lookup() Kuniyuki Iwashima
2026-09-30 20:03 ` [PATCH v1 net-next 2/8] ipv6: Rename ip6_neigh_lookup() to __ip6_dst_neigh_lookup() Kuniyuki Iwashima
2026-09-30 20:03 ` [PATCH v1 net-next 3/8] ipv4: Add wrappers for neigh_lookup() and neigh_create() Kuniyuki Iwashima
2026-09-30 20:03 ` [PATCH v1 net-next 4/8] ipv6: Add wrappers for neigh_lookup() and (__)?neigh_create() Kuniyuki Iwashima
2026-09-30 20:03 ` Kuniyuki Iwashima [this message]
2026-09-30 20:03 ` [PATCH v1 net-next 6/8] ipv6: Use ipv6_neigh_lookup() and friends Kuniyuki Iwashima
2026-10-02  2:03   ` netdev-bot+sashiko
2026-10-02 17:01     ` Kuniyuki Iwashima
2026-09-30 20:03 ` [PATCH v1 net-next 7/8] ipv4: Use ipv4_neigh_lookup() " Kuniyuki Iwashima
2026-10-02  2:03   ` netdev-bot+sashiko
2026-09-30 20:03 ` [PATCH v1 net-next 8/8] neighbour: Remove __neigh_lookup() and __neigh_lookup_errno() Kuniyuki Iwashima

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260930200326.718459-6-kuniyu@google.com \
    --to=kuniyu@google.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=edumazet@kernel.org \
    --cc=horms@kernel.org \
    --cc=idosch@nvidia.com \
    --cc=kuba@kernel.org \
    --cc=kuni1840@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=petrm@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.