Re: [PATCH iproute2 net-next] tc: flower: support matching flags

2017-01-19 Thread Paul Blakey



On 18/01/2017 14:41, Jiri Benc wrote:

On Wed, 4 Jan 2017 12:55:59 +0100, Jiri Benc wrote:

On Wed, 4 Jan 2017 13:51:13 +0200, Paul Blakey wrote:

It mimics the kernel packing of flags, I have no problem either way
(flags, or ip_flags/tcp_flags pairs), what do you think jiri?


What Simon says makes sense to me. ip_flags and tcp_flags sounds like
the best solution so far (even better than my original suggestion).


Is there any progress with the follow up patch? I don't think we want
iproute2 with the magic numbers to be released.

Thanks,

 Jiri





Hi,
I've posted a patch:
"[PATCH iproute2 net-next] tc: flower: Refactor matching flags to be 
more user friendly"


Thanks,
Paul.


Re: [PATCH iproute2 net-next] tc: flower: support matching flags

2017-01-18 Thread Jiri Benc
On Wed, 4 Jan 2017 12:55:59 +0100, Jiri Benc wrote:
> On Wed, 4 Jan 2017 13:51:13 +0200, Paul Blakey wrote:
> > It mimics the kernel packing of flags, I have no problem either way 
> > (flags, or ip_flags/tcp_flags pairs), what do you think jiri?
> 
> What Simon says makes sense to me. ip_flags and tcp_flags sounds like
> the best solution so far (even better than my original suggestion).

Is there any progress with the follow up patch? I don't think we want
iproute2 with the magic numbers to be released.

Thanks,

 Jiri


Re: [PATCH iproute2 net-next] tc: flower: support matching flags

2017-01-04 Thread Paul Blakey



On 04/01/2017 12:33, Simon Horman wrote:

On Tue, Jan 03, 2017 at 01:54:34PM +0200, Paul Blakey wrote:

...

Hi Paul,


Matching name was from the idea that we are doing is matching.
And regarding documentation/flag names I didn't want tc tool to be need of a
update each time a new flag is introduced,
But I guess I can add two options like with ip_proto where you can specify
known flags by name but can also give a value.
What do you think about that?

flags  / 
FLAGS => frag/no_frag/tcp_syn/no_tcp_syn ['|']*
e.g: flags frag|no_tcp_syn or flags 0x01/0x15
and the mask will have a on bits corresponds only to those flags specified.

I suppose a flag is a flag and bitwise masking allows arbitrary matching
on one or more flags. But I wonder if, as per your example above,
it makes sense to mix IP (frag) and TCP flags in the same field of the
classifier.
It mimics the kernel packing of flags, I have no problem either way 
(flags, or ip_flags/tcp_flags pairs), what do you think jiri?




Re: [PATCH iproute2 net-next] tc: flower: support matching flags

2017-01-04 Thread Jiri Benc
On Wed, 4 Jan 2017 13:51:13 +0200, Paul Blakey wrote:
> It mimics the kernel packing of flags, I have no problem either way 
> (flags, or ip_flags/tcp_flags pairs), what do you think jiri?

What Simon says makes sense to me. ip_flags and tcp_flags sounds like
the best solution so far (even better than my original suggestion).

Thanks,

 Jiri


Re: [PATCH iproute2 net-next] tc: flower: support matching flags

2017-01-04 Thread Simon Horman
On Tue, Jan 03, 2017 at 01:54:34PM +0200, Paul Blakey wrote:

...

Hi Paul,

> Matching name was from the idea that we are doing is matching.
> And regarding documentation/flag names I didn't want tc tool to be need of a
> update each time a new flag is introduced,
> But I guess I can add two options like with ip_proto where you can specify
> known flags by name but can also give a value.
> What do you think about that?
> 
> flags  / 
> FLAGS => frag/no_frag/tcp_syn/no_tcp_syn ['|']*
> e.g: flags frag|no_tcp_syn or flags 0x01/0x15
> and the mask will have a on bits corresponds only to those flags specified.

I suppose a flag is a flag and bitwise masking allows arbitrary matching
on one or more flags. But I wonder if, as per your example above,
it makes sense to mix IP (frag) and TCP flags in the same field of the
classifier.


Re: [PATCH iproute2 net-next] tc: flower: support matching flags

