|
|
36cfb7 |
From 13e1ae7b588c723091f81538bb5834b274f0b0c7 Mon Sep 17 00:00:00 2001
|
|
|
36cfb7 |
From: Andrea Claudi <aclaudi@redhat.com>
|
|
|
36cfb7 |
Date: Tue, 18 Jun 2019 20:02:54 +0200
|
|
|
36cfb7 |
Subject: [PATCH] tc: introduce support for block-handle for filter operations
|
|
|
36cfb7 |
|
|
|
36cfb7 |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1721291
|
|
|
36cfb7 |
Upstream Status: iproute2.git commit 0c7cef9669a82
|
|
|
36cfb7 |
Conflicts: context change due to missing commit 485d0c6001c4a
|
|
|
36cfb7 |
("tc: Add batchsize feature for filter and actions"),
|
|
|
36cfb7 |
also adjust code to use fprintf instead of print_string
|
|
|
36cfb7 |
due to missing commit 249284ff5a44a ("tc: jsonify filter core")
|
|
|
36cfb7 |
|
|
|
36cfb7 |
commit 0c7cef9669a82d4ad0438922f7ce57c18100d6b8
|
|
|
36cfb7 |
Author: Jiri Pirko <jiri@mellanox.com>
|
|
|
36cfb7 |
Date: Sat Jan 20 11:00:28 2018 +0100
|
|
|
36cfb7 |
|
|
|
36cfb7 |
tc: introduce support for block-handle for filter operations
|
|
|
36cfb7 |
|
|
|
36cfb7 |
So far, qdisc was the only handle that could be used to manipulate
|
|
|
36cfb7 |
filters. Kernel added support for using block to manipulate it. So add
|
|
|
36cfb7 |
the support to use block index to manipulate filters. The magic
|
|
|
36cfb7 |
TCM_IFINDEX_MAGIC_BLOCK indicates the block index is in use.
|
|
|
36cfb7 |
|
|
|
36cfb7 |
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
|
|
|
36cfb7 |
Signed-off-by: David Ahern <dsahern@gmail.com>
|
|
|
36cfb7 |
---
|
|
|
36cfb7 |
man/man8/tc.8 | 18 +++++++++
|
|
|
36cfb7 |
tc/tc_filter.c | 102 +++++++++++++++++++++++++++++++++++++++++--------
|
|
|
36cfb7 |
2 files changed, 104 insertions(+), 16 deletions(-)
|
|
|
36cfb7 |
|
|
|
36cfb7 |
diff --git a/man/man8/tc.8 b/man/man8/tc.8
|
|
|
36cfb7 |
index a341a8f995f85..c493ccfa7c900 100644
|
|
|
36cfb7 |
--- a/man/man8/tc.8
|
|
|
36cfb7 |
+++ b/man/man8/tc.8
|
|
|
36cfb7 |
@@ -41,6 +41,19 @@ tc \- show / manipulate traffic control settings
|
|
|
36cfb7 |
.B flowid
|
|
|
36cfb7 |
\fIflow-id\fR
|
|
|
36cfb7 |
|
|
|
36cfb7 |
+.B tc
|
|
|
36cfb7 |
+.RI "[ " OPTIONS " ]"
|
|
|
36cfb7 |
+.B filter [ add | change | replace | delete | get ] block
|
|
|
36cfb7 |
+\fIBLOCK_INDEX\fR
|
|
|
36cfb7 |
+.B [ handle \fIfilter-id\fR ]
|
|
|
36cfb7 |
+.B protocol
|
|
|
36cfb7 |
+\fIprotocol\fR
|
|
|
36cfb7 |
+.B prio
|
|
|
36cfb7 |
+\fIpriority\fR filtertype
|
|
|
36cfb7 |
+[ filtertype specific parameters ]
|
|
|
36cfb7 |
+.B flowid
|
|
|
36cfb7 |
+\fIflow-id\fR
|
|
|
36cfb7 |
+
|
|
|
36cfb7 |
.B tc
|
|
|
36cfb7 |
.RI "[ " OPTIONS " ]"
|
|
|
36cfb7 |
.RI "[ " FORMAT " ]"
|
|
|
36cfb7 |
@@ -58,6 +71,11 @@ tc \- show / manipulate traffic control settings
|
|
|
36cfb7 |
.RI "[ " OPTIONS " ]"
|
|
|
36cfb7 |
.B filter show dev
|
|
|
36cfb7 |
\fIDEV\fR
|
|
|
36cfb7 |
+.P
|
|
|
36cfb7 |
+.B tc
|
|
|
36cfb7 |
+.RI "[ " OPTIONS " ]"
|
|
|
36cfb7 |
+.B filter show block
|
|
|
36cfb7 |
+\fIBLOCK_INDEX\fR
|
|
|
36cfb7 |
|
|
|
36cfb7 |
.P
|
|
|
36cfb7 |
.ti 8
|
|
|
36cfb7 |
diff --git a/tc/tc_filter.c b/tc/tc_filter.c
|
|
|
36cfb7 |
index e479039159df6..5676ed3a74383 100644
|
|
|
36cfb7 |
--- a/tc/tc_filter.c
|
|
|
36cfb7 |
+++ b/tc/tc_filter.c
|
|
|
36cfb7 |
@@ -29,14 +29,17 @@
|
|
|
36cfb7 |
static void usage(void)
|
|
|
36cfb7 |
{
|
|
|
36cfb7 |
fprintf(stderr,
|
|
|
36cfb7 |
- "Usage: tc filter [ add | del | change | replace | show ] dev STRING\n"
|
|
|
36cfb7 |
- "Usage: tc filter get dev STRING parent CLASSID protocol PROTO handle FILTERID pref PRIO FILTER_TYPE\n"
|
|
|
36cfb7 |
+ "Usage: tc filter [ add | del | change | replace | show ] [ dev STRING ]\n"
|
|
|
36cfb7 |
+ " tc filter [ add | del | change | replace | show ] [ block BLOCK_INDEX ]\n"
|
|
|
36cfb7 |
+ " tc filter get dev STRING parent CLASSID protocol PROTO handle FILTERID pref PRIO FILTER_TYPE\n"
|
|
|
36cfb7 |
+ " tc filter get block BLOCK_INDEX protocol PROTO handle FILTERID pref PRIO FILTER_TYPE\n"
|
|
|
36cfb7 |
" [ pref PRIO ] protocol PROTO [ chain CHAIN_INDEX ]\n"
|
|
|
36cfb7 |
" [ estimator INTERVAL TIME_CONSTANT ]\n"
|
|
|
36cfb7 |
" [ root | ingress | egress | parent CLASSID ]\n"
|
|
|
36cfb7 |
" [ handle FILTERID ] [ [ FILTER_TYPE ] [ help | OPTIONS ] ]\n"
|
|
|
36cfb7 |
"\n"
|
|
|
36cfb7 |
" tc filter show [ dev STRING ] [ root | ingress | egress | parent CLASSID ]\n"
|
|
|
36cfb7 |
+ " tc filter show [ block BLOCK_INDEX ]\n"
|
|
|
36cfb7 |
"Where:\n"
|
|
|
36cfb7 |
"FILTER_TYPE := { rsvp | u32 | bpf | fw | route | etc. }\n"
|
|
|
36cfb7 |
"FILTERID := ... format depends on classifier, see there\n"
|
|
|
36cfb7 |
@@ -61,6 +64,7 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv)
|
|
|
36cfb7 |
int protocol_set = 0;
|
|
|
36cfb7 |
__u32 chain_index;
|
|
|
36cfb7 |
int chain_index_set = 0;
|
|
|
36cfb7 |
+ __u32 block_index = 0;
|
|
|
36cfb7 |
char *fhandle = NULL;
|
|
|
36cfb7 |
char d[16] = {};
|
|
|
36cfb7 |
char k[16] = {};
|
|
|
36cfb7 |
@@ -74,7 +78,21 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv)
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
if (d[0])
|
|
|
36cfb7 |
duparg("dev", *argv);
|
|
|
36cfb7 |
+ if (block_index) {
|
|
|
36cfb7 |
+ fprintf(stderr, "Error: \"dev\" and \"block\" are mutually exlusive\n");
|
|
|
36cfb7 |
+ return -1;
|
|
|
36cfb7 |
+ }
|
|
|
36cfb7 |
strncpy(d, *argv, sizeof(d)-1);
|
|
|
36cfb7 |
+ } else if (matches(*argv, "block") == 0) {
|
|
|
36cfb7 |
+ NEXT_ARG();
|
|
|
36cfb7 |
+ if (block_index)
|
|
|
36cfb7 |
+ duparg("block", *argv);
|
|
|
36cfb7 |
+ if (d[0]) {
|
|
|
36cfb7 |
+ fprintf(stderr, "Error: \"dev\" and \"block\" are mutually exlusive\n");
|
|
|
36cfb7 |
+ return -1;
|
|
|
36cfb7 |
+ }
|
|
|
36cfb7 |
+ if (get_u32(&block_index, *argv, 0) || !block_index)
|
|
|
36cfb7 |
+ invarg("invalid block index value", *argv);
|
|
|
36cfb7 |
} else if (strcmp(*argv, "root") == 0) {
|
|
|
36cfb7 |
if (req.t.tcm_parent) {
|
|
|
36cfb7 |
fprintf(stderr,
|
|
|
36cfb7 |
@@ -169,6 +187,9 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv)
|
|
|
36cfb7 |
fprintf(stderr, "Cannot find device \"%s\"\n", d);
|
|
|
36cfb7 |
return 1;
|
|
|
36cfb7 |
}
|
|
|
36cfb7 |
+ } else if (block_index) {
|
|
|
36cfb7 |
+ req.t.tcm_ifindex = TCM_IFINDEX_MAGIC_BLOCK;
|
|
|
36cfb7 |
+ req.t.tcm_block_index = block_index;
|
|
|
36cfb7 |
}
|
|
|
36cfb7 |
|
|
|
36cfb7 |
if (q) {
|
|
|
36cfb7 |
@@ -207,6 +228,7 @@ static __u32 filter_prio;
|
|
|
36cfb7 |
static __u32 filter_protocol;
|
|
|
36cfb7 |
static __u32 filter_chain_index;
|
|
|
36cfb7 |
static int filter_chain_index_set;
|
|
|
36cfb7 |
+static __u32 filter_block_index;
|
|
|
36cfb7 |
__u16 f_proto;
|
|
|
36cfb7 |
|
|
|
36cfb7 |
int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
|
|
|
36cfb7 |
@@ -251,19 +273,25 @@ int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
|
|
|
36cfb7 |
fprintf(fp, "added ");
|
|
|
36cfb7 |
|
|
|
36cfb7 |
fprintf(fp, "filter ");
|
|
|
36cfb7 |
- if (!filter_ifindex || filter_ifindex != t->tcm_ifindex)
|
|
|
36cfb7 |
- fprintf(fp, "dev %s ", ll_index_to_name(t->tcm_ifindex));
|
|
|
36cfb7 |
-
|
|
|
36cfb7 |
- if (!filter_parent || filter_parent != t->tcm_parent) {
|
|
|
36cfb7 |
- if (t->tcm_parent == TC_H_ROOT)
|
|
|
36cfb7 |
- fprintf(fp, "root ");
|
|
|
36cfb7 |
- else if (t->tcm_parent == TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_INGRESS))
|
|
|
36cfb7 |
- fprintf(fp, "ingress ");
|
|
|
36cfb7 |
- else if (t->tcm_parent == TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_EGRESS))
|
|
|
36cfb7 |
- fprintf(fp, "egress ");
|
|
|
36cfb7 |
- else {
|
|
|
36cfb7 |
- print_tc_classid(abuf, sizeof(abuf), t->tcm_parent);
|
|
|
36cfb7 |
- fprintf(fp, "parent %s ", abuf);
|
|
|
36cfb7 |
+ if (t->tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK) {
|
|
|
36cfb7 |
+ if (!filter_block_index ||
|
|
|
36cfb7 |
+ filter_block_index != t->tcm_block_index)
|
|
|
36cfb7 |
+ fprintf(fp, "block %u ", t->tcm_block_index);
|
|
|
36cfb7 |
+ } else {
|
|
|
36cfb7 |
+ if (!filter_ifindex || filter_ifindex != t->tcm_ifindex)
|
|
|
36cfb7 |
+ fprintf(fp, "dev %s ", ll_index_to_name(t->tcm_ifindex));
|
|
|
36cfb7 |
+
|
|
|
36cfb7 |
+ if (!filter_parent || filter_parent != t->tcm_parent) {
|
|
|
36cfb7 |
+ if (t->tcm_parent == TC_H_ROOT)
|
|
|
36cfb7 |
+ fprintf(fp, "root ");
|
|
|
36cfb7 |
+ else if (t->tcm_parent == TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_INGRESS))
|
|
|
36cfb7 |
+ fprintf(fp, "ingress ");
|
|
|
36cfb7 |
+ else if (t->tcm_parent == TC_H_MAKE(TC_H_CLSACT, TC_H_MIN_EGRESS))
|
|
|
36cfb7 |
+ fprintf(fp, "egress ");
|
|
|
36cfb7 |
+ else {
|
|
|
36cfb7 |
+ print_tc_classid(abuf, sizeof(abuf), t->tcm_parent);
|
|
|
36cfb7 |
+ fprintf(fp, "parent %s ", abuf);
|
|
|
36cfb7 |
+ }
|
|
|
36cfb7 |
}
|
|
|
36cfb7 |
}
|
|
|
36cfb7 |
|
|
|
36cfb7 |
@@ -337,6 +365,7 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv)
|
|
|
36cfb7 |
int protocol_set = 0;
|
|
|
36cfb7 |
__u32 chain_index;
|
|
|
36cfb7 |
int chain_index_set = 0;
|
|
|
36cfb7 |
+ __u32 block_index = 0;
|
|
|
36cfb7 |
__u32 parent_handle = 0;
|
|
|
36cfb7 |
char *fhandle = NULL;
|
|
|
36cfb7 |
char d[16] = {};
|
|
|
36cfb7 |
@@ -347,7 +376,21 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv)
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
if (d[0])
|
|
|
36cfb7 |
duparg("dev", *argv);
|
|
|
36cfb7 |
+ if (block_index) {
|
|
|
36cfb7 |
+ fprintf(stderr, "Error: \"dev\" and \"block\" are mutually exlusive\n");
|
|
|
36cfb7 |
+ return -1;
|
|
|
36cfb7 |
+ }
|
|
|
36cfb7 |
strncpy(d, *argv, sizeof(d)-1);
|
|
|
36cfb7 |
+ } else if (matches(*argv, "block") == 0) {
|
|
|
36cfb7 |
+ NEXT_ARG();
|
|
|
36cfb7 |
+ if (block_index)
|
|
|
36cfb7 |
+ duparg("block", *argv);
|
|
|
36cfb7 |
+ if (d[0]) {
|
|
|
36cfb7 |
+ fprintf(stderr, "Error: \"dev\" and \"block\" are mutually exlusive\n");
|
|
|
36cfb7 |
+ return -1;
|
|
|
36cfb7 |
+ }
|
|
|
36cfb7 |
+ if (get_u32(&block_index, *argv, 0) || !block_index)
|
|
|
36cfb7 |
+ invarg("invalid block index value", *argv);
|
|
|
36cfb7 |
} else if (strcmp(*argv, "root") == 0) {
|
|
|
36cfb7 |
if (req.t.tcm_parent) {
|
|
|
36cfb7 |
fprintf(stderr,
|
|
|
36cfb7 |
@@ -461,8 +504,12 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv)
|
|
|
36cfb7 |
return 1;
|
|
|
36cfb7 |
}
|
|
|
36cfb7 |
filter_ifindex = req.t.tcm_ifindex;
|
|
|
36cfb7 |
+ } else if (block_index) {
|
|
|
36cfb7 |
+ req.t.tcm_ifindex = TCM_IFINDEX_MAGIC_BLOCK;
|
|
|
36cfb7 |
+ req.t.tcm_block_index = block_index;
|
|
|
36cfb7 |
+ filter_block_index = block_index;
|
|
|
36cfb7 |
} else {
|
|
|
36cfb7 |
- fprintf(stderr, "Must specify netdevice \"dev\"\n");
|
|
|
36cfb7 |
+ fprintf(stderr, "Must specify netdevice \"dev\" or block index \"block\"\n");
|
|
|
36cfb7 |
return -1;
|
|
|
36cfb7 |
}
|
|
|
36cfb7 |
|
|
|
36cfb7 |
@@ -510,6 +557,7 @@ static int tc_filter_list(int argc, char **argv)
|
|
|
36cfb7 |
__u32 prio = 0;
|
|
|
36cfb7 |
__u32 protocol = 0;
|
|
|
36cfb7 |
__u32 chain_index;
|
|
|
36cfb7 |
+ __u32 block_index = 0;
|
|
|
36cfb7 |
char *fhandle = NULL;
|
|
|
36cfb7 |
|
|
|
36cfb7 |
while (argc > 0) {
|
|
|
36cfb7 |
@@ -517,7 +565,21 @@ static int tc_filter_list(int argc, char **argv)
|
|
|
36cfb7 |
NEXT_ARG();
|
|
|
36cfb7 |
if (d[0])
|
|
|
36cfb7 |
duparg("dev", *argv);
|
|
|
36cfb7 |
+ if (block_index) {
|
|
|
36cfb7 |
+ fprintf(stderr, "Error: \"dev\" cannot be used in the same time as \"block\"\n");
|
|
|
36cfb7 |
+ return -1;
|
|
|
36cfb7 |
+ }
|
|
|
36cfb7 |
strncpy(d, *argv, sizeof(d)-1);
|
|
|
36cfb7 |
+ } else if (matches(*argv, "block") == 0) {
|
|
|
36cfb7 |
+ NEXT_ARG();
|
|
|
36cfb7 |
+ if (block_index)
|
|
|
36cfb7 |
+ duparg("block", *argv);
|
|
|
36cfb7 |
+ if (d[0]) {
|
|
|
36cfb7 |
+ fprintf(stderr, "Error: \"block\" cannot be used in the same time as \"dev\"\n");
|
|
|
36cfb7 |
+ return -1;
|
|
|
36cfb7 |
+ }
|
|
|
36cfb7 |
+ if (get_u32(&block_index, *argv, 0) || !block_index)
|
|
|
36cfb7 |
+ invarg("invalid block index value", *argv);
|
|
|
36cfb7 |
} else if (strcmp(*argv, "root") == 0) {
|
|
|
36cfb7 |
if (req.t.tcm_parent) {
|
|
|
36cfb7 |
fprintf(stderr,
|
|
|
36cfb7 |
@@ -606,6 +668,14 @@ static int tc_filter_list(int argc, char **argv)
|
|
|
36cfb7 |
return 1;
|
|
|
36cfb7 |
}
|
|
|
36cfb7 |
filter_ifindex = req.t.tcm_ifindex;
|
|
|
36cfb7 |
+ } else if (block_index) {
|
|
|
36cfb7 |
+ if (!tc_qdisc_block_exists(block_index)) {
|
|
|
36cfb7 |
+ fprintf(stderr, "Cannot find block \"%u\"\n", block_index);
|
|
|
36cfb7 |
+ return 1;
|
|
|
36cfb7 |
+ }
|
|
|
36cfb7 |
+ req.t.tcm_ifindex = TCM_IFINDEX_MAGIC_BLOCK;
|
|
|
36cfb7 |
+ req.t.tcm_block_index = block_index;
|
|
|
36cfb7 |
+ filter_block_index = block_index;
|
|
|
36cfb7 |
}
|
|
|
36cfb7 |
|
|
|
36cfb7 |
if (filter_chain_index_set)
|
|
|
36cfb7 |
--
|
|
|
36cfb7 |
2.20.1
|
|
|
36cfb7 |
|