Commit d91641d9 authored by Thomas Graf's avatar Thomas Graf Committed by David S. Miller

openvswitch: Rename GENEVE_TUN_OPTS() to TUN_METADATA_OPTS()

Also factors out Geneve validation code into a new separate function
validate_and_copy_geneve_opts().

A subsequent patch will introduce VXLAN options. Rename the existing
GENEVE_TUN_OPTS() to reflect its extended purpose of carrying generic
tunnel metadata options.
Signed-off-by: default avatarThomas Graf <tgraf@suug.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ac5132d1
...@@ -691,7 +691,7 @@ int ovs_flow_key_extract(const struct ovs_tunnel_info *tun_info, ...@@ -691,7 +691,7 @@ int ovs_flow_key_extract(const struct ovs_tunnel_info *tun_info,
BUILD_BUG_ON((1 << (sizeof(tun_info->options_len) * BUILD_BUG_ON((1 << (sizeof(tun_info->options_len) *
8)) - 1 8)) - 1
> sizeof(key->tun_opts)); > sizeof(key->tun_opts));
memcpy(GENEVE_OPTS(key, tun_info->options_len), memcpy(TUN_METADATA_OPTS(key, tun_info->options_len),
tun_info->options, tun_info->options_len); tun_info->options, tun_info->options_len);
key->tun_opts_len = tun_info->options_len; key->tun_opts_len = tun_info->options_len;
} else { } else {
......
...@@ -53,7 +53,7 @@ struct ovs_key_ipv4_tunnel { ...@@ -53,7 +53,7 @@ struct ovs_key_ipv4_tunnel {
struct ovs_tunnel_info { struct ovs_tunnel_info {
struct ovs_key_ipv4_tunnel tunnel; struct ovs_key_ipv4_tunnel tunnel;
const struct geneve_opt *options; const void *options;
u8 options_len; u8 options_len;
}; };
...@@ -61,10 +61,10 @@ struct ovs_tunnel_info { ...@@ -61,10 +61,10 @@ struct ovs_tunnel_info {
* maximum size. This allows us to get the benefits of variable length * maximum size. This allows us to get the benefits of variable length
* matching for small options. * matching for small options.
*/ */
#define GENEVE_OPTS(flow_key, opt_len) \ #define TUN_METADATA_OFFSET(opt_len) \
((struct geneve_opt *)((flow_key)->tun_opts + \ (FIELD_SIZEOF(struct sw_flow_key, tun_opts) - opt_len)
FIELD_SIZEOF(struct sw_flow_key, tun_opts) - \ #define TUN_METADATA_OPTS(flow_key, opt_len) \
opt_len)) ((void *)((flow_key)->tun_opts + TUN_METADATA_OFFSET(opt_len)))
static inline void __ovs_flow_tun_info_init(struct ovs_tunnel_info *tun_info, static inline void __ovs_flow_tun_info_init(struct ovs_tunnel_info *tun_info,
__be32 saddr, __be32 daddr, __be32 saddr, __be32 daddr,
...@@ -73,7 +73,7 @@ static inline void __ovs_flow_tun_info_init(struct ovs_tunnel_info *tun_info, ...@@ -73,7 +73,7 @@ static inline void __ovs_flow_tun_info_init(struct ovs_tunnel_info *tun_info,
__be16 tp_dst, __be16 tp_dst,
__be64 tun_id, __be64 tun_id,
__be16 tun_flags, __be16 tun_flags,
const struct geneve_opt *opts, const void *opts,
u8 opts_len) u8 opts_len)
{ {
tun_info->tunnel.tun_id = tun_id; tun_info->tunnel.tun_id = tun_id;
...@@ -105,7 +105,7 @@ static inline void ovs_flow_tun_info_init(struct ovs_tunnel_info *tun_info, ...@@ -105,7 +105,7 @@ static inline void ovs_flow_tun_info_init(struct ovs_tunnel_info *tun_info,
__be16 tp_dst, __be16 tp_dst,
__be64 tun_id, __be64 tun_id,
__be16 tun_flags, __be16 tun_flags,
const struct geneve_opt *opts, const void *opts,
u8 opts_len) u8 opts_len)
{ {
__ovs_flow_tun_info_init(tun_info, iph->saddr, iph->daddr, __ovs_flow_tun_info_init(tun_info, iph->saddr, iph->daddr,
......
...@@ -432,8 +432,7 @@ static int genev_tun_opt_from_nlattr(const struct nlattr *a, ...@@ -432,8 +432,7 @@ static int genev_tun_opt_from_nlattr(const struct nlattr *a,
SW_FLOW_KEY_PUT(match, tun_opts_len, 0xff, true); SW_FLOW_KEY_PUT(match, tun_opts_len, 0xff, true);
} }
opt_key_offset = (unsigned long)GENEVE_OPTS((struct sw_flow_key *)0, opt_key_offset = TUN_METADATA_OFFSET(nla_len(a));
nla_len(a));
SW_FLOW_KEY_MEMCPY_OFFSET(match, opt_key_offset, nla_data(a), SW_FLOW_KEY_MEMCPY_OFFSET(match, opt_key_offset, nla_data(a),
nla_len(a), is_mask); nla_len(a), is_mask);
return 0; return 0;
...@@ -558,8 +557,7 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr, ...@@ -558,8 +557,7 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
static int __ipv4_tun_to_nlattr(struct sk_buff *skb, static int __ipv4_tun_to_nlattr(struct sk_buff *skb,
const struct ovs_key_ipv4_tunnel *output, const struct ovs_key_ipv4_tunnel *output,
const struct geneve_opt *tun_opts, const void *tun_opts, int swkey_tun_opts_len)
int swkey_tun_opts_len)
{ {
if (output->tun_flags & TUNNEL_KEY && if (output->tun_flags & TUNNEL_KEY &&
nla_put_be64(skb, OVS_TUNNEL_KEY_ATTR_ID, output->tun_id)) nla_put_be64(skb, OVS_TUNNEL_KEY_ATTR_ID, output->tun_id))
...@@ -600,8 +598,7 @@ static int __ipv4_tun_to_nlattr(struct sk_buff *skb, ...@@ -600,8 +598,7 @@ static int __ipv4_tun_to_nlattr(struct sk_buff *skb,
static int ipv4_tun_to_nlattr(struct sk_buff *skb, static int ipv4_tun_to_nlattr(struct sk_buff *skb,
const struct ovs_key_ipv4_tunnel *output, const struct ovs_key_ipv4_tunnel *output,
const struct geneve_opt *tun_opts, const void *tun_opts, int swkey_tun_opts_len)
int swkey_tun_opts_len)
{ {
struct nlattr *nla; struct nlattr *nla;
int err; int err;
...@@ -1148,10 +1145,10 @@ int ovs_nla_put_flow(const struct sw_flow_key *swkey, ...@@ -1148,10 +1145,10 @@ int ovs_nla_put_flow(const struct sw_flow_key *swkey,
goto nla_put_failure; goto nla_put_failure;
if ((swkey->tun_key.ipv4_dst || is_mask)) { if ((swkey->tun_key.ipv4_dst || is_mask)) {
const struct geneve_opt *opts = NULL; const void *opts = NULL;
if (output->tun_key.tun_flags & TUNNEL_OPTIONS_PRESENT) if (output->tun_key.tun_flags & TUNNEL_OPTIONS_PRESENT)
opts = GENEVE_OPTS(output, swkey->tun_opts_len); opts = TUN_METADATA_OPTS(output, swkey->tun_opts_len);
if (ipv4_tun_to_nlattr(skb, &output->tun_key, opts, if (ipv4_tun_to_nlattr(skb, &output->tun_key, opts,
swkey->tun_opts_len)) swkey->tun_opts_len))
...@@ -1540,6 +1537,34 @@ void ovs_match_init(struct sw_flow_match *match, ...@@ -1540,6 +1537,34 @@ void ovs_match_init(struct sw_flow_match *match,
} }
} }
static int validate_geneve_opts(struct sw_flow_key *key)
{
struct geneve_opt *option;
int opts_len = key->tun_opts_len;
bool crit_opt = false;
option = (struct geneve_opt *)TUN_METADATA_OPTS(key, key->tun_opts_len);
while (opts_len > 0) {
int len;
if (opts_len < sizeof(*option))
return -EINVAL;
len = sizeof(*option) + option->length * 4;
if (len > opts_len)
return -EINVAL;
crit_opt |= !!(option->type & GENEVE_CRIT_OPT_TYPE);
option = (struct geneve_opt *)((u8 *)option + len);
opts_len -= len;
};
key->tun_key.tun_flags |= crit_opt ? TUNNEL_CRIT_OPT : 0;
return 0;
}
static int validate_and_copy_set_tun(const struct nlattr *attr, static int validate_and_copy_set_tun(const struct nlattr *attr,
struct sw_flow_actions **sfa, bool log) struct sw_flow_actions **sfa, bool log)
{ {
...@@ -1555,28 +1580,9 @@ static int validate_and_copy_set_tun(const struct nlattr *attr, ...@@ -1555,28 +1580,9 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
return err; return err;
if (key.tun_opts_len) { if (key.tun_opts_len) {
struct geneve_opt *option = GENEVE_OPTS(&key, err = validate_geneve_opts(&key);
key.tun_opts_len); if (err < 0)
int opts_len = key.tun_opts_len; return err;
bool crit_opt = false;
while (opts_len > 0) {
int len;
if (opts_len < sizeof(*option))
return -EINVAL;
len = sizeof(*option) + option->length * 4;
if (len > opts_len)
return -EINVAL;
crit_opt |= !!(option->type & GENEVE_CRIT_OPT_TYPE);
option = (struct geneve_opt *)((u8 *)option + len);
opts_len -= len;
};
key.tun_key.tun_flags |= crit_opt ? TUNNEL_CRIT_OPT : 0;
}; };
start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SET, log); start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SET, log);
...@@ -1597,9 +1603,9 @@ static int validate_and_copy_set_tun(const struct nlattr *attr, ...@@ -1597,9 +1603,9 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
* everything else will go away after flow setup. We can append * everything else will go away after flow setup. We can append
* it to tun_info and then point there. * it to tun_info and then point there.
*/ */
memcpy((tun_info + 1), GENEVE_OPTS(&key, key.tun_opts_len), memcpy((tun_info + 1),
key.tun_opts_len); TUN_METADATA_OPTS(&key, key.tun_opts_len), key.tun_opts_len);
tun_info->options = (struct geneve_opt *)(tun_info + 1); tun_info->options = (tun_info + 1);
} else { } else {
tun_info->options = NULL; tun_info->options = NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment