lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20170428120301.16500-4-simon.horman@netronome.com>
Date:   Fri, 28 Apr 2017 14:03:01 +0200
From:   Simon Horman <simon.horman@...ronome.com>
To:     Stephen Hemminger <stephen@...workplumber.org>
Cc:     Jiri Pirko <jiri@...nulli.us>, Jamal Hadi Salim <jhs@...atatu.com>,
        Cong Wang <xiyou.wangcong@...il.com>,
        Dinan Gunawardena <dinan.gunawardena@...ronome.com>,
        netdev@...r.kernel.org, oss-drivers@...ronome.com,
        Simon Horman <simon.horman@...ronome.com>
Subject: [PATCH/RFC iproute2/net-next 3/3] tc: flower: allow control of tree traversal on packet parse errors

Allow control how the tree of qdisc, classes and filters is further
traversed if an error is encountered when parsing the packet in order to
match the cls_flower filters at a particular prio.

By default continue to the next filter, the behaviour without this patch.

A use-case for this is to allow configuration of dropping of packets with
truncated headers.

For example, the following drops IPv4 packets that cannot be parsed by the
flow dissector up to the end of the UDP ports - e.g. because they are
truncated, and instantiates a continue action based on the port for packets
that can be parsed.

 # tc qdisc del dev eth0 ingress; tc qdisc add dev eth0 ingress
 # tc filter add dev eth0 protocol ip parent ffff: flower \
       indev eth0 ip_proto udp dst_port 80 header_parse_err_action drop \
       action continue

Signed-off-by: Simon Horman <simon.horman@...ronome.com>
---
 man/man8/tc-flower.8 | 29 +++++++++++++++++++++++++++--
 tc/f_flower.c        | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8
index ba290657c224..73d525d10ccd 100644
--- a/man/man8/tc-flower.8
+++ b/man/man8/tc-flower.8
@@ -7,6 +7,8 @@ flower \- flow based traffic control filter
 .ti -8
 .BR tc " " filter " ... " flower " [ "
 .IR MATCH_LIST " ] [ "
+.B header_parse_err_action
+.IR CONTROL " ] [ "
 .B action
 .IR ACTION_SPEC " ] [ "
 .B classid
@@ -64,6 +66,28 @@ action from the generic action framework may be called.
 .BI action " ACTION_SPEC"
 Apply an action from the generic actions framework on matching packets.
 .TP
+.BI header_parse_err_action " CONTROL"
+Control how the tree of qdisc, classes and filters is further
+traversed if an error is encountered when parsing the packet in order to
+match against the \fIMATCH_LIST\fR.
+.RS
+.TP
+.B drop
+.TQ
+.B shot
+Drop the packet.
+.TP
+.B continue
+Continue classification with the next filter in line.
+.TP
+.B pass
+Finish classification process and return to calling qdisc for further packet
+processing. This is the default.
+.P
+All filters with the same prio must have the same header_parse_err_action
+value -  drop and shot are considered to be the same value.
+.RE
+.TP
 .BI classid " CLASSID"
 Specify a class to pass matching packets on to.
 .I CLASSID
@@ -219,8 +243,9 @@ and finally ICMP matches (\fBcode\fR and \fBtype\fR) depend on
 being set to
 .BR icmp " or " icmpv6.
 .P
-There can be only used one mask per one prio. If user needs to specify different
-mask, he has to use different prio.
+There can be only used one mask and header_parse_err_action per one prio.
+If user needs to specify different mask or header_parse_err_action,
+he has to use different prio.
 .SH SEE ALSO
 .BR tc (8),
 .BR tc-flow (8)
diff --git a/tc/f_flower.c b/tc/f_flower.c
index 5aac4a0837f4..7bbc15b79fdd 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -43,6 +43,7 @@ static void explain(void)
 	fprintf(stderr,
 		"Usage: ... flower [ MATCH-LIST ]\n"
 		"                  [ skip_sw | skip_hw ]\n"
+		"                  [ header_parse_err_action CONTROL ]\n"
 		"                  [ action ACTION-SPEC ] [ classid CLASSID ]\n"
 		"\n"
 		"Where: MATCH-LIST := [ MATCH-LIST ] MATCH\n"
@@ -72,6 +73,7 @@ static void explain(void)
 		"       FILTERID := X:Y:Z\n"
 		"       MASKED_LLADDR := { LLADDR | LLADDR/MASK | LLADDR/BITS }\n"
 		"       ACTION-SPEC := ... look at individual actions\n"
+		"       CONTROL := ... drop | shot | continue | pass\n"
 		"\n"
 		"NOTE: CLASSID, IP-PROTO are parsed as hexadecimal input.\n"
 		"NOTE: There can be only used one mask per one prio. If user needs\n"
@@ -507,12 +509,14 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
 	struct tcmsg *t = NLMSG_DATA(n);
 	struct rtattr *tail;
 	__be16 eth_type = TC_H_MIN(t->tcm_info);
+	int err_action = TC_ACT_UNSPEC;
 	__be16 vlan_ethtype = 0;
 	__u8 ip_proto = 0xff;
 	__u32 flags = 0;
 	__u32 mtf = 0;
 	__u32 mtf_mask = 0;
 
+
 	if (handle) {
 		ret = get_u32(&t->tcm_handle, handle, 0);
 		if (ret) {
@@ -788,6 +792,23 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
 				return -1;
 			}
 			continue;
+		} else if (matches(*argv, "header_parse_err_action") == 0) {
+			NEXT_ARG();
+
+			if (!argc || action_a2n(*argv, &err_action, false)) {
+				fprintf(stderr, "Illegal \"header_parse_err_action\"\n");
+				return -1;
+			}
+
+			switch (err_action) {
+			case TC_ACT_UNSPEC:
+			case TC_ACT_OK:
+			case TC_ACT_SHOT:
+				break;
+			default:
+				fprintf(stderr, "Illegal \"header_parse_err_action\"\n");
+				return -1;
+			}
 		} else if (strcmp(*argv, "help") == 0) {
 			explain();
 			return -1;
@@ -820,6 +841,12 @@ parse_done:
 			return ret;
 	}
 
+	ret = addattr32(n, MAX_MSG, TCA_FLOWER_HEADER_PARSE_ERR_ACT,
+			err_action);
+	if (ret)
+		return ret;
+
+
 	tail->rta_len = (((void *)n)+n->nlmsg_len) - (void *)tail;
 
 	return 0;
@@ -1173,6 +1200,12 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
 			fprintf(f, "\n  skip_sw");
 	}
 
+	if (tb[TCA_FLOWER_HEADER_PARSE_ERR_ACT]) {
+		int act = rta_getattr_u32(tb[TCA_FLOWER_HEADER_PARSE_ERR_ACT]);
+
+		fprintf(f, "\n  header_parse_err_action %s", action_n2a(act));
+	}
+
 	if (tb[TCA_FLOWER_ACT])
 		tc_print_action(f, tb[TCA_FLOWER_ACT]);
 
-- 
2.12.2.816.g2cccc81164

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