* [patch net-next 1/7] net: procfs: use index hashlist instead of name hashlist
2019-09-30 9:48 [patch net-next 0/7] net: introduce alternative names for network interfaces Jiri Pirko
@ 2019-09-30 9:48 ` Jiri Pirko
2019-09-30 9:48 ` [patch net-next 2/7] net: introduce name_node struct to be used in hashlist Jiri Pirko
` (8 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2019-09-30 9:48 UTC (permalink / raw)
To: netdev
Cc: davem, jakub.kicinski, dsahern, roopa, dcbw, nikolay, mkubecek,
andrew, parav, saeedm, f.fainelli, stephen, sd, sbrivio, pabeni,
mlxsw
From: Jiri Pirko <jiri@mellanox.com>
Name hashlist is going to be used for more than just dev->name, so use
rather index hashlist for iteration over net_device instances.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
net/core/net-procfs.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/core/net-procfs.c b/net/core/net-procfs.c
index 36347933ec3a..6bbd06f7dc7d 100644
--- a/net/core/net-procfs.c
+++ b/net/core/net-procfs.c
@@ -20,8 +20,8 @@ static inline struct net_device *dev_from_same_bucket(struct seq_file *seq, loff
struct hlist_head *h;
unsigned int count = 0, offset = get_offset(*pos);
- h = &net->dev_name_head[get_bucket(*pos)];
- hlist_for_each_entry_rcu(dev, h, name_hlist) {
+ h = &net->dev_index_head[get_bucket(*pos)];
+ hlist_for_each_entry_rcu(dev, h, index_hlist) {
if (++count == offset)
return dev;
}
--
2.21.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [patch net-next 2/7] net: introduce name_node struct to be used in hashlist
2019-09-30 9:48 [patch net-next 0/7] net: introduce alternative names for network interfaces Jiri Pirko
2019-09-30 9:48 ` [patch net-next 1/7] net: procfs: use index hashlist instead of name hashlist Jiri Pirko
@ 2019-09-30 9:48 ` Jiri Pirko
2019-09-30 9:48 ` [patch net-next 3/7] net: rtnetlink: add linkprop commands to add and delete alternative ifnames Jiri Pirko
` (7 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2019-09-30 9:48 UTC (permalink / raw)
To: netdev
Cc: davem, jakub.kicinski, dsahern, roopa, dcbw, nikolay, mkubecek,
andrew, parav, saeedm, f.fainelli, stephen, sd, sbrivio, pabeni,
mlxsw
From: Jiri Pirko <jiri@mellanox.com>
Introduce name_node structure to hold name of device and put it into
hashlist instead of putting there struct net_device directly. Add a
necessary infrastructure to manipulate the hashlist. This prepares
the code to use the same hashlist for alternative names introduced
later in this set.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
rfc->v1:
- make char *name const in struct netdev_name_node and in
netdev_name_node_alloc()
- use INIT_HLIST_NODE in netdev_name_node_alloc() and
change kzalloc to kmalloc.
- added patch description
---
include/linux/netdevice.h | 10 +++-
net/core/dev.c | 97 +++++++++++++++++++++++++++++++--------
2 files changed, 87 insertions(+), 20 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 9eda1c31d1f7..e92bc5467256 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -925,6 +925,12 @@ struct dev_ifalias {
struct devlink;
struct tlsdev_ops;
+struct netdev_name_node {
+ struct hlist_node hlist;
+ struct net_device *dev;
+ const char *name;
+};
+
/*
* This structure defines the management hooks for network devices.
* The following hooks can be defined; unless noted otherwise, they are
@@ -1564,7 +1570,7 @@ enum netdev_priv_flags {
* (i.e. as seen by users in the "Space.c" file). It is the name
* of the interface.
*
- * @name_hlist: Device name hash chain, please keep it close to name[]
+ * @name_node: Name hashlist node
* @ifalias: SNMP alias
* @mem_end: Shared memory end
* @mem_start: Shared memory start
@@ -1774,7 +1780,7 @@ enum netdev_priv_flags {
struct net_device {
char name[IFNAMSIZ];
- struct hlist_node name_hlist;
+ struct netdev_name_node *name_node;
struct dev_ifalias __rcu *ifalias;
/*
* I/O specific fields
diff --git a/net/core/dev.c b/net/core/dev.c
index bf3ed413abaf..b9088dee0701 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -228,6 +228,67 @@ static inline void rps_unlock(struct softnet_data *sd)
#endif
}
+static struct netdev_name_node *netdev_name_node_alloc(struct net_device *dev,
+ const char *name)
+{
+ struct netdev_name_node *name_node;
+
+ name_node = kmalloc(sizeof(*name_node), GFP_KERNEL);
+ if (!name_node)
+ return NULL;
+ INIT_HLIST_NODE(&name_node->hlist);
+ name_node->dev = dev;
+ name_node->name = name;
+ return name_node;
+}
+
+static struct netdev_name_node *
+netdev_name_node_head_alloc(struct net_device *dev)
+{
+ return netdev_name_node_alloc(dev, dev->name);
+}
+
+static void netdev_name_node_free(struct netdev_name_node *name_node)
+{
+ kfree(name_node);
+}
+
+static void netdev_name_node_add(struct net *net,
+ struct netdev_name_node *name_node)
+{
+ hlist_add_head_rcu(&name_node->hlist,
+ dev_name_hash(net, name_node->name));
+}
+
+static void netdev_name_node_del(struct netdev_name_node *name_node)
+{
+ hlist_del_rcu(&name_node->hlist);
+}
+
+static struct netdev_name_node *netdev_name_node_lookup(struct net *net,
+ const char *name)
+{
+ struct hlist_head *head = dev_name_hash(net, name);
+ struct netdev_name_node *name_node;
+
+ hlist_for_each_entry(name_node, head, hlist)
+ if (!strcmp(name_node->name, name))
+ return name_node;
+ return NULL;
+}
+
+static struct netdev_name_node *netdev_name_node_lookup_rcu(struct net *net,
+ const char *name)
+{
+ struct hlist_head *head = dev_name_hash(net, name);
+ struct netdev_name_node *name_node;
+
+ hlist_for_each_entry_rcu(name_node, head, hlist)
+ if (!strcmp(name_node->name, name))
+ return name_node;
+ return NULL;
+}
+
/* Device list insertion */
static void list_netdevice(struct net_device *dev)
{
@@ -237,7 +298,7 @@ static void list_netdevice(struct net_device *dev)
write_lock_bh(&dev_base_lock);
list_add_tail_rcu(&dev->dev_list, &net->dev_base_head);
- hlist_add_head_rcu(&dev->name_hlist, dev_name_hash(net, dev->name));
+ netdev_name_node_add(net, dev->name_node);
hlist_add_head_rcu(&dev->index_hlist,
dev_index_hash(net, dev->ifindex));
write_unlock_bh(&dev_base_lock);
@@ -255,7 +316,7 @@ static void unlist_netdevice(struct net_device *dev)
/* Unlink dev from the device chain */
write_lock_bh(&dev_base_lock);
list_del_rcu(&dev->dev_list);
- hlist_del_rcu(&dev->name_hlist);
+ netdev_name_node_del(dev->name_node);
hlist_del_rcu(&dev->index_hlist);
write_unlock_bh(&dev_base_lock);
@@ -733,14 +794,10 @@ EXPORT_SYMBOL_GPL(dev_fill_metadata_dst);
struct net_device *__dev_get_by_name(struct net *net, const char *name)
{
- struct net_device *dev;
- struct hlist_head *head = dev_name_hash(net, name);
+ struct netdev_name_node *node_name;
- hlist_for_each_entry(dev, head, name_hlist)
- if (!strncmp(dev->name, name, IFNAMSIZ))
- return dev;
-
- return NULL;
+ node_name = netdev_name_node_lookup(net, name);
+ return node_name ? node_name->dev : NULL;
}
EXPORT_SYMBOL(__dev_get_by_name);
@@ -758,14 +815,10 @@ EXPORT_SYMBOL(__dev_get_by_name);
struct net_device *dev_get_by_name_rcu(struct net *net, const char *name)
{
- struct net_device *dev;
- struct hlist_head *head = dev_name_hash(net, name);
-
- hlist_for_each_entry_rcu(dev, head, name_hlist)
- if (!strncmp(dev->name, name, IFNAMSIZ))
- return dev;
+ struct netdev_name_node *node_name;
- return NULL;
+ node_name = netdev_name_node_lookup_rcu(net, name);
+ return node_name ? node_name->dev : NULL;
}
EXPORT_SYMBOL(dev_get_by_name_rcu);
@@ -1232,13 +1285,13 @@ int dev_change_name(struct net_device *dev, const char *newname)
netdev_adjacent_rename_links(dev, oldname);
write_lock_bh(&dev_base_lock);
- hlist_del_rcu(&dev->name_hlist);
+ netdev_name_node_del(dev->name_node);
write_unlock_bh(&dev_base_lock);
synchronize_rcu();
write_lock_bh(&dev_base_lock);
- hlist_add_head_rcu(&dev->name_hlist, dev_name_hash(net, dev->name));
+ netdev_name_node_add(net, dev->name_node);
write_unlock_bh(&dev_base_lock);
ret = call_netdevice_notifiers(NETDEV_CHANGENAME, dev);
@@ -8264,6 +8317,8 @@ static void rollback_registered_many(struct list_head *head)
dev_uc_flush(dev);
dev_mc_flush(dev);
+ netdev_name_node_free(dev->name_node);
+
if (dev->netdev_ops->ndo_uninit)
dev->netdev_ops->ndo_uninit(dev);
@@ -8706,6 +8761,10 @@ int register_netdevice(struct net_device *dev)
if (ret < 0)
goto out;
+ dev->name_node = netdev_name_node_head_alloc(dev);
+ if (!dev->name_node)
+ goto out;
+
/* Init, if this function is available */
if (dev->netdev_ops->ndo_init) {
ret = dev->netdev_ops->ndo_init(dev);
@@ -8827,6 +8886,8 @@ int register_netdevice(struct net_device *dev)
return ret;
err_uninit:
+ if (dev->name_node)
+ netdev_name_node_free(dev->name_node);
if (dev->netdev_ops->ndo_uninit)
dev->netdev_ops->ndo_uninit(dev);
if (dev->priv_destructor)
--
2.21.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [patch net-next 3/7] net: rtnetlink: add linkprop commands to add and delete alternative ifnames
2019-09-30 9:48 [patch net-next 0/7] net: introduce alternative names for network interfaces Jiri Pirko
2019-09-30 9:48 ` [patch net-next 1/7] net: procfs: use index hashlist instead of name hashlist Jiri Pirko
2019-09-30 9:48 ` [patch net-next 2/7] net: introduce name_node struct to be used in hashlist Jiri Pirko
@ 2019-09-30 9:48 ` Jiri Pirko
2019-09-30 9:48 ` [patch net-next 4/7] net: rtnetlink: put alternative names to getlink message Jiri Pirko
` (6 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2019-09-30 9:48 UTC (permalink / raw)
To: netdev
Cc: davem, jakub.kicinski, dsahern, roopa, dcbw, nikolay, mkubecek,
andrew, parav, saeedm, f.fainelli, stephen, sd, sbrivio, pabeni,
mlxsw
From: Jiri Pirko <jiri@mellanox.com>
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>
---
rfc->v1:
- make netdev_name_node_alt_create/destroy() char *name arg const
- converted the patch to add/del list of link properties
---
include/linux/netdevice.h | 4 ++
include/uapi/linux/if.h | 1 +
include/uapi/linux/if_link.h | 2 +
include/uapi/linux/rtnetlink.h | 7 +++
net/core/dev.c | 58 ++++++++++++++++++-
net/core/rtnetlink.c | 103 +++++++++++++++++++++++++++++++++
security/selinux/nlmsgtab.c | 4 +-
7 files changed, 177 insertions(+), 2 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e92bc5467256..48cc71aae466 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -927,10 +927,14 @@ struct tlsdev_ops;
struct netdev_name_node {
struct hlist_node hlist;
+ struct list_head list;
struct net_device *dev;
const char *name;
};
+int netdev_name_node_alt_create(struct net_device *dev, const char *name);
+int netdev_name_node_alt_destroy(struct net_device *dev, const char *name);
+
/*
* This structure defines the management hooks for network devices.
* The following hooks can be defined; unless noted otherwise, they are
diff --git a/include/uapi/linux/if.h b/include/uapi/linux/if.h
index 7fea0fd7d6f5..4bf33344aab1 100644
--- a/include/uapi/linux/if.h
+++ b/include/uapi/linux/if.h
@@ -33,6 +33,7 @@
#define IFNAMSIZ 16
#endif /* __UAPI_DEF_IF_IFNAMSIZ */
#define IFALIASZ 256
+#define ALTIFNAMSIZ 128
#include <linux/hdlc/ioctl.h>
/* For glibc compatibility. An empty enum does not compile. */
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 4a8c02cafa9a..8aec8769d944 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -167,6 +167,8 @@ enum {
IFLA_NEW_IFINDEX,
IFLA_MIN_MTU,
IFLA_MAX_MTU,
+ IFLA_PROP_LIST,
+ IFLA_ALT_IFNAME, /* Alternative ifname */
__IFLA_MAX
};
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index ce2a623abb75..1418a8362bb7 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -164,6 +164,13 @@ enum {
RTM_GETNEXTHOP,
#define RTM_GETNEXTHOP RTM_GETNEXTHOP
+ RTM_NEWLINKPROP = 108,
+#define RTM_NEWLINKPROP RTM_NEWLINKPROP
+ RTM_DELLINKPROP,
+#define RTM_DELLINKPROP RTM_DELLINKPROP
+ RTM_GETLINKPROP,
+#define RTM_GETLINKPROP RTM_GETLINKPROP
+
__RTM_MAX,
#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
};
diff --git a/net/core/dev.c b/net/core/dev.c
index b9088dee0701..36e139793e8e 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -245,7 +245,13 @@ static struct netdev_name_node *netdev_name_node_alloc(struct net_device *dev,
static struct netdev_name_node *
netdev_name_node_head_alloc(struct net_device *dev)
{
- return netdev_name_node_alloc(dev, dev->name);
+ struct netdev_name_node *name_node;
+
+ name_node = netdev_name_node_alloc(dev, dev->name);
+ if (!name_node)
+ return NULL;
+ INIT_LIST_HEAD(&name_node->list);
+ return name_node;
}
static void netdev_name_node_free(struct netdev_name_node *name_node)
@@ -289,6 +295,55 @@ static struct netdev_name_node *netdev_name_node_lookup_rcu(struct net *net,
return NULL;
}
+int netdev_name_node_alt_create(struct net_device *dev, const char *name)
+{
+ struct netdev_name_node *name_node;
+ struct net *net = dev_net(dev);
+
+ name_node = netdev_name_node_lookup(net, name);
+ if (name_node)
+ return -EEXIST;
+ name_node = netdev_name_node_alloc(dev, name);
+ if (!name_node)
+ return -ENOMEM;
+ netdev_name_node_add(net, name_node);
+ /* The node that holds dev->name acts as a head of per-device list. */
+ list_add_tail(&name_node->list, &dev->name_node->list);
+
+ return 0;
+}
+EXPORT_SYMBOL(netdev_name_node_alt_create);
+
+static void __netdev_name_node_alt_destroy(struct netdev_name_node *name_node)
+{
+ list_del(&name_node->list);
+ netdev_name_node_del(name_node);
+ kfree(name_node->name);
+ netdev_name_node_free(name_node);
+}
+
+int netdev_name_node_alt_destroy(struct net_device *dev, const char *name)
+{
+ struct netdev_name_node *name_node;
+ struct net *net = dev_net(dev);
+
+ name_node = netdev_name_node_lookup(net, name);
+ if (!name_node)
+ return -ENOENT;
+ __netdev_name_node_alt_destroy(name_node);
+
+ return 0;
+}
+EXPORT_SYMBOL(netdev_name_node_alt_destroy);
+
+static void netdev_name_node_alt_flush(struct net_device *dev)
+{
+ struct netdev_name_node *name_node, *tmp;
+
+ list_for_each_entry_safe(name_node, tmp, &dev->name_node->list, list)
+ __netdev_name_node_alt_destroy(name_node);
+}
+
/* Device list insertion */
static void list_netdevice(struct net_device *dev)
{
@@ -8317,6 +8372,7 @@ static void rollback_registered_many(struct list_head *head)
dev_uc_flush(dev);
dev_mc_flush(dev);
+ netdev_name_node_alt_flush(dev);
netdev_name_node_free(dev->name_node);
if (dev->netdev_ops->ndo_uninit)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 1ee6460f8275..e13646993d82 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -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 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh,
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);
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index 58345ba0528e..c97fdae8f71b 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -83,6 +83,8 @@ static const struct nlmsg_perm nlmsg_route_perms[] =
{ RTM_NEWNEXTHOP, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
{ RTM_DELNEXTHOP, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
{ RTM_GETNEXTHOP, NETLINK_ROUTE_SOCKET__NLMSG_READ },
+ { RTM_NEWLINKPROP, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
+ { RTM_DELLINKPROP, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
};
static const struct nlmsg_perm nlmsg_tcpdiag_perms[] =
@@ -166,7 +168,7 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm)
* structures at the top of this file with the new mappings
* before updating the BUILD_BUG_ON() macro!
*/
- BUILD_BUG_ON(RTM_MAX != (RTM_NEWNEXTHOP + 3));
+ BUILD_BUG_ON(RTM_MAX != (RTM_NEWLINKPROP + 3));
err = nlmsg_perm(nlmsg_type, perm, nlmsg_route_perms,
sizeof(nlmsg_route_perms));
break;
--
2.21.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [patch net-next 4/7] net: rtnetlink: put alternative names to getlink message
2019-09-30 9:48 [patch net-next 0/7] net: introduce alternative names for network interfaces Jiri Pirko
` (2 preceding siblings ...)
2019-09-30 9:48 ` [patch net-next 3/7] net: rtnetlink: add linkprop commands to add and delete alternative ifnames Jiri Pirko
@ 2019-09-30 9:48 ` Jiri Pirko
2019-09-30 9:48 ` [patch net-next 5/7] net: rtnetlink: unify the code in __rtnl_newlink get dev with the rest Jiri Pirko
` (5 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2019-09-30 9:48 UTC (permalink / raw)
To: netdev
Cc: davem, jakub.kicinski, dsahern, roopa, dcbw, nikolay, mkubecek,
andrew, parav, saeedm, f.fainelli, stephen, sd, sbrivio, pabeni,
mlxsw
From: Jiri Pirko <jiri@mellanox.com>
Extend exiting getlink info message with list of properties. Now the
only ones are alternative names.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
rfc->v1:
- move size initialization after early return in
rtnl_alt_ifname_list_size()/rtnl_prop_list_size()
- converted to generic property list
---
net/core/rtnetlink.c | 53 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index e13646993d82..c38917371b84 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -980,6 +980,19 @@ static size_t rtnl_xdp_size(void)
return xdp_size;
}
+static size_t rtnl_prop_list_size(const struct net_device *dev)
+{
+ struct netdev_name_node *name_node;
+ size_t size;
+
+ if (list_empty(&dev->name_node->list))
+ return 0;
+ size = nla_total_size(0);
+ list_for_each_entry(name_node, &dev->name_node->list, list)
+ size += nla_total_size(ALTIFNAMSIZ);
+ return size;
+}
+
static noinline size_t if_nlmsg_size(const struct net_device *dev,
u32 ext_filter_mask)
{
@@ -1027,6 +1040,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
+ nla_total_size(4) /* IFLA_CARRIER_DOWN_COUNT */
+ nla_total_size(4) /* IFLA_MIN_MTU */
+ nla_total_size(4) /* IFLA_MAX_MTU */
+ + rtnl_prop_list_size(dev)
+ 0;
}
@@ -1584,6 +1598,42 @@ static int rtnl_fill_link_af(struct sk_buff *skb,
return 0;
}
+static int rtnl_fill_alt_ifnames(struct sk_buff *skb,
+ const struct net_device *dev)
+{
+ struct netdev_name_node *name_node;
+ int count = 0;
+
+ list_for_each_entry(name_node, &dev->name_node->list, list) {
+ if (nla_put_string(skb, IFLA_ALT_IFNAME, name_node->name))
+ return -EMSGSIZE;
+ count++;
+ }
+ return count;
+}
+
+static int rtnl_fill_prop_list(struct sk_buff *skb,
+ const struct net_device *dev)
+{
+ struct nlattr *prop_list;
+ int ret;
+
+ prop_list = nla_nest_start(skb, IFLA_PROP_LIST);
+ if (!prop_list)
+ return -EMSGSIZE;
+
+ ret = rtnl_fill_alt_ifnames(skb, dev);
+ if (ret <= 0)
+ goto nest_cancel;
+
+ nla_nest_end(skb, prop_list);
+ return 0;
+
+nest_cancel:
+ nla_nest_cancel(skb, prop_list);
+ return ret;
+}
+
static int rtnl_fill_ifinfo(struct sk_buff *skb,
struct net_device *dev, struct net *src_net,
int type, u32 pid, u32 seq, u32 change,
@@ -1697,6 +1747,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb,
goto nla_put_failure_rcu;
rcu_read_unlock();
+ if (rtnl_fill_prop_list(skb, dev))
+ goto nla_put_failure;
+
nlmsg_end(skb, nlh);
return 0;
--
2.21.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [patch net-next 5/7] net: rtnetlink: unify the code in __rtnl_newlink get dev with the rest
2019-09-30 9:48 [patch net-next 0/7] net: introduce alternative names for network interfaces Jiri Pirko
` (3 preceding siblings ...)
2019-09-30 9:48 ` [patch net-next 4/7] net: rtnetlink: put alternative names to getlink message Jiri Pirko
@ 2019-09-30 9:48 ` Jiri Pirko
2019-09-30 9:48 ` [patch net-next 6/7] net: rtnetlink: introduce helper to get net_device instance by ifname Jiri Pirko
` (4 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2019-09-30 9:48 UTC (permalink / raw)
To: netdev
Cc: davem, jakub.kicinski, dsahern, roopa, dcbw, nikolay, mkubecek,
andrew, parav, saeedm, f.fainelli, stephen, sd, sbrivio, pabeni,
mlxsw
From: Jiri Pirko <jiri@mellanox.com>
__rtnl_newlink() code flow is a bit different around tb[IFLA_IFNAME]
processing comparing to the other places. Change that to be unified with
the rest.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
net/core/rtnetlink.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index c38917371b84..a0017737442f 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -3080,12 +3080,10 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
ifm = nlmsg_data(nlh);
if (ifm->ifi_index > 0)
dev = __dev_get_by_index(net, ifm->ifi_index);
- else {
- if (ifname[0])
- dev = __dev_get_by_name(net, ifname);
- else
- dev = NULL;
- }
+ else if (tb[IFLA_IFNAME])
+ dev = __dev_get_by_name(net, ifname);
+ else
+ dev = NULL;
if (dev) {
master_dev = netdev_master_upper_dev_get(dev);
--
2.21.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [patch net-next 6/7] net: rtnetlink: introduce helper to get net_device instance by ifname
2019-09-30 9:48 [patch net-next 0/7] net: introduce alternative names for network interfaces Jiri Pirko
` (4 preceding siblings ...)
2019-09-30 9:48 ` [patch net-next 5/7] net: rtnetlink: unify the code in __rtnl_newlink get dev with the rest Jiri Pirko
@ 2019-09-30 9:48 ` Jiri Pirko
2019-09-30 9:48 ` [patch net-next 7/7] net: rtnetlink: add possibility to use alternative names as message handle Jiri Pirko
` (3 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2019-09-30 9:48 UTC (permalink / raw)
To: netdev
Cc: davem, jakub.kicinski, dsahern, roopa, dcbw, nikolay, mkubecek,
andrew, parav, saeedm, f.fainelli, stephen, sd, sbrivio, pabeni,
mlxsw
From: Jiri Pirko <jiri@mellanox.com>
Introduce helper function rtnl_get_dev() that gets net_device structure
instance pointer according to passed ifname or ifname attribute.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
net/core/rtnetlink.c | 45 ++++++++++++++++++++++++--------------------
1 file changed, 25 insertions(+), 20 deletions(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index a0017737442f..77d4719e5be0 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2778,6 +2778,23 @@ static int do_setlink(const struct sk_buff *skb,
return err;
}
+static struct net_device *rtnl_dev_get(struct net *net,
+ struct nlattr *ifname_attr,
+ char *ifname)
+{
+ char buffer[IFNAMSIZ];
+
+ if (!ifname) {
+ ifname = buffer;
+ if (ifname_attr)
+ nla_strlcpy(ifname, ifname_attr, IFNAMSIZ);
+ else
+ return NULL;
+ }
+
+ return __dev_get_by_name(net, ifname);
+}
+
static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
struct netlink_ext_ack *extack)
{
@@ -2807,7 +2824,7 @@ static int rtnl_setlink(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])
- dev = __dev_get_by_name(net, ifname);
+ dev = rtnl_dev_get(net, NULL, ifname);
else
goto errout;
@@ -2880,7 +2897,6 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh,
struct net *tgt_net = net;
struct net_device *dev = NULL;
struct ifinfomsg *ifm;
- char ifname[IFNAMSIZ];
struct nlattr *tb[IFLA_MAX+1];
int err;
int netnsid = -1;
@@ -2894,9 +2910,6 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh,
if (err < 0)
return err;
- if (tb[IFLA_IFNAME])
- nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
-
if (tb[IFLA_TARGET_NETNSID]) {
netnsid = nla_get_s32(tb[IFLA_TARGET_NETNSID]);
tgt_net = rtnl_get_net_ns_capable(NETLINK_CB(skb).sk, netnsid);
@@ -2909,7 +2922,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])
- dev = __dev_get_by_name(tgt_net, ifname);
+ dev = rtnl_dev_get(net, tb[IFLA_IFNAME], NULL);
else if (tb[IFLA_GROUP])
err = rtnl_group_dellink(tgt_net, nla_get_u32(tb[IFLA_GROUP]));
else
@@ -3081,7 +3094,7 @@ static int __rtnl_newlink(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])
- dev = __dev_get_by_name(net, ifname);
+ dev = rtnl_dev_get(net, NULL, ifname);
else
dev = NULL;
@@ -3363,7 +3376,6 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh,
struct net *net = sock_net(skb->sk);
struct net *tgt_net = net;
struct ifinfomsg *ifm;
- char ifname[IFNAMSIZ];
struct nlattr *tb[IFLA_MAX+1];
struct net_device *dev = NULL;
struct sk_buff *nskb;
@@ -3386,9 +3398,6 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh,
return PTR_ERR(tgt_net);
}
- if (tb[IFLA_IFNAME])
- nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
-
if (tb[IFLA_EXT_MASK])
ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
@@ -3397,7 +3406,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])
- dev = __dev_get_by_name(tgt_net, ifname);
+ dev = rtnl_dev_get(tgt_net, tb[IFLA_IFNAME], NULL);
else
goto out;
@@ -3480,16 +3489,12 @@ static int rtnl_linkprop(int cmd, struct sk_buff *skb, struct nlmsghdr *nlh,
return err;
ifm = nlmsg_data(nlh);
- if (ifm->ifi_index > 0) {
+ 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 {
+ else if (tb[IFLA_IFNAME])
+ dev = rtnl_dev_get(net, tb[IFLA_IFNAME], NULL);
+ else
return -EINVAL;
- }
if (!dev)
return -ENODEV;
--
2.21.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [patch net-next 7/7] net: rtnetlink: add possibility to use alternative names as message handle
2019-09-30 9:48 [patch net-next 0/7] net: introduce alternative names for network interfaces Jiri Pirko
` (5 preceding siblings ...)
2019-09-30 9:48 ` [patch net-next 6/7] net: rtnetlink: introduce helper to get net_device instance by ifname Jiri Pirko
@ 2019-09-30 9:48 ` Jiri Pirko
2019-09-30 9:59 ` [patch net-next 1/2] ip: add support for alternative name addition/deletion/list Jiri Pirko
` (2 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2019-09-30 9:48 UTC (permalink / raw)
To: netdev
Cc: davem, jakub.kicinski, dsahern, roopa, dcbw, nikolay, mkubecek,
andrew, parav, saeedm, f.fainelli, stephen, sd, sbrivio, pabeni,
mlxsw
From: Jiri Pirko <jiri@mellanox.com>
Extend the basic rtnetlink commands to use alternative interface names
as a handle instead of ifindex and ifname.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
rfc->v1:
- rebased on top of changes in the previous patches
---
net/core/rtnetlink.c | 29 ++++++++++++++++++-----------
1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 77d4719e5be0..49fa910b58af 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2780,14 +2780,17 @@ static int do_setlink(const struct sk_buff *skb,
static struct net_device *rtnl_dev_get(struct net *net,
struct nlattr *ifname_attr,
+ struct nlattr *altifname_attr,
char *ifname)
{
- char buffer[IFNAMSIZ];
+ char buffer[ALTIFNAMSIZ];
if (!ifname) {
ifname = buffer;
if (ifname_attr)
nla_strlcpy(ifname, ifname_attr, IFNAMSIZ);
+ else if (altifname_attr)
+ nla_strlcpy(ifname, altifname_attr, ALTIFNAMSIZ);
else
return NULL;
}
@@ -2823,8 +2826,8 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
ifm = nlmsg_data(nlh);
if (ifm->ifi_index > 0)
dev = __dev_get_by_index(net, ifm->ifi_index);
- else if (tb[IFLA_IFNAME])
- dev = rtnl_dev_get(net, NULL, ifname);
+ else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
+ dev = rtnl_dev_get(net, NULL, tb[IFLA_ALT_IFNAME], ifname);
else
goto errout;
@@ -2921,8 +2924,9 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh,
ifm = nlmsg_data(nlh);
if (ifm->ifi_index > 0)
dev = __dev_get_by_index(tgt_net, ifm->ifi_index);
- else if (tb[IFLA_IFNAME])
- dev = rtnl_dev_get(net, tb[IFLA_IFNAME], NULL);
+ else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
+ dev = rtnl_dev_get(net, tb[IFLA_IFNAME],
+ tb[IFLA_ALT_IFNAME], NULL);
else if (tb[IFLA_GROUP])
err = rtnl_group_dellink(tgt_net, nla_get_u32(tb[IFLA_GROUP]));
else
@@ -3093,8 +3097,8 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
ifm = nlmsg_data(nlh);
if (ifm->ifi_index > 0)
dev = __dev_get_by_index(net, ifm->ifi_index);
- else if (tb[IFLA_IFNAME])
- dev = rtnl_dev_get(net, NULL, ifname);
+ else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
+ dev = rtnl_dev_get(net, NULL, tb[IFLA_ALT_IFNAME], ifname);
else
dev = NULL;
@@ -3358,6 +3362,7 @@ static int rtnl_valid_getlink_req(struct sk_buff *skb,
switch (i) {
case IFLA_IFNAME:
+ case IFLA_ALT_IFNAME:
case IFLA_EXT_MASK:
case IFLA_TARGET_NETNSID:
break;
@@ -3405,8 +3410,9 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh,
ifm = nlmsg_data(nlh);
if (ifm->ifi_index > 0)
dev = __dev_get_by_index(tgt_net, ifm->ifi_index);
- else if (tb[IFLA_IFNAME])
- dev = rtnl_dev_get(tgt_net, tb[IFLA_IFNAME], NULL);
+ else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
+ dev = rtnl_dev_get(tgt_net, tb[IFLA_IFNAME],
+ tb[IFLA_ALT_IFNAME], NULL);
else
goto out;
@@ -3491,8 +3497,9 @@ static int rtnl_linkprop(int cmd, struct sk_buff *skb, struct nlmsghdr *nlh,
ifm = nlmsg_data(nlh);
if (ifm->ifi_index > 0)
dev = __dev_get_by_index(net, ifm->ifi_index);
- else if (tb[IFLA_IFNAME])
- dev = rtnl_dev_get(net, tb[IFLA_IFNAME], NULL);
+ else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
+ dev = rtnl_dev_get(net, tb[IFLA_IFNAME],
+ tb[IFLA_ALT_IFNAME], NULL);
else
return -EINVAL;
--
2.21.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [patch net-next 1/2] ip: add support for alternative name addition/deletion/list
2019-09-30 9:48 [patch net-next 0/7] net: introduce alternative names for network interfaces Jiri Pirko
` (6 preceding siblings ...)
2019-09-30 9:48 ` [patch net-next 7/7] net: rtnetlink: add possibility to use alternative names as message handle Jiri Pirko
@ 2019-09-30 9:59 ` Jiri Pirko
2019-09-30 10:09 ` Jiri Pirko
2019-09-30 16:27 ` Stephen Hemminger
2019-09-30 9:59 ` [patch net-next 2/2] ip: allow to use alternative names as handle Jiri Pirko
2019-10-01 21:51 ` [patch net-next 0/7] net: introduce alternative names for network interfaces David Miller
9 siblings, 2 replies; 14+ messages in thread
From: Jiri Pirko @ 2019-09-30 9:59 UTC (permalink / raw)
To: netdev
Cc: davem, jakub.kicinski, dsahern, roopa, dcbw, nikolay, mkubecek,
andrew, parav, saeedm, f.fainelli, stephen, sd, sbrivio, pabeni,
mlxsw
From: Jiri Pirko <jiri@mellanox.com>
Implement addition/deletion of lists of properties, currently
alternative ifnames. Also extent the ip link show command to list them.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
rfc->v1:
- convert to generic property lists
- added patch description
- use ll_name_to_index() and ifindex as handle
- fixed parsing with nested flag on
- adjusted output
- added arg name to check_altifname header prototype
- added help and man parts
---
include/uapi/linux/if_link.h | 2 +
include/uapi/linux/rtnetlink.h | 7 +++
include/utils.h | 1 +
ip/ipaddress.c | 20 ++++++++-
ip/iplink.c | 82 +++++++++++++++++++++++++++++++++-
lib/utils.c | 19 +++++---
man/man8/ip-link.8.in | 11 +++++
7 files changed, 134 insertions(+), 8 deletions(-)
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index d36919fb4024..1c49f436424d 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -167,6 +167,8 @@ enum {
IFLA_NEW_IFINDEX,
IFLA_MIN_MTU,
IFLA_MAX_MTU,
+ IFLA_PROP_LIST,
+ IFLA_ALT_IFNAME, /* Alternative ifname */
__IFLA_MAX
};
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index 358e83ee134d..4b93791cdbd4 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -164,6 +164,13 @@ enum {
RTM_GETNEXTHOP,
#define RTM_GETNEXTHOP RTM_GETNEXTHOP
+ RTM_NEWLINKPROP = 108,
+#define RTM_NEWLINKPROP RTM_NEWLINKPROP
+ RTM_DELLINKPROP,
+#define RTM_DELLINKPROP RTM_DELLINKPROP
+ RTM_GETLINKPROP,
+#define RTM_GETLINKPROP RTM_GETLINKPROP
+
__RTM_MAX,
#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
};
diff --git a/include/utils.h b/include/utils.h
index 794d36053634..001491a1eb40 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -196,6 +196,7 @@ void duparg(const char *, const char *) __attribute__((noreturn));
void duparg2(const char *, const char *) __attribute__((noreturn));
int nodev(const char *dev);
int check_ifname(const char *);
+int check_altifname(const char *name);
int get_ifname(char *, const char *);
const char *get_ifname_rta(int ifindex, const struct rtattr *rta);
bool matches(const char *prefix, const char *string);
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index bc8f5ba13c33..2881b2e356ff 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -879,7 +879,7 @@ int print_linkinfo(struct nlmsghdr *n, void *arg)
if (filter.up && !(ifi->ifi_flags&IFF_UP))
return -1;
- parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
+ parse_rtattr_flags(tb, IFLA_MAX, IFLA_RTA(ifi), len, NLA_F_NESTED);
name = get_ifname_rta(ifi->ifi_index, tb[IFLA_IFNAME]);
if (!name)
@@ -1139,7 +1139,23 @@ int print_linkinfo(struct nlmsghdr *n, void *arg)
close_json_array(PRINT_JSON, NULL);
}
- print_string(PRINT_FP, NULL, "%s", "\n");
+ if (tb[IFLA_PROP_LIST]) {
+ struct rtattr *i, *proplist = tb[IFLA_PROP_LIST];
+ int rem = RTA_PAYLOAD(proplist);
+
+ open_json_array(PRINT_JSON, "altnames");
+ for (i = RTA_DATA(proplist); RTA_OK(i, rem);
+ i = RTA_NEXT(i, rem)) {
+ if (i->rta_type != IFLA_ALT_IFNAME)
+ continue;
+ print_string(PRINT_FP, "NULL", "%s altname ", _SL_);
+ print_string(PRINT_ANY, NULL,
+ "%s", rta_getattr_str(i));
+ }
+ close_json_array(PRINT_JSON, NULL);
+ }
+
+ print_string(PRINT_FP, NULL, "%s", _SL_);
fflush(fp);
return 1;
}
diff --git a/ip/iplink.c b/ip/iplink.c
index 212a088535da..e3f8a28fe94c 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -111,7 +111,9 @@ void iplink_usage(void)
"\n"
" ip link xstats type TYPE [ ARGS ]\n"
"\n"
- " ip link afstats [ dev DEVICE ]\n");
+ " ip link afstats [ dev DEVICE ]\n"
+ " ip link prop add dev DEVICE [ altname NAME .. ]\n"
+ " ip link prop del dev DEVICE [ altname NAME .. ]\n");
if (iplink_have_newlink()) {
fprintf(stderr,
@@ -1617,6 +1619,81 @@ static int iplink_afstats(int argc, char **argv)
return 0;
}
+static int iplink_prop_mod(int argc, char **argv, struct iplink_req *req)
+{
+ struct rtattr *proplist;
+ char *dev = NULL;
+ char *name;
+
+ proplist = addattr_nest(&req->n, sizeof(*req),
+ IFLA_PROP_LIST | NLA_F_NESTED);
+
+ while (argc > 0) {
+ if (matches(*argv, "altname") == 0) {
+ NEXT_ARG();
+ if (check_altifname(*argv))
+ invarg("not a valid altname", *argv);
+ name = *argv;
+ addattr_l(&req->n, sizeof(*req), IFLA_ALT_IFNAME,
+ name, strlen(name) + 1);
+ } else if (matches(*argv, "help") == 0) {
+ usage();
+ } else {
+ if (strcmp(*argv, "dev") == 0)
+ NEXT_ARG();
+ if (dev)
+ duparg2("dev", *argv);
+ if (check_altifname(*argv))
+ invarg("\"dev\" not a valid ifname", *argv);
+ dev = *argv;
+ }
+ argv++; argc--;
+ }
+ addattr_nest_end(&req->n, proplist);
+
+ if (!dev) {
+ fprintf(stderr, "Not enough of information: \"dev\" argument is required.\n");
+ exit(-1);
+ }
+
+ req->i.ifi_index = ll_name_to_index(dev);
+ if (!req->i.ifi_index)
+ return nodev(dev);
+
+ if (rtnl_talk(&rth, &req->n, NULL) < 0)
+ return -2;
+
+ return 0;
+}
+
+static int iplink_prop(int argc, char **argv)
+{
+ struct iplink_req req = {
+ .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
+ .n.nlmsg_flags = NLM_F_REQUEST,
+ .i.ifi_family = preferred_family,
+ };
+
+ if (argc <= 0) {
+ usage();
+ exit(-1);
+ }
+
+ if (matches(*argv, "add") == 0) {
+ req.n.nlmsg_flags |= NLM_F_EXCL | NLM_F_CREATE | NLM_F_APPEND;
+ req.n.nlmsg_type = RTM_NEWLINKPROP;
+ } else if (matches(*argv, "del") == 0) {
+ req.n.nlmsg_flags |= RTM_DELLINK;
+ req.n.nlmsg_type = RTM_DELLINKPROP;
+ } else if (matches(*argv, "help") == 0) {
+ usage();
+ } else {
+ fprintf(stderr, "Operator required\n");
+ exit(-1);
+ }
+ return iplink_prop_mod(argc - 1, argv + 1, &req);
+}
+
static void do_help(int argc, char **argv)
{
struct link_util *lu = NULL;
@@ -1674,6 +1751,9 @@ int do_iplink(int argc, char **argv)
return 0;
}
+ if (matches(*argv, "prop") == 0)
+ return iplink_prop(argc-1, argv+1);
+
if (matches(*argv, "help") == 0) {
do_help(argc-1, argv+1);
return 0;
diff --git a/lib/utils.c b/lib/utils.c
index 95d46ff210aa..bbb3bdcfa80b 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -824,14 +824,10 @@ int nodev(const char *dev)
return -1;
}
-int check_ifname(const char *name)
+static int __check_ifname(const char *name)
{
- /* These checks mimic kernel checks in dev_valid_name */
if (*name == '\0')
return -1;
- if (strlen(name) >= IFNAMSIZ)
- return -1;
-
while (*name) {
if (*name == '/' || isspace(*name))
return -1;
@@ -840,6 +836,19 @@ int check_ifname(const char *name)
return 0;
}
+int check_ifname(const char *name)
+{
+ /* These checks mimic kernel checks in dev_valid_name */
+ if (strlen(name) >= IFNAMSIZ)
+ return -1;
+ return __check_ifname(name);
+}
+
+int check_altifname(const char *name)
+{
+ return __check_ifname(name);
+}
+
/* buf is assumed to be IFNAMSIZ */
int get_ifname(char *buf, const char *name)
{
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index a8ae72d2b097..7cb4d56726d8 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -244,6 +244,17 @@ ip-link \- network device configuration
.IR VLAN-QOS " ] ["
.B proto
.IR VLAN-PROTO " ] ]"
+.in -8
+
+.ti -8
+.BI "ip link prop add"
+.RB "[ " altname
+.IR NAME " .. ]"
+
+.ti -8
+.BI "ip link prop del"
+.RB "[ " altname
+.IR NAME " .. ]"
.SH "DESCRIPTION"
.SS ip link add - add virtual link
--
2.21.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [patch net-next 1/2] ip: add support for alternative name addition/deletion/list
2019-09-30 9:59 ` [patch net-next 1/2] ip: add support for alternative name addition/deletion/list Jiri Pirko
@ 2019-09-30 10:09 ` Jiri Pirko
2019-09-30 16:27 ` Stephen Hemminger
1 sibling, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2019-09-30 10:09 UTC (permalink / raw)
To: netdev
Cc: davem, jakub.kicinski, dsahern, roopa, dcbw, nikolay, mkubecek,
andrew, parav, saeedm, f.fainelli, stephen, sd, sbrivio, pabeni,
mlxsw
In subject of this and the next one should be iproute2-next, of course.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [patch net-next 1/2] ip: add support for alternative name addition/deletion/list
2019-09-30 9:59 ` [patch net-next 1/2] ip: add support for alternative name addition/deletion/list Jiri Pirko
2019-09-30 10:09 ` Jiri Pirko
@ 2019-09-30 16:27 ` Stephen Hemminger
2019-09-30 17:51 ` Jiri Pirko
1 sibling, 1 reply; 14+ messages in thread
From: Stephen Hemminger @ 2019-09-30 16:27 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, jakub.kicinski, dsahern, roopa, dcbw, nikolay,
mkubecek, andrew, parav, saeedm, f.fainelli, sd, sbrivio, pabeni,
mlxsw
On Mon, 30 Sep 2019 11:59:02 +0200
Jiri Pirko <jiri@resnulli.us> wrote:
> + open_json_array(PRINT_JSON, "altnames");
> + for (i = RTA_DATA(proplist); RTA_OK(i, rem);
> + i = RTA_NEXT(i, rem)) {
> + if (i->rta_type != IFLA_ALT_IFNAME)
> + continue;
> + print_string(PRINT_FP, "NULL", "%s altname ", _SL_);
You can pass real NULL versus quoted NULL when doing print to file only
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [patch net-next 1/2] ip: add support for alternative name addition/deletion/list
2019-09-30 16:27 ` Stephen Hemminger
@ 2019-09-30 17:51 ` Jiri Pirko
0 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2019-09-30 17:51 UTC (permalink / raw)
To: Stephen Hemminger
Cc: netdev, davem, jakub.kicinski, dsahern, roopa, dcbw, nikolay,
mkubecek, andrew, parav, saeedm, f.fainelli, sd, sbrivio, pabeni,
mlxsw
Mon, Sep 30, 2019 at 06:27:18PM CEST, stephen@networkplumber.org wrote:
>On Mon, 30 Sep 2019 11:59:02 +0200
>Jiri Pirko <jiri@resnulli.us> wrote:
>
>> + open_json_array(PRINT_JSON, "altnames");
>> + for (i = RTA_DATA(proplist); RTA_OK(i, rem);
>> + i = RTA_NEXT(i, rem)) {
>> + if (i->rta_type != IFLA_ALT_IFNAME)
>> + continue;
>> + print_string(PRINT_FP, "NULL", "%s altname ", _SL_);
>
>You can pass real NULL versus quoted NULL when doing print to file only
Okay, will do.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [patch net-next 2/2] ip: allow to use alternative names as handle
2019-09-30 9:48 [patch net-next 0/7] net: introduce alternative names for network interfaces Jiri Pirko
` (7 preceding siblings ...)
2019-09-30 9:59 ` [patch net-next 1/2] ip: add support for alternative name addition/deletion/list Jiri Pirko
@ 2019-09-30 9:59 ` Jiri Pirko
2019-10-01 21:51 ` [patch net-next 0/7] net: introduce alternative names for network interfaces David Miller
9 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2019-09-30 9:59 UTC (permalink / raw)
To: netdev
Cc: davem, jakub.kicinski, dsahern, roopa, dcbw, nikolay, mkubecek,
andrew, parav, saeedm, f.fainelli, stephen, sd, sbrivio, pabeni,
mlxsw
From: Jiri Pirko <jiri@mellanox.com>
Extend ll_name_to_index() to get the index of a netdevice using
alternative interface name. Allow alternative long names to pass checks
in couple of ip link/addr commands.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
rfc->v1:
- added patch description
---
ip/iplink.c | 5 +++--
lib/ll_map.c | 41 ++++++++++++++++++++++++++++++++++++++++-
2 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/ip/iplink.c b/ip/iplink.c
index e3f8a28fe94c..1684e259b538 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -931,7 +931,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type)
NEXT_ARG();
if (dev != name)
duparg2("dev", *argv);
- if (check_ifname(*argv))
+ if (check_altifname(*argv))
invarg("\"dev\" not a valid ifname", *argv);
dev = *argv;
}
@@ -1106,7 +1106,8 @@ int iplink_get(char *name, __u32 filt_mask)
if (name) {
addattr_l(&req.n, sizeof(req),
- IFLA_IFNAME, name, strlen(name) + 1);
+ !check_ifname(name) ? IFLA_IFNAME : IFLA_ALT_IFNAME,
+ name, strlen(name) + 1);
}
addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filt_mask);
diff --git a/lib/ll_map.c b/lib/ll_map.c
index e0ed54bf77c9..04dfb0f2320b 100644
--- a/lib/ll_map.c
+++ b/lib/ll_map.c
@@ -70,7 +70,7 @@ static struct ll_cache *ll_get_by_name(const char *name)
struct ll_cache *im
= container_of(n, struct ll_cache, name_hash);
- if (strncmp(im->name, name, IFNAMSIZ) == 0)
+ if (strcmp(im->name, name) == 0)
return im;
}
@@ -240,6 +240,43 @@ int ll_index_to_flags(unsigned idx)
return im ? im->flags : -1;
}
+static int altnametoindex(const char *name)
+{
+ struct {
+ struct nlmsghdr n;
+ struct ifinfomsg ifm;
+ char buf[1024];
+ } req = {
+ .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
+ .n.nlmsg_flags = NLM_F_REQUEST,
+ .n.nlmsg_type = RTM_GETLINK,
+ };
+ struct rtnl_handle rth = {};
+ struct nlmsghdr *answer;
+ struct ifinfomsg *ifm;
+ int rc = 0;
+
+ if (rtnl_open(&rth, 0) < 0)
+ return 0;
+
+ addattr32(&req.n, sizeof(req), IFLA_EXT_MASK,
+ RTEXT_FILTER_VF | RTEXT_FILTER_SKIP_STATS);
+ addattr_l(&req.n, sizeof(req), IFLA_ALT_IFNAME, name, strlen(name) + 1);
+
+ if (rtnl_talk_suppress_rtnl_errmsg(&rth, &req.n, &answer) < 0)
+ goto out;
+
+ ifm = NLMSG_DATA(answer);
+ rc = ifm->ifi_index;
+
+ free(answer);
+
+ rtnl_close(&rth);
+out:
+ return rc;
+}
+
+
unsigned ll_name_to_index(const char *name)
{
const struct ll_cache *im;
@@ -257,6 +294,8 @@ unsigned ll_name_to_index(const char *name)
idx = if_nametoindex(name);
if (idx == 0)
idx = ll_idx_a2n(name);
+ if (idx == 0)
+ idx = altnametoindex(name);
return idx;
}
--
2.21.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [patch net-next 0/7] net: introduce alternative names for network interfaces
2019-09-30 9:48 [patch net-next 0/7] net: introduce alternative names for network interfaces Jiri Pirko
` (8 preceding siblings ...)
2019-09-30 9:59 ` [patch net-next 2/2] ip: allow to use alternative names as handle Jiri Pirko
@ 2019-10-01 21:51 ` David Miller
9 siblings, 0 replies; 14+ messages in thread
From: David Miller @ 2019-10-01 21:51 UTC (permalink / raw)
To: jiri
Cc: netdev, jakub.kicinski, dsahern, roopa, dcbw, nikolay, mkubecek,
andrew, parav, saeedm, f.fainelli, stephen, sd, sbrivio, pabeni,
mlxsw
From: Jiri Pirko <jiri@resnulli.us>
Date: Mon, 30 Sep 2019 11:48:13 +0200
> This patchset introduces alternative names for network interfaces.
> Main goal is to:
> 1) Overcome the IFNAMSIZ limitation (altname limitation is 128 bytes)
> 2) Allow to have multiple names at the same time (multiple udev patterns)
> 3) Allow to use alternative names as handle for commands
Ok, let's see where this goes.
Series applied, thanks Jiri.
^ permalink raw reply [flat|nested] 14+ messages in thread