mirror of
https://github.com/openvswitch/ovs
synced 2025-10-15 14:17:18 +00:00
odp-util: Return exact mask if netlink mask attribute is missing.
In the ODP context an empty mask netlink attribute usually means that the flow should be an exact match. odp_flow_key_to_mask{,_udpif}() instead return a struct flow_wildcards with matches only on recirc_id and vlan_tci. A more appropriate behavior is to handle a missing (zero length) netlink mask specially (like we do in userspace and Linux datapath) and create an exact match flow_wildcards from the original flow. This fixes a bug in revalidate_ukey(): every flow created with megaflows disabled would be revalidated away, because the mask would seem too generic. (Another possible fix would be to handle the special case of a missing mask in revalidate_ukey(), but this seems a more generic solution).
This commit is contained in:
@@ -5152,6 +5152,26 @@ odp_flow_key_to_flow(const struct nlattr *key, size_t key_len,
|
||||
return odp_flow_key_to_flow__(key, key_len, NULL, 0, flow, flow, false);
|
||||
}
|
||||
|
||||
static enum odp_key_fitness
|
||||
odp_flow_key_to_mask__(const struct nlattr *mask_key, size_t mask_key_len,
|
||||
const struct nlattr *flow_key, size_t flow_key_len,
|
||||
struct flow_wildcards *mask,
|
||||
const struct flow *src_flow,
|
||||
bool udpif)
|
||||
{
|
||||
if (mask_key_len) {
|
||||
return odp_flow_key_to_flow__(mask_key, mask_key_len,
|
||||
flow_key, flow_key_len,
|
||||
&mask->masks, src_flow, udpif);
|
||||
|
||||
} else {
|
||||
/* A missing mask means that the flow should be exact matched.
|
||||
* Generate an appropriate exact wildcard for the flow. */
|
||||
flow_wildcards_init_for_packet(mask, src_flow);
|
||||
|
||||
return ODP_FIT_PERFECT;
|
||||
}
|
||||
}
|
||||
/* Converts the 'mask_key_len' bytes of OVS_KEY_ATTR_* attributes in 'mask_key'
|
||||
* to a mask structure in 'mask'. 'flow' must be a previously translated flow
|
||||
* corresponding to 'mask' and similarly flow_key/flow_key_len must be the
|
||||
@@ -5160,10 +5180,11 @@ odp_flow_key_to_flow(const struct nlattr *key, size_t key_len,
|
||||
enum odp_key_fitness
|
||||
odp_flow_key_to_mask(const struct nlattr *mask_key, size_t mask_key_len,
|
||||
const struct nlattr *flow_key, size_t flow_key_len,
|
||||
struct flow *mask, const struct flow *flow)
|
||||
struct flow_wildcards *mask, const struct flow *flow)
|
||||
{
|
||||
return odp_flow_key_to_flow__(mask_key, mask_key_len, flow_key, flow_key_len,
|
||||
mask, flow, false);
|
||||
return odp_flow_key_to_mask__(mask_key, mask_key_len,
|
||||
flow_key, flow_key_len,
|
||||
mask, flow, false);
|
||||
}
|
||||
|
||||
/* These functions are similar to their non-"_udpif" variants but output a
|
||||
@@ -5185,10 +5206,12 @@ odp_flow_key_to_flow_udpif(const struct nlattr *key, size_t key_len,
|
||||
enum odp_key_fitness
|
||||
odp_flow_key_to_mask_udpif(const struct nlattr *mask_key, size_t mask_key_len,
|
||||
const struct nlattr *flow_key, size_t flow_key_len,
|
||||
struct flow *mask, const struct flow *flow)
|
||||
struct flow_wildcards *mask,
|
||||
const struct flow *flow)
|
||||
{
|
||||
return odp_flow_key_to_flow__(mask_key, mask_key_len, flow_key, flow_key_len,
|
||||
mask, flow, true);
|
||||
return odp_flow_key_to_mask__(mask_key, mask_key_len,
|
||||
flow_key, flow_key_len,
|
||||
mask, flow, true);
|
||||
}
|
||||
|
||||
/* Returns 'fitness' as a string, for use in debug messages. */
|
||||
|
Reference in New Issue
Block a user