naccyde / rpms / iproute

Forked from rpms/iproute 7 months ago
Clone

Blame SOURCES/0131-tc_filter-add-support-for-chain-index.patch

36cfb7
From 55c511b5caab0bfb9997bca9031947a45fe7854b Mon Sep 17 00:00:00 2001
36cfb7
From: Andrea Claudi <aclaudi@redhat.com>
36cfb7
Date: Wed, 5 Jun 2019 13:09:39 +0200
36cfb7
Subject: [PATCH] tc_filter: add support for chain index
36cfb7
36cfb7
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1714660
36cfb7
Upstream Status: iproute2.git commit 732f03461bc48
36cfb7
36cfb7
commit 732f03461bc48cf94946ee3cc92ab5832862b989
36cfb7
Author: Jiri Pirko <jiri@mellanox.com>
36cfb7
Date:   Tue May 16 19:29:35 2017 +0200
36cfb7
36cfb7
    tc_filter: add support for chain index
36cfb7
36cfb7
    Allow user to put filter to a specific chain identified by index.
36cfb7
36cfb7
    Signed-off-by: Jiri Pirko <jiri@mellanox.com>
36cfb7
---
36cfb7
 tc/tc_filter.c | 87 +++++++++++++++++++++++++++++++++++++++++---------
36cfb7
 1 file changed, 72 insertions(+), 15 deletions(-)
36cfb7
36cfb7
diff --git a/tc/tc_filter.c b/tc/tc_filter.c
36cfb7
index a6bb73d12eaba..8dbebf1ffa32a 100644
36cfb7
--- a/tc/tc_filter.c
36cfb7
+++ b/tc/tc_filter.c
36cfb7
@@ -31,7 +31,7 @@ static void usage(void)
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
-		"       [ pref PRIO ] protocol PROTO\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
@@ -59,6 +59,8 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv)
36cfb7
 	__u32 prio = 0;
36cfb7
 	__u32 protocol = 0;
36cfb7
 	int protocol_set = 0;
36cfb7
+	__u32 chain_index;
36cfb7
+	int chain_index_set = 0;
36cfb7
 	char *fhandle = NULL;
36cfb7
 	char  d[16] = {};
36cfb7
 	char  k[16] = {};
36cfb7
@@ -127,6 +129,13 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv)
36cfb7
 				invarg("invalid protocol", *argv);
36cfb7
 			protocol = id;
36cfb7
 			protocol_set = 1;
36cfb7
+		} else if (matches(*argv, "chain") == 0) {
36cfb7
+			NEXT_ARG();
36cfb7
+			if (chain_index_set)
36cfb7
+				duparg("chain", *argv);
36cfb7
+			if (get_u32(&chain_index, *argv, 0))
36cfb7
+				invarg("invalid chain index value", *argv);
36cfb7
+			chain_index_set = 1;
36cfb7
 		} else if (matches(*argv, "estimator") == 0) {
36cfb7
 			if (parse_estimator(&argc, &argv, &est) < 0)
36cfb7
 				return -1;
36cfb7
@@ -146,6 +155,9 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv)
36cfb7
 
36cfb7
 	req.t.tcm_info = TC_H_MAKE(prio<<16, protocol);
36cfb7
 
36cfb7
+	if (chain_index_set)
36cfb7
+		addattr32(&req.n, sizeof(req), TCA_CHAIN, chain_index);
36cfb7
+
36cfb7
 	if (k[0])
36cfb7
 		addattr_l(&req.n, sizeof(req), TCA_KIND, k, strlen(k)+1);
36cfb7
 
36cfb7
@@ -167,6 +179,7 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv)
36cfb7
 			return -1;
36cfb7
 		}
36cfb7
 	}
36cfb7
+
36cfb7
 	if (est.ewma_log)
36cfb7
 		addattr_l(&req.n, sizeof(req), TCA_RATE, &est, sizeof(est));
36cfb7
 
36cfb7
@@ -193,6 +206,8 @@ static __u32 filter_parent;
36cfb7
 static int filter_ifindex;
36cfb7
 static __u32 filter_prio;
36cfb7
 static __u32 filter_protocol;
36cfb7
+static __u32 filter_chain_index;
36cfb7
+static int filter_chain_index_set;
36cfb7
 __u16 f_proto;
36cfb7
 
36cfb7
 int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
36cfb7
@@ -270,6 +285,15 @@ int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
36cfb7
 		}
36cfb7
 	}
