Re: [PATCH net-next 4/6] net/sched: allow flower to match tunnel options

2018-08-07 Thread Or Gerlitz
On Tue, Aug 7, 2018 at 6:36 PM, Simon Horman  wrote:
> From: Pieter Jansen van Vuuren 
>
> Allow matching on options in Geneve tunnel headers.
> This makes use of existing tunnel metadata support.
>
> The options can be described in the form
> CLASS:TYPE:DATA/CLASS_MASK:TYPE_MASK:DATA_MASK, where CLASS is
> represented as a 16bit hexadecimal value, TYPE as an 8bit
> hexadecimal value and DATA as a variable length hexadecimal value.
>
> e.g.
>  # ip link add name geneve0 type geneve dstport 0 external
>  # tc qdisc add dev geneve0 ingress
>  # tc filter add dev geneve0 protocol ip parent : \
>  flower \
>enc_src_ip 10.0.99.192 \
>enc_dst_ip 10.0.99.193 \
>enc_key_id 11 \
>geneve_opts 0102:80:1122334421314151/:ff: \
>ip_proto udp \
>action mirred egress redirect dev eth1
>
> This patch adds support for matching Geneve options in the order
> supplied by the user. This leads to an efficient implementation in
> the software datapath (and in our opinion hardware datapaths that
> offload this feature). It is also compatible with Geneve options
> matching provided by the Open vSwitch kernel datapath which is
> relevant here as the Flower classifier may be used as a mechanism
> to program flows into hardware as a form of Open vSwitch datapath
> offload (sometimes referred to as OVS-TC). The netlink
> Kernel/Userspace API may be extended, for example by adding a flag,
> if other matching options are desired, for example matching given
> options in any order. This would require an implementation in the
> TC software datapath. And be done in a way that drivers that
> facilitate offload of the Flower classifier can reject or accept
> such flows based on hardware datapath capabilities.
>
> This approach was discussed and agreed on at Netconf 2018 in Seoul.

2017, please fix

2018 was in Montreal


[PATCH net-next 4/6] net/sched: allow flower to match tunnel options

2018-08-07 Thread Simon Horman
From: Pieter Jansen van Vuuren 

Allow matching on options in Geneve tunnel headers.
This makes use of existing tunnel metadata support.

The options can be described in the form
CLASS:TYPE:DATA/CLASS_MASK:TYPE_MASK:DATA_MASK, where CLASS is
represented as a 16bit hexadecimal value, TYPE as an 8bit
hexadecimal value and DATA as a variable length hexadecimal value.

e.g.
 # ip link add name geneve0 type geneve dstport 0 external
 # tc qdisc add dev geneve0 ingress
 # tc filter add dev geneve0 protocol ip parent : \
 flower \
   enc_src_ip 10.0.99.192 \
   enc_dst_ip 10.0.99.193 \
   enc_key_id 11 \
   geneve_opts 0102:80:1122334421314151/:ff: \
   ip_proto udp \
   action mirred egress redirect dev eth1

This patch adds support for matching Geneve options in the order
supplied by the user. This leads to an efficient implementation in
the software datapath (and in our opinion hardware datapaths that
offload this feature). It is also compatible with Geneve options
matching provided by the Open vSwitch kernel datapath which is
relevant here as the Flower classifier may be used as a mechanism
to program flows into hardware as a form of Open vSwitch datapath
offload (sometimes referred to as OVS-TC). The netlink
Kernel/Userspace API may be extended, for example by adding a flag,
if other matching options are desired, for example matching given
options in any order. This would require an implementation in the
TC software datapath. And be done in a way that drivers that
facilitate offload of the Flower classifier can reject or accept
such flows based on hardware datapath capabilities.

This approach was discussed and agreed on at Netconf 2018 in Seoul.

Signed-off-by: Simon Horman 
Signed-off-by: Pieter Jansen van Vuuren 
Acked-by: Jakub Kicinski 
---
 include/uapi/linux/pkt_cls.h |  26 +
 net/sched/cls_flower.c   | 244 ++-
 2 files changed, 269 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index 48e5b5d49a34..be382fb0592d 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -480,12 +480,38 @@ enum {
TCA_FLOWER_KEY_ENC_IP_TTL,  /* u8 */
TCA_FLOWER_KEY_ENC_IP_TTL_MASK, /* u8 */
 
+   TCA_FLOWER_KEY_ENC_OPTS,
+   TCA_FLOWER_KEY_ENC_OPTS_MASK,
+
__TCA_FLOWER_MAX,
 };
 
 #define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
 
 enum {
+   TCA_FLOWER_KEY_ENC_OPTS_UNSPEC,
+   TCA_FLOWER_KEY_ENC_OPTS_GENEVE, /* Nested
+* TCA_FLOWER_KEY_ENC_OPT_GENEVE_
+* attributes
+*/
+   __TCA_FLOWER_KEY_ENC_OPTS_MAX,
+};
+
+#define TCA_FLOWER_KEY_ENC_OPTS_MAX (__TCA_FLOWER_KEY_ENC_OPTS_MAX - 1)
+
+enum {
+   TCA_FLOWER_KEY_ENC_OPT_GENEVE_UNSPEC,
+   TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS,/* u16 */
+   TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE, /* u8 */
+   TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA, /* 4 to 128 bytes */
+
+   __TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX,
+};
+
+#define TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX \
+   (__TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX - 1)
+
+enum {
TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0),
TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1),
 };
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index a3b69bb6f4b0..9da244235170 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -53,6 +54,7 @@ struct fl_flow_key {
struct flow_dissector_key_tcp tcp;
struct flow_dissector_key_ip ip;
struct flow_dissector_key_ip enc_ip;
+   struct flow_dissector_key_enc_opts enc_opts;
 } __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. 
*/
 
 struct fl_flow_mask_range {
@@ -482,6 +484,21 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 
1] = {
[TCA_FLOWER_KEY_ENC_IP_TOS_MASK] = { .type = NLA_U8 },
[TCA_FLOWER_KEY_ENC_IP_TTL]  = { .type = NLA_U8 },
[TCA_FLOWER_KEY_ENC_IP_TTL_MASK] = { .type = NLA_U8 },
+   [TCA_FLOWER_KEY_ENC_OPTS]   = { .type = NLA_NESTED },
+   [TCA_FLOWER_KEY_ENC_OPTS_MASK]  = { .type = NLA_NESTED },
+};
+
+static const struct nla_policy
+enc_opts_policy[TCA_FLOWER_KEY_ENC_OPTS_MAX + 1] = {
+   [TCA_FLOWER_KEY_ENC_OPTS_GENEVE]= { .type = NLA_NESTED },
+};
+
+static const struct nla_policy
+geneve_opt_policy[TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX + 1] = {
+   [TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS]  = { .type = NLA_U16 },
+   [TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE]   = { .type = NLA_U8 },
+   [TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA]   = { .type = NLA_BINARY,
+  .len = 128 },
 };
 
 static void fl_set_key_val(struct nlattr **tb,
@@