On Thu, 27 Jun 2019 20:39:48 +0200 Michal Kubecek <mkube...@suse.cz> wrote:
> > > > $ ip li set dev enp3s0 alias "Onboard Ethernet" > > # ip link show "Onboard Ethernet" > > Device "Onboard Ethernet" does not exist. > > > > So it does not really appear to be an alias, it is a label. To be > > truly useful, it needs to be more than a label, it needs to be a real > > alias which you can use. > > That's exactly what I meant: to be really useful, one should be able to > use the alias(es) for setting device options, for adding routes, in > netfilter rules etc. > > Michal The kernel doesn't enforce uniqueness of alias. Also current kernel RTM_GETLINK doesn't do filter by alias (easily fixed). If it did, then handling it in iproute would be something like: diff --git a/lib/ll_map.c b/lib/ll_map.c index e0ed54bf77c9..c798ba542224 100644 --- a/lib/ll_map.c +++ b/lib/ll_map.c @@ -26,15 +26,18 @@ struct ll_cache { struct hlist_node idx_hash; struct hlist_node name_hash; + struct hlist_node alias_hash; unsigned flags; unsigned index; unsigned short type; - char name[]; + char *alias; + char name[IFNAMSIZ]; }; #define IDXMAP_SIZE 1024 static struct hlist_head idx_head[IDXMAP_SIZE]; static struct hlist_head name_head[IDXMAP_SIZE]; +static struct hlist_head alias_head[IDXMAP_SIZE]; static struct ll_cache *ll_get_by_index(unsigned index) { @@ -77,10 +80,26 @@ static struct ll_cache *ll_get_by_name(const char *name) return NULL; } +static struct ll_cache *ll_get_by_alias(const char *alias) +{ + struct hlist_node *n; + unsigned h = namehash(alias) & (IDXMAP_SIZE - 1); + + hlist_for_each(n, &alias_head[h]) { + struct ll_cache *im + = container_of(n, struct ll_cache, alias_hash); + + if (strcmp(im->alias, alias) == 0) + return im; + } + + return NULL; +} + int ll_remember_index(struct nlmsghdr *n, void *arg) { unsigned int h; - const char *ifname; + const char *ifname, *ifalias; struct ifinfomsg *ifi = NLMSG_DATA(n); struct ll_cache *im; struct rtattr *tb[IFLA_MAX+1]; @@ -96,6 +115,10 @@ int ll_remember_index(struct nlmsghdr *n, void *arg) if (im) { hlist_del(&im->name_hash); hlist_del(&im->idx_hash); + if (im->alias) { + hlist_del(&im->alias_hash); + free(im->alias); + } free(im); } return 0; @@ -106,6 +129,8 @@ int ll_remember_index(struct nlmsghdr *n, void *arg) if (ifname == NULL) return 0; + ifalias = tb[IFLA_IFALIAS] ? rta_getattr_str(tb[IFLA_IFALIAS]) : NULL; + if (im) { /* change to existing entry */ if (strcmp(im->name, ifname) != 0) { @@ -114,6 +139,14 @@ int ll_remember_index(struct nlmsghdr *n, void *arg) hlist_add_head(&im->name_hash, &name_head[h]); } + if (im->alias) { + hlist_del(&im->alias_hash); + if (ifalias) { + h = namehash(ifalias) & (IDXMAP_SIZE - 1); + hlist_add_head(&im->alias_hash, &alias_head[h]); + } + } + im->flags = ifi->ifi_flags; return 0; } @@ -132,6 +165,12 @@ int ll_remember_index(struct nlmsghdr *n, void *arg) h = namehash(ifname) & (IDXMAP_SIZE - 1); hlist_add_head(&im->name_hash, &name_head[h]); + if (ifalias) { + im->alias = strdup(ifalias); + h = namehash(ifalias) & (IDXMAP_SIZE - 1); + hlist_add_head(&im->alias_hash, &alias_head[h]); + } + return 0; } @@ -152,7 +191,7 @@ static unsigned int ll_idx_a2n(const char *name) return idx; } -static int ll_link_get(const char *name, int index) +static int ll_link_get(const char *name, const char *alias, int index) { struct { struct nlmsghdr n; @@ -176,6 +215,9 @@ static int ll_link_get(const char *name, int index) if (name) addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, strlen(name) + 1); + if (alias) + addattr_l(&req.n, sizeof(req), IFLA_IFALIAS, alias, + strlen(alias) + 1); if (rtnl_talk_suppress_rtnl_errmsg(&rth, &req.n, &answer) < 0) goto out; @@ -206,7 +248,7 @@ const char *ll_index_to_name(unsigned int idx) if (im) return im->name; - if (ll_link_get(NULL, idx) == idx) { + if (ll_link_get(NULL, NULL, idx) == idx) { im = ll_get_by_index(idx); if (im) return im->name; @@ -252,7 +294,13 @@ unsigned ll_name_to_index(const char *name) if (im) return im->index; - idx = ll_link_get(name, 0); + im = ll_get_by_alias(name); + if (im) + return im->index; + + idx = ll_link_get(name, NULL, 0); + if (idx == 0) + idx = ll_link_get(NULL, name, 0); if (idx == 0) idx = if_nametoindex(name); if (idx == 0) @@ -270,7 +318,10 @@ void ll_drop_by_index(unsigned index) hlist_del(&im->idx_hash); hlist_del(&im->name_hash); - + if (im->alias) { + hlist_del(&im->alias_hash); + free(im->alias); + } free(im); }