diff --git a/ip/ipaddress.c b/ip/ipaddress.c index 5b9a4385..d2524e89 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -229,6 +229,7 @@ static void print_vfinfo(FILE *fp, struct rtattr *vfinfo) struct ifla_vf_vlan *vf_vlan; struct ifla_vf_tx_rate *vf_tx_rate; struct ifla_vf_spoofchk *vf_spoofchk; + struct ifla_vf_link_state *vf_linkstate; struct rtattr *vf[IFLA_VF_MAX+1]; struct rtattr *tmp; SPRINT_BUF(b1); @@ -255,6 +256,20 @@ static void print_vfinfo(FILE *fp, struct rtattr *vfinfo) else vf_spoofchk = RTA_DATA(vf[IFLA_VF_SPOOFCHK]); + if (vf_spoofchk) { + /* Check if the link state vf info type is supported by + * this kernel. + */ + tmp = (struct rtattr *)((char *)vf[IFLA_VF_SPOOFCHK] + + vf[IFLA_VF_SPOOFCHK]->rta_len); + + if (tmp->rta_type != IFLA_VF_LINK_STATE) + vf_linkstate = NULL; + else + vf_linkstate = RTA_DATA(vf[IFLA_VF_LINK_STATE]); + } else + vf_linkstate = NULL; + fprintf(fp, "\n vf %d MAC %s", vf_mac->vf, ll_addr_n2a((unsigned char *)&vf_mac->mac, ETH_ALEN, 0, b1, sizeof(b1))); @@ -270,6 +285,14 @@ static void print_vfinfo(FILE *fp, struct rtattr *vfinfo) else fprintf(fp, ", spoof checking off"); } + if (vf_linkstate) { + if (vf_linkstate->link_state == IFLA_VF_LINK_STATE_AUTO) + fprintf(fp, ", link-state auto"); + else if (vf_linkstate->link_state == IFLA_VF_LINK_STATE_ENABLE) + fprintf(fp, ", link-state enable"); + else + fprintf(fp, ", link-state disable"); + } } static void print_link_stats64(FILE *fp, const struct rtnl_link_stats64 *s) { diff --git a/ip/iplink.c b/ip/iplink.c index dc980195..ada9d425 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -77,6 +77,7 @@ void iplink_usage(void) fprintf(stderr, " [ rate TXRATE ] ] \n"); fprintf(stderr, " [ spoofchk { on | off} ] ] \n"); + fprintf(stderr, " [ state { auto | enable | disable} ] ]\n"); fprintf(stderr, " [ master DEVICE ]\n"); fprintf(stderr, " [ nomaster ]\n"); fprintf(stderr, " ip link show [ DEVICE | group GROUP ] [up]\n"); @@ -255,6 +256,19 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp, ivs.vf = vf; addattr_l(&req->n, sizeof(*req), IFLA_VF_SPOOFCHK, &ivs, sizeof(ivs)); + } else if (matches(*argv, "state") == 0) { + struct ifla_vf_link_state ivl; + NEXT_ARG(); + if (matches(*argv, "auto") == 0) + ivl.link_state = IFLA_VF_LINK_STATE_AUTO; + else if (matches(*argv, "enable") == 0) + ivl.link_state = IFLA_VF_LINK_STATE_ENABLE; + else if (matches(*argv, "disable") == 0) + ivl.link_state = IFLA_VF_LINK_STATE_DISABLE; + else + invarg("Invalid \"state\" value\n", *argv); + ivl.vf = vf; + addattr_l(&req->n, sizeof(*req), IFLA_VF_LINK_STATE, &ivl, sizeof(ivl)); } else { /* rewind arg */ PREV_ARG(); diff --git a/ip/iproute.c b/ip/iproute.c index d3c56d3d..b069f1e0 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -52,6 +52,7 @@ static const char *mx_names[RTAX_MAX+1] = { [RTAX_FEATURES] = "features", [RTAX_RTO_MIN] = "rto_min", [RTAX_INITRWND] = "initrwnd", + [RTAX_QUICKACK] = "quickack", }; static void usage(void) __attribute__((noreturn)); @@ -79,6 +80,7 @@ static void usage(void) fprintf(stderr, " [ window NUMBER] [ cwnd NUMBER ] [ initcwnd NUMBER ]\n"); fprintf(stderr, " [ ssthresh NUMBER ] [ realms REALM ] [ src ADDRESS ]\n"); fprintf(stderr, " [ rto_min TIME ] [ hoplimit NUMBER ] [ initrwnd NUMBER ]\n"); + fprintf(stderr, " [ quickack BOOL ]\n"); fprintf(stderr, "TYPE := [ unicast | local | broadcast | multicast | throw |\n"); fprintf(stderr, " unreachable | prohibit | blackhole | nat ]\n"); fprintf(stderr, "TABLE_ID := [ local | main | default | all | NUMBER ]\n"); @@ -86,6 +88,7 @@ static void usage(void) fprintf(stderr, "NHFLAGS := [ onlink | pervasive ]\n"); fprintf(stderr, "RTPROTO := [ kernel | boot | static | NUMBER ]\n"); fprintf(stderr, "TIME := NUMBER[s|ms]\n"); + fprintf(stderr, "BOOL := [1|0]\n"); exit(-1); } @@ -885,6 +888,14 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) if (get_unsigned(&win, *argv, 0)) invarg("\"initrwnd\" value is invalid\n", *argv); rta_addattr32(mxrta, sizeof(mxbuf), RTAX_INITRWND, win); + } else if (matches(*argv, "quickack") == 0) { + unsigned quickack; + NEXT_ARG(); + if (get_unsigned(&quickack, *argv, 0)) + invarg("\"quickack\" value is invalid\n", *argv); + if (quickack != 1 && quickack != 0) + invarg("\"quickack\" value should be 0 or 1\n", *argv); + rta_addattr32(mxrta, sizeof(mxbuf), RTAX_QUICKACK, quickack); } else if (matches(*argv, "rttvar") == 0) { unsigned win; NEXT_ARG(); diff --git a/man/man8/ip-route.8.in b/man/man8/ip-route.8.in index 654816f1..7191bce4 100644 --- a/man/man8/ip-route.8.in +++ b/man/man8/ip-route.8.in @@ -111,6 +111,8 @@ replace " } " .IR NUMBER " ] [ " .B initrwnd .IR NUMBER " ]" +.B quickack +.IR BOOL " ]" .ti -8 .IR TYPE " := [ " @@ -406,6 +408,10 @@ the initial receive window size for connections to this destination. Actual window size is this value multiplied by the MSS of the connection. The default value is zero, meaning to use Slow Start value. +.TP +.BI quickack " BOOL " "(3.11+ only)" +Enable or disable quick ack for connections to this destination. + .TP .BI advmss " NUMBER " "(2.3.15+ only)" the MSS ('Maximal Segment Size') to advertise to these