From: Jiri Pirko <j...@mellanox.com> Signed-off-by: Jiri Pirko <j...@mellanox.com> --- include/uapi/linux/pkt_sched.h | 11 +++++++++ tc/q_clsact.c | 56 ++++++++++++++++++++++++++++++++++++++---- tc/q_ingress.c | 32 +++++++++++++++++++++--- 3 files changed, 91 insertions(+), 8 deletions(-)
diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h index 37b5096..8cc554a 100644 --- a/include/uapi/linux/pkt_sched.h +++ b/include/uapi/linux/pkt_sched.h @@ -934,4 +934,15 @@ enum { #define TCA_CBS_MAX (__TCA_CBS_MAX - 1) +/* Ingress/clsact */ + +enum { + TCA_CLSACT_UNSPEC, + TCA_CLSACT_INGRESS_BLOCK, + TCA_CLSACT_EGRESS_BLOCK, + __TCA_CLSACT_MAX +}; + +#define TCA_CLSACT_MAX (__TCA_CLSACT_MAX - 1) + #endif diff --git a/tc/q_clsact.c b/tc/q_clsact.c index 341f653..06d67db 100644 --- a/tc/q_clsact.c +++ b/tc/q_clsact.c @@ -7,23 +7,69 @@ static void explain(void) { - fprintf(stderr, "Usage: ... clsact\n"); + fprintf(stderr, "Usage: ... clsact [ingress_block BLOCK_INDEX] [egress_block BLOCK_INDEX]\n"); } static int clsact_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n, const char *dev) { - if (argc > 0) { - fprintf(stderr, "What is \"%s\"?\n", *argv); - explain(); - return -1; + struct rtattr *tail; + unsigned int ingress_block = 0; + unsigned int egress_block = 0; + + while (argc > 0) { + if (strcmp(*argv, "ingress_block") == 0) { + NEXT_ARG(); + if (get_unsigned(&ingress_block, *argv, 0)) { + fprintf(stderr, "Illegal \"ingress_block\"\n"); + return -1; + } + } else if (strcmp(*argv, "egress_block") == 0) { + NEXT_ARG(); + if (get_unsigned(&egress_block, *argv, 0)) { + fprintf(stderr, "Illegal \"egress_block\"\n"); + return -1; + } + } else { + fprintf(stderr, "What is \"%s\"?\n", *argv); + explain(); + return -1; + } + NEXT_ARG_FWD(); } + tail = NLMSG_TAIL(n); + addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); + if (ingress_block) + addattr32(n, 1024, TCA_CLSACT_INGRESS_BLOCK, ingress_block); + if (egress_block) + addattr32(n, 1024, TCA_CLSACT_EGRESS_BLOCK, egress_block); + tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; return 0; } static int clsact_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) { + struct rtattr *tb[TCA_CLSACT_MAX + 1]; + unsigned int block; + + if (!opt) + return 0; + + parse_rtattr_nested(tb, TCA_CLSACT_MAX, opt); + + if (tb[TCA_CLSACT_INGRESS_BLOCK] && + RTA_PAYLOAD(tb[TCA_CLSACT_INGRESS_BLOCK]) >= sizeof(__u32)) { + block = rta_getattr_u32(tb[TCA_CLSACT_INGRESS_BLOCK]); + print_uint(PRINT_ANY, "ingress_block", + "ingress_block %u ", block); + } + if (tb[TCA_CLSACT_EGRESS_BLOCK] && + RTA_PAYLOAD(tb[TCA_CLSACT_EGRESS_BLOCK]) >= sizeof(__u32)) { + block = rta_getattr_u32(tb[TCA_CLSACT_EGRESS_BLOCK]); + print_uint(PRINT_ANY, "egress_block", + "egress_block %u ", block); + } return 0; } diff --git a/tc/q_ingress.c b/tc/q_ingress.c index 1e42229..6899c4d 100644 --- a/tc/q_ingress.c +++ b/tc/q_ingress.c @@ -17,30 +17,56 @@ static void explain(void) { - fprintf(stderr, "Usage: ... ingress\n"); + fprintf(stderr, "Usage: ... ingress [block BLOCK_INDEX]\n"); } static int ingress_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n, const char *dev) { + struct rtattr *tail; + unsigned int block; + while (argc > 0) { if (strcmp(*argv, "handle") == 0) { NEXT_ARG(); - argc--; argv++; + } else if (strcmp(*argv, "block") == 0) { + NEXT_ARG(); + if (get_unsigned(&block, *argv, 0)) { + fprintf(stderr, "Illegal \"block\"\n"); + return -1; + } } else { fprintf(stderr, "What is \"%s\"?\n", *argv); explain(); return -1; } + NEXT_ARG_FWD(); } + tail = NLMSG_TAIL(n); + addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); + if (block) + addattr32(n, 1024, TCA_CLSACT_INGRESS_BLOCK, block); + tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; return 0; } static int ingress_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) { - fprintf(f, "---------------- "); + struct rtattr *tb[TCA_CLSACT_MAX + 1]; + unsigned int block; + + if (!opt) + return 0; + + parse_rtattr_nested(tb, TCA_CLSACT_MAX, opt); + + if (tb[TCA_CLSACT_INGRESS_BLOCK] && + RTA_PAYLOAD(tb[TCA_CLSACT_INGRESS_BLOCK]) >= sizeof(__u32)) { + block = rta_getattr_u32(tb[TCA_CLSACT_INGRESS_BLOCK]); + print_uint(PRINT_ANY, "block", "block %u ", block); + } return 0; } -- 2.9.5