2017-01-03 Thread Jiri Benc
On Tue, 3 Jan 2017 13:54:34 +0200, Paul Blakey wrote:
> Matching name was from the idea that we are doing is matching.

But we don't have matching_src_mac etc., either, although we're
matching on those fields.

> And regarding documentation/flag names I didn't want tc tool to be need 
> of a update each time a new flag is introduced,

It will be needed anyway because the whole thing would be useless
without proper documentation. So each time a new flag is added, a new
patch to the tc tool will be needed, at least with an addition to its
man page.

Please, let's focus on the *user*. The tc tool is hard to grasp for
users as it is. It's crystal clear to you but you know the kernel
internals. I'm very sure that except for the few kernel developers, no
one would understand what the "flags" field does. And even among the
kernel developers, very few would remember what the magic numeric
values mean.

If we want wider adoption of flower, we should make it as easy to use
as possible. Even when it means a bit more work for us.

> But I guess I can add two options like with ip_proto where you can 
> specify known flags by name but can also give a value.
> What do you think about that?
> 
> flags  / 
> FLAGS => frag/no_frag/tcp_syn/no_tcp_syn ['|']*
> e.g: flags frag|no_tcp_syn or flags 0x01/0x15
> and the mask will have a on bits corresponds only to those flags specified.

This works for me, too.

Thanks!

 Jiri


Re: [PATCH iproute2 net-next] tc: flower: support matching flags

2017-01-03 Thread Paul Blakey

On 02/01/2017 20:55, Jiri Benc wrote:

On Wed, 28 Dec 2016 15:06:49 +0200, Paul Blakey wrote:

Enhance flower to support matching on flags.

The 1st flag allows to match on whether the packet is
an IP fragment.

Example:

# add a flower filter that will drop fragmented packets
# (bit 0 of control flags)
tc filter add dev ens4f0 protocol ip parent : \
flower \
src_mac e4:1d:2d:fd:8b:01 \
dst_mac e4:1d:2d:fd:8b:02 \
indev ens4f0 \
matching_flags 0x1/0x1 \
action drop

This is very poor API. First, how is the user supposed to know what
those magic values in "matching_flags" mean? At the very least, it
should be documented in the man page.

Second, why "matching_flags"? That name suggests that those modify the
way the matching is done (to illustrate my point, I'd expect things
like "if the packet is too short, match this rule anyway" to be a
"matching flag"). But this is not the case. What's wrong with plain
"flags"? Or, if you want to be more specific, perhaps packet_flags?

Third, all of this looks very wrong anyway. There should be separate
keywords for individual flags. In this case, there should be an
"ip_fragment" flag. The tc tool should be responsible for putting the
flags together and creating the appropriate mask. The example would
then be:

tc filter add dev ens4f0 protocol ip parent : \
flower \
src_mac e4:1d:2d:fd:8b:01 \
dst_mac e4:1d:2d:fd:8b:02 \
indev ens4f0 \
ip_fragment yes\
action drop

I don't care whether it's "ip_fragment yes/no", "ip_fragment 1/0",
"ip_fragment/noip_fragment" or similar. The important thing is it's a
boolean flag; if specified, it's set to 0/1 and unmasked, if not
specified, it's wildcarded.

Stephen, I understand that you already applied this patch but given how
horrible the proposed API is and that's even undocumented in this
patch, please reconsider this. If this is released, the API is set in
stone and, frankly, it's very user unfriendly this way.

Paul, could you please prepare a patch that would introduce a more sane
API? I'd strongly prefer what I described under "third" but should you
strongly disagree, at least implement "second" and document the
currently known flag values.

Thanks,

  Jiri


Matching name was from the idea that we are doing is matching.
And regarding documentation/flag names I didn't want tc tool to be need 
of a update each time a new flag is introduced,
But I guess I can add two options like with ip_proto where you can 
specify known flags by name but can also give a value.

What do you think about that?

flags  / 
FLAGS => frag/no_frag/tcp_syn/no_tcp_syn ['|']*
e.g: flags frag|no_tcp_syn or flags 0x01/0x15
and the mask will have a on bits corresponds only to those flags specified.






Re: [PATCH iproute2 net-next] tc: flower: support matching flags

