naccyde / rpms / iproute

Forked from rpms/iproute 7 months ago
Clone

Blame SOURCES/0164-tc-Add-support-for-the-matchall-traffic-classifier.patch

4aca6e
From 13127e1bbe84181c259c61eb65ca2b707f3ed31b Mon Sep 17 00:00:00 2001
4aca6e
From: Ivan Vecera <ivecera@redhat.com>
4aca6e
Date: Wed, 31 May 2017 15:38:41 +0200
4aca6e
Subject: [PATCH 164/169] tc: Add support for the matchall traffic classifier.
4aca6e
4aca6e
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1435624
4aca6e
Upstream status: iproute2.git commit d5cbf3ff0561b
4aca6e
4aca6e
Upstream commit(s):
4aca6e
commit d5cbf3ff0561b6c8158c3538c7fe1946add9dec3
4aca6e
Author: Yotam Gigi <yotamg@mellanox.com>
4aca6e
Date:   Wed Aug 31 09:28:26 2016 +0200
4aca6e
4aca6e
    tc: Add support for the matchall traffic classifier.
4aca6e
4aca6e
    The matchall classifier matches every packet and allows the user to apply
4aca6e
    actions on it. In addition, it supports the skip_sw and skip_hw (as can
4aca6e
    be found on u32 and flower filter) that direct the kernel to skip the
4aca6e
    software/hardware processing of the actions.
4aca6e
4aca6e
    This filter is very useful in usecases where every packet should be
4aca6e
    matched. For example, packet mirroring (SPAN) can be setup very easily
4aca6e
    using that filter.
4aca6e
4aca6e
    Signed-off-by: Yotam Gigi <yotamg@mellanox.com>
4aca6e
    Signed-off-by: Jiri Pirko <jiri@mellanox.com>
4aca6e
4aca6e
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
4aca6e
---
4aca6e
 tc/Makefile     |   1 +
4aca6e
 tc/f_matchall.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4aca6e
 2 files changed, 144 insertions(+)
4aca6e
 create mode 100644 tc/f_matchall.c
4aca6e
4aca6e
diff --git a/tc/Makefile b/tc/Makefile
4aca6e
index a6ad9aee..6967a942 100644
4aca6e
--- a/tc/Makefile
4aca6e
+++ b/tc/Makefile
4aca6e
@@ -59,6 +59,7 @@ TCMODULES += q_mqprio.o
4aca6e
 TCMODULES += q_codel.o
4aca6e
 TCMODULES += q_fq_codel.o
4aca6e
 TCMODULES += q_fq.o
4aca6e
+TCMODULES += f_matchall.o
4aca6e
 
4aca6e
 ifeq ($(TC_CONFIG_IPSET), y)
4aca6e
   ifeq ($(TC_CONFIG_XT), y)
