Commit 6ef87f9c authored by Daniel Borkmann's avatar Daniel Borkmann Committed by Stephen Hemminger

ip: route: add congestion control metric

This patch adds configuration and dumping of congestion control metric
for ip route, for example:

  ip route add <dst> dev foo congctl [lock] dctcp

Reference: http://thread.gmane.org/gmane.linux.network/344733Signed-off-by: default avatarDaniel Borkmann <dborkman@redhat.com>
parent f233410d
...@@ -53,6 +53,7 @@ static const char *mx_names[RTAX_MAX+1] = { ...@@ -53,6 +53,7 @@ static const char *mx_names[RTAX_MAX+1] = {
[RTAX_RTO_MIN] = "rto_min", [RTAX_RTO_MIN] = "rto_min",
[RTAX_INITRWND] = "initrwnd", [RTAX_INITRWND] = "initrwnd",
[RTAX_QUICKACK] = "quickack", [RTAX_QUICKACK] = "quickack",
[RTAX_CC_ALGO] = "congctl",
}; };
static void usage(void) __attribute__((noreturn)); static void usage(void) __attribute__((noreturn));
...@@ -80,8 +81,7 @@ static void usage(void) ...@@ -80,8 +81,7 @@ static void usage(void)
fprintf(stderr, " [ window NUMBER] [ cwnd NUMBER ] [ initcwnd NUMBER ]\n"); fprintf(stderr, " [ window NUMBER] [ cwnd NUMBER ] [ initcwnd NUMBER ]\n");
fprintf(stderr, " [ ssthresh NUMBER ] [ realms REALM ] [ src ADDRESS ]\n"); fprintf(stderr, " [ ssthresh NUMBER ] [ realms REALM ] [ src ADDRESS ]\n");
fprintf(stderr, " [ rto_min TIME ] [ hoplimit NUMBER ] [ initrwnd NUMBER ]\n"); fprintf(stderr, " [ rto_min TIME ] [ hoplimit NUMBER ] [ initrwnd NUMBER ]\n");
fprintf(stderr, " [ features FEATURES ]\n"); fprintf(stderr, " [ features FEATURES ] [ quickack BOOL ] [ congctl NAME ]\n");
fprintf(stderr, " [ quickack BOOL ]\n");
fprintf(stderr, "TYPE := [ unicast | local | broadcast | multicast | throw |\n"); fprintf(stderr, "TYPE := [ unicast | local | broadcast | multicast | throw |\n");
fprintf(stderr, " unreachable | prohibit | blackhole | nat ]\n"); fprintf(stderr, " unreachable | prohibit | blackhole | nat ]\n");
fprintf(stderr, "TABLE_ID := [ local | main | default | all | NUMBER ]\n"); fprintf(stderr, "TABLE_ID := [ local | main | default | all | NUMBER ]\n");
...@@ -536,7 +536,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) ...@@ -536,7 +536,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
mxlock = *(unsigned*)RTA_DATA(mxrta[RTAX_LOCK]); mxlock = *(unsigned*)RTA_DATA(mxrta[RTAX_LOCK]);
for (i=2; i<= RTAX_MAX; i++) { for (i=2; i<= RTAX_MAX; i++) {
unsigned val; __u32 val;
if (mxrta[i] == NULL) if (mxrta[i] == NULL)
continue; continue;
...@@ -545,10 +545,12 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) ...@@ -545,10 +545,12 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
fprintf(fp, " %s", mx_names[i]); fprintf(fp, " %s", mx_names[i]);
else else
fprintf(fp, " metric %d", i); fprintf(fp, " metric %d", i);
if (mxlock & (1<<i)) if (mxlock & (1<<i))
fprintf(fp, " lock"); fprintf(fp, " lock");
if (i != RTAX_CC_ALGO)
val = rta_getattr_u32(mxrta[i]);
val = *(unsigned*)RTA_DATA(mxrta[i]);
switch (i) { switch (i) {
case RTAX_FEATURES: case RTAX_FEATURES:
print_rtax_features(fp, val); print_rtax_features(fp, val);
...@@ -573,6 +575,10 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) ...@@ -573,6 +575,10 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
fprintf(fp, " %gs", val/1e3); fprintf(fp, " %gs", val/1e3);
else else
fprintf(fp, " %ums", val); fprintf(fp, " %ums", val);
break;
case RTAX_CC_ALGO:
fprintf(fp, " %s", rta_getattr_str(mxrta[i]));
break;
} }
} }
} }
...@@ -925,6 +931,14 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) ...@@ -925,6 +931,14 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
if (quickack != 1 && quickack != 0) if (quickack != 1 && quickack != 0)
invarg("\"quickack\" value should be 0 or 1\n", *argv); invarg("\"quickack\" value should be 0 or 1\n", *argv);
rta_addattr32(mxrta, sizeof(mxbuf), RTAX_QUICKACK, quickack); rta_addattr32(mxrta, sizeof(mxbuf), RTAX_QUICKACK, quickack);
} else if (matches(*argv, "congctl") == 0) {
NEXT_ARG();
if (strcmp(*argv, "lock") == 0) {
mxlock |= 1 << RTAX_CC_ALGO;
NEXT_ARG();
}
rta_addattr_l(mxrta, sizeof(mxbuf), RTAX_CC_ALGO, *argv,
strlen(*argv));
} else if (matches(*argv, "rttvar") == 0) { } else if (matches(*argv, "rttvar") == 0) {
unsigned win; unsigned win;
NEXT_ARG(); NEXT_ARG();
......
...@@ -116,7 +116,9 @@ replace " } " ...@@ -116,7 +116,9 @@ replace " } "
.B features .B features
.IR FEATURES " ] [ " .IR FEATURES " ] [ "
.B quickack .B quickack
.IR BOOL " ]" .IR BOOL " ] [ "
.B congctl
.IR NAME " ]"
.ti -8 .ti -8
.IR TYPE " := [ " .IR TYPE " := [ "
...@@ -432,6 +434,21 @@ sysctl is set to 0. ...@@ -432,6 +434,21 @@ sysctl is set to 0.
.BI quickack " BOOL " "(3.11+ only)" .BI quickack " BOOL " "(3.11+ only)"
Enable or disable quick ack for connections to this destination. Enable or disable quick ack for connections to this destination.
.TP
.BI congctl " NAME " "(3.20+ only)"
.TP
.BI "congctl lock" " NAME " "(3.20+ only)"
Sets a specific TCP congestion control algorithm only for a given destination.
If not specified, Linux keeps the current global default TCP congestion control
algorithm, or the one set from the application. If the modifier
.B lock
is not used, an application may nevertheless overwrite the suggested congestion
control algorithm for that destination. If the modifier
.B lock
is used, then an application is not allowed to overwrite the specified congestion
control algorithm for that destination, thus it will be enforced/guaranteed to
use the proposed algorithm.
.TP .TP
.BI advmss " NUMBER " "(2.3.15+ only)" .BI advmss " NUMBER " "(2.3.15+ only)"
the MSS ('Maximal Segment Size') to advertise to these the MSS ('Maximal Segment Size') to advertise to these
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment