Blame SOURCES/0108-tc-flower-Add-skip_-hw-sw-support.patch

4aca6e
From 080a2a99ff48cb30a5efb105dba3d1040dac6e21 Mon Sep 17 00:00:00 2001
4aca6e
From: Phil Sutter <psutter@redhat.com>
4aca6e
Date: Fri, 17 Mar 2017 13:21:33 +0100
4aca6e
Subject: [PATCH] tc: flower: Add skip_{hw|sw} support
4aca6e
4aca6e
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1422629
4aca6e
Upstream Status: iproute2.git commit cfcabf18d84a2
4aca6e
4aca6e
commit cfcabf18d84a2f4908cb5b4489f67c2cd3f70426
4aca6e
Author: Amir Vadai <amirva@mellanox.com>
4aca6e
Date:   Mon Jul 4 10:34:11 2016 +0300
4aca6e
4aca6e
    tc: flower: Add skip_{hw|sw} support
4aca6e
4aca6e
    On devices that support TC flower offloads, these flags enable a filter to be
4aca6e
    added only to HW or only to SW. skip_sw and skip_hw are mutually exclusive
4aca6e
    flags. By default without any flags, the filter is added to both HW and SW,
4aca6e
    but no error checks are done in case of failure to add to HW.
4aca6e
    With skip-sw, failure to add to HW is treated as an error.
4aca6e
4aca6e
    Here is a sample script that adds 2 filters, one with skip_sw and the other
4aca6e
    with skip_hw flag.
4aca6e
4aca6e
       # add ingress qdisc
4aca6e
       tc qdisc add dev enp0s9 ingress
4aca6e
4aca6e
       # enable hw tc offload.
4aca6e
       ethtool -K enp0s9 hw-tc-offload on
4aca6e
4aca6e
       # add a flower filter with skip-sw flag.
4aca6e
       tc filter add dev enp0s9 protocol ip parent ffff: flower \
4aca6e
               ip_proto 1 indev enp0s9 skip_sw \
4aca6e
               action drop
4aca6e
4aca6e
       # add a flower filter with skip-hw flag.
4aca6e
       tc filter add dev enp0s9 protocol ip parent ffff: flower \
4aca6e
               ip_proto 3 indev enp0s9 skip_hw \
4aca6e
               action drop
4aca6e
4aca6e
    Signed-off-by: Amir Vadai <amirva@mellanox.com>
4aca6e
    Acked-by: Jiri Pirko <jiri@mellanox.com>
4aca6e
---
4aca6e
 man/man8/tc-flower.8 | 11 ++++++++++-
4aca6e
 tc/f_flower.c        | 17 +++++++++++++++++
4aca6e
 2 files changed, 27 insertions(+), 1 deletion(-)
4aca6e
4aca6e
diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8
4aca6e
index df4d8e1..9ae10e6 100644
4aca6e
--- a/man/man8/tc-flower.8
4aca6e
+++ b/man/man8/tc-flower.8
4aca6e
@@ -18,7 +18,9 @@ flower \- flow based traffic control filter
4aca6e
 .ti -8
4aca6e
 .IR MATCH " := { "
4aca6e
 .B indev
4aca6e
-.IR ifname " | { "
4aca6e
+.IR ifname " | "
4aca6e
+.BR skip_sw " | " skip_hw
4aca6e
+.R " | { "
4aca6e
 .BR dst_mac " | " src_mac " } "
4aca6e
 .IR mac_address " | "
4aca6e
 .BR eth_type " { " ipv4 " | " ipv6 " | "
4aca6e
@@ -55,6 +57,13 @@ is the name of an interface which must exist at the time of
4aca6e
 .B tc
4aca6e
 invocation.
4aca6e
 .TP
4aca6e
+.BI skip_sw
4aca6e
+Do not process filter by software. If hardware has no offload support for this
4aca6e
+filter, or TC offload is not enabled for the interface, operation will fail.
4aca6e
+.TP
4aca6e
+.BI skip_hw
4aca6e
+Do not process filter by hardware.
4aca6e
+.TP
4aca6e
 .BI dst_mac " mac_address"