4aca6e
diff --git a/tc/f_matchall.c b/tc/f_matchall.c
4aca6e
new file mode 100644
4aca6e
index 00000000..04e524e3
4aca6e
--- /dev/null
4aca6e
+++ b/tc/f_matchall.c
4aca6e
@@ -0,0 +1,143 @@
4aca6e
+/*
4aca6e
+ * f_matchall.c		Match-all Classifier
4aca6e
+ *
4aca6e
+ *		This program is free software; you can distribute it and/or
4aca6e
+ *		modify it under the terms of the GNU General Public License
4aca6e
+ *		as published by the Free Software Foundation; either version
4aca6e
+ *		2 of the License, or (at your option) any later version.
4aca6e
+ *
4aca6e
+ * Authors:	Jiri Pirko <jiri@mellanox.com>, Yotam Gigi <yotamg@mellanox.com>
4aca6e
+ *
4aca6e
+ */
4aca6e
+
4aca6e
+#include <stdio.h>
4aca6e
+#include <stdlib.h>
4aca6e
+#include <unistd.h>
4aca6e
+#include <syslog.h>
4aca6e
+#include <fcntl.h>
4aca6e
+#include <sys/socket.h>
4aca6e
+#include <netinet/in.h>
4aca6e
+#include <arpa/inet.h>
4aca6e
+#include <string.h>
4aca6e
+#include <linux/if.h>
4aca6e
+
4aca6e
+#include "utils.h"
4aca6e
+#include "tc_util.h"
4aca6e
+
4aca6e
+static void explain(void)
4aca6e
+{
4aca6e
+	fprintf(stderr, "Usage: ... matchall [skip_sw | skip_hw]\n");
4aca6e
+	fprintf(stderr, "                 [ action ACTION_SPEC ] [ classid CLASSID ]\n");
4aca6e
+	fprintf(stderr, "\n");
4aca6e
+	fprintf(stderr, "Where: SELECTOR := SAMPLE SAMPLE ...\n");
4aca6e
+	fprintf(stderr, "       FILTERID := X:Y:Z\n");
4aca6e
+	fprintf(stderr, "       ACTION_SPEC := ... look at individual actions\n");
4aca6e
+	fprintf(stderr, "\nNOTE: CLASSID is parsed as hexadecimal input.\n");
4aca6e
+}
4aca6e
+
4aca6e
+static int matchall_parse_opt(struct filter_util *qu, char *handle,
4aca6e
+			   int argc, char **argv, struct nlmsghdr *n)
4aca6e
+{
4aca6e
+	struct tcmsg *t = NLMSG_DATA(n);
4aca6e
+	struct rtattr *tail;
4aca6e
+	__u32 flags = 0;
4aca6e
+	long h = 0;
4aca6e
+
4aca6e
+	if (handle) {
4aca6e
+		h = strtol(handle, NULL, 0);
4aca6e
+		if (h == LONG_MIN || h == LONG_MAX) {
4aca6e
+			fprintf(stderr, "Illegal handle \"%s\", must be numeric.\n",
4aca6e
+			    handle);
4aca6e
+			return -1;
4aca6e
+		}
4aca6e
+	}
4aca6e
+	t->tcm_handle = h;
4aca6e
+
4aca6e
+	if (argc == 0)
4aca6e
+		return 0;
4aca6e
+
4aca6e
+	tail = (struct rtattr *)(((void *)n)+NLMSG_ALIGN(n->nlmsg_len));
4aca6e
+	addattr_l(n, MAX_MSG, TCA_OPTIONS, NULL, 0);
4aca6e
+
4aca6e
+	while (argc > 0) {
4aca6e
+		if (matches(*argv, "classid") == 0 ||
4aca6e
+			   strcmp(*argv, "flowid") == 0) {
4aca6e
+			unsigned int handle;
4aca6e
+
4aca6e
+			NEXT_ARG();
4aca6e
+			if (get_tc_classid(&handle, *argv)) {
4aca6e
+				fprintf(stderr, "Illegal \"classid\"\n");
4aca6e
+				return -1;
4aca6e
+			}
4aca6e
+			addattr_l(n, MAX_MSG, TCA_MATCHALL_CLASSID, &handle, 4);
4aca6e
+		} else if (matches(*argv, "action") == 0) {
4aca6e
+			NEXT_ARG();
4aca6e
+			if (parse_action(&argc, &argv, TCA_MATCHALL_ACT, n)) {
4aca6e
+				fprintf(stderr, "Illegal \"action\"\n");
4aca6e
+				return -1;
4aca6e
+			}
4aca6e
+			continue;
4aca6e
+
4aca6e
+		} else if (strcmp(*argv, "skip_hw") == 0) {
4aca6e
+			NEXT_ARG();
4aca6e
+			flags |= TCA_CLS_FLAGS_SKIP_HW;
4aca6e
+			continue;
4aca6e
+		} else if (strcmp(*argv, "skip_sw") == 0) {
4aca6e
+			NEXT_ARG();
4aca6e
+			flags |= TCA_CLS_FLAGS_SKIP_SW;
4aca6e
+			continue;
4aca6e
+		} else if (strcmp(*argv, "help") == 0) {
4aca6e
+			explain();
4aca6e
+			return -1;
4aca6e
+		} else {
4aca6e
+			fprintf(stderr, "What is \"%s\"?\n", *argv);
4aca6e
+			explain();
4aca6e
+			return -1;
4aca6e
+		}
4aca6e
+		argc--; argv++;
4aca6e
+	}
4aca6e
+
4aca6e
+	if (flags) {
4aca6e
+		if (!(flags ^ (TCA_CLS_FLAGS_SKIP_HW |
4aca6e
+			       TCA_CLS_FLAGS_SKIP_SW))) {
4aca6e
+			fprintf(stderr,
4aca6e
+				"skip_hw and skip_sw are mutually exclusive\n");
4aca6e
+			return -1;
4aca6e
+		}
4aca6e
+		addattr_l(n, MAX_MSG, TCA_MATCHALL_FLAGS, &flags, 4);
4aca6e
+	}
4aca6e
+
4aca6e
+	tail->rta_len = (((void *)n)+n->nlmsg_len) - (void *)tail;
4aca6e
+	return 0;
4aca6e
+}
4aca6e
+
4aca6e
+static int matchall_print_opt(struct filter_util *qu, FILE *f,
4aca6e
+			   struct rtattr *opt, __u32 handle)
4aca6e
+{
4aca6e
+	struct rtattr *tb[TCA_MATCHALL_MAX+1];
4aca6e
+
4aca6e
+	if (opt == NULL)
4aca6e
+		return 0;
4aca6e
+
4aca6e
+	parse_rtattr_nested(tb, TCA_MATCHALL_MAX, opt);
4aca6e
+
4aca6e
+	if (handle)
4aca6e
+		fprintf(f, "handle 0x%x ", handle);
4aca6e
+
4aca6e
+	if (tb[TCA_MATCHALL_CLASSID]) {
4aca6e
+		SPRINT_BUF(b1);
4aca6e
+		fprintf(f, "flowid %s ",
4aca6e
+			sprint_tc_classid(rta_getattr_u32(tb[TCA_MATCHALL_CLASSID]), b1));
4aca6e
+	}
4aca6e
+
4aca6e
+	if (tb[TCA_MATCHALL_ACT])
4aca6e
+		tc_print_action(f, tb[TCA_MATCHALL_ACT]);
4aca6e
+
4aca6e
+	return 0;
4aca6e
+}
4aca6e
+
4aca6e
+struct filter_util matchall_filter_util = {
4aca6e
+	.id = "matchall",
4aca6e
+	.parse_fopt = matchall_parse_opt,
4aca6e
+	.print_fopt = matchall_print_opt,
4aca6e
+};
4aca6e
-- 
4aca6e
2.13.0
4aca6e