diff options
Diffstat (limited to 'ip/iplink.c')
-rw-r--r-- | ip/iplink.c | 81 |
1 files changed, 80 insertions, 1 deletions
diff --git a/ip/iplink.c b/ip/iplink.c index 212a0885..bf90fad1 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 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; |