net: rtnetlink: add linkprop commands to add and delete alternative ifnames
Add two commands to add and delete list of link properties. Implement the first property type along - alternative ifnames. Each net device can have multiple alternative names. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
ff92741270
commit
36fbf1e52b
@@ -1750,6 +1750,9 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
|
||||
[IFLA_CARRIER_DOWN_COUNT] = { .type = NLA_U32 },
|
||||
[IFLA_MIN_MTU] = { .type = NLA_U32 },
|
||||
[IFLA_MAX_MTU] = { .type = NLA_U32 },
|
||||
[IFLA_PROP_LIST] = { .type = NLA_NESTED },
|
||||
[IFLA_ALT_IFNAME] = { .type = NLA_STRING,
|
||||
.len = ALTIFNAMSIZ - 1 },
|
||||
};
|
||||
|
||||
static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
|
||||
@@ -3373,6 +3376,103 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int rtnl_alt_ifname(int cmd, struct net_device *dev, struct nlattr *attr,
|
||||
bool *changed, struct netlink_ext_ack *extack)
|
||||
{
|
||||
char *alt_ifname;
|
||||
int err;
|
||||
|
||||
err = nla_validate(attr, attr->nla_len, IFLA_MAX, ifla_policy, extack);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
alt_ifname = nla_data(attr);
|
||||
if (cmd == RTM_NEWLINKPROP) {
|
||||
alt_ifname = kstrdup(alt_ifname, GFP_KERNEL);
|
||||
if (!alt_ifname)
|
||||
return -ENOMEM;
|
||||
err = netdev_name_node_alt_create(dev, alt_ifname);
|
||||
if (err) {
|
||||
kfree(alt_ifname);
|
||||
return err;
|
||||
}
|
||||
} else if (cmd == RTM_DELLINKPROP) {
|
||||
err = netdev_name_node_alt_destroy(dev, alt_ifname);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
WARN_ON(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*changed = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtnl_linkprop(int cmd, struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct net *net = sock_net(skb->sk);
|
||||
struct nlattr *tb[IFLA_MAX + 1];
|
||||
struct net_device *dev;
|
||||
struct ifinfomsg *ifm;
|
||||
bool changed = false;
|
||||
struct nlattr *attr;
|
||||
int err, rem;
|
||||
|
||||
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, extack);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = rtnl_ensure_unique_netns(tb, extack, true);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ifm = nlmsg_data(nlh);
|
||||
if (ifm->ifi_index > 0) {
|
||||
dev = __dev_get_by_index(net, ifm->ifi_index);
|
||||
} else if (tb[IFLA_IFNAME]) {
|
||||
char ifname[IFNAMSIZ];
|
||||
|
||||
nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
|
||||
dev = __dev_get_by_name(net, ifname);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
||||
if (!tb[IFLA_PROP_LIST])
|
||||
return 0;
|
||||
|
||||
nla_for_each_nested(attr, tb[IFLA_PROP_LIST], rem) {
|
||||
switch (nla_type(attr)) {
|
||||
case IFLA_ALT_IFNAME:
|
||||
err = rtnl_alt_ifname(cmd, dev, attr, &changed, extack);
|
||||
if (err)
|
||||
return err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
netdev_state_change(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtnl_newlinkprop(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
return rtnl_linkprop(RTM_NEWLINKPROP, skb, nlh, extack);
|
||||
}
|
||||
|
||||
static int rtnl_dellinkprop(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
return rtnl_linkprop(RTM_DELLINKPROP, skb, nlh, extack);
|
||||
}
|
||||
|
||||
static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
{
|
||||
struct net *net = sock_net(skb->sk);
|
||||
@@ -5331,6 +5431,9 @@ void __init rtnetlink_init(void)
|
||||
rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, 0);
|
||||
rtnl_register(PF_UNSPEC, RTM_GETNETCONF, NULL, rtnl_dump_all, 0);
|
||||
|
||||
rtnl_register(PF_UNSPEC, RTM_NEWLINKPROP, rtnl_newlinkprop, NULL, 0);
|
||||
rtnl_register(PF_UNSPEC, RTM_DELLINKPROP, rtnl_dellinkprop, NULL, 0);
|
||||
|
||||
rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, 0);
|
||||
rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, 0);
|
||||
rtnl_register(PF_BRIDGE, RTM_GETNEIGH, rtnl_fdb_get, rtnl_fdb_dump, 0);
|
||||
|
Reference in New Issue
Block a user