All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 net-next 0/7] nexthop: Convert RTM_{NEW,DEL}NEXTHOP to per-netns RTNL.
@ 2025-03-18 23:31 Kuniyuki Iwashima
  2025-03-18 23:31 ` [PATCH v1 net-next 1/7] nexthop: Move nlmsg_parse() in rtm_to_nh_config() to rtm_new_nexthop() Kuniyuki Iwashima
                   ` (7 more replies)
  0 siblings, 8 replies; 10+ messages in thread
From: Kuniyuki Iwashima @ 2025-03-18 23:31 UTC (permalink / raw)
  To: David Ahern, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

Patch 1 - 5 move some validation for RTM_NEWNEXTHOP so that it can be
done without RTNL.

Patch 6 & 7 converts RTM_NEWNEXTHOP and RTM_DELNEXTHOP to per-netns RTNL.

Note that RTM_GETNEXTHOP and RTM_GETNEXTHOPBUCKET are not touched in
this series.

rtm_get_nexthop() can be easily converted to RCU, but rtm_dump_nexthop()
needs more work due to the left-to-right rbtree walk, which looks prone
to node deletion and tree rotation without a retry mechanism.


Kuniyuki Iwashima (7):
  nexthop: Move nlmsg_parse() in rtm_to_nh_config() to
    rtm_new_nexthop().
  nexthop: Split nh_check_attr_group().
  nexthop: Move NHA_OIF validation to rtm_to_nh_config_rtnl().
  nexthop: Check NLM_F_REPLACE and NHA_ID in rtm_new_nexthop().
  nexthop: Remove redundant group len check in nexthop_create_group().
  nexthop: Convert RTM_NEWNEXTHOP to per-netns RTNL.
  nexthop: Convert RTM_DELNEXTHOP to per-netns RTNL.

 net/ipv4/nexthop.c | 183 +++++++++++++++++++++++++++------------------
 1 file changed, 112 insertions(+), 71 deletions(-)

-- 
2.48.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v1 net-next 1/7] nexthop: Move nlmsg_parse() in rtm_to_nh_config() to rtm_new_nexthop().
  2025-03-18 23:31 [PATCH v1 net-next 0/7] nexthop: Convert RTM_{NEW,DEL}NEXTHOP to per-netns RTNL Kuniyuki Iwashima
@ 2025-03-18 23:31 ` Kuniyuki Iwashima
  2025-03-18 23:31 ` [PATCH v1 net-next 2/7] nexthop: Split nh_check_attr_group() Kuniyuki Iwashima
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Kuniyuki Iwashima @ 2025-03-18 23:31 UTC (permalink / raw)
  To: David Ahern, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

We will split rtm_to_nh_config() into non-RTNL and RTNL parts,
and then the latter also needs tb.