36cfb7
 	fprintf(fp, "%s ", rta_getattr_str(tb[TCA_KIND]));
36cfb7
+
36cfb7
+	if (tb[TCA_CHAIN]) {
36cfb7
+		__u32 chain_index = rta_getattr_u32(tb[TCA_CHAIN]);
36cfb7
+
36cfb7
+		if (!filter_chain_index_set ||
36cfb7
+		    filter_chain_index != chain_index)
36cfb7
+			fprintf(fp, "chain %u ", chain_index);
36cfb7
+	}
36cfb7
+
36cfb7
 	q = get_filter_kind(RTA_DATA(tb[TCA_KIND]));
36cfb7
 	if (tb[TCA_OPTIONS]) {
36cfb7
 		if (q)
36cfb7
@@ -312,6 +336,8 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv)
36cfb7
 	__u32 prio = 0;
36cfb7
 	__u32 protocol = 0;
36cfb7
 	int protocol_set = 0;
36cfb7
+	__u32 chain_index;
36cfb7
+	int chain_index_set = 0;
36cfb7
 	__u32 parent_handle = 0;
36cfb7
 	char *fhandle = NULL;
36cfb7
 	char  d[16] = {};
36cfb7
@@ -376,6 +402,13 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv)
36cfb7
 				invarg("invalid protocol", *argv);
36cfb7
 			protocol = id;
36cfb7
 			protocol_set = 1;
36cfb7
+		} else if (matches(*argv, "chain") == 0) {
36cfb7
+			NEXT_ARG();
36cfb7
+			if (chain_index_set)
36cfb7
+				duparg("chain", *argv);
36cfb7
+			if (get_u32(&chain_index, *argv, 0))
36cfb7
+				invarg("invalid chain index value", *argv);
36cfb7
+			chain_index_set = 1;
36cfb7
 		} else if (matches(*argv, "help") == 0) {
36cfb7
 			usage();
36cfb7
 			return 0;
36cfb7
@@ -405,6 +438,9 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv)
36cfb7
 
36cfb7
 	req.t.tcm_info = TC_H_MAKE(prio<<16, protocol);
36cfb7
 
36cfb7
+	if (chain_index_set)
36cfb7
+		addattr32(&req.n, sizeof(req), TCA_CHAIN, chain_index);
36cfb7
+
36cfb7
 	if (req.t.tcm_parent == TC_H_UNSPEC) {
36cfb7
 		fprintf(stderr, "Must specify filter parent\n");
36cfb7
 		return -1;
36cfb7
@@ -462,10 +498,20 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv)
36cfb7
 
36cfb7
 static int tc_filter_list(int argc, char **argv)
36cfb7
 {
36cfb7
-	struct tcmsg t = { .tcm_family = AF_UNSPEC };
36cfb7
+	struct {
36cfb7
+		struct nlmsghdr n;
36cfb7
+		struct tcmsg t;
36cfb7
+		char buf[MAX_MSG];
36cfb7
+	} req = {
36cfb7
+		.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)),
36cfb7
+		.n.nlmsg_type = RTM_GETTFILTER,
36cfb7
+		.t.tcm_parent = TC_H_UNSPEC,
36cfb7
+		.t.tcm_family = AF_UNSPEC,
36cfb7
+	};
36cfb7
 	char d[16] = {};
36cfb7
 	__u32 prio = 0;
36cfb7
 	__u32 protocol = 0;
36cfb7
+	__u32 chain_index;
36cfb7
 	char *fhandle = NULL;
36cfb7
 
