summaryrefslogtreecommitdiff
path: root/ip/iplink.c
diff options
context:
space:
mode:
Diffstat (limited to 'ip/iplink.c')
-rw-r--r--ip/iplink.c81
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;