As a prep, let's move nlmsg_parse() to rtm_new_nexthop().

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 net/ipv4/nexthop.c | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
index 01df7dd795f0..487933ecdb68 100644
--- a/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -3016,19 +3016,13 @@ static int rtm_to_nh_config_grp_res(struct nlattr *res, struct nh_config *cfg,
 }
 
 static int rtm_to_nh_config(struct net *net, struct sk_buff *skb,
-			    struct nlmsghdr *nlh, struct nh_config *cfg,
+			    struct nlmsghdr *nlh, struct nlattr **tb,
+			    struct nh_config *cfg,
 			    struct netlink_ext_ack *extack)
 {
 	struct nhmsg *nhm = nlmsg_data(nlh);
-	struct nlattr *tb[ARRAY_SIZE(rtm_nh_policy_new)];
 	int err;
 
-	err = nlmsg_parse(nlh, sizeof(*nhm), tb,
-			  ARRAY_SIZE(rtm_nh_policy_new) - 1,
-			  rtm_nh_policy_new, extack);
-	if (err < 0)
-		return err;
-
 	err = -EINVAL;
 	if (nhm->resvd || nhm->nh_scope) {
 		NL_SET_ERR_MSG(extack, "Invalid values in ancillary header");
@@ -3093,7 +3087,8 @@ static int rtm_to_nh_config(struct net *net, struct sk_buff *skb,
 			NL_SET_ERR_MSG(extack, "Invalid group type");
 			goto out;
 		}
-		err = nh_check_attr_group(net, tb, ARRAY_SIZE(tb),
+
+		err = nh_check_attr_group(net, tb, ARRAY_SIZE(rtm_nh_policy_new),
 					  cfg->nh_grp_type, extack);
 		if (err)
 			goto out;
@@ -3211,18 +3206,26 @@ static int rtm_to_nh_config(struct net *net, struct sk_buff *skb,
 static int rtm_new_nexthop(struct sk_buff *skb, struct nlmsghdr *nlh,
 			   struct netlink_ext_ack *extack)
 {
+	struct nlattr *tb[ARRAY_SIZE(rtm_nh_policy_new)];
 	struct net *net = sock_net(skb->sk);
 	struct nh_config cfg;
 	struct nexthop *nh;
 	int err;
 
-	err = rtm_to_nh_config(net, skb, nlh, &cfg, extack);
-	if (!err) {
-		nh = nexthop_add(net, &cfg, extack);
-		if (IS_ERR(nh))
-			err = PTR_ERR(nh);
-	}
+	err = nlmsg_parse(nlh, sizeof(struct nhmsg), tb,
+			  ARRAY_SIZE(rtm_nh_policy_new) - 1,
+			  rtm_nh_policy_new, extack);
+	if (err < 0)
+		goto out;
 
+	err = rtm_to_nh_config(net, skb, nlh, tb, &cfg, extack);
+	if (err)
+		goto out;
+
+	nh = nexthop_add(net, &cfg, extack);
+	if (IS_ERR(nh))
+		err = PTR_ERR(nh);
+out:
 	return err;
 }
 
-- 
2.48.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v1 net-next 2/7] nexthop: Split nh_check_attr_group().
  2025-03-18 23:31 [PATCH v1 net-next 0/7] nexthop: Convert RTM_{NEW,DEL}NEXTHOP to per-netns RTNL Kuniyuki Iwashima
  2025-03-18 23:31 ` [PATCH v1 net-next 1/7] nexthop: Move nlmsg_parse() in rtm_to_nh_config() to rtm_new_nexthop() Kuniyuki Iwashima
@ 2025-03-18 23:31 ` Kuniyuki Iwashima
  2025-03-18 23:31 ` [PATCH v1 net-next 3/7] nexthop: Move NHA_OIF validation to rtm_to_nh_config_rtnl() Kuniyuki Iwashima
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Kuniyuki Iwashima @ 2025-03-18 23:31 UTC (permalink / raw)
  To: David Ahern, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

We will push RTNL down to rtm_new_nexthop(), and then we want
to move non-RTNL operations out of the scope.

nh_check_attr_group() validates NHA_GROUP attributes, and some
validation requires RTNL.

Let's factorise such parts as nh_check_attr_group_rtnl() and
call it from rtm_to_nh_config_rtnl().

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 net/ipv4/nexthop.c | 68 ++++++++++++++++++++++++++++++++--------------
 1 file changed, 47 insertions(+), 21 deletions(-)

diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
index 487933ecdb68..98d5bf6e40f9 100644
--- a/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -1272,10 +1272,8 @@ static int nh_check_attr_group(struct net *net,
 			       u16 nh_grp_type, struct netlink_ext_ack *extack)
 {
 	unsigned int len = nla_len(tb[NHA_GROUP]);
-	u8 nh_family = AF_UNSPEC;
 	struct nexthop_grp *nhg;
 	unsigned int i, j;
-	u8 nhg_fdb = 0;
 
 	if (!len || len & (sizeof(struct nexthop_grp) - 1)) {
 		NL_SET_ERR_MSG(extack,
@@ -1307,10 +1305,41 @@ static int nh_check_attr_group(struct net *net,
 		}
 	}
 
-	if (tb[NHA_FDB])
-		nhg_fdb = 1;
 	nhg = nla_data(tb[NHA_GROUP]);
-	for (i = 0; i < len; ++i) {
+	for (i = NHA_GROUP_TYPE + 1; i < tb_size; ++i) {
+		if (!tb[i])
+			continue;
+		switch (i) {
+		case NHA_HW_STATS_ENABLE:
+		case NHA_FDB:
+			continue;
+		case NHA_RES_GROUP:
+			if (nh_grp_type == NEXTHOP_GRP_TYPE_RES)
+				continue;
+			break;
+		}
+		NL_SET_ERR_MSG(extack,
+			       "No other attributes can be set in nexthop groups");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int nh_check_attr_group_rtnl(struct net *net, struct nlattr *tb[],
+				    struct netlink_ext_ack *extack)
+{
+	u8 nh_family = AF_UNSPEC;
+	struct nexthop_grp *nhg;
+	unsigned int len;
+	unsigned int i;
+	u8 nhg_fdb;
+
+	len = nla_len(tb[NHA_GROUP]) / sizeof(*nhg);
+	nhg = nla_data(tb[NHA_GROUP]);
+	nhg_fdb = !!tb[NHA_FDB];
+
+	for (i = 0; i < len; i++) {
 		struct nexthop *nh;
 		bool is_fdb_nh;
 
@@ -1330,22 +1359,6 @@ static int nh_check_attr_group(struct net *net,
 			return -EINVAL;
 		}
 	}
-	for (i = NHA_GROUP_TYPE + 1; i < tb_size; ++i) {
-		if (!tb[i])
-			continue;
-		switch (i) {
-		case NHA_HW_STATS_ENABLE:
-		case NHA_FDB:
-			continue;
-		case NHA_RES_GROUP:
-			if (nh_grp_type == NEXTHOP_GRP_TYPE_RES)
-				continue;
-			break;
-		}
-		NL_SET_ERR_MSG(extack,
-			       "No other attributes can be set in nexthop groups");
-		return -EINVAL;
-	}
 
 	return 0;
 }
@@ -3202,6 +3215,15 @@ static int rtm_to_nh_config(struct net *net, struct sk_buff *skb,
 	return err;
 }
 
+static int rtm_to_nh_config_rtnl(struct net *net, struct nlattr **tb,
+				 struct netlink_ext_ack *extack)
+{
+	if (tb[NHA_GROUP])
+		return nh_check_attr_group_rtnl(net, tb, extack);
+
+	return 0;
+}
+
 /* rtnl */
 static int rtm_new_nexthop(struct sk_buff *skb, struct nlmsghdr *nlh,
 			   struct netlink_ext_ack *extack)
@@ -3222,6 +3244,10 @@ static int rtm_new_nexthop(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (err)
 		goto out;
 
+	err = rtm_to_nh_config_rtnl(net, tb, extack);
+	if (!err)
+		goto out;
+
 	nh = nexthop_add(net, &cfg, extack);
 	if (IS_ERR(nh))
 		err = PTR_ERR(nh);
-- 
2.48.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v1 net-next 3/7] nexthop: Move NHA_OIF validation to rtm_to_nh_config_rtnl().
  2025-03-18 23:31 [PATCH v1 net-next 0/7] nexthop: Convert RTM_{NEW,DEL}NEXTHOP to per-netns RTNL Kuniyuki Iwashima
  2025-03-18 23:31 ` [PATCH v1 net-next 1/7] nexthop: Move nlmsg_parse() in rtm_to_nh_config() to rtm_new_nexthop() Kuniyuki Iwashima
  2025-03-18 23:31 ` [PATCH v1 net-next 2/7] nexthop: Split nh_check_attr_group() Kuniyuki Iwashima
@ 2025-03-18 23:31 ` Kuniyuki Iwashima
  2025-03-18 23:31 ` [PATCH v1 net-next 4/7] nexthop: Check NLM_F_REPLACE and NHA_ID in rtm_new_nexthop() Kuniyuki Iwashima
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Kuniyuki Iwashima @ 2025-03-18 23:31 UTC (permalink / raw)
  To: David Ahern, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

NHA_OIF needs to look up a device by __dev_get_by_index(),
which requires RTNL.

Let's move NHA_OIF validation to rtm_to_nh_config_rtnl().

Note that the proceeding checks made the original !cfg->nh_fdb
check redundant.

  NHA_FDB is set           -> NHA_OIF cannot be set
  NHA_FDB is set but false -> NHA_OIF must be set
  NHA_FDB is not set       -> NHA_OIF must be set

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 net/ipv4/nexthop.c | 43 +++++++++++++++++++++++--------------------
 1 file changed, 23 insertions(+), 20 deletions(-)

diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
index 98d5bf6e40f9..f21ea1ddd68f 100644
--- a/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -3134,25 +3134,6 @@ static int rtm_to_nh_config(struct net *net, struct sk_buff *skb,
 		goto out;
 	}
 
-	if (!cfg->nh_fdb && tb[NHA_OIF]) {
-		cfg->nh_ifindex = nla_get_u32(tb[NHA_OIF]);
-		if (cfg->nh_ifindex)
-			cfg->dev = __dev_get_by_index(net, cfg->nh_ifindex);
-
-		if (!cfg->dev) {
-			NL_SET_ERR_MSG(extack, "Invalid device index");
-			goto out;
-		} else if (!(cfg->dev->flags & IFF_UP)) {
-			NL_SET_ERR_MSG(extack, "Nexthop device is not up");
-			err = -ENETDOWN;
-			goto out;
-		} else if (!netif_carrier_ok(cfg->dev)) {
-			NL_SET_ERR_MSG(extack, "Carrier for nexthop device is down");
-			err = -ENETDOWN;
-			goto out;
-		}
-	}
-
 	err = -EINVAL;
 	if (tb[NHA_GATEWAY]) {
 		struct nlattr *gwa = tb[NHA_GATEWAY];
@@ -3216,11 +3197,33 @@ static int rtm_to_nh_config(struct net *net, struct sk_buff *skb,
 }
 
 static int rtm_to_nh_config_rtnl(struct net *net, struct nlattr **tb,
+				 struct nh_config *cfg,
 				 struct netlink_ext_ack *extack)
 {
 	if (tb[NHA_GROUP])
 		return nh_check_attr_group_rtnl(net, tb, extack);
 
+	if (tb[NHA_OIF]) {
+		cfg->nh_ifindex = nla_get_u32(tb[NHA_OIF]);
+		if (cfg->nh_ifindex)
+			cfg->dev = __dev_get_by_index(net, cfg->nh_ifindex);
+
+		if (!cfg->dev) {
+			NL_SET_ERR_MSG(extack, "Invalid device index");
+			return -EINVAL;
+		}
+
+		if (!(cfg->dev->flags & IFF_UP)) {
+			NL_SET_ERR_MSG(extack, "Nexthop device is not up");
+			return -ENETDOWN;
+		}
+
+		if (!netif_carrier_ok(cfg->dev)) {
+			NL_SET_ERR_MSG(extack, "Carrier for nexthop device is down");
+			return -ENETDOWN;
+		}
+	}
+
 	return 0;
 }
 
@@ -3244,7 +3247,7 @@ static int rtm_new_nexthop(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (err)
 		goto out;
 
-	err = rtm_to_nh_config_rtnl(net, tb, extack);
+	err = rtm_to_nh_config_rtnl(net, tb, &cfg, extack);
 	if (!err)
 		goto out;
 
-- 
2.48.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v1 net-next 4/7] nexthop: Check NLM_F_REPLACE and NHA_ID in rtm_new_nexthop().
  2025-03-18 23:31 [PATCH v1 net-next 0/7] nexthop: Convert RTM_{NEW,DEL}NEXTHOP to per-netns RTNL Kuniyuki Iwashima
                   ` (2 preceding siblings ...)
  2025-03-18 23:31 ` [PATCH v1 net-next 3/7] nexthop: Move NHA_OIF validation to rtm_to_nh_config_rtnl() Kuniyuki Iwashima
@ 2025-03-18 23:31 ` Kuniyuki Iwashima
  2025-03-18 23:31 ` [PATCH v1 net-next 5/7] nexthop: Remove redundant group len check in nexthop_create_group() Kuniyuki Iwashima
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Kuniyuki Iwashima @ 2025-03-18 23:31 UTC (permalink / raw)
  To: David Ahern, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

nexthop_add() checks if NLM_F_REPLACE is specified without
non-zero NHA_ID, which does not require RTNL.

Let's move the check to rtm_new_nexthop().

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 net/ipv4/nexthop.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
index f21ea1ddd68f..09f5f31f34a0 100644
--- a/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -2928,11 +2928,6 @@ static struct nexthop *nexthop_add(struct net *net, struct nh_config *cfg,
 	struct nexthop *nh;
 	int err;
 
-	if (cfg->nlflags & NLM_F_REPLACE && !cfg->nh_id) {
-		NL_SET_ERR_MSG(extack, "Replace requires nexthop id");
-		return ERR_PTR(-EINVAL);
-	}
-
 	if (!cfg->nh_id) {
 		cfg->nh_id = nh_find_unused_id(net);
 		if (!cfg->nh_id) {
@@ -3247,6 +3242,12 @@ static int rtm_new_nexthop(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (err)
 		goto out;
 
+	if (cfg.nlflags & NLM_F_REPLACE && !cfg.nh_id) {
+		NL_SET_ERR_MSG(extack, "Replace requires nexthop id");
+		err = -EINVAL;
+		goto out;
+	}
+
 	err = rtm_to_nh_config_rtnl(net, tb, &cfg, extack);
 	if (!err)
 		goto out;
-- 
2.48.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v1 net-next 5/7] nexthop: Remove redundant group len check in nexthop_create_group().
  2025-03-18 23:31 [PATCH v1 net-next 0/7] nexthop: Convert RTM_{NEW,DEL}NEXTHOP to per-netns RTNL Kuniyuki Iwashima
                   ` (3 preceding siblings ...)
  2025-03-18 23:31 ` [PATCH v1 net-next 4/7] nexthop: Check NLM_F_REPLACE and NHA_ID in rtm_new_nexthop() Kuniyuki Iwashima
@ 2025-03-18 23:31 ` Kuniyuki Iwashima
  2025-03-18 23:31 ` [PATCH v1 net-next 6/7] nexthop: Convert RTM_NEWNEXTHOP to per-netns RTNL Kuniyuki Iwashima
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Kuniyuki Iwashima @ 2025-03-18 23:31 UTC (permalink / raw)
  To: David Ahern, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

The number of NHA_GROUP entries is guaranteed to be non-zero in
nh_check_attr_group().

Let's remove the redundant check in nexthop_create_group().

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 net/ipv4/nexthop.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
index 09f5f31f34a0..409f13d64ed4 100644
--- a/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -2692,9 +2692,6 @@ static struct nexthop *nexthop_create_group(struct net *net,
 	int err;
 	int i;
 
-	if (WARN_ON(!num_nh))
-		return ERR_PTR(-EINVAL);
-
 	nh = nexthop_alloc();
 	if (!nh)
 		return ERR_PTR(-ENOMEM);
-- 
2.48.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v1 net-next 6/7] nexthop: Convert RTM_NEWNEXTHOP to per-netns RTNL.
  2025-03-18 23:31 [PATCH v1 net-next 0/7] nexthop: Convert RTM_{NEW,DEL}NEXTHOP to per-netns RTNL Kuniyuki Iwashima
                   ` (4 preceding siblings ...)
  2025-03-18 23:31 ` [PATCH v1 net-next 5/7] nexthop: Remove redundant group len check in nexthop_create_group() Kuniyuki Iwashima
@ 2025-03-18 23:31 ` Kuniyuki Iwashima
  2025-03-18 23:31 ` [PATCH v1 net-next 7/7] nexthop: Convert RTM_DELNEXTHOP " Kuniyuki Iwashima
  2025-03-19  7:57 ` [PATCH v1 net-next 0/7] nexthop: Convert RTM_{NEW,DEL}NEXTHOP " Paolo Abeni
  7 siblings, 0 replies; 10+ messages in thread
From: Kuniyuki Iwashima @ 2025-03-18 23:31 UTC (permalink / raw)
  To: David Ahern, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

If we pass false to the rtnl_held param of lwtunnel_valid_encap_type(),
we can move RTNL down before rtm_to_nh_config_rtnl().

Let's use rtnl_net_lock() in rtm_new_nexthop().

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 net/ipv4/nexthop.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
index 409f13d64ed4..ea62454e0a0c 100644
--- a/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -3169,7 +3169,7 @@ static int rtm_to_nh_config(struct net *net, struct sk_buff *skb,
 
 		cfg->nh_encap_type = nla_get_u16(tb[NHA_ENCAP_TYPE]);
 		err = lwtunnel_valid_encap_type(cfg->nh_encap_type,
-						extack, true);
+						extack, false);
 		if (err < 0)
 			goto out;
 
@@ -3245,13 +3245,18 @@ static int rtm_new_nexthop(struct sk_buff *skb, struct nlmsghdr *nlh,
 		goto out;
 	}
 
+	rtnl_net_lock(net);
+
 	err = rtm_to_nh_config_rtnl(net, tb, &cfg, extack);
 	if (!err)
-		goto out;
+		goto unlock;
 
 	nh = nexthop_add(net, &cfg, extack);
 	if (IS_ERR(nh))
 		err = PTR_ERR(nh);
+
+unlock:
+	rtnl_net_unlock(net);
 out:
 	return err;
 }
@@ -4067,18 +4072,19 @@ static struct pernet_operations nexthop_net_ops = {
 };
 
 static const struct rtnl_msg_handler nexthop_rtnl_msg_handlers[] __initconst = {
-	{.msgtype = RTM_NEWNEXTHOP, .doit = rtm_new_nexthop},
+	{.msgtype = RTM_NEWNEXTHOP, .doit = rtm_new_nexthop,
+	 .flags = RTNL_FLAG_DOIT_PERNET},
 	{.msgtype = RTM_DELNEXTHOP, .doit = rtm_del_nexthop},
 	{.msgtype = RTM_GETNEXTHOP, .doit = rtm_get_nexthop,
 	 .dumpit = rtm_dump_nexthop},
 	{.msgtype = RTM_GETNEXTHOPBUCKET, .doit = rtm_get_nexthop_bucket,
 	 .dumpit = rtm_dump_nexthop_bucket},
 	{.protocol = PF_INET, .msgtype = RTM_NEWNEXTHOP,
-	 .doit = rtm_new_nexthop},
+	 .doit = rtm_new_nexthop, .flags = RTNL_FLAG_DOIT_PERNET},
 	{.protocol = PF_INET, .msgtype = RTM_GETNEXTHOP,
 	 .dumpit = rtm_dump_nexthop},
 	{.protocol = PF_INET6, .msgtype = RTM_NEWNEXTHOP,
-	 .doit = rtm_new_nexthop},
+	 .doit = rtm_new_nexthop, .flags = RTNL_FLAG_DOIT_PERNET},
 	{.protocol = PF_INET6, .msgtype = RTM_GETNEXTHOP,
 	 .dumpit = rtm_dump_nexthop},
 };
