Commit fa76c167 authored by Kuniyuki Iwashima's avatar Kuniyuki Iwashima Committed by Paolo Abeni
Browse files

ipv6: Move some validation from ip6_route_info_create() to rtm_to_fib6_config().



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: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
Acked-by: default avatarPaolo Abeni <pabeni@redhat.com>
Link: https://patch.msgid.link/20250418000443.43734-4-kuniyu@amazon.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent bd11ff42
Loading
Loading
Loading
Loading
+42 −37
Original line number Diff line number Diff line
@@ -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;