2017-01-02 Thread Jiri Benc
On Wed, 28 Dec 2016 15:06:49 +0200, Paul Blakey wrote:
> Enhance flower to support matching on flags.
> 
> The 1st flag allows to match on whether the packet is
> an IP fragment.
> 
> Example:
> 
>   # add a flower filter that will drop fragmented packets
>   # (bit 0 of control flags)
>   tc filter add dev ens4f0 protocol ip parent : \
>   flower \
>   src_mac e4:1d:2d:fd:8b:01 \
>   dst_mac e4:1d:2d:fd:8b:02 \
>   indev ens4f0 \
>   matching_flags 0x1/0x1 \
>   action drop

This is very poor API. First, how is the user supposed to know what
those magic values in "matching_flags" mean? At the very least, it
should be documented in the man page.

Second, why "matching_flags"? That name suggests that those modify the
way the matching is done (to illustrate my point, I'd expect things
like "if the packet is too short, match this rule anyway" to be a
"matching flag"). But this is not the case. What's wrong with plain
"flags"? Or, if you want to be more specific, perhaps packet_flags?

Third, all of this looks very wrong anyway. There should be separate
keywords for individual flags. In this case, there should be an
"ip_fragment" flag. The tc tool should be responsible for putting the
flags together and creating the appropriate mask. The example would
then be:

tc filter add dev ens4f0 protocol ip parent : \
flower \
src_mac e4:1d:2d:fd:8b:01 \
dst_mac e4:1d:2d:fd:8b:02 \
indev ens4f0 \
ip_fragment yes\
action drop

I don't care whether it's "ip_fragment yes/no", "ip_fragment 1/0",
"ip_fragment/noip_fragment" or similar. The important thing is it's a
boolean flag; if specified, it's set to 0/1 and unmasked, if not
specified, it's wildcarded.

Stephen, I understand that you already applied this patch but given how
horrible the proposed API is and that's even undocumented in this
patch, please reconsider this. If this is released, the API is set in
stone and, frankly, it's very user unfriendly this way.

Paul, could you please prepare a patch that would introduce a more sane
API? I'd strongly prefer what I described under "third" but should you
strongly disagree, at least implement "second" and document the
currently known flag values.

Thanks,

 Jiri


Re: [PATCH iproute2 net-next] tc: flower: support matching flags

2016-12-29 Thread Stephen Hemminger
On Wed, 28 Dec 2016 15:06:49 +0200
Paul Blakey  wrote:

> Enhance flower to support matching on flags.
> 
> The 1st flag allows to match on whether the packet is
> an IP fragment.
> 
> Example:
> 
>   # add a flower filter that will drop fragmented packets
>   # (bit 0 of control flags)
>   tc filter add dev ens4f0 protocol ip parent : \
>   flower \
>   src_mac e4:1d:2d:fd:8b:01 \
>   dst_mac e4:1d:2d:fd:8b:02 \
>   indev ens4f0 \
>   matching_flags 0x1/0x1 \
>   action drop
> 
> Signed-off-by: Paul Blakey 
> Signed-off-by: Or Gerlitz 
> Reviewed-by: Roi Dayan 

Applied. Had to manually fixup merge conflicts with other flower changes.



[PATCH iproute2 net-next] tc: flower: support matching flags

2016-12-28 Thread Paul Blakey
Enhance flower to support matching on flags.

The 1st flag allows to match on whether the packet is
an IP fragment.

Example:

# add a flower filter that will drop fragmented packets
# (bit 0 of control flags)
tc filter add dev ens4f0 protocol ip parent : \
flower \
src_mac e4:1d:2d:fd:8b:01 \
dst_mac e4:1d:2d:fd:8b:02 \
indev ens4f0 \
matching_flags 0x1/0x1 \
action drop

Signed-off-by: Paul Blakey 
Signed-off-by: Or Gerlitz 
Reviewed-by: Roi Dayan 
---
 man/man8/tc-flower.8 | 11 +++
 tc/f_flower.c| 53 +++-
 2 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8
index 90fdfba..40117a9 100644
--- a/man/man8/tc-flower.8
+++ b/man/man8/tc-flower.8
@@ -39,6 +39,8 @@ flower \- flow based traffic control filter
 .IR KEY-ID " | {"
 .BR enc_dst_ip " | " enc_src_ip " } { "
 .IR ipv4_address " | " ipv6_address " } | "