36cfb7
 	while (argc > 0) {
36cfb7
@@ -475,39 +521,39 @@ static int tc_filter_list(int argc, char **argv)
36cfb7
 				duparg("dev", *argv);
36cfb7
 			strncpy(d, *argv, sizeof(d)-1);
36cfb7
 		} else if (strcmp(*argv, "root") == 0) {
36cfb7
-			if (t.tcm_parent) {
36cfb7
+			if (req.t.tcm_parent) {
36cfb7
 				fprintf(stderr,
36cfb7
 					"Error: \"root\" is duplicate parent ID\n");
36cfb7
 				return -1;
36cfb7
 			}
36cfb7
-			filter_parent = t.tcm_parent = TC_H_ROOT;
36cfb7
+			filter_parent = req.t.tcm_parent = TC_H_ROOT;
36cfb7
 		} else if (strcmp(*argv, "ingress") == 0) {
36cfb7
-			if (t.tcm_parent) {
36cfb7
+			if (req.t.tcm_parent) {
36cfb7
 				fprintf(stderr,
36cfb7
 					"Error: \"ingress\" is duplicate parent ID\n");
36cfb7
 				return -1;
36cfb7
 			}
36cfb7
 			filter_parent = TC_H_MAKE(TC_H_CLSACT,
36cfb7
 						  TC_H_MIN_INGRESS);
36cfb7
-			t.tcm_parent = filter_parent;
36cfb7
+			req.t.tcm_parent = filter_parent;
36cfb7
 		} else if (strcmp(*argv, "egress") == 0) {
36cfb7
-			if (t.tcm_parent) {
36cfb7
+			if (req.t.tcm_parent) {
36cfb7
 				fprintf(stderr,
36cfb7
 					"Error: \"egress\" is duplicate parent ID\n");
36cfb7
 				return -1;
36cfb7
 			}
36cfb7
 			filter_parent = TC_H_MAKE(TC_H_CLSACT,
36cfb7
 						  TC_H_MIN_EGRESS);
36cfb7
-			t.tcm_parent = filter_parent;
36cfb7
+			req.t.tcm_parent = filter_parent;
36cfb7
 		} else if (strcmp(*argv, "parent") == 0) {
36cfb7
 			__u32 handle;
36cfb7
 
36cfb7
 			NEXT_ARG();
36cfb7
-			if (t.tcm_parent)
36cfb7
+			if (req.t.tcm_parent)
36cfb7
 				duparg("parent", *argv);
36cfb7
 			if (get_tc_classid(&handle, *argv))
36cfb7
 				invarg("invalid parent ID", *argv);
36cfb7
-			filter_parent = t.tcm_parent = handle;
36cfb7
+			filter_parent = req.t.tcm_parent = handle;
36cfb7
 		} else if (strcmp(*argv, "handle") == 0) {
36cfb7
 			NEXT_ARG();
36cfb7
 			if (fhandle)
36cfb7
@@ -531,6 +577,14 @@ static int tc_filter_list(int argc, char **argv)
36cfb7
 				invarg("invalid protocol", *argv);
36cfb7
 			protocol = res;
36cfb7
 			filter_protocol = protocol;
36cfb7
+		} else if (matches(*argv, "chain") == 0) {
36cfb7
+			NEXT_ARG();
36cfb7
+			if (filter_chain_index_set)
36cfb7
+				duparg("chain", *argv);
36cfb7
+			if (get_u32(&chain_index, *argv, 0))
36cfb7
+				invarg("invalid chain index value", *argv);
36cfb7
+			filter_chain_index_set = 1;
36cfb7
+			filter_chain_index = chain_index;
36cfb7
 		} else if (matches(*argv, "help") == 0) {
36cfb7
 			usage();
36cfb7
 		} else {
36cfb7
@@ -543,20 +597,23 @@ static int tc_filter_list(int argc, char **argv)
36cfb7
 		argc--; argv++;
36cfb7
 	}
36cfb7
 
36cfb7
-	t.tcm_info = TC_H_MAKE(prio<<16, protocol);
36cfb7
+	req.t.tcm_info = TC_H_MAKE(prio<<16, protocol);
36cfb7
 
36cfb7
 	ll_init_map(&rth);
36cfb7
 
36cfb7
 	if (d[0]) {
36cfb7
-		t.tcm_ifindex = ll_name_to_index(d);
36cfb7
-		if (t.tcm_ifindex == 0) {
36cfb7
+		req.t.tcm_ifindex = ll_name_to_index(d);
36cfb7
+		if (req.t.tcm_ifindex == 0) {
36cfb7
 			fprintf(stderr, "Cannot find device \"%s\"\n", d);
36cfb7
 			return 1;
36cfb7
 		}
36cfb7
-		filter_ifindex = t.tcm_ifindex;
36cfb7
+		filter_ifindex = req.t.tcm_ifindex;
36cfb7
 	}
36cfb7
 
36cfb7
-	if (rtnl_dump_request(&rth, RTM_GETTFILTER, &t, sizeof(t)) < 0) {
36cfb7
+	if (filter_chain_index_set)
36cfb7
+		addattr32(&req.n, sizeof(req), TCA_CHAIN, chain_index);
36cfb7
+
36cfb7
+	if (rtnl_dump_request_n(&rth, &req.n) < 0) {
36cfb7
 		perror("Cannot send dump request");
36cfb7
 		return 1;
36cfb7
 	}
36cfb7
-- 
e138d9
2.21.0
36cfb7