From: Stanislav Fomichev Date: Tue, 27 May 2025 21:55:06 +0000 (-0700) Subject: ip: support setting multiple features X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=98c04e53cb3e44feb2c4f2543e02801819d825fb;p=thirdparty%2Fiproute2.git ip: support setting multiple features Commit a043bea75002 ("ip route: add support for TCP usec TS") added support for tcp_usec_ts but the existing code was not adjusted to handle multiple features in the same invocation: $ ip route add .. dev .. features tcp_usec_ts ecn Error: either "to" is duplicate, or "ecn" is garbage. The code exits the while loop as soon as it encounters any feature, make it more flexible. Tested with the following: $ ip route add .. dev .. features tcp_usec_ts ecn $ ip route add .. dev .. features tcp_usec_ts ecn quickack 1 Cc: Stephen Hemminger Fixes: a043bea75002 ("ip route: add support for TCP usec TS") Signed-off-by: Stanislav Fomichev Signed-off-by: David Ahern --- diff --git a/ip/iproute.c b/ip/iproute.c index 0e2c171f..c2538894 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -1134,6 +1134,27 @@ static int parse_nexthops(struct nlmsghdr *n, struct rtmsg *r, return 0; } +static unsigned int parse_features(int *argcp, char ***argvp) +{ + unsigned int features = 0; + char **argv = *argvp; + int argc = *argcp; + + while (++argv, --argc > 0) { + if (strcmp(*argv, "ecn") == 0) { + features |= RTAX_FEATURE_ECN; + } else if (strcmp(*argv, "tcp_usec_ts") == 0) { + features |= RTAX_FEATURE_TCP_USEC_TS; + } else { + break; + } + } + + *argcp = argc; + *argvp = argv; + return features; +} + static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv) { struct { @@ -1374,17 +1395,14 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv) } else if (matches(*argv, "features") == 0) { unsigned int features = 0; - while (argc > 0) { - NEXT_ARG(); + features = parse_features(&argc, &argv); + if (!features) + invarg("\"features\" value not valid\n", *argv); - if (strcmp(*argv, "ecn") == 0) - features |= RTAX_FEATURE_ECN; - else if (strcmp(*argv, "tcp_usec_ts") == 0) - features |= RTAX_FEATURE_TCP_USEC_TS; - else - invarg("\"features\" value not valid\n", *argv); - break; - } + /* parse_features stops at the first feature it can't + * parse, rewind one argument back. + */ + PREV_ARG(); rta_addattr32(mxrta, sizeof(mxbuf), RTAX_FEATURES, features);