-- 
2.48.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v1 net-next 7/7] nexthop: Convert RTM_DELNEXTHOP to per-netns RTNL.
  2025-03-18 23:31 [PATCH v1 net-next 0/7] nexthop: Convert RTM_{NEW,DEL}NEXTHOP to per-netns RTNL Kuniyuki Iwashima
                   ` (5 preceding siblings ...)
  2025-03-18 23:31 ` [PATCH v1 net-next 6/7] nexthop: Convert RTM_NEWNEXTHOP to per-netns RTNL Kuniyuki Iwashima
@ 2025-03-18 23:31 ` Kuniyuki Iwashima
  2025-03-19  7:57 ` [PATCH v1 net-next 0/7] nexthop: Convert RTM_{NEW,DEL}NEXTHOP " Paolo Abeni
  7 siblings, 0 replies; 10+ messages in thread
From: Kuniyuki Iwashima @ 2025-03-18 23:31 UTC (permalink / raw)
  To: David Ahern, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni
  Cc: Simon Horman, Kuniyuki Iwashima, Kuniyuki Iwashima, netdev

In rtm_del_nexthop(), only nexthop_find_by_id() and remove_nexthop()
require RTNL as they touch net->nexthop.rb_root.

Let's move RTNL down as rtnl_net_lock() before nexthop_find_by_id().

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
---
 net/ipv4/nexthop.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
