{
MFF_IPV6_LABEL, "ipv6_label", NULL,
4, 20,
- MFM_NONE, FWW_IPV6_LABEL,
+ MFM_FULLY, 0,
MFS_HEXADECIMAL,
MFP_IPV6,
false,
}, {
MFF_ARP_SHA, "arp_sha", NULL,
MF_FIELD_SIZES(mac),
- MFM_NONE, FWW_ARP_SHA,
+ MFM_FULLY, 0,
MFS_ETHERNET,
MFP_ARP,
false,
}, {
MFF_ARP_THA, "arp_tha", NULL,
MF_FIELD_SIZES(mac),
- MFM_NONE, FWW_ARP_THA,
+ MFM_FULLY, 0,
MFS_ETHERNET,
MFP_ARP,
false,
}, {
MFF_ND_SLL, "nd_sll", NULL,
MF_FIELD_SIZES(mac),
- MFM_NONE, FWW_ARP_SHA,
+ MFM_FULLY, 0,
MFS_ETHERNET,
MFP_ND_SOLICIT,
false,
}, {
MFF_ND_TLL, "nd_tll", NULL,
MF_FIELD_SIZES(mac),
- MFM_NONE, FWW_ARP_THA,
+ MFM_FULLY, 0,
MFS_ETHERNET,
MFP_ND_ADVERT,
false,
case MFF_IP_DSCP:
case MFF_IP_ECN:
case MFF_IP_TTL:
- case MFF_IPV6_LABEL:
case MFF_ARP_OP:
- case MFF_ARP_SHA:
- case MFF_ARP_THA:
- case MFF_ND_SLL:
- case MFF_ND_TLL:
assert(mf->fww_bit != 0);
return (wc->wildcards & mf->fww_bit) != 0;
case MFF_ETH_DST:
return eth_addr_is_zero(wc->dl_dst_mask);
+ case MFF_ARP_SHA:
+ case MFF_ND_SLL:
+ return eth_addr_is_zero(wc->arp_sha_mask);
+
+ case MFF_ARP_THA:
+ case MFF_ND_TLL:
+ return eth_addr_is_zero(wc->arp_tha_mask);
+
case MFF_VLAN_TCI:
return !wc->vlan_tci_mask;
case MFF_VLAN_VID:
case MFF_IPV6_DST:
return ipv6_mask_is_any(&wc->ipv6_dst_mask);
+ case MFF_IPV6_LABEL:
+ return !wc->ipv6_label_mask;
+
case MFF_ND_TARGET:
return ipv6_mask_is_any(&wc->nd_target_mask);
case MFF_IP_DSCP:
case MFF_IP_ECN:
case MFF_IP_TTL:
- case MFF_IPV6_LABEL:
case MFF_ARP_OP:
- case MFF_ARP_SHA:
- case MFF_ARP_THA:
- case MFF_ND_SLL:
- case MFF_ND_TLL:
assert(mf->fww_bit != 0);
memset(mask, wc->wildcards & mf->fww_bit ? 0x00 : 0xff, mf->n_bytes);
break;
case MFF_IPV6_DST:
mask->ipv6 = wc->ipv6_dst_mask;
break;
+ case MFF_IPV6_LABEL:
+ mask->be32 = wc->ipv6_label_mask;
+ break;
case MFF_ND_TARGET:
mask->ipv6 = wc->nd_target_mask;
case MFF_ARP_TPA:
mask->be32 = wc->nw_dst_mask;
break;
+ case MFF_ARP_SHA:
+ case MFF_ND_SLL:
+ memcpy(mask->mac, wc->arp_sha_mask, ETH_ADDR_LEN);
+ break;
+ case MFF_ARP_THA:
+ case MFF_ND_TLL:
+ memcpy(mask->mac, wc->arp_tha_mask, ETH_ADDR_LEN);
+ break;
case MFF_TCP_SRC:
case MFF_UDP_SRC:
break;
case MFF_IPV6_LABEL:
- rule->wc.wildcards |= FWW_IPV6_LABEL;
+ rule->wc.ipv6_label_mask = 0;
rule->flow.ipv6_label = 0;
break;
case MFF_ARP_SHA:
case MFF_ND_SLL:
- rule->wc.wildcards |= FWW_ARP_SHA;
- memset(rule->flow.arp_sha, 0, sizeof rule->flow.arp_sha);
+ memset(rule->flow.arp_sha, 0, ETH_ADDR_LEN);
+ memset(rule->wc.arp_sha_mask, 0, ETH_ADDR_LEN);
break;
case MFF_ARP_THA:
case MFF_ND_TLL:
- rule->wc.wildcards |= FWW_ARP_THA;
- memset(rule->flow.arp_tha, 0, sizeof rule->flow.arp_tha);
+ memset(rule->flow.arp_tha, 0, ETH_ADDR_LEN);
+ memset(rule->wc.arp_tha_mask, 0, ETH_ADDR_LEN);
break;
case MFF_TCP_SRC:
case MFF_ETH_TYPE:
case MFF_VLAN_VID:
case MFF_VLAN_PCP:
- case MFF_IPV6_LABEL:
case MFF_IP_PROTO:
case MFF_IP_TTL:
case MFF_IP_DSCP:
case MFF_IP_ECN:
case MFF_ARP_OP:
- case MFF_ARP_SHA:
- case MFF_ARP_THA:
case MFF_ICMPV4_TYPE:
case MFF_ICMPV4_CODE:
case MFF_ICMPV6_TYPE:
case MFF_ICMPV6_CODE:
- case MFF_ND_SLL:
- case MFF_ND_TLL:
NOT_REACHED();
case MFF_TUN_ID:
cls_rule_set_dl_src_masked(rule, value->mac, mask->mac);
break;
+ case MFF_ARP_SHA:
+ case MFF_ND_SLL:
+ cls_rule_set_arp_sha_masked(rule, value->mac, mask->mac);
+ break;
+
+ case MFF_ARP_THA:
+ case MFF_ND_TLL:
+ cls_rule_set_arp_tha_masked(rule, value->mac, mask->mac);
+ break;
+
case MFF_VLAN_TCI:
cls_rule_set_dl_tci_masked(rule, value->be16, mask->be16);
break;
cls_rule_set_ipv6_dst_masked(rule, &value->ipv6, &mask->ipv6);
break;
+ case MFF_IPV6_LABEL:
+ if ((mask->be32 & htonl(IPV6_LABEL_MASK)) == htonl(IPV6_LABEL_MASK)) {
+ mf_set_value(mf, value, rule);
+ } else {
+ cls_rule_set_ipv6_label_masked(rule, value->be32, mask->be32);
+ }
+ break;
+
case MFF_ND_TARGET:
cls_rule_set_nd_target_masked(rule, &value->ipv6, &mask->ipv6);
break;