You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
4.6 KiB
154 lines
4.6 KiB
From 7cbf364a5f68ba008c5e0702266fe3dc606b1d6f Mon Sep 17 00:00:00 2001 |
|
From: Kamal Heib <kheib@redhat.com> |
|
Date: Thu, 9 Nov 2017 04:44:32 -0500 |
|
Subject: [PATCH] tc: flower: add support for tcp flags |
|
|
|
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1456539 |
|
|
|
commit 0c30d14d0a2fc2fb6b7fef62bea05f2e5c3eb26a |
|
Author: Jiri Pirko <jiri@mellanox.com> |
|
Date: Tue May 23 23:51:39 2017 +0200 |
|
|
|
tc: flower: add support for tcp flags |
|
|
|
Allow user to insert a flower classifier filter rule which includes |
|
match for tcp flags. |
|
|
|
Signed-off-by: Jiri Pirko <jiri@mellanox.com> |
|
|
|
Signed-off-by: Kamal Heib <kheib@redhat.com> |
|
--- |
|
man/man8/tc-flower.8 | 8 +++++++ |
|
tc/f_flower.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ |
|
2 files changed, 70 insertions(+) |
|
|
|
diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8 |
|
index ba29065..7648079 100644 |
|
--- a/man/man8/tc-flower.8 |
|
+++ b/man/man8/tc-flower.8 |
|
@@ -35,6 +35,8 @@ flower \- flow based traffic control filter |
|
.IR PREFIX " | { " |
|
.BR dst_port " | " src_port " } " |
|
.IR port_number " } | " |
|
+.B tcp_flags |
|
+.IR MASKED_TCP_FLAGS " | " |
|
.B type |
|
.IR MASKED_TYPE " | " |
|
.B code |
|
@@ -136,6 +138,12 @@ Match on layer 4 protocol source or destination port number. Only available for |
|
.BR ip_proto " values " udp ", " tcp " and " sctp |
|
which have to be specified in beforehand. |
|
.TP |
|
+.BI tcp_flags " MASKED_TCP_FLAGS" |
|
+Match on TCP flags represented as 12bit bitfield in in hexadecimal format. |
|
+A mask may be optionally provided to limit the bits which are matched. A mask |
|
+is provided by following the value with a slash and then the mask. If the mask |
|
+is missing then a match on all bits is assumed. |
|
+.TP |
|
.BI type " MASKED_TYPE" |
|
.TQ |
|
.BI code " MASKED_CODE" |
|
diff --git a/tc/f_flower.c b/tc/f_flower.c |
|
index ebc63ca..1b6b46e 100644 |
|
--- a/tc/f_flower.c |
|
+++ b/tc/f_flower.c |
|
@@ -57,6 +57,7 @@ static void explain(void) |
|
" src_ip PREFIX |\n" |
|
" dst_port PORT-NUMBER |\n" |
|
" src_port PORT-NUMBER |\n" |
|
+ " tcp_flags MASKED-TCP_FLAGS |\n" |
|
" type MASKED-ICMP-TYPE |\n" |
|
" code MASKED-ICMP-CODE |\n" |
|
" arp_tip IPV4-PREFIX |\n" |
|
@@ -474,6 +475,41 @@ static int flower_parse_port(char *str, __u8 ip_proto, |
|
return 0; |
|
} |
|
|
|
+#define TCP_FLAGS_MAX_MASK 0xfff |
|
+ |
|
+static int flower_parse_tcp_flags(char *str, int flags_type, int mask_type, |
|
+ struct nlmsghdr *n) |
|
+{ |
|
+ char *slash; |
|
+ int ret, err = -1; |
|
+ __u16 flags; |
|
+ |
|
+ slash = strchr(str, '/'); |
|
+ if (slash) |
|
+ *slash = '\0'; |
|
+ |
|
+ ret = get_u16(&flags, str, 16); |
|
+ if (ret < 0 || flags & ~TCP_FLAGS_MAX_MASK) |
|
+ goto err; |
|
+ |
|
+ addattr16(n, MAX_MSG, flags_type, htons(flags)); |
|
+ |
|
+ if (slash) { |
|
+ ret = get_u16(&flags, slash + 1, 16); |
|
+ if (ret < 0 || flags & ~TCP_FLAGS_MAX_MASK) |
|
+ goto err; |
|
+ } else { |
|
+ flags = TCP_FLAGS_MAX_MASK; |
|
+ } |
|
+ addattr16(n, MAX_MSG, mask_type, htons(flags)); |
|
+ |
|
+ err = 0; |
|
+err: |
|
+ if (slash) |
|
+ *slash = '/'; |
|
+ return err; |
|
+} |
|
+ |
|
static int flower_parse_key_id(const char *str, int type, struct nlmsghdr *n) |
|
{ |
|
int ret; |
|
@@ -671,6 +707,16 @@ static int flower_parse_opt(struct filter_util *qu, char *handle, |
|
fprintf(stderr, "Illegal \"src_port\"\n"); |
|
return -1; |
|
} |
|
+ } else if (matches(*argv, "tcp_flags") == 0) { |
|
+ NEXT_ARG(); |
|
+ ret = flower_parse_tcp_flags(*argv, |
|
+ TCA_FLOWER_KEY_TCP_FLAGS, |
|
+ TCA_FLOWER_KEY_TCP_FLAGS_MASK, |
|
+ n); |
|
+ if (ret < 0) { |
|
+ fprintf(stderr, "Illegal \"tcp_flags\"\n"); |
|
+ return -1; |
|
+ } |
|
} else if (matches(*argv, "type") == 0) { |
|
NEXT_ARG(); |
|
ret = flower_parse_icmp(*argv, eth_type, ip_proto, |
|
@@ -1000,6 +1046,19 @@ static void flower_print_port(FILE *f, char *name, struct rtattr *attr) |
|
fprintf(f, "\n %s %d", name, rta_getattr_be16(attr)); |
|
} |
|
|
|
+static void flower_print_tcp_flags(FILE *f, char *name, |
|
+ struct rtattr *flags_attr, |
|
+ struct rtattr *mask_attr) |
|
+{ |
|
+ if (!flags_attr) |
|
+ return; |
|
+ fprintf(f, "\n %s %x", name, rta_getattr_be16(flags_attr)); |
|
+ if (!mask_attr) |
|
+ return; |
|
+ fprintf(f, "/%x", rta_getattr_be16(mask_attr)); |
|
+} |
|
+ |
|
+ |
|
static void flower_print_key_id(FILE *f, const char *name, |
|
struct rtattr *attr) |
|
{ |
|
@@ -1110,6 +1169,9 @@ static int flower_print_opt(struct filter_util *qu, FILE *f, |
|
if (nl_type >= 0) |
|
flower_print_port(f, "src_port", tb[nl_type]); |
|
|
|
+ flower_print_tcp_flags(f, "tcp_flags", tb[TCA_FLOWER_KEY_TCP_FLAGS], |
|
+ tb[TCA_FLOWER_KEY_TCP_FLAGS_MASK]); |
|
+ |
|
nl_type = flower_icmp_attr_type(eth_type, ip_proto, |
|
FLOWER_ICMP_FIELD_TYPE); |
|
nl_mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto, |
|
-- |
|
1.8.3.1 |
|
|
|
|