|
|
4aca6e |
From aa7beedaa4ac1371c1d08e8afc8d9b6cfd72e22e Mon Sep 17 00:00:00 2001
|
|
|
4aca6e |
From: Phil Sutter <psutter@redhat.com>
|
|
|
4aca6e |
Date: Fri, 17 Mar 2017 13:25:13 +0100
|
|
|
4aca6e |
Subject: [PATCH] tc: flower: support masked ICMP code and type match
|
|
|
4aca6e |
|
|
|
4aca6e |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1422629
|
|
|
4aca6e |
Upstream Status: iproute2.git commit 6374961a00d4b
|
|
|
4aca6e |
|
|
|
4aca6e |
commit 6374961a00d4b862bdf87c0f22af86d3ff7d0d67
|
|
|
4aca6e |
Author: Simon Horman <simon.horman@netronome.com>
|
|
|
4aca6e |
Date: Thu Feb 9 14:49:01 2017 +0100
|
|
|
4aca6e |
|
|
|
4aca6e |
tc: flower: support masked ICMP code and type match
|
|
|
4aca6e |
|
|
|
4aca6e |
Extend ICMP code and type match to support masks.
|
|
|
4aca6e |
|
|
|
4aca6e |
Also add missing documentation to synopsis in manpage.
|
|
|
4aca6e |
|
|
|
4aca6e |
tc qdisc add dev eth0 ingress
|
|
|
4aca6e |
tc filter add dev eth0 protocol ipv6 parent ffff: flower \
|
|
|
4aca6e |
indev eth0 ip_proto icmpv6 type 128/240 code 0 action drop
|
|
|
4aca6e |
|
|
|
4aca6e |
Signed-off-by: Simon Horman <simon.horman@netronome.com>
|
|
|
4aca6e |
---
|
|
|
4aca6e |
man/man8/tc-flower.8 | 16 ++++++++++----
|
|
|
4aca6e |
tc/f_flower.c | 59 ++++++++++++++++++++++++++++++----------------------
|
|
|
4aca6e |
2 files changed, 46 insertions(+), 29 deletions(-)
|
|
|
4aca6e |
|
|
|
4aca6e |
diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8
|
|
|
4aca6e |
index b1bef8b..fc5bac5 100644
|
|
|
4aca6e |
--- a/man/man8/tc-flower.8
|
|
|
4aca6e |
+++ b/man/man8/tc-flower.8
|
|
|
4aca6e |
@@ -34,7 +34,11 @@ flower \- flow based traffic control filter
|
|
|
4aca6e |
.BR dst_ip " | " src_ip " } "
|
|
|
4aca6e |
.IR PREFIX " | { "
|
|
|
4aca6e |
.BR dst_port " | " src_port " } "
|
|
|
4aca6e |
-.IR port_number " } | { "
|
|
|
4aca6e |
+.IR port_number " } | "
|
|
|
4aca6e |
+.B type
|
|
|
4aca6e |
+.IR MASKED_TYPE " | "
|
|
|
4aca6e |
+.B code
|
|
|
4aca6e |
+.IR MASKED_CODE " | { "
|
|
|
4aca6e |
.BR arp_tip " | " arp_sip " } "
|
|
|
4aca6e |
.IR IPV4_PREFIX " | "
|
|
|
4aca6e |
.BR arp_op " { " request " | " reply " | "
|
|
|
4aca6e |
@@ -132,10 +136,14 @@ Match on layer 4 protocol source or destination port number. Only available for
|
|
|
4aca6e |
.BR ip_proto " values " udp ", " tcp " and " sctp
|
|
|
4aca6e |
which have to be specified in beforehand.
|
|
|
4aca6e |
.TP
|
|
|
4aca6e |
-.BI type " NUMBER"
|
|
|
4aca6e |
+.BI type " MASKED_TYPE"
|
|
|
4aca6e |
.TQ
|
|
|
4aca6e |
-.BI code " NUMBER"
|
|
|
4aca6e |
-Match on ICMP type or code. Only available for
|
|
|
4aca6e |
+.BI code " MASKED_CODE"
|
|
|
4aca6e |
+Match on ICMP type or code. A mask may be optionally provided to limit the
|
|
|
4aca6e |
+bits of the address which are matched. A mask is provided by following the
|
|
|
4aca6e |
+address with a slash and then the mask. The mask must be as a number which
|
|
|
4aca6e |
+represents a bitwise mask If the mask is missing then a match on all bits
|
|
|
4aca6e |
+is assumed. Only available for
|
|
|
4aca6e |
.BR ip_proto " values " icmp " and " icmpv6
|
|
|
4aca6e |
which have to be specified in beforehand.
|
|
|
4aca6e |
.TP
|
|
|
4aca6e |
diff --git a/tc/f_flower.c b/tc/f_flower.c
|
|
|
4aca6e |
index 9c13e53..e9d3a96 100644
|
|
|
4aca6e |
--- a/tc/f_flower.c
|
|
|
4aca6e |
+++ b/tc/f_flower.c
|
|
|
4aca6e |
@@ -57,8 +57,8 @@ static void explain(void)
|
|
|
4aca6e |
" src_ip PREFIX |\n"
|
|
|
4aca6e |
" dst_port PORT-NUMBER |\n"
|
|
|
4aca6e |
" src_port PORT-NUMBER |\n"
|
|
|
4aca6e |
- " type ICMP-TYPE |\n"
|
|
|
4aca6e |
- " code ICMP-CODE |\n"
|
|
|
4aca6e |
+ " type MASKED-ICMP-TYPE |\n"
|
|
|
4aca6e |
+ " code MASKED-ICMP-CODE |\n"
|
|
|
4aca6e |
" arp_tip IPV4-PREFIX |\n"
|
|
|
4aca6e |
" arp_sip IPV4-PREFIX |\n"
|
|
|
4aca6e |
" arp_op [ request | reply | OP ] |\n"
|
|
|
4aca6e |
@@ -407,24 +407,32 @@ static int flower_icmp_attr_type(__be16 eth_type, __u8 ip_proto,
|
|
|
4aca6e |
return -1;
|
|
|
4aca6e |
}
|
|
|
4aca6e |
|
|
|
4aca6e |
+static int flower_icmp_attr_mask_type(__be16 eth_type, __u8 ip_proto,
|
|
|
4aca6e |
+ enum flower_icmp_field field)
|
|
|
4aca6e |
+{
|
|
|
4aca6e |
+ if (eth_type == htons(ETH_P_IP) && ip_proto == IPPROTO_ICMP)
|
|
|
4aca6e |
+ return field == FLOWER_ICMP_FIELD_CODE ?
|
|
|
4aca6e |
+ TCA_FLOWER_KEY_ICMPV4_CODE_MASK :
|
|
|
4aca6e |
+ TCA_FLOWER_KEY_ICMPV4_TYPE_MASK;
|
|
|
4aca6e |
+ else if (eth_type == htons(ETH_P_IPV6) && ip_proto == IPPROTO_ICMPV6)
|
|
|
4aca6e |
+ return field == FLOWER_ICMP_FIELD_CODE ?
|
|
|
4aca6e |
+ TCA_FLOWER_KEY_ICMPV6_CODE_MASK :
|
|
|
4aca6e |
+ TCA_FLOWER_KEY_ICMPV6_TYPE_MASK;
|
|
|
4aca6e |
+
|
|
|
4aca6e |
+ return -1;
|
|
|
4aca6e |
+}
|
|
|
4aca6e |
+
|
|
|
4aca6e |
static int flower_parse_icmp(char *str, __u16 eth_type, __u8 ip_proto,
|
|
|
4aca6e |
enum flower_icmp_field field, struct nlmsghdr *n)
|
|
|
4aca6e |
{
|
|
|
4aca6e |
- int ret;
|
|
|
4aca6e |
- int type;
|
|
|
4aca6e |
- uint8_t value;
|
|
|
4aca6e |
-
|
|
|
4aca6e |
- type = flower_icmp_attr_type(eth_type, ip_proto, field);
|
|
|
4aca6e |
- if (type < 0)
|
|
|
4aca6e |
- return -1;
|
|
|
4aca6e |
+ int value_type, mask_type;
|
|
|
4aca6e |
|
|
|
4aca6e |
- ret = get_u8(&value, str, 10);
|
|
|
4aca6e |
- if (ret)
|
|
|
4aca6e |
+ value_type = flower_icmp_attr_type(eth_type, ip_proto, field);
|
|
|
4aca6e |
+ mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto, field);
|
|
|
4aca6e |
+ if (value_type < 0 || mask_type < 0)
|
|
|
4aca6e |
return -1;
|
|
|
4aca6e |
|
|
|
4aca6e |
- addattr8(n, MAX_MSG, type, value);
|
|
|
4aca6e |
-
|
|
|
4aca6e |
- return 0;
|
|
|
4aca6e |
+ return flower_parse_u8(str, value_type, mask_type, NULL, NULL, n);
|
|
|
4aca6e |
}
|
|
|
4aca6e |
|
|
|
4aca6e |
static int flower_port_attr_type(__u8 ip_proto, enum flower_endpoint endpoint)
|
|
|
4aca6e |
@@ -1000,12 +1008,6 @@ static void flower_print_key_id(FILE *f, const char *name,
|
|
|
4aca6e |
fprintf(f, "\n %s %d", name, rta_getattr_be32(attr));
|
|
|
4aca6e |
}
|
|
|
4aca6e |
|
|
|
4aca6e |
-static void flower_print_icmp(FILE *f, char *name, struct rtattr *attr)
|
|
|
4aca6e |
-{
|
|
|
4aca6e |
- if (attr)
|
|
|
4aca6e |
- fprintf(f, "\n %s %d", name, rta_getattr_u8(attr));
|
|
|
4aca6e |
-}
|
|
|
4aca6e |
-
|
|
|
4aca6e |
static void flower_print_masked_u8(FILE *f, const char *name,
|
|
|
4aca6e |
struct rtattr *attr,
|
|
|
4aca6e |
struct rtattr *mask_attr,
|
|
|
4aca6e |
@@ -1045,9 +1047,9 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
|
|
|
4aca6e |
struct rtattr *opt, __u32 handle)
|
|
|
4aca6e |
{
|
|
|
4aca6e |
struct rtattr *tb[TCA_FLOWER_MAX + 1];
|
|
|
4aca6e |
+ int nl_type, nl_mask_type;
|
|
|
4aca6e |
__be16 eth_type = 0;
|
|
|
4aca6e |
__u8 ip_proto = 0xff;
|
|
|
4aca6e |
- int nl_type;
|
|
|
4aca6e |
|
|
|
4aca6e |
if (!opt)
|
|
|
4aca6e |
return 0;
|
|
|
4aca6e |
@@ -1111,12 +1113,19 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
|
|
|
4aca6e |
|
|
|
4aca6e |
nl_type = flower_icmp_attr_type(eth_type, ip_proto,
|
|
|
4aca6e |
FLOWER_ICMP_FIELD_TYPE);
|
|
|
4aca6e |
- if (nl_type >= 0)
|
|
|
4aca6e |
- flower_print_icmp(f, "icmp_type", tb[nl_type]);
|
|
|
4aca6e |
+ nl_mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto,
|
|
|
4aca6e |
+ FLOWER_ICMP_FIELD_TYPE);
|
|
|
4aca6e |
+ if (nl_type >= 0 && nl_mask_type >= 0)
|
|
|
4aca6e |
+ flower_print_masked_u8(f, "icmp_type", tb[nl_type],
|
|
|
4aca6e |
+ tb[nl_mask_type], NULL);
|
|
|
4aca6e |
+
|
|
|
4aca6e |
nl_type = flower_icmp_attr_type(eth_type, ip_proto,
|
|
|
4aca6e |
FLOWER_ICMP_FIELD_CODE);
|
|
|
4aca6e |
- if (nl_type >= 0)
|
|
|
4aca6e |
- flower_print_icmp(f, "icmp_code", tb[nl_type]);
|
|
|
4aca6e |
+ nl_mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto,
|
|
|
4aca6e |
+ FLOWER_ICMP_FIELD_CODE);
|
|
|
4aca6e |
+ if (nl_type >= 0 && nl_mask_type >= 0)
|
|
|
4aca6e |
+ flower_print_masked_u8(f, "icmp_code", tb[nl_type],
|
|
|
4aca6e |
+ tb[nl_mask_type], NULL);
|
|
|
4aca6e |
|
|
|
4aca6e |
flower_print_ip4_addr(f, "arp_sip", tb[TCA_FLOWER_KEY_ARP_SIP],
|
|
|
4aca6e |
tb[TCA_FLOWER_KEY_ARP_SIP_MASK]);
|
|
|
4aca6e |
--
|
|
|
4aca6e |
1.8.3.1
|
|
|
4aca6e |
|