]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ipv6: Move some validation from ip6_route_info_create() to rtm_to_fib6_config().
authorKuniyuki Iwashima <kuniyu@amazon.com>
Fri, 18 Apr 2025 00:03:44 +0000 (17:03 -0700)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 24 Apr 2025 07:29:55 +0000 (09:29 +0200)
ip6_route_info_create() is called from 3 functions:

  * ip6_route_add()
  * ip6_route_multipath_add()
  * addrconf_f6i_alloc()

addrconf_f6i_alloc() does not need validation for struct fib6_config in
ip6_route_info_create().

ip6_route_multipath_add() calls ip6_route_info_create() for multiple
routes with slightly different fib6_config instances, which is copied
from the base config passed from userspace.  So, we need not validate
the same config repeatedly.

Let's move such validation into rtm_to_fib6_config().

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Acked-by: Paolo Abeni <pabeni@redhat.com>
Link: https://patch.msgid.link/20250418000443.43734-4-kuniyu@amazon.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
net/ipv6/route.c

index 1c304f259d9b41158a765b06d22277dce637fecf..aa92e02a47f498f4d3aaa4359468c45c0bbf3b52 100644 (file)
@@ -3740,38 +3740,6 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
        int err = -EINVAL;
        int addr_type;
 
-       /* RTF_PCPU is an internal flag; can not be set by userspace */
-       if (cfg->fc_flags & RTF_PCPU) {
-               NL_SET_ERR_MSG(extack, "Userspace can not set RTF_PCPU");
-               goto out;
-       }
-
-       /* RTF_CACHE is an internal flag; can not be set by userspace */
-       if (cfg->fc_flags & RTF_CACHE) {
-               NL_SET_ERR_MSG(extack, "Userspace can not set RTF_CACHE");
-               goto out;
-       }
-
-       if (cfg->fc_type > RTN_MAX) {
-               NL_SET_ERR_MSG(extack, "Invalid route type");
-               goto out;
-       }
-
-       if (cfg->fc_dst_len > 128) {
-               NL_SET_ERR_MSG(extack, "Invalid prefix length");
-               goto out;
-       }
-       if (cfg->fc_src_len > 128) {
-               NL_SET_ERR_MSG(extack, "Invalid source address length");
-               goto out;
-       }
-#ifndef CONFIG_IPV6_SUBTREES
-       if (cfg->fc_src_len) {
-               NL_SET_ERR_MSG(extack,
-                              "Specifying source address requires IPV6_SUBTREES to be enabled");
-               goto out;
-       }
-#endif
        if (cfg->fc_nh_id) {
                nh = nexthop_find_by_id(net, cfg->fc_nh_id);
                if (!nh) {
@@ -3836,11 +3804,6 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
        rt->fib6_src.plen = cfg->fc_src_len;
 #endif
        if (nh) {
-               if (rt->fib6_src.plen) {
-                       NL_SET_ERR_MSG(extack, "Nexthops can not be used with source routing");
-                       err = -EINVAL;
-                       goto out_free;
-               }
                if (!nexthop_get(nh)) {
                        NL_SET_ERR_MSG(extack, "Nexthop has been deleted");
                        err = -ENOENT;
@@ -5240,6 +5203,48 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
                }
        }
 
+       if (newroute) {
+               /* RTF_PCPU is an internal flag; can not be set by userspace */
+               if (cfg->fc_flags & RTF_PCPU) {
+                       NL_SET_ERR_MSG(extack, "Userspace can not set RTF_PCPU");
+                       goto errout;
+               }
+
+               /* RTF_CACHE is an internal flag; can not be set by userspace */
+               if (cfg->fc_flags & RTF_CACHE) {
+                       NL_SET_ERR_MSG(extack, "Userspace can not set RTF_CACHE");
+                       goto errout;
+               }
+
+               if (cfg->fc_type > RTN_MAX) {
+                       NL_SET_ERR_MSG(extack, "Invalid route type");
+                       goto errout;
+               }
+
+               if (cfg->fc_dst_len > 128) {
+                       NL_SET_ERR_MSG(extack, "Invalid prefix length");
+                       goto errout;
+               }
+
+#ifdef CONFIG_IPV6_SUBTREES
+               if (cfg->fc_src_len > 128) {
+                       NL_SET_ERR_MSG(extack, "Invalid source address length");
+                       goto errout;
+               }
+
+               if (cfg->fc_nh_id &&  cfg->fc_src_len) {
+                       NL_SET_ERR_MSG(extack, "Nexthops can not be used with source routing");
+                       goto errout;
+               }
+#else
+               if (cfg->fc_src_len) {
+                       NL_SET_ERR_MSG(extack,
+                                      "Specifying source address requires IPV6_SUBTREES to be enabled");
+                       goto errout;
+               }
+#endif
+       }
+
        err = 0;
 errout:
        return err;