+.B matching_flags
+.IR MATCHING-FLAGS " }"
 .SH DESCRIPTION
 The
 .B flower
@@ -134,6 +136,15 @@ Match on IP tunnel metadata. Key id
 is a 32 bit tunnel key id (e.g. VNI for VXLAN tunnel).
 .I ADDRESS
 must be a valid IPv4 or IPv6 address.
+.TP
+.BI matching_flags " MATCHING-FLAGS"
+Match on various dissector flags.
+.I MATCHING-FLAGS
+may be specified with or without a mask:
+.BR FLAGS
+or
+.BR FLAGS/FLAGS_MASK
+where each arg is an unsigned 32bit value in hexadecimal format.
 .SH NOTES
 As stated above where applicable, matches of a certain layer implicitly depend
 on the matches of the next lower layer. Precisely, layer one and two matches
diff --git a/tc/f_flower.c b/tc/f_flower.c
index 5dac427..479f5e6 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -56,7 +56,8 @@ static void explain(void)
"   code ICMP-CODE }\n"
"   enc_dst_ip [ IPV4-ADDR | IPV6-ADDR ] 
|\n"
"   enc_src_ip [ IPV4-ADDR | IPV6-ADDR ] 
|\n"
-   "   enc_key_id [ KEY-ID ] }\n"
+   "   enc_key_id [ KEY-ID ] |\n"
+   "   matching_flags MATCHING-FLAGS }\n"
"   FILTERID := X:Y:Z\n"
"   ACTION-SPEC := ... look at individual actions\n"
"\n"
@@ -99,6 +100,31 @@ static int flower_parse_vlan_eth_type(char *str, __be16 
eth_type, int type,
return 0;
 }
 
+static int flower_parse_matching_flags(char *str, int type, int mask_type,
+  struct nlmsghdr *n)
+{
+   __u32 mtf, mtf_mask;
+   char *c;
+
+   c = strchr(str, '/');
+   if (c)
+   *c = '\0';
+
+   if (get_u32(&mtf, str, 0))
+   return -1;
+
+   if (c) {
+   if (get_u32(&mtf_mask, ++c, 0))
+   return -1;
+   } else {
+   mtf_mask = 0x;
+   }
+
+   addattr32(n, MAX_MSG, type, htonl(mtf));
+   addattr32(n, MAX_MSG, mask_type, htonl(mtf_mask));
+   return 0;
+}
+
 static int flower_parse_ip_proto(char *str, __be16 eth_type, int type,
 __u8 *p_ip_proto, struct nlmsghdr *n)
 {
@@ -314,6 +340,16 @@ static int flower_parse_opt(struct filter_util *qu, char 
*handle,
return -1;
}
addattr_l(n, MAX_MSG, TCA_FLOWER_CLASSID, &handle, 4);
+   } else if (matches(*argv, "matching_flags") == 0) {
+   NEXT_ARG();
+   ret = flower_parse_matching_flags(*argv,
+ TCA_FLOWER_KEY_FLAGS,
+ 
TCA_FLOWER_KEY_FLAGS_MASK,
+ n);
+   if (ret < 0) {
+   fprintf(stderr, "Illegal \"matching_flags\"\n");
+   return -1;
+   }
} else if (matches(*argv, "skip_hw") == 0) {
flags |= TCA_CLS_FLAGS_SKIP_HW;
} else if (matches(*argv, "skip_sw") == 0) {
@@ -604,6 +640,17 @@ static void flower_print_ip_proto(FILE *f, __u8 
*p_ip_proto,
*p_ip_proto = ip_proto;
 }
 
+static void flower_print_matching_flags(FILE *f, char *name,
+   struct rtattr *attr,
+   struct rtattr *mask_attr)
+{
+   if (!mask_attr || RTA_PAYLOAD(mask_attr) != 4)
+   return;
+
+   fprintf(f, "\n  %s 0x%08x/0x%08x", name, ntohl(rta_getattr_u32(attr)),
+   mask_attr ? ntohl(rta_getattr_u32(mask_attr)) : 0x);
+}
+
 static void flower_print_ip_addr(FILE *f, char *name, __be16 eth_type,
 struct rtattr *