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: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
ac5132d1a0
commit
d91641d9b5
@ -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 {
|
|||||||
|
|
||||||
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 {
|
|||||||
* 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,
|
|||||||
__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,
|
|||||||
__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,
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
|||||||
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,
|
|||||||
* 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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user