Re: [PATCH iproute2-next] tc: m_tunnel_key: Add tunnel option support to act_tunnel_key

2018-07-06 Thread David Ahern
On 7/5/18 6:12 PM, Jakub Kicinski wrote:
> From: Simon Horman 
> 
> Allow setting tunnel options using the act_tunnel_key action.
> 
> Options are expressed as class:type:data and multiple options
> may be listed using a comma delimiter.
> 
>  # ip link add name geneve0 type geneve dstport 0 external
>  # tc qdisc add dev eth0 ingress
>  # tc filter add dev eth0 protocol ip parent : \
>  flower indev eth0 \
> ip_proto udp \
> action tunnel_key \
> set src_ip 10.0.99.192 \
> dst_ip 10.0.99.193 \
> dst_port 6081 \
> id 11 \
> geneve_opts 0102:80:00800022,0102:80:00800022 \
> action mirred egress redirect dev geneve0
> 
> Signed-off-by: Simon Horman 
> Signed-off-by: Pieter Jansen van Vuuren 
> Reviewed-by: Jakub Kicinski 
> ---
>  man/man8/tc-tunnel_key.8 |  12 ++-
>  tc/m_tunnel_key.c| 177 +++
>  2 files changed, 188 insertions(+), 1 deletion(-)
> 

applied to iproute2-next. Thanks




Re: [PATCH iproute2-next] tc: m_tunnel_key: Add tunnel option support to act_tunnel_key

2018-07-06 Thread Jakub Kicinski
On Fri, Jul 6, 2018 at 6:32 AM, Roman Mashak  wrote:
> Jakub Kicinski  writes:
>
>> From: Simon Horman 
>>
>> Allow setting tunnel options using the act_tunnel_key action.
>>
>> Options are expressed as class:type:data and multiple options
>> may be listed using a comma delimiter.
>>
>>  # ip link add name geneve0 type geneve dstport 0 external
>>  # tc qdisc add dev eth0 ingress
>>  # tc filter add dev eth0 protocol ip parent : \
>>  flower indev eth0 \
>> ip_proto udp \
>> action tunnel_key \
>> set src_ip 10.0.99.192 \
>> dst_ip 10.0.99.193 \
>> dst_port 6081 \
>> id 11 \
>> geneve_opts 0102:80:00800022,0102:80:00800022 \
>> action mirred egress redirect dev geneve0
>
> [...]
>
> Jakub, could you also add relevant tests for the new option in file
> $(kernel)/tools/testing/selftests/tc-testing/tc-tests/actions/tunnel_key.json?

We'll look into it!


Re: [PATCH iproute2-next] tc: m_tunnel_key: Add tunnel option support to act_tunnel_key

2018-07-06 Thread Roman Mashak
Jakub Kicinski  writes:

> From: Simon Horman 
>
> Allow setting tunnel options using the act_tunnel_key action.
>
> Options are expressed as class:type:data and multiple options
> may be listed using a comma delimiter.
>
>  # ip link add name geneve0 type geneve dstport 0 external
>  # tc qdisc add dev eth0 ingress
>  # tc filter add dev eth0 protocol ip parent : \
>  flower indev eth0 \
> ip_proto udp \
> action tunnel_key \
> set src_ip 10.0.99.192 \
> dst_ip 10.0.99.193 \
> dst_port 6081 \
> id 11 \
> geneve_opts 0102:80:00800022,0102:80:00800022 \
> action mirred egress redirect dev geneve0

[...]

Jakub, could you also add relevant tests for the new option in file
$(kernel)/tools/testing/selftests/tc-testing/tc-tests/actions/tunnel_key.json?


[PATCH iproute2-next] tc: m_tunnel_key: Add tunnel option support to act_tunnel_key

2018-07-05 Thread Jakub Kicinski
From: Simon Horman 

Allow setting tunnel options using the act_tunnel_key action.

Options are expressed as class:type:data and multiple options
may be listed using a comma delimiter.

 # ip link add name geneve0 type geneve dstport 0 external
 # tc qdisc add dev eth0 ingress
 # tc filter add dev eth0 protocol ip parent : \
 flower indev eth0 \
ip_proto udp \
action tunnel_key \
set src_ip 10.0.99.192 \
dst_ip 10.0.99.193 \
dst_port 6081 \
id 11 \
geneve_opts 0102:80:00800022,0102:80:00800022 \
action mirred egress redirect dev geneve0