index ea62454e0a0c..66d7796ba174 100644
--- a/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -3314,13 +3314,17 @@ static int rtm_del_nexthop(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (err)
 		return err;
 
+	rtnl_net_lock(net);
+
 	nh = nexthop_find_by_id(net, id);
-	if (!nh)
-		return -ENOENT;
+	if (nh)
+		remove_nexthop(net, nh, &nlinfo);
+	else
+		err = -ENOENT;
 
-	remove_nexthop(net, nh, &nlinfo);
+	rtnl_net_unlock(net);
 
-	return 0;
+	return err;
 }
 
 /* rtnl */
@@ -4074,7 +4078,8 @@ static struct pernet_operations nexthop_net_ops = {
 static const struct rtnl_msg_handler nexthop_rtnl_msg_handlers[] __initconst = {
 	{.msgtype = RTM_NEWNEXTHOP, .doit = rtm_new_nexthop,
 	 .flags = RTNL_FLAG_DOIT_PERNET},
-	{.msgtype = RTM_DELNEXTHOP, .doit = rtm_del_nexthop},
+	{.msgtype = RTM_DELNEXTHOP, .doit = rtm_del_nexthop,
+	 .flags = RTNL_FLAG_DOIT_PERNET},
 	{.msgtype = RTM_GETNEXTHOP, .doit = rtm_get_nexthop,
 	 .dumpit = rtm_dump_nexthop},
 	{.msgtype = RTM_GETNEXTHOPBUCKET, .doit = rtm_get_nexthop_bucket,
-- 
2.48.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v1 net-next 0/7] nexthop: Convert RTM_{NEW,DEL}NEXTHOP to per-netns RTNL.
  2025-03-18 23:31 [PATCH v1 net-next 0/7] nexthop: Convert RTM_{NEW,DEL}NEXTHOP to per-netns RTNL Kuniyuki Iwashima
                   ` (6 preceding siblings ...)
  2025-03-18 23:31 ` [PATCH v1 net-next 7/7] nexthop: Convert RTM_DELNEXTHOP " Kuniyuki Iwashima
@ 2025-03-19  7:57 ` Paolo Abeni
  2025-03-19 15:57   ` Kuniyuki Iwashima
  7 siblings, 1 reply; 10+ messages in thread
From: Paolo Abeni @ 2025-03-19  7:57 UTC (permalink / raw)
  To: Kuniyuki Iwashima, David Ahern, David S. Miller, Eric Dumazet,
	Jakub Kicinski
  Cc: Simon Horman, Kuniyuki Iwashima, netdev

Hi,

On 3/19/25 12:31 AM, Kuniyuki Iwashima wrote:
> Patch 1 - 5 move some validation for RTM_NEWNEXTHOP so that it can be
> done without RTNL.
> 
> Patch 6 & 7 converts RTM_NEWNEXTHOP and RTM_DELNEXTHOP to per-netns RTNL.
> 
> Note that RTM_GETNEXTHOP and RTM_GETNEXTHOPBUCKET are not touched in
> this series.
> 
> rtm_get_nexthop() can be easily converted to RCU, but rtm_dump_nexthop()
> needs more work due to the left-to-right rbtree walk, which looks prone
> to node deletion and tree rotation without a retry mechanism.
> 
> 
> Kuniyuki Iwashima (7):
>   nexthop: Move nlmsg_parse() in rtm_to_nh_config() to
>     rtm_new_nexthop().
>   nexthop: Split nh_check_attr_group().
>   nexthop: Move NHA_OIF validation to rtm_to_nh_config_rtnl().
>   nexthop: Check NLM_F_REPLACE and NHA_ID in rtm_new_nexthop().
>   nexthop: Remove redundant group len check in nexthop_create_group().
>   nexthop: Convert RTM_NEWNEXTHOP to per-netns RTNL.
>   nexthop: Convert RTM_DELNEXTHOP to per-netns RTNL.
> 
>  net/ipv4/nexthop.c | 183 +++++++++++++++++++++++++++------------------
>  1 file changed, 112 insertions(+), 71 deletions(-)

This series is apparently causing NULL ptr deref in the nexthop.sh
netdevsim selftests. Unfortunately, due to a transient nipa infra
outage, a lot of stuff landed into the same batch, so I'm not 110% this
series is the real curprit but looks like a reasonable suspect.

Kuniyuki, could you please have a look?

---
[    1.653896] BUG: kernel NULL pointer dereference, address:
0000000000000068
[    1.653963] #PF: supervisor read access in kernel mode
[    1.654003] #PF: error_code(0x0000) - not-present page
[    1.654037] PGD 7828067 P4D 7828067 PUD 782a067 PMD 0
[    1.654077] Oops: Oops: 0000 [#1] PREEMPT SMP NOPTI
[    1.654119] CPU: 0 UID: 0 PID: 303 Comm: ip Not tainted
6.14.0-rc6-virtme #1
[    1.654176] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
[    1.654219] RIP: 0010:rtm_new_nexthop+0x645/0x2260
[    1.654263] Code: 70 02 00 00 48 85 db 75 0e eb 1f 48 83 c3 10 48 8b
1b 48 85 db 74 13 3b 43 60 72 ef 76 0c 48 83 c3 08 48 8b 1b 48 85 db 75
ed <8b> 53 68 4c 8d 63 68 85 d2 0f 84 f1 02 00 00 8d 4a 01 89 d0 f0 41
[    1.654390] RSP: 0018:ffffae348037b860 EFLAGS: 00010246
[    1.654430] RAX: 0000000000000001 RBX: 0000000000000000 RCX:
0000000000000000
[    1.654482] RDX: 0000000000000000 RSI: 0000000000000000 RDI:
ffff992d066b8000
[    1.654534] RBP: ffffae348037bab0 R08: ffff992d012d2fa8 R09:
ffff992d055d1780
[    1.654587] R10: ffffae348037b860 R11: ffff992d055d17c8 R12:
ffffae348037bb60
[    1.654638] R13: 0000000000000000 R14: 0000000000000001 R15:
ffff992d055d17c8
[    1.654692] FS:  00007f8b6fb0c800(0000) GS:ffff992d3ec00000(0000)
knlGS:0000000000000000
[    1.654749] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[    1.654791] CR2: 0000000000000068 CR3: 00000000067ae005 CR4:
0000000000772ef0
[    1.654844] DR0: 0000000000000000 DR1: 0000000000000000 DR2:
0000000000000000
[    1.654900] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7:
0000000000000400
[    1.654957] PKRU: 55555554
[    1.654974] Call Trace:
[    1.654993]  <TASK>
[    1.655015]  ? __die+0x24/0x70
[    1.655049]  ? page_fault_oops+0x15a/0x450
[    1.655080]  ? mas_topiary_replace+0x9ba/0xca0
[    1.655121]  ? exc_page_fault+0x69/0x150
[    1.655162]  ? asm_exc_page_fault+0x26/0x30
[    1.655202]  ? rtm_new_nexthop+0x645/0x2260
[    1.655239]  ? virtqueue_notify+0x1c/0x40
[    1.655269]  ? virtio_fs_enqueue_req+0x50c/0x570
[    1.655311]  ? __pfx_rtm_new_nexthop+0x10/0x10
[    1.655351]  ? rtnetlink_rcv_msg+0x361/0x410
[    1.655391]  rtnetlink_rcv_msg+0x361/0x410
[    1.655417]  ? __remove_hrtimer+0x39/0x90
[    1.655448]  ? sysvec_apic_timer_interrupt+0xf/0x90
[    1.655494]  ? __pfx_rtnetlink_rcv_msg+0x10/0x10
[    1.655528]  netlink_rcv_skb+0x58/0x110
[    1.655560]  netlink_unicast+0x247/0x370
[    1.655592]  netlink_sendmsg+0x1bf/0x3e0
[    1.655624]  ____sys_sendmsg+0x2bc/0x320
[    1.655656]  ? copy_msghdr_from_user+0x6d/0xa0
[    1.655696]  ___sys_sendmsg+0x88/0xd0
[    1.655729]  __sys_sendmsg+0x6c/0xc0
[    1.655760]  do_syscall_64+0x9e/0x1a0
[    1.655793]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[    1.655834] RIP: 0033:0x7f8b6fd189a7
[    1.655864] Code: 0a 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b9 0f
1f 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 2e 00 00 00 0f
05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 89 54 24 1c 48 89 74 24 10
[    1.655986] RSP: 002b:00007ffebd919418 EFLAGS: 00000246 ORIG_RAX:
000000000000002e
[    1.656043] RAX: ffffffffffffffda RBX: 00007ffebd919f80 RCX:
00007f8b6fd189a7
[    1.656099] RDX: 0000000000000000 RSI: 00007ffebd919480 RDI:
0000000000000005
[    1.656151] RBP: 00007ffebd919940 R08: 0000000006ba3910 R09:
0000000000000000
[    1.656202] R10: 00007f8b6fbd1708 R11: 0000000000000246 R12:
0000000006ba3918
[    1.656254] R13: 0000000067da36b9 R14: 0000000000498600 R15:
0000000006ba3910
[    1.656307]  </TASK>
[    1.656324] Modules linked in: netdevsim
[    1.656356] CR2: 0000000000000068


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v1 net-next 0/7] nexthop: Convert RTM_{NEW,DEL}NEXTHOP to per-netns RTNL.
  2025-03-19  7:57 ` [PATCH v1 net-next 0/7] nexthop: Convert RTM_{NEW,DEL}NEXTHOP " Paolo Abeni
@ 2025-03-19 15:57   ` Kuniyuki Iwashima
  0 siblings, 0 replies; 10+ messages in thread
From: Kuniyuki Iwashima @ 2025-03-19 15:57 UTC (permalink / raw)
  To: pabeni; +Cc: davem, dsahern, edumazet, horms, kuba, kuni1840, kuniyu, netdev

From: Paolo Abeni <pabeni@redhat.com>
Date: Wed, 19 Mar 2025 08:57:52 +0100
> Hi,
> 
> On 3/19/25 12:31 AM, Kuniyuki Iwashima wrote:
> > Patch 1 - 5 move some validation for RTM_NEWNEXTHOP so that it can be
> > done without RTNL.
> > 
> > Patch 6 & 7 converts RTM_NEWNEXTHOP and RTM_DELNEXTHOP to per-netns RTNL.
> > 
> > Note that RTM_GETNEXTHOP and RTM_GETNEXTHOPBUCKET are not touched in
> > this series.
> > 
> > rtm_get_nexthop() can be easily converted to RCU, but rtm_dump_nexthop()
> > needs more work due to the left-to-right rbtree walk, which looks prone
> > to node deletion and tree rotation without a retry mechanism.
> > 
> > 
> > Kuniyuki Iwashima (7):
> >   nexthop: Move nlmsg_parse() in rtm_to_nh_config() to
> >     rtm_new_nexthop().
> >   nexthop: Split nh_check_attr_group().
> >   nexthop: Move NHA_OIF validation to rtm_to_nh_config_rtnl().
> >   nexthop: Check NLM_F_REPLACE and NHA_ID in rtm_new_nexthop().
> >   nexthop: Remove redundant group len check in nexthop_create_group().
> >   nexthop: Convert RTM_NEWNEXTHOP to per-netns RTNL.
> >   nexthop: Convert RTM_DELNEXTHOP to per-netns RTNL.
> > 
> >  net/ipv4/nexthop.c | 183 +++++++++++++++++++++++++++------------------
> >  1 file changed, 112 insertions(+), 71 deletions(-)
> 
> This series is apparently causing NULL ptr deref in the nexthop.sh
> netdevsim selftests. Unfortunately, due to a transient nipa infra
> outage, a lot of stuff landed into the same batch, so I'm not 110% this
> series is the real curprit but looks like a reasonable suspect.
> 
> Kuniyuki, could you please have a look?
> 
> ---
> [    1.653896] BUG: kernel NULL pointer dereference, address:
> 0000000000000068
> [    1.653963] #PF: supervisor read access in kernel mode
> [    1.654003] #PF: error_code(0x0000) - not-present page
> [    1.654037] PGD 7828067 P4D 7828067 PUD 782a067 PMD 0
> [    1.654077] Oops: Oops: 0000 [#1] PREEMPT SMP NOPTI
> [    1.654119] CPU: 0 UID: 0 PID: 303 Comm: ip Not tainted
> 6.14.0-rc6-virtme #1
> [    1.654176] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
> [    1.654219] RIP: 0010:rtm_new_nexthop+0x645/0x2260

Sorry, I failed to resolve conflict during the last minute rebase,
and the normal test bailed out here...

---8<---
@@ -3245,7 +3248,7 @@ static int rtm_new_nexthop(struct sk_buff *skb, struct nlmsghdr *nlh,
 		goto out;
 
 	err = rtm_to_nh_config_rtnl(net, tb, extack);
-	if (!err)
+	if (err)
 		goto out;
 
 	nh = nexthop_add(net, &cfg, extack);
---8<---

The failed test case created a nexthop group with an invalid ID,
and nexthop_get() for nh by nexthop_find_by_id() assumes nh is not
NULL because it's checked in advance.

Will squash the diff above in v2.

Thanks!

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2025-03-19 15:59 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-18 23:31 [PATCH v1 net-next 0/7] nexthop: Convert RTM_{NEW,DEL}NEXTHOP to per-netns RTNL Kuniyuki Iwashima
2025-03-18 23:31 ` [PATCH v1 net-next 1/7] nexthop: Move nlmsg_parse() in rtm_to_nh_config() to rtm_new_nexthop() Kuniyuki Iwashima
2025-03-18 23:31 ` [PATCH v1 net-next 2/7] nexthop: Split nh_check_attr_group() Kuniyuki Iwashima
2025-03-18 23:31 ` [PATCH v1 net-next 3/7] nexthop: Move NHA_OIF validation to rtm_to_nh_config_rtnl() Kuniyuki Iwashima
2025-03-18 23:31 ` [PATCH v1 net-next 4/7] nexthop: Check NLM_F_REPLACE and NHA_ID in rtm_new_nexthop() Kuniyuki Iwashima
2025-03-18 23:31 ` [PATCH v1 net-next 5/7] nexthop: Remove redundant group len check in nexthop_create_group() Kuniyuki Iwashima
2025-03-18 23:31 ` [PATCH v1 net-next 6/7] nexthop: Convert RTM_NEWNEXTHOP to per-netns RTNL Kuniyuki Iwashima
2025-03-18 23:31 ` [PATCH v1 net-next 7/7] nexthop: Convert RTM_DELNEXTHOP " Kuniyuki Iwashima
2025-03-19  7:57 ` [PATCH v1 net-next 0/7] nexthop: Convert RTM_{NEW,DEL}NEXTHOP " Paolo Abeni
2025-03-19 15:57   ` Kuniyuki Iwashima

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.