Not to be used in production.

cheers,
jamal
diff --git a/tc/f_basic.c b/tc/f_basic.c
index d663668..8370ea6 100644
--- a/tc/f_basic.c
+++ b/tc/f_basic.c
@@ -135,7 +135,7 @@ static int basic_print_opt(struct filter_util *qu, FILE *f,
        }
 
        if (tb[TCA_BASIC_ACT]) {
-               tc_print_action(f, tb[TCA_BASIC_ACT]);
+               tc_print_action(f, tb[TCA_BASIC_ACT], 0);
        }
 
        return 0;
diff --git a/tc/f_bpf.c b/tc/f_bpf.c
index df8a259..52027af 100644
--- a/tc/f_bpf.c
+++ b/tc/f_bpf.c
@@ -231,7 +231,7 @@ static int bpf_print_opt(struct filter_util *qu, FILE *f,
        }
 
        if (tb[TCA_BPF_ACT])
-               tc_print_action(f, tb[TCA_BPF_ACT]);
+               tc_print_action(f, tb[TCA_BPF_ACT], 0);
 
        return 0;
 }
diff --git a/tc/f_cgroup.c b/tc/f_cgroup.c
index ecf9909..633700e 100644
--- a/tc/f_cgroup.c
+++ b/tc/f_cgroup.c
@@ -102,7 +102,7 @@ static int cgroup_print_opt(struct filter_util *qu, FILE *f,
        }
 
        if (tb[TCA_CGROUP_ACT])
-               tc_print_action(f, tb[TCA_CGROUP_ACT]);
+               tc_print_action(f, tb[TCA_CGROUP_ACT], 0);
 
        return 0;
 }
diff --git a/tc/f_flow.c b/tc/f_flow.c
index 09ddcaa..b157104 100644
--- a/tc/f_flow.c
+++ b/tc/f_flow.c
@@ -347,7 +347,7 @@ static int flow_print_opt(struct filter_util *fu, FILE *f, 
struct rtattr *opt,
                tc_print_police(f, tb[TCA_FLOW_POLICE]);
        if (tb[TCA_FLOW_ACT]) {
                fprintf(f, "\n");
-               tc_print_action(f, tb[TCA_FLOW_ACT]);
+               tc_print_action(f, tb[TCA_FLOW_ACT], 0);
        }
        return 0;
 }
diff --git a/tc/f_flower.c b/tc/f_flower.c
index 5aac4a0..04733d9 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -1174,7 +1174,7 @@ static int flower_print_opt(struct filter_util *qu, FILE 
*f,
        }
 
        if (tb[TCA_FLOWER_ACT])
-               tc_print_action(f, tb[TCA_FLOWER_ACT]);
+               tc_print_action(f, tb[TCA_FLOWER_ACT], 0);
 
        return 0;
 }
diff --git a/tc/f_fw.c b/tc/f_fw.c
index 790bef9..c39789b 100644
--- a/tc/f_fw.c
+++ b/tc/f_fw.c
@@ -160,7 +160,7 @@ static int fw_print_opt(struct filter_util *qu, FILE *f, 
struct rtattr *opt, __u
 
        if (tb[TCA_FW_ACT]) {
                fprintf(f, "\n");
-               tc_print_action(f, tb[TCA_FW_ACT]);
+               tc_print_action(f, tb[TCA_FW_ACT], 0);
        }
        return 0;
 }
diff --git a/tc/f_matchall.c b/tc/f_matchall.c
index ac48630..5c8fe2a 100644
--- a/tc/f_matchall.c
+++ b/tc/f_matchall.c
@@ -140,7 +140,7 @@ static int matchall_print_opt(struct filter_util *qu, FILE 
*f,
        }
 
        if (tb[TCA_MATCHALL_ACT])
-               tc_print_action(f, tb[TCA_MATCHALL_ACT]);
+               tc_print_action(f, tb[TCA_MATCHALL_ACT], 0);
 
        return 0;
 }
diff --git a/tc/f_route.c b/tc/f_route.c
index 30514c4..e88313f 100644
--- a/tc/f_route.c
+++ b/tc/f_route.c
@@ -168,7 +168,7 @@ static int route_print_opt(struct filter_util *qu, FILE *f, 
struct rtattr *opt,
        if (tb[TCA_ROUTE4_POLICE])
                tc_print_police(f, tb[TCA_ROUTE4_POLICE]);
        if (tb[TCA_ROUTE4_ACT])
-               tc_print_action(f, tb[TCA_ROUTE4_ACT]);
+               tc_print_action(f, tb[TCA_ROUTE4_ACT], 0);
        return 0;
 }
 