Signed-off-by: Simon Horman 
Signed-off-by: Pieter Jansen van Vuuren 
Reviewed-by: Jakub Kicinski 
---
 man/man8/tc-tunnel_key.8 |  12 ++-
 tc/m_tunnel_key.c| 177 +++
 2 files changed, 188 insertions(+), 1 deletion(-)

diff --git a/man/man8/tc-tunnel_key.8 b/man/man8/tc-tunnel_key.8
index e979a74715cb..7d4b30e41faf 100644
--- a/man/man8/tc-tunnel_key.8
+++ b/man/man8/tc-tunnel_key.8
@@ -64,7 +64,9 @@ and
 .B dst_ip
 options.
 .B dst_port
-is optional.
+and
+.B geneve_opts
+are optional.
 .RS
 .TP
 .B id
@@ -79,6 +81,14 @@ Outer header destination IP address (IPv4 or IPv6)
 .B dst_port
 Outer header destination UDP port
 .TP
+.B geneve_opts
+Geneve variable length options.
+.B geneve_opts
+is specified in the form CLASS:TYPE:DATA, where CLASS is represented as a
+16bit hexadecimal value, TYPE as an 8bit hexadecimal value and DATA as a
+variable length hexadecimal value. Additionally multiple options may be
+listed using a comma delimiter.
+.TP
 .RB [ no ] csum
 Controlls outer UDP checksum. When set to
 .B csum
diff --git a/tc/m_tunnel_key.c b/tc/m_tunnel_key.c
index 0fa461549ad9..5a0e3fc3c48f 100644
--- a/tc/m_tunnel_key.c
+++ b/tc/m_tunnel_key.c
@@ -29,6 +29,7 @@ static void explain(void)
"src_ip  (mandatory)\n"
"dst_ip  (mandatory)\n"
"dst_port \n"
+   "geneve_opts \n"
"csum | nocsum (default is \"csum\")\n");
 }
 
@@ -81,6 +82,114 @@ static int tunnel_key_parse_dst_port(char *str, int type, 
struct nlmsghdr *n)
return 0;
 }
 
+static int tunnel_key_parse_be16(char *str, int base, int type,
+struct nlmsghdr *n)
+{
+   int ret;
+   __be16 value;
+
+   ret = get_be16(, str, base);
+   if (ret)
+   return ret;
+
+   addattr16(n, MAX_MSG, type, value);
+
+   return 0;
+}
+
+static int tunnel_key_parse_u8(char *str, int base, int type,
+  struct nlmsghdr *n)
+{
+   int ret;
+   __u8 value;
+
+   ret = get_u8(, str, base);
+   if (ret)
+   return ret;
+
+   addattr8(n, MAX_MSG, type, value);
+
+   return 0;
+}
+
+static int tunnel_key_parse_geneve_opt(char *str, struct nlmsghdr *n)
+{
+   char *token, *saveptr = NULL;
+   struct rtattr *nest;
+   int i, ret;
+
+   nest = addattr_nest(n, MAX_MSG, TCA_TUNNEL_KEY_ENC_OPTS_GENEVE);
+
+   token = strtok_r(str, ":", );
+   i = 1;
+   while (token) {
+   switch (i) {
+   case TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS:
+   {
+   ret = tunnel_key_parse_be16(token, 16, i, n);
+   if (ret)
+   return ret;
+   break;
+   }
+   case TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE:
+   {
+   ret = tunnel_key_parse_u8(token, 16, i, n);
+   if (ret)
+   return ret;
+   break;
+   }
+   case TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA:
+   {
+   size_t token_len = strlen(token);
+   uint8_t *opts;
+
+   opts = malloc(token_len / 2);
+   if (!opts)
+   return -1;
+   if (hex2mem(token, opts, token_len / 2) < 0) {
+   free(opts);
+   return -1;
+   }
+   addattr_l(n, MAX_MSG, i, opts, token_len / 2);
+   free(opts);
+
+   break;
+   }
+   default:
+   return -1;
+   }
+
+   token = strtok_r(NULL, ":", );
+   i++;
+   }
+
+   addattr_nest_end(n, nest);
+
+   return 0;
+}
+
+static int tunnel_key_parse_geneve_opts(char *str, struct nlmsghdr *n)
+{
+   char *token, *saveptr = NULL;
+   struct rtattr *nest;
+   int ret;
+
+   nest = addattr_nest(n, MAX_MSG, TCA_TUNNEL_KEY_ENC_OPTS);
+
+   token = strtok_r(str, ",", );
+   while (token) {
+   ret = tunnel_key_parse_geneve_opt(token, n);
+   if (ret)
+   return