* [PATCH iproute2-next] tc: m_tunnel_key: Add tunnel option support to act_tunnel_key
@ 2018-07-06 0:12 Jakub Kicinski
2018-07-06 13:32 ` Roman Mashak
2018-07-06 16:12 ` David Ahern
0 siblings, 2 replies; 4+ messages in thread
From: Jakub Kicinski @ 2018-07-06 0:12 UTC (permalink / raw)
To: dsahern
Cc: stephen, oss-drivers, netdev, Simon Horman, Pieter Jansen van Vuuren
From: Simon Horman <simon.horman@netronome.com>
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 ffff: \
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 <simon.horman@netronome.com>
Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
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 <IP> (mandatory)\n"
"dst_ip <IP> (mandatory)\n"
"dst_port <UDP_PORT>\n"
+ "geneve_opts <OPTIONS>\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(&value, 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(&value, 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, ":", &saveptr);
+ 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, ":", &saveptr);
+ 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, ",", &saveptr);
+ while (token) {
+ ret = tunnel_key_parse_geneve_opt(token, n);
+ if (ret)
+ return ret;
+
+ token = strtok_r(NULL, ",", &saveptr);
+ }
+
+ addattr_nest_end(n, nest);
+
+ return 0;
+}
+
static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p,
int tca_id, struct nlmsghdr *n)
{
@@ -157,6 +266,13 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p,
fprintf(stderr, "Illegal \"dst port\"\n");
return -1;
}
+ } else if (matches(*argv, "geneve_opts") == 0) {
+ NEXT_ARG();
+
+ if (tunnel_key_parse_geneve_opts(*argv, n)) {
+ fprintf(stderr, "Illegal \"geneve_opts\"\n");
+ return -1;
+ }
} else if (matches(*argv, "csum") == 0) {
csum = 1;
} else if (matches(*argv, "nocsum") == 0) {
@@ -260,6 +376,65 @@ static void tunnel_key_print_flag(FILE *f, const char *name_on,
rta_getattr_u8(attr) ? name_on : name_off);
}
+static void tunnel_key_print_geneve_options(const char *name,
+ struct rtattr *attr)
+{
+ struct rtattr *tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX + 1];
+ struct rtattr *i = RTA_DATA(attr);
+ int ii, data_len = 0, offset = 0;
+ int rem = RTA_PAYLOAD(attr);
+ char strbuf[rem * 2 + 1];
+ char data[rem * 2 + 1];
+ uint8_t data_r[rem];
+ uint16_t clss;
+ uint8_t type;
+
+ open_json_array(PRINT_JSON, name);
+ print_string(PRINT_FP, name, "\n\t%s ", "geneve_opt");
+
+ while (rem) {
+ parse_rtattr(tb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX, i, rem);
+ clss = rta_getattr_be16(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS]);
+ type = rta_getattr_u8(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE]);
+ data_len = RTA_PAYLOAD(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]);
+ hexstring_n2a(RTA_DATA(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]),
+ data_len, data, sizeof(data));
+ hex2mem(data, data_r, data_len);
+ offset += data_len + 20;
+ rem -= data_len + 20;
+ i = RTA_DATA(attr) + offset;
+
+ open_json_object(NULL);
+ print_uint(PRINT_JSON, "class", NULL, clss);
+ print_uint(PRINT_JSON, "type", NULL, type);
+ open_json_array(PRINT_JSON, "data");
+ for (ii = 0; ii < data_len; ii++)
+ print_uint(PRINT_JSON, NULL, NULL, data_r[ii]);
+ close_json_array(PRINT_JSON, "data");
+ close_json_object();
+
+ sprintf(strbuf, "%04x:%02x:%s", clss, type, data);
+ if (rem)
+ print_string(PRINT_FP, NULL, "%s,", strbuf);
+ else
+ print_string(PRINT_FP, NULL, "%s", strbuf);
+ }
+
+ close_json_array(PRINT_JSON, name);
+}
+
+static void tunnel_key_print_key_opt(const char *name, struct rtattr *attr)
+{
+ struct rtattr *tb[TCA_TUNNEL_KEY_ENC_OPTS_MAX + 1];
+
+ if (!attr)
+ return;
+
+ parse_rtattr_nested(tb, TCA_TUNNEL_KEY_ENC_OPTS_MAX, attr);
+ tunnel_key_print_geneve_options(name,
+ tb[TCA_TUNNEL_KEY_ENC_OPTS_GENEVE]);
+}
+
static int print_tunnel_key(struct action_util *au, FILE *f, struct rtattr *arg)
{
struct rtattr *tb[TCA_TUNNEL_KEY_MAX + 1];
@@ -297,6 +472,8 @@ static int print_tunnel_key(struct action_util *au, FILE *f, struct rtattr *arg)
tb[TCA_TUNNEL_KEY_ENC_KEY_ID]);
tunnel_key_print_dst_port(f, "dst_port",
tb[TCA_TUNNEL_KEY_ENC_DST_PORT]);
+ tunnel_key_print_key_opt("geneve_opts",
+ tb[TCA_TUNNEL_KEY_ENC_OPTS]);
tunnel_key_print_flag(f, "nocsum", "csum",
tb[TCA_TUNNEL_KEY_NO_CSUM]);
break;
--
2.17.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH iproute2-next] tc: m_tunnel_key: Add tunnel option support to act_tunnel_key
2018-07-06 0:12 [PATCH iproute2-next] tc: m_tunnel_key: Add tunnel option support to act_tunnel_key Jakub Kicinski
@ 2018-07-06 13:32 ` Roman Mashak
2018-07-06 15:19 ` Jakub Kicinski
2018-07-06 16:12 ` David Ahern
1 sibling, 1 reply; 4+ messages in thread
From: Roman Mashak @ 2018-07-06 13:32 UTC (permalink / raw)
To: Jakub Kicinski
Cc: dsahern, stephen, oss-drivers, netdev, Simon Horman,
Pieter Jansen van Vuuren
Jakub Kicinski <jakub.kicinski@netronome.com> writes:
> From: Simon Horman <simon.horman@netronome.com>
>
> 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 ffff: \
> 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?
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH iproute2-next] tc: m_tunnel_key: Add tunnel option support to act_tunnel_key
2018-07-06 13:32 ` Roman Mashak
@ 2018-07-06 15:19 ` Jakub Kicinski
0 siblings, 0 replies; 4+ messages in thread
From: Jakub Kicinski @ 2018-07-06 15:19 UTC (permalink / raw)
To: Roman Mashak
Cc: David Ahern, stephen, oss-drivers, Linux Netdev List,
Simon Horman, Pieter Jansen van Vuuren
On Fri, Jul 6, 2018 at 6:32 AM, Roman Mashak <mrv@mojatatu.com> wrote:
> Jakub Kicinski <jakub.kicinski@netronome.com> writes:
>
>> From: Simon Horman <simon.horman@netronome.com>
>>
>> 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 ffff: \
>> 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!
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH iproute2-next] tc: m_tunnel_key: Add tunnel option support to act_tunnel_key
2018-07-06 0:12 [PATCH iproute2-next] tc: m_tunnel_key: Add tunnel option support to act_tunnel_key Jakub Kicinski
2018-07-06 13:32 ` Roman Mashak
@ 2018-07-06 16:12 ` David Ahern
1 sibling, 0 replies; 4+ messages in thread
From: David Ahern @ 2018-07-06 16:12 UTC (permalink / raw)
To: Jakub Kicinski
Cc: stephen, oss-drivers, netdev, Simon Horman, Pieter Jansen van Vuuren
On 7/5/18 6:12 PM, Jakub Kicinski wrote:
> From: Simon Horman <simon.horman@netronome.com>
>
> 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 ffff: \
> 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 <simon.horman@netronome.com>
> Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
> Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> ---
> 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
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2018-07-06 16:11 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-06 0:12 [PATCH iproute2-next] tc: m_tunnel_key: Add tunnel option support to act_tunnel_key Jakub Kicinski
2018-07-06 13:32 ` Roman Mashak
2018-07-06 15:19 ` Jakub Kicinski
2018-07-06 16:12 ` David Ahern
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.