Commit 9b9674f3 authored by Kuniyuki Iwashima's avatar Kuniyuki Iwashima Committed by Jakub Kicinski
Browse files

nexthop: Split nh_check_attr_group().



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
nexthop_find_by_id() 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: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
Reviewed-by: default avatarDavid Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20250319230743.65267-3-kuniyu@amazon.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent ec8de754
Loading
Loading
Loading
Loading
+47 −21
Original line number Diff line number Diff line
@@ -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);