|
|
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 |
|