]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
tc: Fix binding of gact action by index.
authorRoman Mashak <mrv@mojatatu.com>
Thu, 6 Jun 2019 21:32:09 +0000 (17:32 -0400)
committerStephen Hemminger <stephen@networkplumber.org>
Thu, 6 Jun 2019 21:41:31 +0000 (14:41 -0700)
The following operation fails:
% sudo tc actions add action pipe index 1
% sudo tc filter add dev lo parent ffff: \
       protocol ip pref 10 u32 match ip src 127.0.0.2 \
       flowid 1:10 action gact index 1

Bad action type index
Usage: ... gact <ACTION> [RAND] [INDEX]
Where:  ACTION := reclassify | drop | continue | pass | pipe |
                  goto chain <CHAIN_INDEX> | jump <JUMP_COUNT>
        RAND := random <RANDTYPE> <ACTION> <VAL>
        RANDTYPE := netrand | determ
        VAL : = value not exceeding 10000
        JUMP_COUNT := Absolute jump from start of action list
        INDEX := index value used

However, passing a control action of gact rule during filter binding works:

% sudo tc filter add dev lo parent ffff: \
       protocol ip pref 10 u32 match ip src 127.0.0.2 \
       flowid 1:10 action gact pipe index 1

Binding by reference, i.e. by index, has to consistently work with
any tc action.

Since tc is sensitive to the order of keywords passed on the command line,
we can teach gact to skip parsing arguments as soon as it sees 'gact'
followed by 'index' keyword.

Signed-off-by: Roman Mashak <mrv@mojatatu.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
tc/m_gact.c

index a0a3c33d23dac4e9149062b6956b00069e6d8d37..5b781e16446dd288382ad3af6f3b23496b0e547e 100644 (file)
@@ -89,6 +89,9 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p,
 
        if (!matches(*argv, "gact"))
                NEXT_ARG_FWD();
+       /* we're binding existing gact action to filter by index. */
+       if (!matches(*argv, "index"))
+               goto skip_args;
        if (parse_action_control(&argc, &argv, &p.action, false))
                usage();        /* does not return */
 
@@ -133,6 +136,7 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p,
 
        if (argc > 0) {
                if (matches(*argv, "index") == 0) {
+skip_args:
                        NEXT_ARG();
                        if (get_u32(&p.index, *argv, 10)) {
                                fprintf(stderr, "Illegal \"index\"\n");