4aca6e
 .TQ
4aca6e
 .BI src_mac " mac_address"
4aca6e
diff --git a/tc/f_flower.c b/tc/f_flower.c
4aca6e
index 11e6242..01527c8 100644
4aca6e
--- a/tc/f_flower.c
4aca6e
+++ b/tc/f_flower.c
4aca6e
@@ -25,6 +25,7 @@
4aca6e
 static void explain(void)
4aca6e
 {
4aca6e
 	fprintf(stderr, "Usage: ... flower [ MATCH-LIST ]\n");
4aca6e
+	fprintf(stderr, "                  [ skip_sw | skip_hw ]\n");
4aca6e
 	fprintf(stderr, "                  [ action ACTION-SPEC ] [ classid CLASSID ]\n");
4aca6e
 	fprintf(stderr, "\n");
4aca6e
 	fprintf(stderr, "Where: MATCH-LIST := [ MATCH-LIST ] MATCH\n");
4aca6e
@@ -167,6 +168,7 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
4aca6e
 	struct rtattr *tail;
4aca6e
 	__be16 eth_type = TC_H_MIN(t->tcm_info);
4aca6e
 	__u8 ip_proto = 0xff;
4aca6e
+	__u32 flags = 0;
4aca6e
 
4aca6e
 	if (handle) {
4aca6e
 		ret = get_u32(&t->tcm_handle, handle, 0);
4aca6e
@@ -196,6 +198,10 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
4aca6e
 				return -1;
4aca6e
 			}
4aca6e
 			addattr_l(n, MAX_MSG, TCA_FLOWER_CLASSID, &handle, 4);
4aca6e
+		} else if (matches(*argv, "skip_hw") == 0) {
4aca6e
+			flags |= TCA_CLS_FLAGS_SKIP_HW;
4aca6e
+		} else if (matches(*argv, "skip_sw") == 0) {
4aca6e
+			flags |= TCA_CLS_FLAGS_SKIP_SW;
4aca6e
 		} else if (matches(*argv, "indev") == 0) {
4aca6e
 			char ifname[IFNAMSIZ];
4aca6e
 
4aca6e
@@ -294,6 +300,8 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
4aca6e
 	}
4aca6e
 
4aca6e
 parse_done:
4aca6e
+	addattr32(n, MAX_MSG, TCA_FLOWER_FLAGS, flags);
4aca6e
+
4aca6e
 	ret = addattr16(n, MAX_MSG, TCA_FLOWER_KEY_ETH_TYPE, eth_type);
4aca6e
 	if (ret) {
4aca6e
 		fprintf(stderr, "Illegal \"eth_type\"(0x%x)\n",
4aca6e
@@ -498,6 +506,15 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
4aca6e
 			  tb[TCA_FLOWER_KEY_TCP_SRC],
4aca6e
 			  tb[TCA_FLOWER_KEY_UDP_SRC]);
4aca6e
 
4aca6e
+	if (tb[TCA_FLOWER_FLAGS])  {
4aca6e
+		__u32 flags = rta_getattr_u32(tb[TCA_FLOWER_FLAGS]);
4aca6e
+
4aca6e
+		if (flags & TCA_CLS_FLAGS_SKIP_HW)
4aca6e
+			fprintf(f, "\n  skip_hw");
4aca6e
+		if (flags & TCA_CLS_FLAGS_SKIP_SW)
4aca6e
+			fprintf(f, "\n  skip_sw");
4aca6e
+	}
4aca6e
+
4aca6e
 	if (tb[TCA_FLOWER_ACT]) {
4aca6e
 		tc_print_action(f, tb[TCA_FLOWER_ACT]);
4aca6e
 	}
4aca6e
-- 
4aca6e
1.8.3.1
4aca6e