Add ability to set link state with ip
Exposes existing netlink operations to modify link state of devices.
diff --git a/ip/ip_common.h b/ip/ip_common.h
index b45c5ee..6288437 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -1,3 +1,4 @@
+extern int get_operstate(const char *name);
extern int print_linkinfo(const struct sockaddr_nl *who,
struct nlmsghdr *n,
void *arg);
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index aea1a81..9306a37 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -131,6 +131,16 @@
fprintf(f, "state %s ", oper_states[state]);
}
+int get_operstate(const char *name)
+{
+ int i;
+
+ for (i = 0; i < sizeof(oper_states)/sizeof(oper_states[0]); i++)
+ if (strcasecmp(name, oper_states[i]) == 0)
+ return i;
+ return -1;
+}
+
static void print_queuelen(FILE *f, struct rtattr *tb[IFLA_MAX + 1])
{
int qlen;
diff --git a/ip/iplink.c b/ip/iplink.c
index 814a92c..a58e4d0 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -433,10 +433,18 @@
} else if (strcmp(*argv, "mode") == 0) {
int mode;
NEXT_ARG();
- mode = get_link_mode(*argv);
+ mode = get_link_mode(*argv);
if (mode < 0)
invarg("Invalid link mode\n", *argv);
addattr8(&req->n, sizeof(*req), IFLA_LINKMODE, mode);
+ } else if (strcmp(*argv, "state") == 0) {
+ int state;
+ NEXT_ARG();
+ state = get_operstate(*argv);
+ if (state < 0)
+ invarg("Invalid operstate\n", *argv);
+
+ addattr8(&req->n, sizeof(*req), IFLA_OPERSTATE, state);
} else {
if (strcmp(*argv, "dev") == 0) {
NEXT_ARG();
diff --git a/man/man8/ip-link.8 b/man/man8/ip-link.8
index acc6d28..72f4cfd 100644
--- a/man/man8/ip-link.8
+++ b/man/man8/ip-link.8
@@ -103,6 +103,9 @@
.B mode
.IR LINKMODE " |"
.br
+.B state
+.IR LINKSTATE " |"
+.br
.B master
.IR DEVICE
.br
@@ -260,6 +263,10 @@
of UP when driver is ready.
.TP
+.BI state " LINKSTATE"
+allows setting the operational link state. The values (defined in RFC2863)
+are: UP, DOWN, TESTING, UNKNOWN, DORMANT, NOTPRESENT, LOWERLAYERDOWN.
+.TP
.BI alias " NAME"
give the device a symbolic name for easy reference.