* [PATCH iproute2/net-next repost 0/3] tc: flower: support masked ICMP code and type match
@ 2017-02-09 13:48 Simon Horman
2017-02-09 13:48 ` [PATCH iproute2/net-next repost 1/3] tc: flower: provide generic masked u8 parser helper Simon Horman
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Simon Horman @ 2017-02-09 13:48 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Jiri Pirko, Dinan Gunawardena, netdev, oss-drivers, Simon Horman
Hi,
this short series allows the tc tool to configure masked matches on the
ICMP code and type. Unmasked matches are already supported by the tool.
This does not depend on any kernel changes as support for both masked and
unmasked matches were added to the kernel at the same time.
Sample usage:
tc qdisc add dev eth0 ingress
tc filter add dev eth0 protocol ipv6 parent ffff: flower \
indev eth0 ip_proto icmpv6 type 128/240 code 0 action drop
Reposting after breaking out of a larger patchset.
Simon Horman (3):
tc: flower: provide generic masked u8 parser helper
tc: flower: provide generic masked u8 print helper
tc: flower: support masked ICMP code and type match
man/man8/tc-flower.8 | 16 ++++--
tc/f_flower.c | 158 ++++++++++++++++++++++++++++++++++-----------------
2 files changed, 119 insertions(+), 55 deletions(-)
--
2.7.0.rc3.207.g0ac5344
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH iproute2/net-next repost 1/3] tc: flower: provide generic masked u8 parser helper
2017-02-09 13:48 [PATCH iproute2/net-next repost 0/3] tc: flower: support masked ICMP code and type match Simon Horman
@ 2017-02-09 13:48 ` Simon Horman
2017-02-09 13:49 ` [PATCH iproute2/net-next repost 2/3] tc: flower: provide generic masked u8 print helper Simon Horman
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Simon Horman @ 2017-02-09 13:48 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Jiri Pirko, Dinan Gunawardena, netdev, oss-drivers, Simon Horman
Provide generic masked u8 paser helper and use it to parse arp operations.
Also consistently use __u8 rather than uint8_t, in keeping with the
pervasive style in the file.
Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
tc/f_flower.c | 55 ++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 40 insertions(+), 15 deletions(-)
diff --git a/tc/f_flower.c b/tc/f_flower.c
index 0f2251315975..5554cc05118b 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -309,33 +309,30 @@ static int flower_parse_arp_ip_addr(char *str, __be16 eth_type,
TCA_FLOWER_UNSPEC, TCA_FLOWER_UNSPEC, n);
}
-static int flower_parse_arp_op(char *str, __be16 eth_type,
- int op_type, int mask_type,
- struct nlmsghdr *n)
+static int flower_parse_u8(char *str, int value_type, int mask_type,
+ int (*value_from_name)(const char *str,
+ __u8 *value),
+ bool (*value_validate)(__u8 value),
+ struct nlmsghdr *n)
{
char *slash;
int ret, err = -1;
- uint8_t value, mask;
+ __u8 value, mask;
slash = strchr(str, '/');
if (slash)
*slash = '\0';
- if (!flower_eth_type_arp(eth_type))
- goto err;
-
- if (!strcmp(str, "request")) {
- value = ARPOP_REQUEST;
- } else if (!strcmp(str, "reply")) {
- value = ARPOP_REPLY;
- } else {
+ ret = value_from_name ? value_from_name(str, &value) : -1;
+ if (ret < 0) {
ret = get_u8(&value, str, 10);
if (ret)
goto err;
- if (value && value != ARPOP_REQUEST && value != ARPOP_REPLY)
- goto err;
}
+ if (value_validate && !value_validate(value))
+ goto err;
+
if (slash) {
ret = get_u8(&mask, slash + 1, 10);
if (ret)
@@ -345,7 +342,7 @@ static int flower_parse_arp_op(char *str, __be16 eth_type,
mask = UINT8_MAX;
}
- addattr8(n, MAX_MSG, op_type, value);
+ addattr8(n, MAX_MSG, value_type, value);
addattr8(n, MAX_MSG, mask_type, mask);
err = 0;
@@ -355,6 +352,34 @@ err:
return err;
}
+static int flower_arp_op_from_name(const char *name, __u8 *op)
+{
+ if (!strcmp(name, "request"))
+ *op = ARPOP_REQUEST;
+ else if (!strcmp(name, "reply"))
+ *op = ARPOP_REPLY;
+ else
+ return -1;
+
+ return 0;
+}
+
+static bool flow_arp_op_validate(__u8 op)
+{
+ return !op || op == ARPOP_REQUEST || op == ARPOP_REPLY;
+}
+
+static int flower_parse_arp_op(char *str, __be16 eth_type,
+ int op_type, int mask_type,
+ struct nlmsghdr *n)
+{
+ if (!flower_eth_type_arp(eth_type))
+ return -1;
+
+ return flower_parse_u8(str, op_type, mask_type, flower_arp_op_from_name,
+ flow_arp_op_validate, n);
+}
+
static int flower_icmp_attr_type(__be16 eth_type, __u8 ip_proto,
enum flower_icmp_field field)
{
--
2.7.0.rc3.207.g0ac5344
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH iproute2/net-next repost 2/3] tc: flower: provide generic masked u8 print helper
2017-02-09 13:48 [PATCH iproute2/net-next repost 0/3] tc: flower: support masked ICMP code and type match Simon Horman
2017-02-09 13:48 ` [PATCH iproute2/net-next repost 1/3] tc: flower: provide generic masked u8 parser helper Simon Horman
@ 2017-02-09 13:49 ` Simon Horman
2017-02-09 13:49 ` [PATCH iproute2/net-next repost 3/3] tc: flower: support masked ICMP code and type match Simon Horman
2017-02-19 0:14 ` [PATCH iproute2/net-next repost 0/3] " Stephen Hemminger
3 siblings, 0 replies; 5+ messages in thread
From: Simon Horman @ 2017-02-09 13:49 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Jiri Pirko, Dinan Gunawardena, netdev, oss-drivers, Simon Horman
Provide generic masked u8 print helper and use it to print arp operations.
Also:
* Make name parameter of arp op print helper const.
* Consistently use __u8 rather than uint8_t, in keeping with the
pervasive style in the file.
Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
tc/f_flower.c | 44 +++++++++++++++++++++++++++++++++-----------
1 file changed, 33 insertions(+), 11 deletions(-)
diff --git a/tc/f_flower.c b/tc/f_flower.c
index 5554cc05118b..6a0bedcc4d5d 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -352,6 +352,18 @@ err:
return err;
}
+static const char *flower_print_arp_op_to_name(__u8 op)
+{
+ switch (op) {
+ case ARPOP_REQUEST:
+ return "request";
+ case ARPOP_REPLY:
+ return "reply";
+ default:
+ return NULL;
+ }
+}
+
static int flower_arp_op_from_name(const char *name, __u8 *op)
{
if (!strcmp(name, "request"))
@@ -993,31 +1005,41 @@ static void flower_print_icmp(FILE *f, char *name, struct rtattr *attr)
fprintf(f, "\n %s %d", name, rta_getattr_u8(attr));
}
-static void flower_print_arp_op(FILE *f, char *name,
- struct rtattr *op_attr,
- struct rtattr *mask_attr)
+static void flower_print_masked_u8(FILE *f, const char *name,
+ struct rtattr *attr,
+ struct rtattr *mask_attr,
+ const char *(*value_to_str)(__u8 value))
{
- uint8_t op, mask;
+ const char *value_str = NULL;
+ __u8 value, mask;
- if (!op_attr)
+ if (!attr)
return;
- op = rta_getattr_u8(op_attr);
+ value = rta_getattr_u8(attr);
mask = mask_attr ? rta_getattr_u8(mask_attr) : UINT8_MAX;
+ if (mask == UINT8_MAX && value_to_str)
+ value_str = value_to_str(value);
fprintf(f, "\n %s ", name);
- if (mask == UINT8_MAX && op == ARPOP_REQUEST)
- fprintf(f, "request");
- else if (mask == UINT8_MAX && op == ARPOP_REPLY)
- fprintf(f, "reply");
+ if (value_str)
+ fputs(value_str, f);
else
- fprintf(f, "%d", op);
+ fprintf(f, "%d", value);
if (mask != UINT8_MAX)
fprintf(f, "/%d", mask);
}
+static void flower_print_arp_op(FILE *f, const char *name,
+ struct rtattr *op_attr,
+ struct rtattr *mask_attr)
+{
+ flower_print_masked_u8(f, name, op_attr, mask_attr,
+ flower_print_arp_op_to_name);
+}
+
static int flower_print_opt(struct filter_util *qu, FILE *f,
struct rtattr *opt, __u32 handle)
{
--
2.7.0.rc3.207.g0ac5344
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH iproute2/net-next repost 3/3] tc: flower: support masked ICMP code and type match
2017-02-09 13:48 [PATCH iproute2/net-next repost 0/3] tc: flower: support masked ICMP code and type match Simon Horman
2017-02-09 13:48 ` [PATCH iproute2/net-next repost 1/3] tc: flower: provide generic masked u8 parser helper Simon Horman
2017-02-09 13:49 ` [PATCH iproute2/net-next repost 2/3] tc: flower: provide generic masked u8 print helper Simon Horman
@ 2017-02-09 13:49 ` Simon Horman
2017-02-19 0:14 ` [PATCH iproute2/net-next repost 0/3] " Stephen Hemminger
3 siblings, 0 replies; 5+ messages in thread
From: Simon Horman @ 2017-02-09 13:49 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Jiri Pirko, Dinan Gunawardena, netdev, oss-drivers, Simon Horman
Extend ICMP code and type match to support masks.
Also add missing documentation to synopsis in manpage.
tc qdisc add dev eth0 ingress
tc filter add dev eth0 protocol ipv6 parent ffff: flower \
indev eth0 ip_proto icmpv6 type 128/240 code 0 action drop
Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
man/man8/tc-flower.8 | 16 ++++++++++----
tc/f_flower.c | 59 ++++++++++++++++++++++++++++++----------------------
2 files changed, 46 insertions(+), 29 deletions(-)
diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8
index b1bef8b7637a..fc5bac503324 100644
--- a/man/man8/tc-flower.8
+++ b/man/man8/tc-flower.8
@@ -34,7 +34,11 @@ flower \- flow based traffic control filter
.BR dst_ip " | " src_ip " } "
.IR PREFIX " | { "
.BR dst_port " | " src_port " } "
-.IR port_number " } | { "
+.IR port_number " } | "
+.B type
+.IR MASKED_TYPE " | "
+.B code
+.IR MASKED_CODE " | { "
.BR arp_tip " | " arp_sip " } "
.IR IPV4_PREFIX " | "
.BR arp_op " { " request " | " reply " | "
@@ -132,10 +136,14 @@ 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 type " NUMBER"
+.BI type " MASKED_TYPE"
.TQ
-.BI code " NUMBER"
-Match on ICMP type or code. Only available for
+.BI code " MASKED_CODE"
+Match on ICMP type or code. A mask may be optionally provided to limit the
+bits of the address which are matched. A mask is provided by following the
+address with a slash and then the mask. The mask must be as a number which
+represents a bitwise mask If the mask is missing then a match on all bits
+is assumed. Only available for
.BR ip_proto " values " icmp " and " icmpv6
which have to be specified in beforehand.
.TP
diff --git a/tc/f_flower.c b/tc/f_flower.c
index 6a0bedcc4d5d..6bd03f2b8e4b 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -57,8 +57,8 @@ static void explain(void)
" src_ip PREFIX |\n"
" dst_port PORT-NUMBER |\n"
" src_port PORT-NUMBER |\n"
- " type ICMP-TYPE |\n"
- " code ICMP-CODE |\n"
+ " type MASKED-ICMP-TYPE |\n"
+ " code MASKED-ICMP-CODE |\n"
" arp_tip IPV4-PREFIX |\n"
" arp_sip IPV4-PREFIX |\n"
" arp_op [ request | reply | OP ] |\n"
@@ -407,24 +407,32 @@ static int flower_icmp_attr_type(__be16 eth_type, __u8 ip_proto,
return -1;
}
+static int flower_icmp_attr_mask_type(__be16 eth_type, __u8 ip_proto,
+ enum flower_icmp_field field)
+{
+ if (eth_type == htons(ETH_P_IP) && ip_proto == IPPROTO_ICMP)
+ return field == FLOWER_ICMP_FIELD_CODE ?
+ TCA_FLOWER_KEY_ICMPV4_CODE_MASK :
+ TCA_FLOWER_KEY_ICMPV4_TYPE_MASK;
+ else if (eth_type == htons(ETH_P_IPV6) && ip_proto == IPPROTO_ICMPV6)
+ return field == FLOWER_ICMP_FIELD_CODE ?
+ TCA_FLOWER_KEY_ICMPV6_CODE_MASK :
+ TCA_FLOWER_KEY_ICMPV6_TYPE_MASK;
+
+ return -1;
+}
+
static int flower_parse_icmp(char *str, __u16 eth_type, __u8 ip_proto,
enum flower_icmp_field field, struct nlmsghdr *n)
{
- int ret;
- int type;
- uint8_t value;
-
- type = flower_icmp_attr_type(eth_type, ip_proto, field);
- if (type < 0)
- return -1;
+ int value_type, mask_type;
- ret = get_u8(&value, str, 10);
- if (ret)
+ value_type = flower_icmp_attr_type(eth_type, ip_proto, field);
+ mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto, field);
+ if (value_type < 0 || mask_type < 0)
return -1;
- addattr8(n, MAX_MSG, type, value);
-
- return 0;
+ return flower_parse_u8(str, value_type, mask_type, NULL, NULL, n);
}
static int flower_port_attr_type(__u8 ip_proto, enum flower_endpoint endpoint)
@@ -999,12 +1007,6 @@ static void flower_print_key_id(FILE *f, const char *name,
fprintf(f, "\n %s %d", name, rta_getattr_be32(attr));
}
-static void flower_print_icmp(FILE *f, char *name, struct rtattr *attr)
-{
- if (attr)
- fprintf(f, "\n %s %d", name, rta_getattr_u8(attr));
-}
-
static void flower_print_masked_u8(FILE *f, const char *name,
struct rtattr *attr,
struct rtattr *mask_attr,
@@ -1044,9 +1046,9 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
struct rtattr *opt, __u32 handle)
{
struct rtattr *tb[TCA_FLOWER_MAX + 1];
+ int nl_type, nl_mask_type;
__be16 eth_type = 0;
__u8 ip_proto = 0xff;
- int nl_type;
if (!opt)
return 0;
@@ -1110,12 +1112,19 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
nl_type = flower_icmp_attr_type(eth_type, ip_proto,
FLOWER_ICMP_FIELD_TYPE);
- if (nl_type >= 0)
- flower_print_icmp(f, "icmp_type", tb[nl_type]);
+ nl_mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto,
+ FLOWER_ICMP_FIELD_TYPE);
+ if (nl_type >= 0 && nl_mask_type >= 0)
+ flower_print_masked_u8(f, "icmp_type", tb[nl_type],
+ tb[nl_mask_type], NULL);
+
nl_type = flower_icmp_attr_type(eth_type, ip_proto,
FLOWER_ICMP_FIELD_CODE);
- if (nl_type >= 0)
- flower_print_icmp(f, "icmp_code", tb[nl_type]);
+ nl_mask_type = flower_icmp_attr_mask_type(eth_type, ip_proto,
+ FLOWER_ICMP_FIELD_CODE);
+ if (nl_type >= 0 && nl_mask_type >= 0)
+ flower_print_masked_u8(f, "icmp_code", tb[nl_type],
+ tb[nl_mask_type], NULL);
flower_print_ip4_addr(f, "arp_sip", tb[TCA_FLOWER_KEY_ARP_SIP],
tb[TCA_FLOWER_KEY_ARP_SIP_MASK]);
--
2.7.0.rc3.207.g0ac5344
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH iproute2/net-next repost 0/3] tc: flower: support masked ICMP code and type match
2017-02-09 13:48 [PATCH iproute2/net-next repost 0/3] tc: flower: support masked ICMP code and type match Simon Horman
` (2 preceding siblings ...)
2017-02-09 13:49 ` [PATCH iproute2/net-next repost 3/3] tc: flower: support masked ICMP code and type match Simon Horman
@ 2017-02-19 0:14 ` Stephen Hemminger
3 siblings, 0 replies; 5+ messages in thread
From: Stephen Hemminger @ 2017-02-19 0:14 UTC (permalink / raw)
To: Simon Horman; +Cc: Jiri Pirko, Dinan Gunawardena, netdev, oss-drivers
On Thu, 9 Feb 2017 14:48:58 +0100
Simon Horman <simon.horman@netronome.com> wrote:
> Hi,
>
> this short series allows the tc tool to configure masked matches on the
> ICMP code and type. Unmasked matches are already supported by the tool.
>
> This does not depend on any kernel changes as support for both masked and
> unmasked matches were added to the kernel at the same time.
>
> Sample usage:
>
> tc qdisc add dev eth0 ingress
> tc filter add dev eth0 protocol ipv6 parent ffff: flower \
> indev eth0 ip_proto icmpv6 type 128/240 code 0 action drop
>
> Reposting after breaking out of a larger patchset.
>
> Simon Horman (3):
> tc: flower: provide generic masked u8 parser helper
> tc: flower: provide generic masked u8 print helper
> tc: flower: support masked ICMP code and type match
>
> man/man8/tc-flower.8 | 16 ++++--
> tc/f_flower.c | 158 ++++++++++++++++++++++++++++++++++-----------------
> 2 files changed, 119 insertions(+), 55 deletions(-)
>
Applied to net-next
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-02-19 0:14 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-02-09 13:48 [PATCH iproute2/net-next repost 0/3] tc: flower: support masked ICMP code and type match Simon Horman
2017-02-09 13:48 ` [PATCH iproute2/net-next repost 1/3] tc: flower: provide generic masked u8 parser helper Simon Horman
2017-02-09 13:49 ` [PATCH iproute2/net-next repost 2/3] tc: flower: provide generic masked u8 print helper Simon Horman
2017-02-09 13:49 ` [PATCH iproute2/net-next repost 3/3] tc: flower: support masked ICMP code and type match Simon Horman
2017-02-19 0:14 ` [PATCH iproute2/net-next repost 0/3] " Stephen Hemminger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).