rtnetlink: enable alt_ifname for setlink/newlink
authorFlorent Fourcot <florent.fourcot@wifirst.fr>
Fri, 15 Apr 2022 16:53:28 +0000 (18:53 +0200)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 19 Apr 2022 11:38:43 +0000 (13:38 +0200)
buffer called "ifname" given in function rtnl_dev_get
is always valid when called by setlink/newlink,
but contains only empty string when IFLA_IFNAME is not given. So
IFLA_ALT_IFNAME is always ignored

This patch fixes rtnl_dev_get function with a remove of ifname argument,
and move ifname copy in do_setlink when required.

It extends feature of commit 76c9ac0ee878,
"net: rtnetlink: add possibility to use alternative names as message
handle""

CC: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Florent Fourcot <florent.fourcot@wifirst.fr>
Signed-off-by: Brian Baboch <brian.baboch@wifirst.fr>
Reviewed-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
net/core/rtnetlink.c

index 2f538ab512d04e1c4763eb896f4aa66e20ff5c8a..5899b1d2de144e536e5d551c2ce50aa6969ec374 100644 (file)
@@ -2644,17 +2644,23 @@ static int do_set_proto_down(struct net_device *dev,
 static int do_setlink(const struct sk_buff *skb,
                      struct net_device *dev, struct ifinfomsg *ifm,
                      struct netlink_ext_ack *extack,
-                     struct nlattr **tb, char *ifname, int status)
+                     struct nlattr **tb, int status)
 {
        const struct net_device_ops *ops = dev->netdev_ops;
+       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
+               ifname[0] = '\0';
+
        if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD] || tb[IFLA_TARGET_NETNSID]) {
-               const char *pat = ifname && ifname[0] ? ifname : NULL;
+               const char *pat = ifname[0] ? ifname : NULL;
                struct net *net;
                int new_ifindex;
 
@@ -3010,21 +3016,16 @@ errout:
 }
 
 static struct net_device *rtnl_dev_get(struct net *net,
-                                      struct nlattr *ifname_attr,
-                                      struct nlattr *altifname_attr,
-                                      char *ifname)
-{
-       char buffer[ALTIFNAMSIZ];
-
-       if (!ifname) {
-               ifname = buffer;
-               if (ifname_attr)
-                       nla_strscpy(ifname, ifname_attr, IFNAMSIZ);
-               else if (altifname_attr)
-                       nla_strscpy(ifname, altifname_attr, ALTIFNAMSIZ);
-               else
-                       return NULL;
-       }
+                                      struct nlattr *tb[])
+{
+       char ifname[ALTIFNAMSIZ];
+
+       if (tb[IFLA_IFNAME])
+               nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
+       else if (tb[IFLA_ALT_IFNAME])
+               nla_strscpy(ifname, tb[IFLA_ALT_IFNAME], ALTIFNAMSIZ);
+       else
+               return NULL;
 
        return __dev_get_by_name(net, ifname);
 }
@@ -3037,7 +3038,6 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
        struct net_device *dev;
        int err;
        struct nlattr *tb[IFLA_MAX+1];
-       char ifname[IFNAMSIZ];
 
        err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFLA_MAX,
                                     ifla_policy, extack);
@@ -3048,17 +3048,12 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
        if (err < 0)
                goto errout;
 
-       if (tb[IFLA_IFNAME])
-               nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
-       else
-               ifname[0] = '\0';
-
        err = -EINVAL;
        ifm = nlmsg_data(nlh);
        if (ifm->ifi_index > 0)
                dev = __dev_get_by_index(net, ifm->ifi_index);
        else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
-               dev = rtnl_dev_get(net, NULL, tb[IFLA_ALT_IFNAME], ifname);
+               dev = rtnl_dev_get(net, tb);
        else
                goto errout;
 
@@ -3067,7 +3062,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
                goto errout;
        }
 
-       err = do_setlink(skb, dev, ifm, extack, tb, ifname, 0);
+       err = do_setlink(skb, dev, ifm, extack, tb, 0);
 errout:
        return err;
 }
@@ -3156,8 +3151,7 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh,
        if (ifm->ifi_index > 0)
                dev = __dev_get_by_index(tgt_net, ifm->ifi_index);
        else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
-               dev = rtnl_dev_get(net, tb[IFLA_IFNAME],
-                                  tb[IFLA_ALT_IFNAME], NULL);
+               dev = rtnl_dev_get(net, tb);
        else if (tb[IFLA_GROUP])
                err = rtnl_group_dellink(tgt_net, nla_get_u32(tb[IFLA_GROUP]));
        else
@@ -3299,7 +3293,7 @@ static int rtnl_group_changelink(const struct sk_buff *skb,
 
        for_each_netdev_safe(net, dev, aux) {
                if (dev->group == group) {
-                       err = do_setlink(skb, dev, ifm, extack, tb, NULL, 0);
+                       err = do_setlink(skb, dev, ifm, extack, tb, 0);
                        if (err < 0)
                                return err;
                }
@@ -3341,18 +3335,13 @@ replay:
        if (err < 0)
                return err;
 
-       if (tb[IFLA_IFNAME])
-               nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
-       else
-               ifname[0] = '\0';
-
        ifm = nlmsg_data(nlh);
        if (ifm->ifi_index > 0) {
                link_specified = true;
                dev = __dev_get_by_index(net, ifm->ifi_index);
        } else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME]) {
                link_specified = true;
-               dev = rtnl_dev_get(net, NULL, tb[IFLA_ALT_IFNAME], ifname);
+               dev = rtnl_dev_get(net, tb);
        } else {
                link_specified = false;
                dev = NULL;
@@ -3455,7 +3444,7 @@ replay:
                        status |= DO_SETLINK_NOTIFY;
                }
 
-               return do_setlink(skb, dev, ifm, extack, tb, ifname, status);
+               return do_setlink(skb, dev, ifm, extack, tb, status);
        }
 
        if (!(nlh->nlmsg_flags & NLM_F_CREATE)) {
@@ -3492,7 +3481,9 @@ replay:
        if (!ops->alloc && !ops->setup)
                return -EOPNOTSUPP;
 
-       if (!ifname[0]) {
+       if (tb[IFLA_IFNAME]) {
+               nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
+       } else {
                snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind);
                name_assign_type = NET_NAME_ENUM;
        }
@@ -3664,8 +3655,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh,
        if (ifm->ifi_index > 0)
                dev = __dev_get_by_index(tgt_net, ifm->ifi_index);
        else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
-               dev = rtnl_dev_get(tgt_net, tb[IFLA_IFNAME],
-                                  tb[IFLA_ALT_IFNAME], NULL);
+               dev = rtnl_dev_get(tgt_net, tb);
        else
                goto out;
 
@@ -3760,8 +3750,7 @@ static int rtnl_linkprop(int cmd, struct sk_buff *skb, struct nlmsghdr *nlh,
        if (ifm->ifi_index > 0)
                dev = __dev_get_by_index(net, ifm->ifi_index);
        else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
-               dev = rtnl_dev_get(net, tb[IFLA_IFNAME],
-                                  tb[IFLA_ALT_IFNAME], NULL);
+               dev = rtnl_dev_get(net, tb);
        else
                return -EINVAL;