rtnetlink: enable alt_ifname for setlink/newlink
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 76c9ac0ee8
,
"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>
This commit is contained in:
parent
ef2a7c9065
commit
5ea08b5286
@ -2644,17 +2644,23 @@ static int do_set_proto_down(struct net_device *dev,
|
|||||||
static int do_setlink(const struct sk_buff *skb,
|
static int do_setlink(const struct sk_buff *skb,
|
||||||
struct net_device *dev, struct ifinfomsg *ifm,
|
struct net_device *dev, struct ifinfomsg *ifm,
|
||||||
struct netlink_ext_ack *extack,
|
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;
|
const struct net_device_ops *ops = dev->netdev_ops;
|
||||||
|
char ifname[IFNAMSIZ];
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = validate_linkmsg(dev, tb, extack);
|
err = validate_linkmsg(dev, tb, extack);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
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]) {
|
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;
|
struct net *net;
|
||||||
int new_ifindex;
|
int new_ifindex;
|
||||||
|
|
||||||
@ -3010,21 +3016,16 @@ errout:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct net_device *rtnl_dev_get(struct net *net,
|
static struct net_device *rtnl_dev_get(struct net *net,
|
||||||
struct nlattr *ifname_attr,
|
struct nlattr *tb[])
|
||||||
struct nlattr *altifname_attr,
|
|
||||||
char *ifname)
|
|
||||||
{
|
{
|
||||||
char buffer[ALTIFNAMSIZ];
|
char ifname[ALTIFNAMSIZ];
|
||||||
|
|
||||||
if (!ifname) {
|
if (tb[IFLA_IFNAME])
|
||||||
ifname = buffer;
|
nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
|
||||||
if (ifname_attr)
|
else if (tb[IFLA_ALT_IFNAME])
|
||||||
nla_strscpy(ifname, ifname_attr, IFNAMSIZ);
|
nla_strscpy(ifname, tb[IFLA_ALT_IFNAME], ALTIFNAMSIZ);
|
||||||
else if (altifname_attr)
|
else
|
||||||
nla_strscpy(ifname, altifname_attr, ALTIFNAMSIZ);
|
return NULL;
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return __dev_get_by_name(net, ifname);
|
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;
|
struct net_device *dev;
|
||||||
int err;
|
int err;
|
||||||
struct nlattr *tb[IFLA_MAX+1];
|
struct nlattr *tb[IFLA_MAX+1];
|
||||||
char ifname[IFNAMSIZ];
|
|
||||||
|
|
||||||
err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFLA_MAX,
|
err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFLA_MAX,
|
||||||
ifla_policy, extack);
|
ifla_policy, extack);
|
||||||
@ -3048,17 +3048,12 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto errout;
|
goto errout;
|
||||||
|
|
||||||
if (tb[IFLA_IFNAME])
|
|
||||||
nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
|
|
||||||
else
|
|
||||||
ifname[0] = '\0';
|
|
||||||
|
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
ifm = nlmsg_data(nlh);
|
ifm = nlmsg_data(nlh);
|
||||||
if (ifm->ifi_index > 0)
|
if (ifm->ifi_index > 0)
|
||||||
dev = __dev_get_by_index(net, ifm->ifi_index);
|
dev = __dev_get_by_index(net, ifm->ifi_index);
|
||||||
else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
|
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
|
else
|
||||||
goto errout;
|
goto errout;
|
||||||
|
|
||||||
@ -3067,7 +3062,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = do_setlink(skb, dev, ifm, extack, tb, ifname, 0);
|
err = do_setlink(skb, dev, ifm, extack, tb, 0);
|
||||||
errout:
|
errout:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -3156,8 +3151,7 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||||||
if (ifm->ifi_index > 0)
|
if (ifm->ifi_index > 0)
|
||||||
dev = __dev_get_by_index(tgt_net, ifm->ifi_index);
|
dev = __dev_get_by_index(tgt_net, ifm->ifi_index);
|
||||||
else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
|
else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
|
||||||
dev = rtnl_dev_get(net, tb[IFLA_IFNAME],
|
dev = rtnl_dev_get(net, tb);
|
||||||
tb[IFLA_ALT_IFNAME], NULL);
|
|
||||||
else if (tb[IFLA_GROUP])
|
else if (tb[IFLA_GROUP])
|
||||||
err = rtnl_group_dellink(tgt_net, nla_get_u32(tb[IFLA_GROUP]));
|
err = rtnl_group_dellink(tgt_net, nla_get_u32(tb[IFLA_GROUP]));
|
||||||
else
|
else
|
||||||
@ -3299,7 +3293,7 @@ static int rtnl_group_changelink(const struct sk_buff *skb,
|
|||||||
|
|
||||||
for_each_netdev_safe(net, dev, aux) {
|
for_each_netdev_safe(net, dev, aux) {
|
||||||
if (dev->group == group) {
|
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)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -3341,18 +3335,13 @@ replay:
|
|||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if (tb[IFLA_IFNAME])
|
|
||||||
nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
|
|
||||||
else
|
|
||||||
ifname[0] = '\0';
|
|
||||||
|
|
||||||
ifm = nlmsg_data(nlh);
|
ifm = nlmsg_data(nlh);
|
||||||
if (ifm->ifi_index > 0) {
|
if (ifm->ifi_index > 0) {
|
||||||
link_specified = true;
|
link_specified = true;
|
||||||
dev = __dev_get_by_index(net, ifm->ifi_index);
|
dev = __dev_get_by_index(net, ifm->ifi_index);
|
||||||
} else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME]) {
|
} else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME]) {
|
||||||
link_specified = true;
|
link_specified = true;
|
||||||
dev = rtnl_dev_get(net, NULL, tb[IFLA_ALT_IFNAME], ifname);
|
dev = rtnl_dev_get(net, tb);
|
||||||
} else {
|
} else {
|
||||||
link_specified = false;
|
link_specified = false;
|
||||||
dev = NULL;
|
dev = NULL;
|
||||||
@ -3455,7 +3444,7 @@ replay:
|
|||||||
status |= DO_SETLINK_NOTIFY;
|
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)) {
|
if (!(nlh->nlmsg_flags & NLM_F_CREATE)) {
|
||||||
@ -3492,7 +3481,9 @@ replay:
|
|||||||
if (!ops->alloc && !ops->setup)
|
if (!ops->alloc && !ops->setup)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (!ifname[0]) {
|
if (tb[IFLA_IFNAME]) {
|
||||||
|
nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
|
||||||
|
} else {
|
||||||
snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind);
|
snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind);
|
||||||
name_assign_type = NET_NAME_ENUM;
|
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)
|
if (ifm->ifi_index > 0)
|
||||||
dev = __dev_get_by_index(tgt_net, ifm->ifi_index);
|
dev = __dev_get_by_index(tgt_net, ifm->ifi_index);
|
||||||
else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
|
else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
|
||||||
dev = rtnl_dev_get(tgt_net, tb[IFLA_IFNAME],
|
dev = rtnl_dev_get(tgt_net, tb);
|
||||||
tb[IFLA_ALT_IFNAME], NULL);
|
|
||||||
else
|
else
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -3760,8 +3750,7 @@ static int rtnl_linkprop(int cmd, struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||||||
if (ifm->ifi_index > 0)
|
if (ifm->ifi_index > 0)
|
||||||
dev = __dev_get_by_index(net, ifm->ifi_index);
|
dev = __dev_get_by_index(net, ifm->ifi_index);
|
||||||
else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
|
else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
|
||||||
dev = rtnl_dev_get(net, tb[IFLA_IFNAME],
|
dev = rtnl_dev_get(net, tb);
|
||||||
tb[IFLA_ALT_IFNAME], NULL);
|
|
||||||
else
|
else
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user