Use the classid values reserved in the range :ffe0 - :ffef
to identify hardware traffic classes.

Example:
Match Dst IPv4,Dst Port and route to TC1:
# tc filter add dev eth0 protocol ip parent ffff:\
  prio 1 flower dst_ip 192.168.1.1/32\
  ip_proto udp dst_port 12000 skip_sw\
  hw_tc 1

# tc filter show dev eth0 parent ffff:
filter pref 1 flower chain 0
filter pref 1 flower chain 0 handle 0x1 hw_tc 1
  eth_type ipv4
  ip_proto udp
  dst_ip 192.168.1.1
  dst_port 12000
  skip_sw
  in_hw

Signed-off-by: Amritha Nambiar <amritha.namb...@intel.com>
---
 include/uapi/linux/pkt_sched.h |    1 +
 tc/f_flower.c                  |   35 +++++++++++++++++++++++++++++++----
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h
index e95b5c9..e7cc3d3 100644
--- a/include/uapi/linux/pkt_sched.h
+++ b/include/uapi/linux/pkt_sched.h
@@ -74,6 +74,7 @@ struct tc_estimator {
 #define TC_H_INGRESS    (0xFFFFFFF1U)
 #define TC_H_CLSACT    TC_H_INGRESS
 
+#define TC_H_MIN_PRIORITY      0xFFE0U
 #define TC_H_MIN_INGRESS       0xFFF2U
 #define TC_H_MIN_EGRESS                0xFFF3U
 
diff --git a/tc/f_flower.c b/tc/f_flower.c
index b180210..6ea0fba 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -614,6 +614,25 @@ static int flower_parse_opt(struct filter_util *qu, char 
*handle,
                                return -1;
                        }
                        addattr_l(n, MAX_MSG, TCA_FLOWER_CLASSID, &handle, 4);
+               } else if (matches(*argv, "hw_tc") == 0) {
+                       unsigned int handle;
+                       __u32 tc;
+                       char *end;
+
+                       NEXT_ARG();
+                       tc = strtoul(*argv, &end, 0);
+                       if (*end) {
+                               fprintf(stderr, "Illegal TC index\n");
+                               return -1;
+                       }
+                       if (tc >= TC_QOPT_MAX_QUEUE) {
+                               fprintf(stderr, "TC index exceeds max range\n");
+                               return -1;
+                       }
+                       handle = TC_H_MAKE(TC_H_MAJ(t->tcm_parent),
+                                          TC_H_MIN(tc + TC_H_MIN_PRIORITY));
+                       addattr_l(n, MAX_MSG, TCA_FLOWER_CLASSID, &handle,
+                                 sizeof(handle));
                } else if (matches(*argv, "ip_flags") == 0) {
                        NEXT_ARG();
                        ret = flower_parse_matching_flags(*argv,
@@ -1187,10 +1206,18 @@ static int flower_print_opt(struct filter_util *qu, 
FILE *f,
                fprintf(f, "handle 0x%x ", handle);
 
        if (tb[TCA_FLOWER_CLASSID]) {
-               SPRINT_BUF(b1);
-               fprintf(f, "classid %s ",
-                       
sprint_tc_classid(rta_getattr_u32(tb[TCA_FLOWER_CLASSID]),
-                                         b1));
+               __u32 h = rta_getattr_u32(tb[TCA_FLOWER_CLASSID]);
+
+               if (TC_H_MIN(h) < TC_H_MIN_PRIORITY ||
+                   TC_H_MIN(h) > (TC_H_MIN_PRIORITY + TC_QOPT_MAX_QUEUE - 1)) {
+                       SPRINT_BUF(b1);
+                       fprintf(f, "classid %s ",
+                               
sprint_tc_classid(rta_getattr_u32(tb[TCA_FLOWER_CLASSID]),
+                                                 b1));
+               } else {
+                       fprintf(f, "hw_tc %u ",
+                               TC_H_MIN(h) - TC_H_MIN_PRIORITY);
+               }
        }
 
        if (tb[TCA_FLOWER_INDEV]) {

Reply via email to