]> git.proxmox.com Git - mirror_iproute2.git/commitdiff
ip: add support for alternative name addition/deletion/list
authorJiri Pirko <jiri@mellanox.com>
Thu, 24 Oct 2019 10:20:51 +0000 (12:20 +0200)
committerDavid Ahern <dsahern@gmail.com>
Mon, 28 Oct 2019 14:35:29 +0000 (07:35 -0700)
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>
Signed-off-by: David Ahern <dsahern@gmail.com>
include/utils.h
ip/ipaddress.c
ip/iplink.c
lib/utils.c
man/man8/ip-link.8.in

index 794d360536342383e29bee67094283f95594da6a..001491a1eb405f9143c7f4ca6ea81f0615651e84 100644 (file)
@@ -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);
index bc8f5ba13c33a2b26469b8dd6b374e6101dd3e56..b72eb7a1f80825e8a01dbafda5facb36de31ec4a 100644 (file)
@@ -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;
 }
index 212a088535da826efa3d20237c486740ef9c1047..bf90fad1b3ea4e5bc2fb057f104b236414d27b52 100644 (file)
@@ -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 property add dev DEVICE [ altname NAME .. ]\n"
+               "       ip link property del dev DEVICE [ altname NAME .. ]\n");
 
        if (iplink_have_newlink()) {
                fprintf(stderr,
@@ -1617,6 +1619,80 @@ 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_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 +1750,9 @@ int do_iplink(int argc, char **argv)
                return 0;
        }
 
+       if (matches(*argv, "property") == 0)
+               return iplink_prop(argc-1, argv+1);
+
        if (matches(*argv, "help") == 0) {
                do_help(argc-1, argv+1);
                return 0;
index 95d46ff210aaea64445d15547644494fa546afc0..bbb3bdcfa80b472959c89ef630b4e26bb806819b 100644 (file)
@@ -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)
 {
index 31051c5250a784d556c853d6969378f6b7e1e7d9..9629a649777303788487977f834e5cb02d8ae3e9 100644 (file)
@@ -244,6 +244,17 @@ ip-link \- network device configuration
 .IR VLAN-QOS " ] ["
 .B proto
 .IR VLAN-PROTO " ] ]"
+.in -8
+
+.ti -8
+.BI "ip link property add"
+.RB "[ " altname
+.IR NAME " .. ]"
+
+.ti -8
+.BI "ip link property del"
+.RB "[ " altname
+.IR NAME " .. ]"
 
 .SH "DESCRIPTION"
 .SS ip link add - add virtual link