]> www.infradead.org Git - users/hch/misc.git/commitdiff
nexthop: Split nh_check_attr_group().
authorKuniyuki Iwashima <kuniyu@amazon.com>
Wed, 19 Mar 2025 23:06:47 +0000 (16:06 -0700)
committerJakub Kicinski <kuba@kernel.org>
Tue, 25 Mar 2025 14:31:59 +0000 (07:31 -0700)
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: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20250319230743.65267-3-kuniyu@amazon.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/ipv4/nexthop.c

index 487933ecdb686f7a0078e0a2ed81a152216b2463..d30edc14b039b2e5c200f7692aff13d9ed2683ac 100644 (file)
@@ -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 @@ out:
        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);