Commit 89da780a authored by Xin Long's avatar Xin Long Committed by Jakub Kicinski
Browse files

rtnetlink: move validate_linkmsg out of do_setlink



This patch moves validate_linkmsg() out of do_setlink() to its callers
and deletes the early validate_linkmsg() call in __rtnl_newlink(), so
that it will not call validate_linkmsg() twice in either of the paths:

  - __rtnl_newlink() -> do_setlink()
  - __rtnl_newlink() -> rtnl_newlink_create() -> rtnl_create_link()

Additionally, as validate_linkmsg() is now only called with a real
dev, we can remove the NULL check for dev in validate_linkmsg().

Note that we moved validate_linkmsg() check to the places where it has
not done any changes to the dev, as Jakub suggested.

Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
Reviewed-by: default avatarSimon Horman <simon.horman@corigine.com>
Link: https://lore.kernel.org/r/cf2ef061e08251faf9e8be25ff0d61150c030475.1686585334.git.lucien.xin@gmail.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent fa0e21fa
Loading
Loading
Loading
Loading
+42 −41
Original line number Diff line number Diff line
@@ -2383,7 +2383,6 @@ static int rtnl_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate,
static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[],
			    struct netlink_ext_ack *extack)
{
	if (dev) {
	if (tb[IFLA_ADDRESS] &&
	    nla_len(tb[IFLA_ADDRESS]) < dev->addr_len)
		return -EINVAL;
@@ -2422,7 +2421,6 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[],
		NL_SET_ERR_MSG(extack, "too big gro_ipv4_max_size");
		return -EINVAL;
	}
	}

	if (tb[IFLA_AF_SPEC]) {
		struct nlattr *af;
@@ -2742,10 +2740,6 @@ static int do_setlink(const struct sk_buff *skb,
	char ifname[IFNAMSIZ];
	int err;

	err = validate_linkmsg(dev, tb, extack);
	if (err < 0)
		return err;

	if (tb[IFLA_IFNAME])
		nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
	else
@@ -3162,6 +3156,10 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
		goto errout;
	}

	err = validate_linkmsg(dev, tb, extack);
	if (err < 0)
		goto errout;

	err = do_setlink(skb, dev, ifm, extack, tb, 0);
errout:
	return err;
@@ -3405,6 +3403,9 @@ static int rtnl_group_changelink(const struct sk_buff *skb,

	for_each_netdev_safe(net, dev, aux) {
		if (dev->group == group) {
			err = validate_linkmsg(dev, tb, extack);
			if (err < 0)
				return err;
			err = do_setlink(skb, dev, ifm, extack, tb, 0);
			if (err < 0)
				return err;
@@ -3562,10 +3563,6 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
			m_ops = master_dev->rtnl_link_ops;
	}

	err = validate_linkmsg(dev, tb, extack);
	if (err < 0)
		return err;

	if (tb[IFLA_LINKINFO]) {
		err = nla_parse_nested_deprecated(linkinfo, IFLA_INFO_MAX,
						  tb[IFLA_LINKINFO],
@@ -3629,6 +3626,10 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
		if (nlh->nlmsg_flags & NLM_F_REPLACE)
			return -EOPNOTSUPP;

		err = validate_linkmsg(dev, tb, extack);
		if (err < 0)
			return err;

		if (linkinfo[IFLA_INFO_DATA]) {
			if (!ops || ops != dev->rtnl_link_ops ||
			    !ops->changelink)