From 82499282b27c82a25448dc40948920950c9a6936 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 19 Mar 2012 17:24:43 -0700 Subject: [PATCH] ip: allow set and display of link mode parameter The kernel supports a link mode attribute (which can be dormant or default). This attribute is used to control how the link watch engine handles operstate transistion. This adds a new parameter to ip link command to allow setting and displaying the value. --- --- ip/ipaddress.c | 20 +++++++++++++++++++- ip/iplink.c | 16 ++++++++++++++++ man/man8/ip-link.8 | 11 +++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/ip/ipaddress.c b/ip/ipaddress.c index 8123da1..aea1a81 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -158,6 +158,20 @@ static void print_queuelen(FILE *f, struct rtattr *tb[IFLA_MAX + 1]) fprintf(f, "qlen %d", qlen); } +static const char *link_modes[] = { + "DEFAULT", "DORMANT" +}; + +static void print_linkmode(FILE *f, struct rtattr *tb) +{ + unsigned int mode = rta_getattr_u8(tb); + + if (mode >= sizeof(link_modes) / sizeof(link_modes[0])) + fprintf(f, "mode %d ", mode); + else + fprintf(f, "mode %s ", link_modes[mode]); +} + static void print_linktype(FILE *fp, struct rtattr *tb) { struct rtattr *linkinfo[IFLA_INFO_MAX+1]; @@ -398,9 +412,13 @@ int print_linkinfo(const struct sockaddr_nl *who, SPRINT_BUF(b1); fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1)); } + if (tb[IFLA_OPERSTATE]) print_operstate(fp, *(__u8 *)RTA_DATA(tb[IFLA_OPERSTATE])); - + + if (do_link && tb[IFLA_LINKMODE]) + print_linkmode(fp, tb[IFLA_LINKMODE]); + if (filter.showqueue) print_queuelen(fp, tb); diff --git a/ip/iplink.c b/ip/iplink.c index 8481514..814a92c 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -132,6 +132,15 @@ struct link_util *get_link_kind(const char *id) return l; } +int get_link_mode(const char *mode) +{ + if (strcmp(mode, "default") == 0) + return IF_LINK_MODE_DEFAULT; + if (strcmp(mode, "dormant") == 0) + return IF_LINK_MODE_DORMANT; + return -1; +} + #if IPLINK_IOCTL_COMPAT static int have_rtnl_newlink = -1; @@ -421,6 +430,13 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, duparg("group", *argv); if (rtnl_group_a2n(group, *argv)) invarg("Invalid \"group\" value\n", *argv); + } else if (strcmp(*argv, "mode") == 0) { + int mode; + NEXT_ARG(); + 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, "dev") == 0) { NEXT_ARG(); diff --git a/man/man8/ip-link.8 b/man/man8/ip-link.8 index 8c63584..acc6d28 100644 --- a/man/man8/ip-link.8 +++ b/man/man8/ip-link.8 @@ -100,6 +100,9 @@ ip-link \- network device configuration .B spoofchk { on | off } ] | .br +.B mode +.IR LINKMODE " |" +.br .B master .IR DEVICE .br @@ -248,6 +251,14 @@ move the device to the network namespace associated with the process move the device to the network namespace associated with name .IR "NETNSNAME". +.TP +.BI mode " LINKMODE" +allows setting link mode which determines which RFC2863 operational state +the device will transistion to when it is brought up. Setting +.I dormant +mode changes the behaviour so that device goes into DORMANT state instead +of UP when driver is ready. + .TP .BI alias " NAME" give the device a symbolic name for easy reference. -- 2.39.2