* [PATCH net-next 0/4] net: Geneve options support for TC act_tunnel_key
@ 2018-06-26 18:53 Jakub Kicinski
2018-06-26 18:53 ` [PATCH net-next 1/4] net/sched: act_tunnel_key: disambiguate metadata dst error cases Jakub Kicinski
` (4 more replies)
0 siblings, 5 replies; 9+ messages in thread
From: Jakub Kicinski @ 2018-06-26 18:53 UTC (permalink / raw)
To: davem, jbenc
Cc: Roopa Prabhu, jiri, jhs, xiyou.wangcong, daniel, oss-drivers,
netdev, Jakub Kicinski
Hi,
Simon & Pieter say:
This set adds Geneve Options support to the TC tunnel key action.
It provides the plumbing required to configure Geneve variable length
options. The options can be configured 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.
Pieter Jansen van Vuuren (1):
net: check tunnel option type in tunnel flags
Simon Horman (3):
net/sched: act_tunnel_key: disambiguate metadata dst error cases
net/sched: act_tunnel_key: add extended ack support
net/sched: add tunnel option support to act_tunnel_key
drivers/net/geneve.c | 6 +-
drivers/net/vxlan.c | 3 +-
include/net/ip_tunnels.h | 8 +-
include/uapi/linux/tc_act/tc_tunnel_key.h | 26 +++
net/core/filter.c | 2 +-
net/ipv4/ip_gre.c | 2 +
net/ipv6/ip6_gre.c | 2 +
net/openvswitch/flow_netlink.c | 8 +-
net/sched/act_tunnel_key.c | 242 +++++++++++++++++++++-
9 files changed, 280 insertions(+), 19 deletions(-)
--
2.17.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH net-next 1/4] net/sched: act_tunnel_key: disambiguate metadata dst error cases
2018-06-26 18:53 [PATCH net-next 0/4] net: Geneve options support for TC act_tunnel_key Jakub Kicinski
@ 2018-06-26 18:53 ` Jakub Kicinski
2018-06-26 18:53 ` [PATCH net-next 2/4] net/sched: act_tunnel_key: add extended ack support Jakub Kicinski
` (3 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Jakub Kicinski @ 2018-06-26 18:53 UTC (permalink / raw)
To: davem, jbenc
Cc: Roopa Prabhu, jiri, jhs, xiyou.wangcong, daniel, oss-drivers,
netdev, Simon Horman, David Ahern, Alexander Aring
From: Simon Horman <simon.horman@netronome.com>
Metadata may be NULL for one of two reasons:
* Missing user input
* Failure to allocate the metadata dst
Disambiguate these case by returning -EINVAL for the former and -ENOMEM
for the latter rather than -EINVAL for both cases.
This is in preparation for using extended ack to provide more information
to users when parsing their input.
Cc: David Ahern <dsa@cumulusnetworks.com>
Cc: Alexander Aring <aring@mojatatu.com>
Signed-off-by: Simon Horman <simon.horman@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
net/sched/act_tunnel_key.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
index 626dac81a48a..2edd389e7c92 100644
--- a/net/sched/act_tunnel_key.c
+++ b/net/sched/act_tunnel_key.c
@@ -143,10 +143,13 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
metadata = __ipv6_tun_set_dst(&saddr, &daddr, 0, 0, dst_port,
0, flags,
key_id, 0);
+ } else {
+ ret = -EINVAL;
+ goto err_out;
}
if (!metadata) {
- ret = -EINVAL;
+ ret = -ENOMEM;
goto err_out;
}
--
2.17.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH net-next 2/4] net/sched: act_tunnel_key: add extended ack support
2018-06-26 18:53 [PATCH net-next 0/4] net: Geneve options support for TC act_tunnel_key Jakub Kicinski
2018-06-26 18:53 ` [PATCH net-next 1/4] net/sched: act_tunnel_key: disambiguate metadata dst error cases Jakub Kicinski
@ 2018-06-26 18:53 ` Jakub Kicinski
2018-06-26 19:50 ` David Ahern
2018-06-26 18:53 ` [PATCH net-next 3/4] net: check tunnel option type in tunnel flags Jakub Kicinski
` (2 subsequent siblings)
4 siblings, 1 reply; 9+ messages in thread
From: Jakub Kicinski @ 2018-06-26 18:53 UTC (permalink / raw)
To: davem, jbenc
Cc: Roopa Prabhu, jiri, jhs, xiyou.wangcong, daniel, oss-drivers,
netdev, Simon Horman, David Ahern, Alexander Aring,
Pieter Jansen van Vuuren
From: Simon Horman <simon.horman@netronome.com>
Add extended ack support for the tunnel key action by using NL_SET_ERR_MSG
during validation of user input.
Cc: David Ahern <dsahern@gmail.com>
Cc: Alexander Aring <aring@mojatatu.com>
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>
---
net/sched/act_tunnel_key.c | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)
diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
index 2edd389e7c92..20e98ed8d498 100644
--- a/net/sched/act_tunnel_key.c
+++ b/net/sched/act_tunnel_key.c
@@ -86,16 +86,22 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
int ret = 0;
int err;
- if (!nla)
+ if (!nla) {
+ NL_SET_ERR_MSG(extack, "Tunnel requires attributes to be passed");
return -EINVAL;
+ }
err = nla_parse_nested(tb, TCA_TUNNEL_KEY_MAX, nla, tunnel_key_policy,
- NULL);
- if (err < 0)
+ extack);
+ if (err < 0) {
+ NL_SET_ERR_MSG(extack, "Failed to parse nested tunnel key attributes");
return err;
+ }
- if (!tb[TCA_TUNNEL_KEY_PARMS])
+ if (!tb[TCA_TUNNEL_KEY_PARMS]) {
+ NL_SET_ERR_MSG(extack, "Missing tunnel key parameters");
return -EINVAL;
+ }
parm = nla_data(tb[TCA_TUNNEL_KEY_PARMS]);
exists = tcf_idr_check(tn, parm->index, a, bind);
@@ -107,6 +113,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
break;
case TCA_TUNNEL_KEY_ACT_SET:
if (!tb[TCA_TUNNEL_KEY_ENC_KEY_ID]) {
+ NL_SET_ERR_MSG(extack, "Missing tunnel key id");
ret = -EINVAL;
goto err_out;
}
@@ -144,11 +151,13 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
0, flags,
key_id, 0);
} else {
+ NL_SET_ERR_MSG(extack, "Missing either ipv4 or ipv6 src and dst");
ret = -EINVAL;
goto err_out;
}
if (!metadata) {
+ NL_SET_ERR_MSG(extack, "Cannot allocate tunnel metadata dst");
ret = -ENOMEM;
goto err_out;
}
@@ -156,6 +165,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
metadata->u.tun_info.mode |= IP_TUNNEL_INFO_TX;
break;
default:
+ NL_SET_ERR_MSG(extack, "Unknown tunnel key action");
ret = -EINVAL;
goto err_out;
}
@@ -163,14 +173,18 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
if (!exists) {
ret = tcf_idr_create(tn, parm->index, est, a,
&act_tunnel_key_ops, bind, true);
- if (ret)
+ if (ret) {
+ NL_SET_ERR_MSG(extack, "Cannot create TC IDR");
return ret;
+ }
ret = ACT_P_CREATED;
} else {
tcf_idr_release(*a, bind);
- if (!ovr)
+ if (!ovr) {
+ NL_SET_ERR_MSG(extack, "TC IDR already exists");
return -EEXIST;
+ }
}
t = to_tunnel_key(*a);
@@ -180,6 +194,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
if (unlikely(!params_new)) {
if (ret == ACT_P_CREATED)
tcf_idr_release(*a, bind);
+ NL_SET_ERR_MSG(extack, "Cannot allocate tunnel key parameters");
return -ENOMEM;
}
--
2.17.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH net-next 3/4] net: check tunnel option type in tunnel flags
2018-06-26 18:53 [PATCH net-next 0/4] net: Geneve options support for TC act_tunnel_key Jakub Kicinski
2018-06-26 18:53 ` [PATCH net-next 1/4] net/sched: act_tunnel_key: disambiguate metadata dst error cases Jakub Kicinski
2018-06-26 18:53 ` [PATCH net-next 2/4] net/sched: act_tunnel_key: add extended ack support Jakub Kicinski
@ 2018-06-26 18:53 ` Jakub Kicinski
2018-06-27 3:08 ` kbuild test robot
2018-06-26 18:53 ` [PATCH net-next 4/4] net/sched: add tunnel option support to act_tunnel_key Jakub Kicinski
2018-06-28 7:17 ` [PATCH net-next 0/4] net: Geneve options support for TC act_tunnel_key David Miller
4 siblings, 1 reply; 9+ messages in thread
From: Jakub Kicinski @ 2018-06-26 18:53 UTC (permalink / raw)
To: davem, jbenc
Cc: Roopa Prabhu, jiri, jhs, xiyou.wangcong, daniel, oss-drivers,
netdev, Pieter Jansen van Vuuren, Jakub Kicinski
From: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
Check the tunnel option type stored in tunnel flags when creating options
for tunnels. Thereby ensuring we do not set geneve, vxlan or erspan tunnel
options on interfaces that are not associated with them.
Make sure all users of the infrastructure set correct flags, for the BPF
helper we have to set all bits to keep backward compatibility.
Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
drivers/net/geneve.c | 6 ++++--
drivers/net/vxlan.c | 3 ++-
include/net/ip_tunnels.h | 8 ++++++--
net/core/filter.c | 2 +-
net/ipv4/ip_gre.c | 2 ++
net/ipv6/ip6_gre.c | 2 ++
net/openvswitch/flow_netlink.c | 8 ++++++--
7 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index 3e94375b9b01..471edd76ff55 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -236,7 +236,8 @@ static void geneve_rx(struct geneve_dev *geneve, struct geneve_sock *gs,
}
/* Update tunnel dst according to Geneve options. */
ip_tunnel_info_opts_set(&tun_dst->u.tun_info,
- gnvh->options, gnvh->opt_len * 4);
+ gnvh->options, gnvh->opt_len * 4,
+ TUNNEL_GENEVE_OPT);
} else {
/* Drop packets w/ critical options,
* since we don't support any...
@@ -675,7 +676,8 @@ static void geneve_build_header(struct genevehdr *geneveh,
geneveh->proto_type = htons(ETH_P_TEB);
geneveh->rsvd2 = 0;
- ip_tunnel_info_opts_get(geneveh->options, info);
+ if (info->key.tun_flags & TUNNEL_GENEVE_OPT)
+ ip_tunnel_info_opts_get(geneveh->options, info);
}
static int geneve_build_skb(struct dst_entry *dst, struct sk_buff *skb,
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index cc14e0cd5647..7eb30d7c8bd7 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -2122,7 +2122,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
vni = tunnel_id_to_key32(info->key.tun_id);
ifindex = 0;
dst_cache = &info->dst_cache;
- if (info->options_len)
+ if (info->options_len &&
+ info->key.tun_flags & TUNNEL_VXLAN_OPT)
md = ip_tunnel_info_opts(info);
ttl = info->key.ttl;
tos = info->key.tos;
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 90ff430f5e9d..b0d022ff6ea1 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -466,10 +466,12 @@ static inline void ip_tunnel_info_opts_get(void *to,
}
static inline void ip_tunnel_info_opts_set(struct ip_tunnel_info *info,
- const void *from, int len)
+ const void *from, int len,
+ __be16 flags)
{
memcpy(ip_tunnel_info_opts(info), from, len);
info->options_len = len;
+ info->key.tun_flags |= flags;
}
static inline struct ip_tunnel_info *lwt_tun_info(struct lwtunnel_state *lwtstate)
@@ -511,9 +513,11 @@ static inline void ip_tunnel_info_opts_get(void *to,
}
static inline void ip_tunnel_info_opts_set(struct ip_tunnel_info *info,
- const void *from, int len)
+ const void *from, int len,
+ __be16 flags)
{
info->options_len = 0;
+ info->key.tun_flags |= flags;
}
#endif /* CONFIG_INET */
diff --git a/net/core/filter.c b/net/core/filter.c
index e7f12e9f598c..dade922678f6 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -3582,7 +3582,7 @@ BPF_CALL_3(bpf_skb_set_tunnel_opt, struct sk_buff *, skb,
if (unlikely(size > IP_TUNNEL_OPTS_MAX))
return -ENOMEM;
- ip_tunnel_info_opts_set(info, from, size);
+ ip_tunnel_info_opts_set(info, from, size, TUNNEL_OPTIONS_PRESENT);
return 0;
}
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 2d8efeecf619..c8ca5d8f0f75 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -587,6 +587,8 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev,
goto err_free_skb;
key = &tun_info->key;
+ if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT))
+ goto err_free_rt;
md = ip_tunnel_info_opts(tun_info);
if (!md)
goto err_free_rt;
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index c8cf2fdbb13b..367177786e34 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -990,6 +990,8 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
dsfield = key->tos;
+ if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT))
+ goto tx_err;
md = ip_tunnel_info_opts(tun_info);
if (!md)
goto tx_err;
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index 492ab0c36f7c..26ab964923fd 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -2515,8 +2515,9 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
struct ip_tunnel_info *tun_info;
struct ovs_tunnel_info *ovs_tun;
struct nlattr *a;
- int err = 0, start, opts_type;
+ int err = 0, start, opts_type, dst_opt_type;
+ dst_opt_type = 0;
ovs_match_init(&match, &key, true, NULL);
opts_type = ip_tun_from_nlattr(nla_data(attr), &match, false, log);
if (opts_type < 0)
@@ -2528,10 +2529,13 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
err = validate_geneve_opts(&key);
if (err < 0)
return err;
+ dst_opt_type = TUNNEL_GENEVE_OPT;
break;
case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS:
+ dst_opt_type = TUNNEL_VXLAN_OPT;
break;
case OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS:
+ dst_opt_type = TUNNEL_ERSPAN_OPT;
break;
}
}
@@ -2574,7 +2578,7 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
*/
ip_tunnel_info_opts_set(tun_info,
TUN_METADATA_OPTS(&key, key.tun_opts_len),
- key.tun_opts_len);
+ key.tun_opts_len, dst_opt_type);
add_nested_action_end(*sfa, start);
return err;
--
2.17.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH net-next 4/4] net/sched: add tunnel option support to act_tunnel_key
2018-06-26 18:53 [PATCH net-next 0/4] net: Geneve options support for TC act_tunnel_key Jakub Kicinski
` (2 preceding siblings ...)
2018-06-26 18:53 ` [PATCH net-next 3/4] net: check tunnel option type in tunnel flags Jakub Kicinski
@ 2018-06-26 18:53 ` Jakub Kicinski
2018-06-28 7:17 ` [PATCH net-next 0/4] net: Geneve options support for TC act_tunnel_key David Miller
4 siblings, 0 replies; 9+ messages in thread
From: Jakub Kicinski @ 2018-06-26 18:53 UTC (permalink / raw)
To: davem, jbenc
Cc: Roopa Prabhu, jiri, jhs, xiyou.wangcong, daniel, 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>
---
include/uapi/linux/tc_act/tc_tunnel_key.h | 26 +++
net/sched/act_tunnel_key.c | 214 +++++++++++++++++++++-
2 files changed, 236 insertions(+), 4 deletions(-)
diff --git a/include/uapi/linux/tc_act/tc_tunnel_key.h b/include/uapi/linux/tc_act/tc_tunnel_key.h
index 72bbefe5d1d1..1b7bdd841b98 100644
--- a/include/uapi/linux/tc_act/tc_tunnel_key.h
+++ b/include/uapi/linux/tc_act/tc_tunnel_key.h
@@ -36,9 +36,35 @@ enum {
TCA_TUNNEL_KEY_PAD,
TCA_TUNNEL_KEY_ENC_DST_PORT, /* be16 */
TCA_TUNNEL_KEY_NO_CSUM, /* u8 */
+ TCA_TUNNEL_KEY_ENC_OPTS, /* Nested TCA_TUNNEL_KEY_ENC_OPTS_
+ * attributes
+ */
__TCA_TUNNEL_KEY_MAX,
};
#define TCA_TUNNEL_KEY_MAX (__TCA_TUNNEL_KEY_MAX - 1)
+enum {
+ TCA_TUNNEL_KEY_ENC_OPTS_UNSPEC,
+ TCA_TUNNEL_KEY_ENC_OPTS_GENEVE, /* Nested
+ * TCA_TUNNEL_KEY_ENC_OPTS_
+ * attributes
+ */
+ __TCA_TUNNEL_KEY_ENC_OPTS_MAX,
+};
+
+#define TCA_TUNNEL_KEY_ENC_OPTS_MAX (__TCA_TUNNEL_KEY_ENC_OPTS_MAX - 1)
+
+enum {
+ TCA_TUNNEL_KEY_ENC_OPT_GENEVE_UNSPEC,
+ TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS, /* u16 */
+ TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE, /* u8 */
+ TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA, /* 4 to 128 bytes */
+
+ __TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX,
+};
+
+#define TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX \
+ (__TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX - 1)
+
#endif
diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
index 20e98ed8d498..5eace86ea687 100644
--- a/net/sched/act_tunnel_key.c
+++ b/net/sched/act_tunnel_key.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/rtnetlink.h>
+#include <net/geneve.h>
#include <net/netlink.h>
#include <net/pkt_sched.h>
#include <net/dst.h>
@@ -57,6 +58,135 @@ static int tunnel_key_act(struct sk_buff *skb, const struct tc_action *a,
return action;
}
+static const struct nla_policy
+enc_opts_policy[TCA_TUNNEL_KEY_ENC_OPTS_MAX + 1] = {
+ [TCA_TUNNEL_KEY_ENC_OPTS_GENEVE] = { .type = NLA_NESTED },
+};
+
+static const struct nla_policy
+geneve_opt_policy[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX + 1] = {
+ [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS] = { .type = NLA_U16 },
+ [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE] = { .type = NLA_U8 },
+ [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA] = { .type = NLA_BINARY,
+ .len = 128 },
+};
+
+static int
+tunnel_key_copy_geneve_opt(const struct nlattr *nla, void *dst, int dst_len,
+ struct netlink_ext_ack *extack)
+{
+ struct nlattr *tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX + 1];
+ int err, data_len, opt_len;
+ u8 *data;
+
+ err = nla_parse_nested(tb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX,
+ nla, geneve_opt_policy, extack);
+ if (err < 0)
+ return err;
+
+ if (!tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS] ||
+ !tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE] ||
+ !tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]) {
+ NL_SET_ERR_MSG(extack, "Missing tunnel key geneve option class, type or data");
+ return -EINVAL;
+ }
+
+ data = nla_data(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]);
+ data_len = nla_len(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]);
+ if (data_len < 4) {
+ NL_SET_ERR_MSG(extack, "Tunnel key geneve option data is less than 4 bytes long");
+ return -ERANGE;
+ }
+ if (data_len % 4) {
+ NL_SET_ERR_MSG(extack, "Tunnel key geneve option data is not a multiple of 4 bytes long");
+ return -ERANGE;
+ }
+
+ opt_len = sizeof(struct geneve_opt) + data_len;
+ if (dst) {
+ struct geneve_opt *opt = dst;
+
+ WARN_ON(dst_len < opt_len);
+
+ opt->opt_class =
+ nla_get_u16(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS]);
+ opt->type = nla_get_u8(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE]);
+ opt->length = data_len / 4; /* length is in units of 4 bytes */
+ opt->r1 = 0;
+ opt->r2 = 0;
+ opt->r3 = 0;
+
+ memcpy(opt + 1, data, data_len);
+ }
+
+ return opt_len;
+}
+
+static int tunnel_key_copy_opts(const struct nlattr *nla, u8 *dst,
+ int dst_len, struct netlink_ext_ack *extack)
+{
+ int err, rem, opt_len, len = nla_len(nla), opts_len = 0;
+ const struct nlattr *attr, *head = nla_data(nla);
+
+ err = nla_validate(head, len, TCA_TUNNEL_KEY_ENC_OPTS_MAX,
+ enc_opts_policy, extack);
+ if (err)
+ return err;
+
+ nla_for_each_attr(attr, head, len, rem) {
+ switch (nla_type(attr)) {
+ case TCA_TUNNEL_KEY_ENC_OPTS_GENEVE:
+ opt_len = tunnel_key_copy_geneve_opt(attr, dst,
+ dst_len, extack);
+ if (opt_len < 0)
+ return opt_len;
+ opts_len += opt_len;
+ if (dst) {
+ dst_len -= opt_len;
+ dst += opt_len;
+ }
+ break;
+ }
+ }
+
+ if (!opts_len) {
+ NL_SET_ERR_MSG(extack, "Empty list of tunnel options");
+ return -EINVAL;
+ }
+
+ if (rem > 0) {
+ NL_SET_ERR_MSG(extack, "Trailing data after parsing tunnel key options attributes");
+ return -EINVAL;
+ }
+
+ return opts_len;
+}
+
+static int tunnel_key_get_opts_len(struct nlattr *nla,
+ struct netlink_ext_ack *extack)
+{
+ return tunnel_key_copy_opts(nla, NULL, 0, extack);
+}
+
+static int tunnel_key_opts_set(struct nlattr *nla, struct ip_tunnel_info *info,
+ int opts_len, struct netlink_ext_ack *extack)
+{
+ info->options_len = opts_len;
+ switch (nla_type(nla_data(nla))) {
+ case TCA_TUNNEL_KEY_ENC_OPTS_GENEVE:
+#if IS_ENABLED(CONFIG_INET)
+ info->key.tun_flags |= TUNNEL_GENEVE_OPT;
+ return tunnel_key_copy_opts(nla, ip_tunnel_info_opts(info),
+ opts_len, extack);
+#else
+ return -EAFNOSUPPORT;
+#endif
+ default:
+ NL_SET_ERR_MSG(extack, "Cannot set tunnel options for unknown tunnel type");
+ return -EINVAL;
+ }
+}
+
static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
[TCA_TUNNEL_KEY_PARMS] = { .len = sizeof(struct tc_tunnel_key) },
[TCA_TUNNEL_KEY_ENC_IPV4_SRC] = { .type = NLA_U32 },
@@ -66,6 +196,7 @@ static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
[TCA_TUNNEL_KEY_ENC_KEY_ID] = { .type = NLA_U32 },
[TCA_TUNNEL_KEY_ENC_DST_PORT] = {.type = NLA_U16},
[TCA_TUNNEL_KEY_NO_CSUM] = { .type = NLA_U8 },
+ [TCA_TUNNEL_KEY_ENC_OPTS] = { .type = NLA_NESTED },
};
static int tunnel_key_init(struct net *net, struct nlattr *nla,
@@ -81,6 +212,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
struct tcf_tunnel_key *t;
bool exists = false;
__be16 dst_port = 0;
+ int opts_len = 0;
__be64 key_id;
__be16 flags;
int ret = 0;
@@ -128,6 +260,15 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
if (tb[TCA_TUNNEL_KEY_ENC_DST_PORT])
dst_port = nla_get_be16(tb[TCA_TUNNEL_KEY_ENC_DST_PORT]);
+ if (tb[TCA_TUNNEL_KEY_ENC_OPTS]) {
+ opts_len = tunnel_key_get_opts_len(tb[TCA_TUNNEL_KEY_ENC_OPTS],
+ extack);
+ if (opts_len < 0) {
+ ret = opts_len;
+ goto err_out;
+ }
+ }
+
if (tb[TCA_TUNNEL_KEY_ENC_IPV4_SRC] &&
tb[TCA_TUNNEL_KEY_ENC_IPV4_DST]) {
__be32 saddr;
@@ -138,7 +279,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
metadata = __ip_tun_set_dst(saddr, daddr, 0, 0,
dst_port, flags,
- key_id, 0);
+ key_id, opts_len);
} else if (tb[TCA_TUNNEL_KEY_ENC_IPV6_SRC] &&
tb[TCA_TUNNEL_KEY_ENC_IPV6_DST]) {
struct in6_addr saddr;
@@ -162,6 +303,14 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
goto err_out;
}
+ if (opts_len) {
+ ret = tunnel_key_opts_set(tb[TCA_TUNNEL_KEY_ENC_OPTS],
+ &metadata->u.tun_info,
+ opts_len, extack);
+ if (ret < 0)
+ goto err_out;
+ }
+
metadata->u.tun_info.mode |= IP_TUNNEL_INFO_TX;
break;
default:
@@ -234,6 +383,61 @@ static void tunnel_key_release(struct tc_action *a)
}
}
+static int tunnel_key_geneve_opts_dump(struct sk_buff *skb,
+ const struct ip_tunnel_info *info)
+{
+ int len = info->options_len;
+ u8 *src = (u8 *)(info + 1);
+ struct nlattr *start;
+
+ start = nla_nest_start(skb, TCA_TUNNEL_KEY_ENC_OPTS_GENEVE);
+ if (!start)
+ return -EMSGSIZE;
+
+ while (len > 0) {
+ struct geneve_opt *opt = (struct geneve_opt *)src;
+
+ if (nla_put_u16(skb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS,
+ opt->opt_class) ||
+ nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE,
+ opt->type) ||
+ nla_put(skb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA,
+ opt->length * 4, opt + 1))
+ return -EMSGSIZE;
+
+ len -= sizeof(struct geneve_opt) + opt->length * 4;
+ src += sizeof(struct geneve_opt) + opt->length * 4;
+ }
+
+ nla_nest_end(skb, start);
+ return 0;
+}
+
+static int tunnel_key_opts_dump(struct sk_buff *skb,
+ const struct ip_tunnel_info *info)
+{
+ struct nlattr *start;
+ int err;
+
+ if (!info->options_len)
+ return 0;
+
+ start = nla_nest_start(skb, TCA_TUNNEL_KEY_ENC_OPTS);
+ if (!start)
+ return -EMSGSIZE;
+
+ if (info->key.tun_flags & TUNNEL_GENEVE_OPT) {
+ err = tunnel_key_geneve_opts_dump(skb, info);
+ if (err)
+ return err;
+ } else {
+ return -EINVAL;
+ }
+
+ nla_nest_end(skb, start);
+ return 0;
+}
+
static int tunnel_key_dump_addresses(struct sk_buff *skb,
const struct ip_tunnel_info *info)
{
@@ -284,8 +488,9 @@ static int tunnel_key_dump(struct sk_buff *skb, struct tc_action *a,
goto nla_put_failure;
if (params->tcft_action == TCA_TUNNEL_KEY_ACT_SET) {
- struct ip_tunnel_key *key =
- ¶ms->tcft_enc_metadata->u.tun_info.key;
+ struct ip_tunnel_info *info =
+ ¶ms->tcft_enc_metadata->u.tun_info;
+ struct ip_tunnel_key *key = &info->key;
__be32 key_id = tunnel_id_to_key32(key->tun_id);
if (nla_put_be32(skb, TCA_TUNNEL_KEY_ENC_KEY_ID, key_id) ||
@@ -293,7 +498,8 @@ static int tunnel_key_dump(struct sk_buff *skb, struct tc_action *a,
¶ms->tcft_enc_metadata->u.tun_info) ||
nla_put_be16(skb, TCA_TUNNEL_KEY_ENC_DST_PORT, key->tp_dst) ||
nla_put_u8(skb, TCA_TUNNEL_KEY_NO_CSUM,
- !(key->tun_flags & TUNNEL_CSUM)))
+ !(key->tun_flags & TUNNEL_CSUM)) ||
+ tunnel_key_opts_dump(skb, info))
goto nla_put_failure;
}
--
2.17.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH net-next 2/4] net/sched: act_tunnel_key: add extended ack support
2018-06-26 18:53 ` [PATCH net-next 2/4] net/sched: act_tunnel_key: add extended ack support Jakub Kicinski
@ 2018-06-26 19:50 ` David Ahern
0 siblings, 0 replies; 9+ messages in thread
From: David Ahern @ 2018-06-26 19:50 UTC (permalink / raw)
To: Jakub Kicinski, davem, jbenc
Cc: Roopa Prabhu, jiri, jhs, xiyou.wangcong, daniel, oss-drivers,
netdev, Simon Horman, Alexander Aring, Pieter Jansen van Vuuren
On 6/26/18 12:53 PM, Jakub Kicinski wrote:
> From: Simon Horman <simon.horman@netronome.com>
>
> Add extended ack support for the tunnel key action by using NL_SET_ERR_MSG
> during validation of user input.
>
> Cc: David Ahern <dsahern@gmail.com>
> Cc: Alexander Aring <aring@mojatatu.com>
> 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>
> ---
> net/sched/act_tunnel_key.c | 27 +++++++++++++++++++++------
> 1 file changed, 21 insertions(+), 6 deletions(-)
>
Reviewed-by: David Ahern <dsahern@gmail.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net-next 3/4] net: check tunnel option type in tunnel flags
2018-06-26 18:53 ` [PATCH net-next 3/4] net: check tunnel option type in tunnel flags Jakub Kicinski
@ 2018-06-27 3:08 ` kbuild test robot
0 siblings, 0 replies; 9+ messages in thread
From: kbuild test robot @ 2018-06-27 3:08 UTC (permalink / raw)
To: Jakub Kicinski
Cc: kbuild-all, davem, jbenc, Roopa Prabhu, jiri, jhs,
xiyou.wangcong, daniel, oss-drivers, netdev,
Pieter Jansen van Vuuren, Jakub Kicinski
Hi Pieter,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on net-next/master]
url: https://github.com/0day-ci/linux/commits/Jakub-Kicinski/net-Geneve-options-support-for-TC-act_tunnel_key/20180627-030036
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__
sparse warnings: (new ones prefixed by >>)
>> net/openvswitch/flow_netlink.c:2532:38: sparse: incorrect type in assignment (different base types) @@ expected int [signed] [assigned] dst_opt_type @@ got restrint [signed] [assigned] dst_opt_type @@
net/openvswitch/flow_netlink.c:2532:38: expected int [signed] [assigned] dst_opt_type
net/openvswitch/flow_netlink.c:2532:38: got restricted __be16 [usertype] <noident>
net/openvswitch/flow_netlink.c:2535:38: sparse: incorrect type in assignment (different base types) @@ expected int [signed] [assigned] dst_opt_type @@ got restrint [signed] [assigned] dst_opt_type @@
net/openvswitch/flow_netlink.c:2535:38: expected int [signed] [assigned] dst_opt_type
net/openvswitch/flow_netlink.c:2535:38: got restricted __be16 [usertype] <noident>
net/openvswitch/flow_netlink.c:2538:38: sparse: incorrect type in assignment (different base types) @@ expected int [signed] [assigned] dst_opt_type @@ got restrint [signed] [assigned] dst_opt_type @@
net/openvswitch/flow_netlink.c:2538:38: expected int [signed] [assigned] dst_opt_type
net/openvswitch/flow_netlink.c:2538:38: got restricted __be16 [usertype] <noident>
>> net/openvswitch/flow_netlink.c:2581:51: sparse: incorrect type in argument 4 (different base types) @@ expected restricted __be16 [usertype] flags @@ got icted __be16 [usertype] flags @@
net/openvswitch/flow_netlink.c:2581:51: expected restricted __be16 [usertype] flags
net/openvswitch/flow_netlink.c:2581:51: got int [signed] [assigned] dst_opt_type
net/openvswitch/flow_netlink.c:3064:39: sparse: expression using sizeof(void)
vim +2532 net/openvswitch/flow_netlink.c
2508
2509 static int validate_and_copy_set_tun(const struct nlattr *attr,
2510 struct sw_flow_actions **sfa, bool log)
2511 {
2512 struct sw_flow_match match;
2513 struct sw_flow_key key;
2514 struct metadata_dst *tun_dst;
2515 struct ip_tunnel_info *tun_info;
2516 struct ovs_tunnel_info *ovs_tun;
2517 struct nlattr *a;
2518 int err = 0, start, opts_type, dst_opt_type;
2519
2520 dst_opt_type = 0;
2521 ovs_match_init(&match, &key, true, NULL);
2522 opts_type = ip_tun_from_nlattr(nla_data(attr), &match, false, log);
2523 if (opts_type < 0)
2524 return opts_type;
2525
2526 if (key.tun_opts_len) {
2527 switch (opts_type) {
2528 case OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS:
2529 err = validate_geneve_opts(&key);
2530 if (err < 0)
2531 return err;
> 2532 dst_opt_type = TUNNEL_GENEVE_OPT;
2533 break;
2534 case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS:
2535 dst_opt_type = TUNNEL_VXLAN_OPT;
2536 break;
2537 case OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS:
2538 dst_opt_type = TUNNEL_ERSPAN_OPT;
2539 break;
2540 }
2541 }
2542
2543 start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SET, log);
2544 if (start < 0)
2545 return start;
2546
2547 tun_dst = metadata_dst_alloc(key.tun_opts_len, METADATA_IP_TUNNEL,
2548 GFP_KERNEL);
2549
2550 if (!tun_dst)
2551 return -ENOMEM;
2552
2553 err = dst_cache_init(&tun_dst->u.tun_info.dst_cache, GFP_KERNEL);
2554 if (err) {
2555 dst_release((struct dst_entry *)tun_dst);
2556 return err;
2557 }
2558
2559 a = __add_action(sfa, OVS_KEY_ATTR_TUNNEL_INFO, NULL,
2560 sizeof(*ovs_tun), log);
2561 if (IS_ERR(a)) {
2562 dst_release((struct dst_entry *)tun_dst);
2563 return PTR_ERR(a);
2564 }
2565
2566 ovs_tun = nla_data(a);
2567 ovs_tun->tun_dst = tun_dst;
2568
2569 tun_info = &tun_dst->u.tun_info;
2570 tun_info->mode = IP_TUNNEL_INFO_TX;
2571 if (key.tun_proto == AF_INET6)
2572 tun_info->mode |= IP_TUNNEL_INFO_IPV6;
2573 tun_info->key = key.tun_key;
2574
2575 /* We need to store the options in the action itself since
2576 * everything else will go away after flow setup. We can append
2577 * it to tun_info and then point there.
2578 */
2579 ip_tunnel_info_opts_set(tun_info,
2580 TUN_METADATA_OPTS(&key, key.tun_opts_len),
> 2581 key.tun_opts_len, dst_opt_type);
2582 add_nested_action_end(*sfa, start);
2583
2584 return err;
2585 }
2586
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net-next 0/4] net: Geneve options support for TC act_tunnel_key
2018-06-26 18:53 [PATCH net-next 0/4] net: Geneve options support for TC act_tunnel_key Jakub Kicinski
` (3 preceding siblings ...)
2018-06-26 18:53 ` [PATCH net-next 4/4] net/sched: add tunnel option support to act_tunnel_key Jakub Kicinski
@ 2018-06-28 7:17 ` David Miller
2018-06-28 16:39 ` Jakub Kicinski
4 siblings, 1 reply; 9+ messages in thread
From: David Miller @ 2018-06-28 7:17 UTC (permalink / raw)
To: jakub.kicinski
Cc: jbenc, roopa, jiri, jhs, xiyou.wangcong, daniel, oss-drivers, netdev
From: Jakub Kicinski <jakub.kicinski@netronome.com>
Date: Tue, 26 Jun 2018 11:53:04 -0700
> Hi,
>
> Simon & Pieter say:
>
> This set adds Geneve Options support to the TC tunnel key action.
> It provides the plumbing required to configure Geneve variable length
> options. The options can be configured 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.
Looks like there are some sparse endianness warnings to fix up as
per kbuild robot.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net-next 0/4] net: Geneve options support for TC act_tunnel_key
2018-06-28 7:17 ` [PATCH net-next 0/4] net: Geneve options support for TC act_tunnel_key David Miller
@ 2018-06-28 16:39 ` Jakub Kicinski
0 siblings, 0 replies; 9+ messages in thread
From: Jakub Kicinski @ 2018-06-28 16:39 UTC (permalink / raw)
To: David Miller
Cc: jbenc, roopa, jiri, jhs, xiyou.wangcong, daniel, oss-drivers, netdev
On Thu, 28 Jun 2018 16:17:31 +0900 (KST), David Miller wrote:
> From: Jakub Kicinski <jakub.kicinski@netronome.com>
> Date: Tue, 26 Jun 2018 11:53:04 -0700
>
> > Hi,
> >
> > Simon & Pieter say:
> >
> > This set adds Geneve Options support to the TC tunnel key action.
> > It provides the plumbing required to configure Geneve variable length
> > options. The options can be configured 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.
>
> Looks like there are some sparse endianness warnings to fix up as
> per kbuild robot.
Sorry about that!
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2018-06-28 16:39 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-26 18:53 [PATCH net-next 0/4] net: Geneve options support for TC act_tunnel_key Jakub Kicinski
2018-06-26 18:53 ` [PATCH net-next 1/4] net/sched: act_tunnel_key: disambiguate metadata dst error cases Jakub Kicinski
2018-06-26 18:53 ` [PATCH net-next 2/4] net/sched: act_tunnel_key: add extended ack support Jakub Kicinski
2018-06-26 19:50 ` David Ahern
2018-06-26 18:53 ` [PATCH net-next 3/4] net: check tunnel option type in tunnel flags Jakub Kicinski
2018-06-27 3:08 ` kbuild test robot
2018-06-26 18:53 ` [PATCH net-next 4/4] net/sched: add tunnel option support to act_tunnel_key Jakub Kicinski
2018-06-28 7:17 ` [PATCH net-next 0/4] net: Geneve options support for TC act_tunnel_key David Miller
2018-06-28 16:39 ` Jakub Kicinski
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.