Commit 29d1f730 authored by Florian Westphal's avatar Florian Westphal Committed by Stephen Hemminger

ip route: enable per-route ecn settings via 'features' option

This permits to selectively enable explicit congestion notification via
the routing table.

If this ecn feature is not set, the kernel will use the tcp_ecn sysctl
to decide wheter to use ECN when establising a TCP connection.

At the time of this writing, the kernel supports ecn and allfrags, but
allfrags is of dubious value and not implemented here.

Example:

ip route change 192.168.2.0/24 dev eth0 features ecn
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
parent 81eaf677
...@@ -80,6 +80,7 @@ static void usage(void) ...@@ -80,6 +80,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, " [ quickack BOOL ]\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");
...@@ -89,6 +90,7 @@ static void usage(void) ...@@ -89,6 +90,7 @@ static void usage(void)
fprintf(stderr, "RTPROTO := [ kernel | boot | static | NUMBER ]\n"); fprintf(stderr, "RTPROTO := [ kernel | boot | static | NUMBER ]\n");
fprintf(stderr, "TIME := NUMBER[s|ms]\n"); fprintf(stderr, "TIME := NUMBER[s|ms]\n");
fprintf(stderr, "BOOL := [1|0]\n"); fprintf(stderr, "BOOL := [1|0]\n");
fprintf(stderr, "FEATURES := ecn\n");
exit(-1); exit(-1);
} }
...@@ -280,6 +282,19 @@ static int calc_host_len(const struct rtmsg *r) ...@@ -280,6 +282,19 @@ static int calc_host_len(const struct rtmsg *r)
return -1; return -1;
} }
static void print_rtax_features(FILE *fp, unsigned int features)
{
unsigned int of = features;
if (features & RTAX_FEATURE_ECN) {
fprintf(fp, " ecn");
features &= ~RTAX_FEATURE_ECN;
}
if (features)
fprintf(fp, " 0x%x", of);
}
int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{ {
FILE *fp = (FILE*)arg; FILE *fp = (FILE*)arg;
...@@ -535,6 +550,9 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) ...@@ -535,6 +550,9 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
val = *(unsigned*)RTA_DATA(mxrta[i]); val = *(unsigned*)RTA_DATA(mxrta[i]);
switch (i) { switch (i) {
case RTAX_FEATURES:
print_rtax_features(fp, val);
break;
case RTAX_HOPLIMIT: case RTAX_HOPLIMIT:
if ((int)val == -1) if ((int)val == -1)
val = 0; val = 0;
...@@ -885,6 +903,20 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) ...@@ -885,6 +903,20 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
if (get_unsigned(&win, *argv, 0)) if (get_unsigned(&win, *argv, 0))
invarg("\"initrwnd\" value is invalid\n", *argv); invarg("\"initrwnd\" value is invalid\n", *argv);
rta_addattr32(mxrta, sizeof(mxbuf), RTAX_INITRWND, win); rta_addattr32(mxrta, sizeof(mxbuf), RTAX_INITRWND, win);
} else if (matches(*argv, "features") == 0) {
unsigned int features = 0;
while (argc > 0) {
NEXT_ARG();
if (strcmp(*argv, "ecn") == 0)
features |= RTAX_FEATURE_ECN;
else
invarg("\"features\" value not valid\n", *argv);
break;
}
rta_addattr32(mxrta, sizeof(mxbuf), RTAX_FEATURES, features);
} else if (matches(*argv, "quickack") == 0) { } else if (matches(*argv, "quickack") == 0) {
unsigned quickack; unsigned quickack;
NEXT_ARG(); NEXT_ARG();
......
...@@ -113,6 +113,8 @@ replace " } " ...@@ -113,6 +113,8 @@ replace " } "
.IR NUMBER " ] [ " .IR NUMBER " ] [ "
.B initrwnd .B initrwnd
.IR NUMBER " ] [ " .IR NUMBER " ] [ "
.B features
.IR FEATURES " ] [ "
.B quickack .B quickack
.IR BOOL " ]" .IR BOOL " ]"
...@@ -140,6 +142,10 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]" ...@@ -140,6 +142,10 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]"
.BR kernel " | " boot " | " static " |" .BR kernel " | " boot " | " static " |"
.IR NUMBER " ]" .IR NUMBER " ]"
.ti -8
.IR FEATURES " := [ "
.BR ecn " | ]"
.SH DESCRIPTION .SH DESCRIPTION
.B ip route .B ip route
...@@ -410,6 +416,18 @@ the initial receive window size for connections to this destination. ...@@ -410,6 +416,18 @@ the initial receive window size for connections to this destination.
Actual window size is this value multiplied by the MSS of the connection. Actual window size is this value multiplied by the MSS of the connection.
The default value is zero, meaning to use Slow Start value. The default value is zero, meaning to use Slow Start value.
.TP
.BI features " FEATURES " (3.18+ only)
Enable or disable per-route features. Only available feature at this
time is
.B ecn
to enable explicit congestion notification when initiating connections to the
given destination network.
When responding to a connection request from the given network, ecn will
also be used even if the
.B net.ipv4.tcp_ecn
sysctl is set to 0.
.TP .TP
.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.
......
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