From: Jiri Pirko <j...@mellanox.com>

Allow user to set action "goto" with filter chain index as a parameter.

Signed-off-by: Jiri Pirko <j...@mellanox.com>
---
 include/linux/pkt_cls.h        |  1 +
 include/linux/tc_act/tc_gact.h |  1 +
 tc/m_gact.c                    | 32 ++++++++++++++++++++++++++++----
 tc/tc_util.c                   |  3 +++
 4 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h
index 7a69f2a..4f347b0 100644
--- a/include/linux/pkt_cls.h
+++ b/include/linux/pkt_cls.h
@@ -37,6 +37,7 @@ enum {
 #define TC_ACT_QUEUED          5
 #define TC_ACT_REPEAT          6
 #define TC_ACT_REDIRECT                7
+#define TC_ACT_GOTO_CHAIN      8
 #define TC_ACT_JUMP            0x10000000
 
 /* Action type identifiers*/
diff --git a/include/linux/tc_act/tc_gact.h b/include/linux/tc_act/tc_gact.h
index 70b536a..388733d 100644
--- a/include/linux/tc_act/tc_gact.h
+++ b/include/linux/tc_act/tc_gact.h
@@ -26,6 +26,7 @@ enum {
        TCA_GACT_PARMS,
        TCA_GACT_PROB,
        TCA_GACT_PAD,
+       TCA_GACT_CHAIN,
        __TCA_GACT_MAX
 };
 #define TCA_GACT_MAX (__TCA_GACT_MAX - 1)
diff --git a/tc/m_gact.c b/tc/m_gact.c
index 755a3be..f8d1c1e 100644
--- a/tc/m_gact.c
+++ b/tc/m_gact.c
@@ -43,19 +43,21 @@ static void
 explain(void)
 {
 #ifdef CONFIG_GACT_PROB
-       fprintf(stderr, "Usage: ... gact <ACTION> [RAND] [INDEX]\n");
+       fprintf(stderr, "Usage: ... gact <ACTION> [RAND] [INDEX] [OPTIONS]\n");
        fprintf(stderr,
-               "Where: \tACTION := reclassify | drop | continue | pass | 
pipe\n"
+               "Where: \tACTION := reclassify | drop | continue | pass | pipe 
| goto\n"
                        "\tRAND := random <RANDTYPE> <ACTION> <VAL>\n"
                        "\tRANDTYPE := netrand | determ\n"
                        "\tVAL : = value not exceeding 10000\n"
                        "\tINDEX := index value used\n"
+                       "\tOPTIONS: := chain <CHAIN_INDEX>\n"
                        "\n");
 #else
-       fprintf(stderr, "Usage: ... gact <ACTION> [INDEX]\n");
+       fprintf(stderr, "Usage: ... gact <ACTION> [INDEX] [OPTIONS]\n");
        fprintf(stderr,
-               "Where: \tACTION := reclassify | drop | continue | pass | 
pipe\n"
+               "Where: \tACTION := reclassify | drop | continue | pass | pipe 
| goto\n"
                "\tINDEX := index value used\n"
+               "\tOPTIONS: := chain <CHAIN_INDEX>\n"
                "\n");
 #endif
 }
@@ -93,6 +95,7 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p,
        int rd = 0;
        struct tc_gact_p pp;
 #endif
+       __u32 chain_index;
        struct rtattr *tail;
 
        if (argc < 0)
@@ -173,6 +176,23 @@ parse_gact(struct action_util *a, int *argc_p, char 
***argv_p,
                }
        }
 
+       if (ok && action == TC_ACT_GOTO_CHAIN) {
+               if (matches(*argv, "chain") == 0) {
+                       NEXT_ARG();
+                       if (get_u32(&chain_index, *argv, 10)) {
+                               fprintf(stderr, "Illegal \"chain index\"\n");
+                               return -1;
+                       }
+                       argc--;
+                       argv++;
+               } else if (matches(*argv, "help") == 0) {
+                       usage();
+               } else {
+                       fprintf(stderr, "\"chain\" needs to be specified for 
\"goto\" action\n");
+                       return -1;
+               }
+       }
+
        if (!ok)
                return -1;
 
@@ -184,6 +204,8 @@ parse_gact(struct action_util *a, int *argc_p, char 
***argv_p,
                addattr_l(n, MAX_MSG, TCA_GACT_PROB, &pp, sizeof(pp));
        }
 #endif
+       if (action == TC_ACT_GOTO_CHAIN)
+               addattr32(n, MAX_MSG, TCA_GACT_CHAIN, chain_index);
        tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
 
        *argc_p = argc;
@@ -213,6 +235,8 @@ print_gact(struct action_util *au, FILE * f, struct rtattr 
*arg)
        p = RTA_DATA(tb[TCA_GACT_PARMS]);
 
        fprintf(f, "gact action %s", action_n2a(p->action));
+       if (tb[TCA_GACT_CHAIN])
+               fprintf(f, " chain %u", rta_getattr_u32(tb[TCA_GACT_CHAIN]));
 #ifdef CONFIG_GACT_PROB
        if (tb[TCA_GACT_PROB] != NULL) {
                pp = RTA_DATA(tb[TCA_GACT_PROB]);
diff --git a/tc/tc_util.c b/tc/tc_util.c
index 24ca1f1..a75367f 100644
--- a/tc/tc_util.c
+++ b/tc/tc_util.c
@@ -428,6 +428,8 @@ const char *action_n2a(int action)
                return "pipe";
        case TC_ACT_STOLEN:
                return "stolen";
+       case TC_ACT_GOTO_CHAIN:
+               return "goto";
        default:
                snprintf(buf, 64, "%d", action);
                buf[63] = '\0';
@@ -459,6 +461,7 @@ int action_a2n(char *arg, int *result, bool allow_num)
                {"ok", TC_ACT_OK},
                {"reclassify", TC_ACT_RECLASSIFY},
                {"pipe", TC_ACT_PIPE},
+               {"goto", TC_ACT_GOTO_CHAIN},
                { NULL },
        }, *iter;
 
-- 
2.7.4

Reply via email to