diff --git a/tc/f_rsvp.c b/tc/f_rsvp.c
index 94bfbef..65caeb4 100644
--- a/tc/f_rsvp.c
+++ b/tc/f_rsvp.c
@@ -402,7 +402,7 @@ static int rsvp_print_opt(struct filter_util *qu, FILE *f, 
struct rtattr *opt, _
        }
 
        if (tb[TCA_RSVP_ACT]) {
-               tc_print_action(f, tb[TCA_RSVP_ACT]);
+               tc_print_action(f, tb[TCA_RSVP_ACT], 0);
        }
        if (tb[TCA_RSVP_POLICE])
                tc_print_police(f, tb[TCA_RSVP_POLICE]);
diff --git a/tc/f_tcindex.c b/tc/f_tcindex.c
index 784c890..dd1cb47 100644
--- a/tc/f_tcindex.c
+++ b/tc/f_tcindex.c
@@ -173,7 +173,7 @@ static int tcindex_print_opt(struct filter_util *qu, FILE 
*f,
        }
        if (tb[TCA_TCINDEX_ACT]) {
                fprintf(f, "\n");
-               tc_print_action(f, tb[TCA_TCINDEX_ACT]);
+               tc_print_action(f, tb[TCA_TCINDEX_ACT], 0);
        }
        return 0;
 }
diff --git a/tc/f_u32.c b/tc/f_u32.c
index 92c1fcd..dbc6939 100644
--- a/tc/f_u32.c
+++ b/tc/f_u32.c
@@ -1332,7 +1332,7 @@ static int u32_print_opt(struct filter_util *qu, FILE *f, 
struct rtattr *opt,
        }
 
        if (tb[TCA_U32_ACT])
-               tc_print_action(f, tb[TCA_U32_ACT]);
+               tc_print_action(f, tb[TCA_U32_ACT], 0);
 
        return 0;
 }
diff --git a/tc/m_action.c b/tc/m_action.c
index 6ba7615..c5d390d 100644
--- a/tc/m_action.c
+++ b/tc/m_action.c
@@ -230,7 +230,7 @@ done0:
                                NEXT_ARG();
                                slen = strlen(*argv);
                                if (slen > TC_COOKIE_MAX_SIZE * 2)
-                                       invarg("cookie cannot exceed %d\n",
+                                       invarg("cookie exceeded len\n",
                                               *argv);
 
                                if (hex2mem(*argv, act_ck, slen / 2) < 0)
@@ -341,21 +341,24 @@ tc_print_action_flush(FILE *f, const struct rtattr *arg)
 }
 
 int
