git://git.onelab.eu
/
sliver-openvswitch.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
datapath: Always allow tunnel mask to be specified in the netlink
[sliver-openvswitch.git]
/
datapath
/
flow.c
diff --git
a/datapath/flow.c
b/datapath/flow.c
index
2c11408
..
29d3062
100644
(file)
--- a/
datapath/flow.c
+++ b/
datapath/flow.c
@@
-82,8
+82,9
@@
static void update_range__(struct sw_flow_match *match,
do { \
update_range__(match, offsetof(struct sw_flow_key, field), \
sizeof((match)->key->field), is_mask); \
do { \
update_range__(match, offsetof(struct sw_flow_key, field), \
sizeof((match)->key->field), is_mask); \
- if (is_mask && match->mask != NULL) { \
- (match)->mask->key.field = value; \
+ if (is_mask) { \
+ if ((match)->mask) \
+ (match)->mask->key.field = value; \
} else { \
(match)->key->field = value; \
} \
} else { \
(match)->key->field = value; \
} \
@@
-93,8
+94,9
@@
static void update_range__(struct sw_flow_match *match,
do { \
update_range__(match, offsetof(struct sw_flow_key, field), \
len, is_mask); \
do { \
update_range__(match, offsetof(struct sw_flow_key, field), \
len, is_mask); \
- if (is_mask && match->mask != NULL) { \
- memcpy(&(match)->mask->key.field, value_p, len); \
+ if (is_mask) { \
+ if ((match)->mask) \
+ memcpy(&(match)->mask->key.field, value_p, len);\
} else { \
memcpy(&(match)->key->field, value_p, len); \
} \
} else { \
memcpy(&(match)->key->field, value_p, len); \
} \
@@
-133,6
+135,9
@@
static bool ovs_match_validate(const struct sw_flow_match *match,
| (1ULL << OVS_KEY_ATTR_ARP)
| (1ULL << OVS_KEY_ATTR_ND));
| (1ULL << OVS_KEY_ATTR_ARP)
| (1ULL << OVS_KEY_ATTR_ND));
+ /* Tunnel mask is always allowed. */
+ mask_allowed |= (1ULL << OVS_KEY_ATTR_TUNNEL);
+
if (match->key->phy.in_port == DP_MAX_PORTS &&
match->mask && (match->mask->key.phy.in_port == 0xffff))
mask_allowed |= (1ULL << OVS_KEY_ATTR_IN_PORT);
if (match->key->phy.in_port == DP_MAX_PORTS &&
match->mask && (match->mask->key.phy.in_port == 0xffff))
mask_allowed |= (1ULL << OVS_KEY_ATTR_IN_PORT);
@@
-1363,15
+1368,19
@@
static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs,
__be16 tci;
tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]);
__be16 tci;
tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]);
- if (!is_mask)
- if (!(tci & htons(VLAN_TAG_PRESENT))) {
+ if (!(tci & htons(VLAN_TAG_PRESENT))) {
+ if (is_mask)
+ OVS_NLERR("VLAN TCI mask does not have exact match for VLAN_TAG_PRESENT bit.\n");
+ else
OVS_NLERR("VLAN TCI does not have VLAN_TAG_PRESENT bit set.\n");
OVS_NLERR("VLAN TCI does not have VLAN_TAG_PRESENT bit set.\n");
- return -EINVAL;
- }
+
+ return -EINVAL;
+ }
SW_FLOW_KEY_PUT(match, eth.tci, tci, is_mask);
attrs &= ~(1ULL << OVS_KEY_ATTR_VLAN);
SW_FLOW_KEY_PUT(match, eth.tci, tci, is_mask);
attrs &= ~(1ULL << OVS_KEY_ATTR_VLAN);
- }
+ } else if (!is_mask)
+ SW_FLOW_KEY_PUT(match, eth.tci, htons(0xffff), true);
if (attrs & (1ULL << OVS_KEY_ATTR_ETHERTYPE)) {
__be16 eth_type;
if (attrs & (1ULL << OVS_KEY_ATTR_ETHERTYPE)) {
__be16 eth_type;
@@
-1688,8
+1697,7
@@
int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey,
struct ovs_key_ethernet *eth_key;
struct nlattr *nla, *encap;
struct ovs_key_ethernet *eth_key;
struct nlattr *nla, *encap;
- if (output->phy.priority &&
- nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, output->phy.priority))
+ if (nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, output->phy.priority))
goto nla_put_failure;
if (swkey->tun_key.ipv4_dst &&
goto nla_put_failure;
if (swkey->tun_key.ipv4_dst &&
@@
-1709,8
+1717,7
@@
int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey,
goto nla_put_failure;
}
goto nla_put_failure;
}
- if (output->phy.skb_mark &&
- nla_put_u32(skb, OVS_KEY_ATTR_SKB_MARK, output->phy.skb_mark))
+ if (nla_put_u32(skb, OVS_KEY_ATTR_SKB_MARK, output->phy.skb_mark))
goto nla_put_failure;
nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key));
goto nla_put_failure;
nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key));