@@ -150,18 +150,19 @@ new_cmd(char **argv)
}
-int
-parse_action(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n)
+int parse_action(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n)
{
int argc = *argc_p;
char **argv = *argv_p;
struct rtattr *tail, *tail2;
char k[16];
+ int act_ck_len = 0;
int ok = 0;
int eap = 0; /* expect action parameters */
int ret = 0;
int prio = 0;
+ unsigned char act_ck[TC_COOKIE_MAX_SIZE];
if (argc <= 0)
return -1;
@@ -215,16 +216,39 @@ done0:
addattr_l(n, MAX_MSG, ++prio, NULL, 0);
addattr_l(n, MAX_MSG, TCA_ACT_KIND, k, strlen(k) + 1);
- ret = a->parse_aopt(a, &argc, &argv, TCA_ACT_OPTIONS, n);
+ ret = a->parse_aopt(a, &argc, &argv, TCA_ACT_OPTIONS,
+ n);
if (ret < 0) {
fprintf(stderr, "bad action parsing\n");
goto bad_val;
}
+
+ if (*argv && strcmp(*argv, "cookie") == 0) {
+ int slen;
+
+ NEXT_ARG();
+ slen = strlen(*argv);
+ if (slen > (TC_COOKIE_MAX_SIZE*2))
+ invarg("cookie cannot exceed %d\n",
+ *argv);
+
+ if (hex2mem(*argv, act_ck, slen/2) < 0)
+ invarg("cookie must be a hex string\n",
+ *argv);
+
+ act_ck_len = slen;
+ argc--;
+ argv++;
+ }
+
+ if (act_ck_len)
+ addattr_l(n, MAX_MSG, TCA_ACT_COOKIE,
+ (const void *)&act_ck, act_ck_len);
+
tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
ok++;
}
-
}
if (eap > 0) {
@@ -245,8 +269,7 @@ bad_val:
return -1;
}
-static int
-tc_print_one_action(FILE *f, struct rtattr *arg)
+static int tc_print_one_action(FILE *f, struct rtattr *arg)
{
struct rtattr *tb[TCA_ACT_MAX + 1];
@@ -274,8 +297,17 @@ tc_print_one_action(FILE *f, struct rtattr *arg)
return err;
if (show_stats && tb[TCA_ACT_STATS]) {
+
fprintf(f, "\tAction statistics:\n");
print_tcstats2_attr(f, tb[TCA_ACT_STATS], "\t", NULL);
+ if (tb[TCA_ACT_COOKIE]) {
+ int strsz = RTA_PAYLOAD(tb[TCA_ACT_COOKIE]);
+ char b1[strsz+1];
+
+ fprintf(f, "\n\tcookie len %d %s ", strsz,
+ hexstring_n2a(RTA_DATA(tb[TCA_ACT_COOKIE]),
+ strsz, b1, sizeof(b1)));
+ }
fprintf(f, "\n");
}