-tc_print_action(FILE *f, const struct rtattr *arg)
+tc_print_action(FILE *f, const struct rtattr *arg, unsigned short tot_acts)
 {
 
        int i;
-       struct rtattr *tb[TCA_ACT_MAX_PRIO + 1];
 
        if (arg == NULL)
                return 0;
 
-       parse_rtattr_nested(tb, TCA_ACT_MAX_PRIO, arg);
+       if (!tot_acts)
+               tot_acts = TCA_ACT_MAX_PRIO;
+
+       struct rtattr *tb[tot_acts + 1];
+       parse_rtattr_nested(tb, tot_acts, arg);
 
        if (tab_flush && NULL != tb[0]  && NULL == tb[1])
                return tc_print_action_flush(f, tb[0]);
 
-       for (i = 0; i < TCA_ACT_MAX_PRIO; i++) {
+       for (i = 0; i < tot_acts; i++) {
                if (tb[i]) {
                        fprintf(f, "\n\taction order %d: ", i);
                        if (tc_print_one_action(f, tb[i]) < 0) {
@@ -375,6 +378,7 @@ int print_action(const struct sockaddr_nl *who,
        FILE *fp = (FILE *)arg;
        struct tcamsg *t = NLMSG_DATA(n);
        int len = n->nlmsg_len;
+       __u32 *tot_acts = NULL;
        struct rtattr *tb[TCAA_MAX+1];
 
        len -= NLMSG_LENGTH(sizeof(*t));
@@ -386,6 +390,10 @@ int print_action(const struct sockaddr_nl *who,
 
        parse_rtattr(tb, TCAA_MAX, TA_RTA(t), len);
 
+       if (tb[TCAA_ACT_COUNT])
+               tot_acts = RTA_DATA(tb[TCAA_ACT_COUNT]);
+
+       fprintf(fp, "total acts %d \n", tot_acts?*tot_acts:0);
        if (tb[TCA_ACT_TAB] == NULL) {
                if (n->nlmsg_type != RTM_GETACTION)
                        fprintf(stderr, "print_action: NULL kind\n");
@@ -409,7 +417,9 @@ int print_action(const struct sockaddr_nl *who,
                        fprintf(fp, "Replaced action ");
                }
        }
-       tc_print_action(fp, tb[TCA_ACT_TAB]);
+
+
+       tc_print_action(fp, tb[TCA_ACT_TAB], tot_acts?*tot_acts:0);
 
        return 0;
 }
@@ -422,7 +432,7 @@ static int tc_action_gd(int cmd, unsigned int flags, int 
*argc_p, char ***argv_p
        char **argv = *argv_p;
        int prio = 0;
        int ret = 0;
-       __u32 i;
+       __u32 i = 0;
        struct rtattr *tail;
        struct rtattr *tail2;
        struct nlmsghdr *ans = NULL;
@@ -493,7 +503,8 @@ static int tc_action_gd(int cmd, unsigned int flags, int 
*argc_p, char ***argv_p
                tail2 = NLMSG_TAIL(&req.n);
                addattr_l(&req.n, MAX_MSG, ++prio, NULL, 0);
                addattr_l(&req.n, MAX_MSG, TCA_ACT_KIND, k, strlen(k) + 1);
-               addattr32(&req.n, MAX_MSG, TCA_ACT_INDEX, i);
+               if (i > 0)
+                       addattr32(&req.n, MAX_MSG, TCA_ACT_INDEX, i);
                tail2->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail2;
 
        }
@@ -560,7 +571,8 @@ static int tc_act_list_or_flush(int argc, char **argv, int 
event)
 {
        int ret = 0, prio = 0, msg_size = 0;
        char k[16];
-       struct rtattr *tail, *tail2;
+       struct rtattr *tail, *tail2, *tail3, *tail4;
+       __u32 msec_since = 120*1000; /* need good way to pass via cli */
        struct action_util *a = NULL;
        struct {
                struct nlmsghdr         n;
@@ -597,6 +609,12 @@ static int tc_act_list_or_flush(int argc, char **argv, int 
event)
        tail2->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail2;
        tail->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail;
 
+       tail3 = NLMSG_TAIL(&req.n);
+       addattr32(&req.n, MAX_MSG,/*TCAA_ACT_FLAGS*/2, act_flags);
+       tail3->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail3;
+       tail4 = NLMSG_TAIL(&req.n);
+       addattr32(&req.n, MAX_MSG,/*TCAA_ACT_TIME_FILTER*/4, msec_since);
+       tail4->rta_len = (void *) NLMSG_TAIL(&req.n) - (void *) tail4;
        msg_size = NLMSG_ALIGN(req.n.nlmsg_len) - NLMSG_ALIGN(sizeof(struct 
nlmsghdr));
 
        if (event == RTM_GETACTION) {
diff --git a/tc/tc_util.h b/tc/tc_util.h
index 4db26c6..af578f9 100644
--- a/tc/tc_util.h
+++ b/tc/tc_util.h
@@ -106,7 +106,7 @@ int act_parse_police(struct action_util *a, int *argc_p,
                     char ***argv_p, int tca_id, struct nlmsghdr *n);
 int print_police(struct action_util *a, FILE *f, struct rtattr *tb);
 int police_print_xstats(struct action_util *a, FILE *f, struct rtattr *tb);
-int tc_print_action(FILE *f, const struct rtattr *tb);
+int tc_print_action(FILE *f, const struct rtattr *tb, unsigned short tot_acts);
 int tc_print_ipt(FILE *f, const struct rtattr *tb);
 int parse_action(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n);
 void print_tm(FILE *f, const struct tcf_t *tm);

Reply via email to