const struct nlattr **a, bool is_mask)
{
int err;
+ u64 orig_attrs = attrs;
err = metadata_from_nlattrs(match, &attrs, a, is_mask);
if (err)
__be16 tci;
tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]);
- if (!is_mask && (tci & htons(VLAN_TAG_PRESENT)))
- return -EINVAL;
+ if (!is_mask)
+ if (!(tci & htons(VLAN_TAG_PRESENT)))
+ return -EINVAL;
SW_FLOW_KEY_PUT(match, eth.tci, tci, is_mask);
attrs &= ~(1ULL << OVS_KEY_ATTR_VLAN);
const struct ovs_key_tcp *tcp_key;
tcp_key = nla_data(a[OVS_KEY_ATTR_TCP]);
- SW_FLOW_KEY_PUT(match, ipv4.tp.src,
- tcp_key->tcp_src, is_mask);
- SW_FLOW_KEY_PUT(match, ipv4.tp.dst,
- tcp_key->tcp_dst, is_mask);
+ if (orig_attrs & (1ULL << OVS_KEY_ATTR_IPV4)) {
+ SW_FLOW_KEY_PUT(match, ipv4.tp.src,
+ tcp_key->tcp_src, is_mask);
+ SW_FLOW_KEY_PUT(match, ipv4.tp.dst,
+ tcp_key->tcp_dst, is_mask);
+ } else {
+ SW_FLOW_KEY_PUT(match, ipv6.tp.src,
+ tcp_key->tcp_src, is_mask);
+ SW_FLOW_KEY_PUT(match, ipv6.tp.dst,
+ tcp_key->tcp_dst, is_mask);
+ }
attrs &= ~(1ULL << OVS_KEY_ATTR_TCP);
}
const struct ovs_key_udp *udp_key;
udp_key = nla_data(a[OVS_KEY_ATTR_UDP]);
- SW_FLOW_KEY_PUT(match, ipv4.tp.src,
- udp_key->udp_src, is_mask);
- SW_FLOW_KEY_PUT(match, ipv4.tp.dst,
- udp_key->udp_dst, is_mask);
+ if (orig_attrs & (1ULL << OVS_KEY_ATTR_IPV4)) {
+ SW_FLOW_KEY_PUT(match, ipv4.tp.src,
+ udp_key->udp_src, is_mask);
+ SW_FLOW_KEY_PUT(match, ipv4.tp.dst,
+ udp_key->udp_dst, is_mask);
+ } else {
+ SW_FLOW_KEY_PUT(match, ipv6.tp.src,
+ udp_key->udp_src, is_mask);
+ SW_FLOW_KEY_PUT(match, ipv6.tp.dst,
+ udp_key->udp_dst, is_mask);
+ }
attrs &= ~(1ULL << OVS_KEY_ATTR_UDP);
}
if ((mask_attrs & 1ULL << OVS_KEY_ATTR_ENCAP) && encap_valid) {
__be16 eth_type = 0;
+ mask_attrs &= ~(1ULL << OVS_KEY_ATTR_ENCAP);
if (a[OVS_KEY_ATTR_ETHERTYPE])
eth_type = nla_get_be16(a[OVS_KEY_ATTR_ETHERTYPE]);
if (eth_type == htons(0xffff)) {
if (err)
return -EINVAL;
- ovs_match_init(&match, &flow->key, NULL);
+ memset(&match, 0, sizeof(match));
+ match.key = &flow->key;
err = metadata_from_nlattrs(&match, &attrs, a, false);
if (err)