From 26720e2449918b92be1fd0e3a7c57012c057c733 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 7 Aug 2012 13:38:38 -0700 Subject: [PATCH] flow: Replace flow_wildcards members by a single "struct flow". Signed-off-by: Ben Pfaff --- lib/classifier.c | 208 +++++++++++----------- lib/flow.c | 382 ++++++++++++++++++++-------------------- lib/flow.h | 35 +--- lib/meta-flow.c | 158 ++++++++--------- lib/nx-match.c | 71 ++++---- lib/ofp-util.c | 148 ++++++++-------- ofproto/ofproto.c | 4 +- tests/test-classifier.c | 57 +++--- utilities/ovs-ofctl.c | 14 +- 9 files changed, 533 insertions(+), 544 deletions(-) diff --git a/lib/classifier.c b/lib/classifier.c index d5e383f1..fab856b7 100644 --- a/lib/classifier.c +++ b/lib/classifier.c @@ -128,7 +128,7 @@ void cls_rule_set_metadata_masked(struct cls_rule *rule, ovs_be64 metadata, ovs_be64 mask) { - rule->wc.metadata_mask = mask; + rule->wc.masks.metadata = mask; rule->flow.metadata = metadata & mask; } @@ -142,21 +142,21 @@ void cls_rule_set_tun_id_masked(struct cls_rule *rule, ovs_be64 tun_id, ovs_be64 mask) { - rule->wc.tun_id_mask = mask; + rule->wc.masks.tun_id = mask; rule->flow.tun_id = tun_id & mask; } void cls_rule_set_in_port(struct cls_rule *rule, uint16_t ofp_port) { - rule->wc.in_port_mask = UINT16_MAX; + rule->wc.masks.in_port = UINT16_MAX; rule->flow.in_port = ofp_port; } void cls_rule_set_dl_type(struct cls_rule *rule, ovs_be16 dl_type) { - rule->wc.dl_type_mask = htons(UINT16_MAX); + rule->wc.masks.dl_type = htons(UINT16_MAX); rule->flow.dl_type = dl_type; } @@ -193,7 +193,7 @@ cls_rule_set_eth_masked(const uint8_t value_src[ETH_ADDR_LEN], void cls_rule_set_dl_src(struct cls_rule *rule, const uint8_t dl_src[ETH_ADDR_LEN]) { - cls_rule_set_eth(dl_src, rule->flow.dl_src, rule->wc.dl_src_mask); + cls_rule_set_eth(dl_src, rule->flow.dl_src, rule->wc.masks.dl_src); } /* Modifies 'rule' so that the source Ethernet address @@ -205,7 +205,7 @@ cls_rule_set_dl_src_masked(struct cls_rule *rule, const uint8_t mask[ETH_ADDR_LEN]) { cls_rule_set_eth_masked(dl_src, mask, - rule->flow.dl_src, rule->wc.dl_src_mask); + rule->flow.dl_src, rule->wc.masks.dl_src); } /* Modifies 'rule' so that the destination Ethernet address @@ -213,7 +213,7 @@ cls_rule_set_dl_src_masked(struct cls_rule *rule, void cls_rule_set_dl_dst(struct cls_rule *rule, const uint8_t dl_dst[ETH_ADDR_LEN]) { - cls_rule_set_eth(dl_dst, rule->flow.dl_dst, rule->wc.dl_dst_mask); + cls_rule_set_eth(dl_dst, rule->flow.dl_dst, rule->wc.masks.dl_dst); } /* Modifies 'rule' so that the destination Ethernet address @@ -225,7 +225,7 @@ cls_rule_set_dl_dst_masked(struct cls_rule *rule, const uint8_t mask[ETH_ADDR_LEN]) { cls_rule_set_eth_masked(dl_dst, mask, - rule->flow.dl_dst, rule->wc.dl_dst_mask); + rule->flow.dl_dst, rule->wc.masks.dl_dst); } void @@ -238,7 +238,7 @@ void cls_rule_set_dl_tci_masked(struct cls_rule *rule, ovs_be16 tci, ovs_be16 mask) { rule->flow.vlan_tci = tci & mask; - rule->wc.vlan_tci_mask = mask; + rule->wc.masks.vlan_tci = mask; } /* Modifies 'rule' so that the VLAN VID is wildcarded. If the PCP is already @@ -247,8 +247,8 @@ cls_rule_set_dl_tci_masked(struct cls_rule *rule, ovs_be16 tci, ovs_be16 mask) void cls_rule_set_any_vid(struct cls_rule *rule) { - if (rule->wc.vlan_tci_mask & htons(VLAN_PCP_MASK)) { - rule->wc.vlan_tci_mask &= ~htons(VLAN_VID_MASK); + if (rule->wc.masks.vlan_tci & htons(VLAN_PCP_MASK)) { + rule->wc.masks.vlan_tci &= ~htons(VLAN_VID_MASK); rule->flow.vlan_tci &= ~htons(VLAN_VID_MASK); } else { cls_rule_set_dl_tci_masked(rule, htons(0), htons(0)); @@ -268,9 +268,9 @@ cls_rule_set_dl_vlan(struct cls_rule *rule, ovs_be16 dl_vlan) { flow_set_dl_vlan(&rule->flow, dl_vlan); if (dl_vlan == htons(OFP10_VLAN_NONE)) { - rule->wc.vlan_tci_mask = htons(UINT16_MAX); + rule->wc.masks.vlan_tci = htons(UINT16_MAX); } else { - rule->wc.vlan_tci_mask |= htons(VLAN_VID_MASK | VLAN_CFI); + rule->wc.masks.vlan_tci |= htons(VLAN_VID_MASK | VLAN_CFI); } } @@ -296,7 +296,7 @@ cls_rule_set_vlan_vid_masked(struct cls_rule *rule, mask &= vid_mask; flow_set_vlan_vid(&rule->flow, vid & mask); - rule->wc.vlan_tci_mask = mask | (rule->wc.vlan_tci_mask & pcp_mask); + rule->wc.masks.vlan_tci = mask | (rule->wc.masks.vlan_tci & pcp_mask); } /* Modifies 'rule' so that the VLAN PCP is wildcarded. If the VID is already @@ -305,8 +305,8 @@ cls_rule_set_vlan_vid_masked(struct cls_rule *rule, void cls_rule_set_any_pcp(struct cls_rule *rule) { - if (rule->wc.vlan_tci_mask & htons(VLAN_VID_MASK)) { - rule->wc.vlan_tci_mask &= ~htons(VLAN_PCP_MASK); + if (rule->wc.masks.vlan_tci & htons(VLAN_VID_MASK)) { + rule->wc.masks.vlan_tci &= ~htons(VLAN_PCP_MASK); rule->flow.vlan_tci &= ~htons(VLAN_PCP_MASK); } else { cls_rule_set_dl_tci_masked(rule, htons(0), htons(0)); @@ -319,7 +319,7 @@ void cls_rule_set_dl_vlan_pcp(struct cls_rule *rule, uint8_t dl_vlan_pcp) { flow_set_vlan_pcp(&rule->flow, dl_vlan_pcp); - rule->wc.vlan_tci_mask |= htons(VLAN_CFI | VLAN_PCP_MASK); + rule->wc.masks.vlan_tci |= htons(VLAN_CFI | VLAN_PCP_MASK); } void @@ -332,7 +332,7 @@ void cls_rule_set_tp_src_masked(struct cls_rule *rule, ovs_be16 port, ovs_be16 mask) { rule->flow.tp_src = port & mask; - rule->wc.tp_src_mask = mask; + rule->wc.masks.tp_src = mask; } void @@ -345,21 +345,21 @@ void cls_rule_set_tp_dst_masked(struct cls_rule *rule, ovs_be16 port, ovs_be16 mask) { rule->flow.tp_dst = port & mask; - rule->wc.tp_dst_mask = mask; + rule->wc.masks.tp_dst = mask; } void cls_rule_set_nw_proto(struct cls_rule *rule, uint8_t nw_proto) { rule->flow.nw_proto = nw_proto; - rule->wc.nw_proto_mask = UINT8_MAX; + rule->wc.masks.nw_proto = UINT8_MAX; } void cls_rule_set_nw_src(struct cls_rule *rule, ovs_be32 nw_src) { rule->flow.nw_src = nw_src; - rule->wc.nw_src_mask = htonl(UINT32_MAX); + rule->wc.masks.nw_src = htonl(UINT32_MAX); } void @@ -367,27 +367,27 @@ cls_rule_set_nw_src_masked(struct cls_rule *rule, ovs_be32 nw_src, ovs_be32 mask) { rule->flow.nw_src = nw_src & mask; - rule->wc.nw_src_mask = mask; + rule->wc.masks.nw_src = mask; } void cls_rule_set_nw_dst(struct cls_rule *rule, ovs_be32 nw_dst) { rule->flow.nw_dst = nw_dst; - rule->wc.nw_dst_mask = htonl(UINT32_MAX); + rule->wc.masks.nw_dst = htonl(UINT32_MAX); } void cls_rule_set_nw_dst_masked(struct cls_rule *rule, ovs_be32 ip, ovs_be32 mask) { rule->flow.nw_dst = ip & mask; - rule->wc.nw_dst_mask = mask; + rule->wc.masks.nw_dst = mask; } void cls_rule_set_nw_dscp(struct cls_rule *rule, uint8_t nw_dscp) { - rule->wc.nw_tos_mask |= IP_DSCP_MASK; + rule->wc.masks.nw_tos |= IP_DSCP_MASK; rule->flow.nw_tos &= ~IP_DSCP_MASK; rule->flow.nw_tos |= nw_dscp & IP_DSCP_MASK; } @@ -395,7 +395,7 @@ cls_rule_set_nw_dscp(struct cls_rule *rule, uint8_t nw_dscp) void cls_rule_set_nw_ecn(struct cls_rule *rule, uint8_t nw_ecn) { - rule->wc.nw_tos_mask |= IP_ECN_MASK; + rule->wc.masks.nw_tos |= IP_ECN_MASK; rule->flow.nw_tos &= ~IP_ECN_MASK; rule->flow.nw_tos |= nw_ecn & IP_ECN_MASK; } @@ -403,14 +403,14 @@ cls_rule_set_nw_ecn(struct cls_rule *rule, uint8_t nw_ecn) void cls_rule_set_nw_ttl(struct cls_rule *rule, uint8_t nw_ttl) { - rule->wc.nw_ttl_mask = UINT8_MAX; + rule->wc.masks.nw_ttl = UINT8_MAX; rule->flow.nw_ttl = nw_ttl; } void cls_rule_set_nw_frag(struct cls_rule *rule, uint8_t nw_frag) { - rule->wc.nw_frag_mask |= FLOW_NW_FRAG_MASK; + rule->wc.masks.nw_frag |= FLOW_NW_FRAG_MASK; rule->flow.nw_frag = nw_frag; } @@ -419,7 +419,7 @@ cls_rule_set_nw_frag_masked(struct cls_rule *rule, uint8_t nw_frag, uint8_t mask) { rule->flow.nw_frag = nw_frag & mask; - rule->wc.nw_frag_mask = mask; + rule->wc.masks.nw_frag = mask; } void @@ -437,7 +437,7 @@ cls_rule_set_icmp_code(struct cls_rule *rule, uint8_t icmp_code) void cls_rule_set_arp_sha(struct cls_rule *rule, const uint8_t sha[ETH_ADDR_LEN]) { - cls_rule_set_eth(sha, rule->flow.arp_sha, rule->wc.arp_sha_mask); + cls_rule_set_eth(sha, rule->flow.arp_sha, rule->wc.masks.arp_sha); } void @@ -446,13 +446,13 @@ cls_rule_set_arp_sha_masked(struct cls_rule *rule, const uint8_t mask[ETH_ADDR_LEN]) { cls_rule_set_eth_masked(arp_sha, mask, - rule->flow.arp_sha, rule->wc.arp_sha_mask); + rule->flow.arp_sha, rule->wc.masks.arp_sha); } void cls_rule_set_arp_tha(struct cls_rule *rule, const uint8_t tha[ETH_ADDR_LEN]) { - cls_rule_set_eth(tha, rule->flow.arp_tha, rule->wc.arp_tha_mask); + cls_rule_set_eth(tha, rule->flow.arp_tha, rule->wc.masks.arp_tha); } void @@ -461,14 +461,14 @@ cls_rule_set_arp_tha_masked(struct cls_rule *rule, const uint8_t mask[ETH_ADDR_LEN]) { cls_rule_set_eth_masked(arp_tha, mask, - rule->flow.arp_tha, rule->wc.arp_tha_mask); + rule->flow.arp_tha, rule->wc.masks.arp_tha); } void cls_rule_set_ipv6_src(struct cls_rule *rule, const struct in6_addr *src) { rule->flow.ipv6_src = *src; - rule->wc.ipv6_src_mask = in6addr_exact; + rule->wc.masks.ipv6_src = in6addr_exact; } void @@ -476,14 +476,14 @@ cls_rule_set_ipv6_src_masked(struct cls_rule *rule, const struct in6_addr *src, const struct in6_addr *mask) { rule->flow.ipv6_src = ipv6_addr_bitand(src, mask); - rule->wc.ipv6_src_mask = *mask; + rule->wc.masks.ipv6_src = *mask; } void cls_rule_set_ipv6_dst(struct cls_rule *rule, const struct in6_addr *dst) { rule->flow.ipv6_dst = *dst; - rule->wc.ipv6_dst_mask = in6addr_exact; + rule->wc.masks.ipv6_dst = in6addr_exact; } void @@ -491,7 +491,7 @@ cls_rule_set_ipv6_dst_masked(struct cls_rule *rule, const struct in6_addr *dst, const struct in6_addr *mask) { rule->flow.ipv6_dst = ipv6_addr_bitand(dst, mask); - rule->wc.ipv6_dst_mask = *mask; + rule->wc.masks.ipv6_dst = *mask; } void @@ -505,14 +505,14 @@ cls_rule_set_ipv6_label_masked(struct cls_rule *rule, ovs_be32 ipv6_label, ovs_be32 mask) { rule->flow.ipv6_label = ipv6_label & mask; - rule->wc.ipv6_label_mask = mask; + rule->wc.masks.ipv6_label = mask; } void cls_rule_set_nd_target(struct cls_rule *rule, const struct in6_addr *target) { rule->flow.nd_target = *target; - rule->wc.nd_target_mask = in6addr_exact; + rule->wc.masks.nd_target = in6addr_exact; } void @@ -521,7 +521,7 @@ cls_rule_set_nd_target_masked(struct cls_rule *rule, const struct in6_addr *mask) { rule->flow.nd_target = ipv6_addr_bitand(target, mask); - rule->wc.nd_target_mask = *mask; + rule->wc.masks.nd_target = *mask; } /* Returns true if 'a' and 'b' have the same priority, wildcard the same @@ -612,10 +612,10 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s) ds_put_format(s, "priority=%d,", rule->priority); } - if (wc->dl_type_mask) { + if (wc->masks.dl_type) { skip_type = true; if (f->dl_type == htons(ETH_TYPE_IP)) { - if (wc->nw_proto_mask) { + if (wc->masks.nw_proto) { skip_proto = true; if (f->nw_proto == IPPROTO_ICMP) { ds_put_cstr(s, "icmp,"); @@ -631,7 +631,7 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s) ds_put_cstr(s, "ip,"); } } else if (f->dl_type == htons(ETH_TYPE_IPV6)) { - if (wc->nw_proto_mask) { + if (wc->masks.nw_proto) { skip_proto = true; if (f->nw_proto == IPPROTO_ICMPV6) { ds_put_cstr(s, "icmp6,"); @@ -653,7 +653,7 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s) } } for (i = 0; i < FLOW_N_REGS; i++) { - switch (wc->reg_masks[i]) { + switch (wc->masks.regs[i]) { case 0: break; case UINT32_MAX: @@ -661,11 +661,11 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s) break; default: ds_put_format(s, "reg%d=0x%"PRIx32"/0x%"PRIx32",", - i, f->regs[i], wc->reg_masks[i]); + i, f->regs[i], wc->masks.regs[i]); break; } } - switch (wc->tun_id_mask) { + switch (wc->masks.tun_id) { case 0: break; case CONSTANT_HTONLL(UINT64_MAX): @@ -673,10 +673,10 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s) break; default: ds_put_format(s, "tun_id=%#"PRIx64"/%#"PRIx64",", - ntohll(f->tun_id), ntohll(wc->tun_id_mask)); + ntohll(f->tun_id), ntohll(wc->masks.tun_id)); break; } - switch (wc->metadata_mask) { + switch (wc->masks.metadata) { case 0: break; case CONSTANT_HTONLL(UINT64_MAX): @@ -684,16 +684,16 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s) break; default: ds_put_format(s, "metadata=%#"PRIx64"/%#"PRIx64",", - ntohll(f->metadata), ntohll(wc->metadata_mask)); + ntohll(f->metadata), ntohll(wc->masks.metadata)); break; } - if (wc->in_port_mask) { + if (wc->masks.in_port) { ds_put_format(s, "in_port=%"PRIu16",", f->in_port); } - if (wc->vlan_tci_mask) { - ovs_be16 vid_mask = wc->vlan_tci_mask & htons(VLAN_VID_MASK); - ovs_be16 pcp_mask = wc->vlan_tci_mask & htons(VLAN_PCP_MASK); - ovs_be16 cfi = wc->vlan_tci_mask & htons(VLAN_CFI); + if (wc->masks.vlan_tci) { + ovs_be16 vid_mask = wc->masks.vlan_tci & htons(VLAN_VID_MASK); + ovs_be16 pcp_mask = wc->masks.vlan_tci & htons(VLAN_PCP_MASK); + ovs_be16 cfi = wc->masks.vlan_tci & htons(VLAN_CFI); if (cfi && f->vlan_tci & htons(VLAN_CFI) && (!vid_mask || vid_mask == htons(VLAN_VID_MASK)) @@ -707,36 +707,36 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s) ds_put_format(s, "dl_vlan_pcp=%d,", vlan_tci_to_pcp(f->vlan_tci)); } - } else if (wc->vlan_tci_mask == htons(0xffff)) { + } else if (wc->masks.vlan_tci == htons(0xffff)) { ds_put_format(s, "vlan_tci=0x%04"PRIx16",", ntohs(f->vlan_tci)); } else { ds_put_format(s, "vlan_tci=0x%04"PRIx16"/0x%04"PRIx16",", - ntohs(f->vlan_tci), ntohs(wc->vlan_tci_mask)); + ntohs(f->vlan_tci), ntohs(wc->masks.vlan_tci)); } } - format_eth_masked(s, "dl_src", f->dl_src, wc->dl_src_mask); - format_eth_masked(s, "dl_dst", f->dl_dst, wc->dl_dst_mask); - if (!skip_type && wc->dl_type_mask) { + format_eth_masked(s, "dl_src", f->dl_src, wc->masks.dl_src); + format_eth_masked(s, "dl_dst", f->dl_dst, wc->masks.dl_dst); + if (!skip_type && wc->masks.dl_type) { ds_put_format(s, "dl_type=0x%04"PRIx16",", ntohs(f->dl_type)); } if (f->dl_type == htons(ETH_TYPE_IPV6)) { - format_ipv6_netmask(s, "ipv6_src", &f->ipv6_src, &wc->ipv6_src_mask); - format_ipv6_netmask(s, "ipv6_dst", &f->ipv6_dst, &wc->ipv6_dst_mask); - if (wc->ipv6_label_mask) { - if (wc->ipv6_label_mask == htonl(UINT32_MAX)) { + format_ipv6_netmask(s, "ipv6_src", &f->ipv6_src, &wc->masks.ipv6_src); + format_ipv6_netmask(s, "ipv6_dst", &f->ipv6_dst, &wc->masks.ipv6_dst); + if (wc->masks.ipv6_label) { + if (wc->masks.ipv6_label == htonl(UINT32_MAX)) { ds_put_format(s, "ipv6_label=0x%05"PRIx32",", ntohl(f->ipv6_label)); } else { ds_put_format(s, "ipv6_label=0x%05"PRIx32"/0x%05"PRIx32",", ntohl(f->ipv6_label), - ntohl(wc->ipv6_label_mask)); + ntohl(wc->masks.ipv6_label)); } } } else { - format_ip_netmask(s, "nw_src", f->nw_src, wc->nw_src_mask); - format_ip_netmask(s, "nw_dst", f->nw_dst, wc->nw_dst_mask); + format_ip_netmask(s, "nw_src", f->nw_src, wc->masks.nw_src); + format_ip_netmask(s, "nw_dst", f->nw_dst, wc->masks.nw_dst); } - if (!skip_proto && wc->nw_proto_mask) { + if (!skip_proto && wc->masks.nw_proto) { if (f->dl_type == htons(ETH_TYPE_ARP)) { ds_put_format(s, "arp_op=%"PRIu8",", f->nw_proto); } else { @@ -744,19 +744,19 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s) } } if (f->dl_type == htons(ETH_TYPE_ARP)) { - format_eth_masked(s, "arp_sha", f->arp_sha, wc->arp_sha_mask); - format_eth_masked(s, "arp_tha", f->arp_tha, wc->arp_tha_mask); + format_eth_masked(s, "arp_sha", f->arp_sha, wc->masks.arp_sha); + format_eth_masked(s, "arp_tha", f->arp_tha, wc->masks.arp_tha); } - if (wc->nw_tos_mask & IP_DSCP_MASK) { + if (wc->masks.nw_tos & IP_DSCP_MASK) { ds_put_format(s, "nw_tos=%"PRIu8",", f->nw_tos & IP_DSCP_MASK); } - if (wc->nw_tos_mask & IP_ECN_MASK) { + if (wc->masks.nw_tos & IP_ECN_MASK) { ds_put_format(s, "nw_ecn=%"PRIu8",", f->nw_tos & IP_ECN_MASK); } - if (wc->nw_ttl_mask) { + if (wc->masks.nw_ttl) { ds_put_format(s, "nw_ttl=%"PRIu8",", f->nw_ttl); } - switch (wc->nw_frag_mask) { + switch (wc->masks.nw_frag) { case FLOW_NW_FRAG_ANY | FLOW_NW_FRAG_LATER: ds_put_format(s, "nw_frag=%s,", f->nw_frag & FLOW_NW_FRAG_ANY @@ -775,18 +775,18 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s) break; } if (f->nw_proto == IPPROTO_ICMP) { - format_be16_masked(s, "icmp_type", f->tp_src, wc->tp_src_mask); - format_be16_masked(s, "icmp_code", f->tp_dst, wc->tp_dst_mask); + format_be16_masked(s, "icmp_type", f->tp_src, wc->masks.tp_src); + format_be16_masked(s, "icmp_code", f->tp_dst, wc->masks.tp_dst); } else if (f->nw_proto == IPPROTO_ICMPV6) { - format_be16_masked(s, "icmp_type", f->tp_src, wc->tp_src_mask); - format_be16_masked(s, "icmp_code", f->tp_dst, wc->tp_dst_mask); + format_be16_masked(s, "icmp_type", f->tp_src, wc->masks.tp_src); + format_be16_masked(s, "icmp_code", f->tp_dst, wc->masks.tp_dst); format_ipv6_netmask(s, "nd_target", &f->nd_target, - &wc->nd_target_mask); - format_eth_masked(s, "nd_sll", f->arp_sha, wc->arp_sha_mask); - format_eth_masked(s, "nd_tll", f->arp_tha, wc->arp_tha_mask); + &wc->masks.nd_target); + format_eth_masked(s, "nd_sll", f->arp_sha, wc->masks.arp_sha); + format_eth_masked(s, "nd_tll", f->arp_tha, wc->masks.arp_tha); } else { - format_be16_masked(s, "tp_src", f->tp_src, wc->tp_src_mask); - format_be16_masked(s, "tp_dst", f->tp_dst, wc->tp_dst_mask); + format_be16_masked(s, "tp_src", f->tp_src, wc->masks.tp_src); + format_be16_masked(s, "tp_dst", f->tp_dst, wc->masks.tp_dst); } if (s->length > start_len && ds_last(s) == ',') { @@ -1292,37 +1292,37 @@ flow_equal_except(const struct flow *a, const struct flow *b, BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17); for (i = 0; i < FLOW_N_REGS; i++) { - if ((a->regs[i] ^ b->regs[i]) & wildcards->reg_masks[i]) { + if ((a->regs[i] ^ b->regs[i]) & wildcards->masks.regs[i]) { return false; } } - return (!((a->tun_id ^ b->tun_id) & wildcards->tun_id_mask) - && !((a->metadata ^ b->metadata) & wildcards->metadata_mask) - && !((a->nw_src ^ b->nw_src) & wildcards->nw_src_mask) - && !((a->nw_dst ^ b->nw_dst) & wildcards->nw_dst_mask) - && !((a->in_port ^ b->in_port) & wildcards->in_port_mask) - && !((a->vlan_tci ^ b->vlan_tci) & wildcards->vlan_tci_mask) - && !((a->dl_type ^ b->dl_type) & wildcards->dl_type_mask) - && !((a->tp_src ^ b->tp_src) & wildcards->tp_src_mask) - && !((a->tp_dst ^ b->tp_dst) & wildcards->tp_dst_mask) + return (!((a->tun_id ^ b->tun_id) & wildcards->masks.tun_id) + && !((a->metadata ^ b->metadata) & wildcards->masks.metadata) + && !((a->nw_src ^ b->nw_src) & wildcards->masks.nw_src) + && !((a->nw_dst ^ b->nw_dst) & wildcards->masks.nw_dst) + && !((a->in_port ^ b->in_port) & wildcards->masks.in_port) + && !((a->vlan_tci ^ b->vlan_tci) & wildcards->masks.vlan_tci) + && !((a->dl_type ^ b->dl_type) & wildcards->masks.dl_type) + && !((a->tp_src ^ b->tp_src) & wildcards->masks.tp_src) + && !((a->tp_dst ^ b->tp_dst) & wildcards->masks.tp_dst) && eth_addr_equal_except(a->dl_src, b->dl_src, - wildcards->dl_src_mask) + wildcards->masks.dl_src) && eth_addr_equal_except(a->dl_dst, b->dl_dst, - wildcards->dl_dst_mask) - && !((a->nw_proto ^ b->nw_proto) & wildcards->nw_proto_mask) - && !((a->nw_ttl ^ b->nw_ttl) & wildcards->nw_ttl_mask) - && !((a->nw_tos ^ b->nw_tos) & wildcards->nw_tos_mask) - && !((a->nw_frag ^ b->nw_frag) & wildcards->nw_frag_mask) + wildcards->masks.dl_dst) + && !((a->nw_proto ^ b->nw_proto) & wildcards->masks.nw_proto) + && !((a->nw_ttl ^ b->nw_ttl) & wildcards->masks.nw_ttl) + && !((a->nw_tos ^ b->nw_tos) & wildcards->masks.nw_tos) + && !((a->nw_frag ^ b->nw_frag) & wildcards->masks.nw_frag) && eth_addr_equal_except(a->arp_sha, b->arp_sha, - wildcards->arp_sha_mask) + wildcards->masks.arp_sha) && eth_addr_equal_except(a->arp_tha, b->arp_tha, - wildcards->arp_tha_mask) - && !((a->ipv6_label ^ b->ipv6_label) & wildcards->ipv6_label_mask) + wildcards->masks.arp_tha) + && !((a->ipv6_label ^ b->ipv6_label) & wildcards->masks.ipv6_label) && ipv6_equal_except(&a->ipv6_src, &b->ipv6_src, - &wildcards->ipv6_src_mask) + &wildcards->masks.ipv6_src) && ipv6_equal_except(&a->ipv6_dst, &b->ipv6_dst, - &wildcards->ipv6_dst_mask) + &wildcards->masks.ipv6_dst) && ipv6_equal_except(&a->nd_target, &b->nd_target, - &wildcards->nd_target_mask)); + &wildcards->masks.nd_target)); } diff --git a/lib/flow.c b/lib/flow.c index a16c8ef6..784edc67 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -447,32 +447,32 @@ flow_zero_wildcards(struct flow *flow, const struct flow_wildcards *wildcards) BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17); for (i = 0; i < FLOW_N_REGS; i++) { - flow->regs[i] &= wildcards->reg_masks[i]; + flow->regs[i] &= wildcards->masks.regs[i]; } - flow->tun_id &= wildcards->tun_id_mask; - flow->metadata &= wildcards->metadata_mask; - flow->nw_src &= wildcards->nw_src_mask; - flow->nw_dst &= wildcards->nw_dst_mask; - flow->in_port &= wildcards->in_port_mask; - flow->vlan_tci &= wildcards->vlan_tci_mask; - flow->dl_type &= wildcards->dl_type_mask; - flow->tp_src &= wildcards->tp_src_mask; - flow->tp_dst &= wildcards->tp_dst_mask; - eth_addr_bitand(flow->dl_src, wildcards->dl_src_mask, flow->dl_src); - eth_addr_bitand(flow->dl_dst, wildcards->dl_dst_mask, flow->dl_dst); - flow->ipv6_label &= wildcards->ipv6_label_mask; - flow->nw_proto &= wildcards->nw_proto_mask; - flow->nw_tos &= wildcards->nw_tos_mask; - flow->nw_ttl &= wildcards->nw_ttl_mask; - flow->nw_frag &= wildcards->nw_frag_mask; - eth_addr_bitand(flow->arp_sha, wildcards->arp_sha_mask, flow->arp_sha); - eth_addr_bitand(flow->arp_tha, wildcards->arp_tha_mask, flow->arp_tha); + flow->tun_id &= wildcards->masks.tun_id; + flow->metadata &= wildcards->masks.metadata; + flow->nw_src &= wildcards->masks.nw_src; + flow->nw_dst &= wildcards->masks.nw_dst; + flow->in_port &= wildcards->masks.in_port; + flow->vlan_tci &= wildcards->masks.vlan_tci; + flow->dl_type &= wildcards->masks.dl_type; + flow->tp_src &= wildcards->masks.tp_src; + flow->tp_dst &= wildcards->masks.tp_dst; + eth_addr_bitand(flow->dl_src, wildcards->masks.dl_src, flow->dl_src); + eth_addr_bitand(flow->dl_dst, wildcards->masks.dl_dst, flow->dl_dst); + flow->ipv6_label &= wildcards->masks.ipv6_label; + flow->nw_proto &= wildcards->masks.nw_proto; + flow->nw_tos &= wildcards->masks.nw_tos; + flow->nw_ttl &= wildcards->masks.nw_ttl; + flow->nw_frag &= wildcards->masks.nw_frag; + eth_addr_bitand(flow->arp_sha, wildcards->masks.arp_sha, flow->arp_sha); + eth_addr_bitand(flow->arp_tha, wildcards->masks.arp_tha, flow->arp_tha); flow->ipv6_src = ipv6_addr_bitand(&flow->ipv6_src, - &wildcards->ipv6_src_mask); + &wildcards->masks.ipv6_src); flow->ipv6_dst = ipv6_addr_bitand(&flow->ipv6_dst, - &wildcards->ipv6_dst_mask); + &wildcards->masks.ipv6_dst); flow->nd_target = ipv6_addr_bitand(&flow->nd_target, - &wildcards->nd_target_mask); + &wildcards->masks.nd_target); flow->skb_priority = 0; } @@ -570,29 +570,29 @@ flow_wildcards_init_catchall(struct flow_wildcards *wc) { BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17); - wc->tun_id_mask = htonll(0); - wc->nw_src_mask = htonl(0); - wc->nw_dst_mask = htonl(0); - wc->ipv6_src_mask = in6addr_any; - wc->ipv6_dst_mask = in6addr_any; - wc->ipv6_label_mask = htonl(0); - wc->nd_target_mask = in6addr_any; - memset(wc->reg_masks, 0, sizeof wc->reg_masks); - wc->metadata_mask = htonll(0); - wc->in_port_mask = 0; - wc->vlan_tci_mask = htons(0); - wc->nw_frag_mask = 0; - wc->dl_type_mask = htons(0); - wc->tp_src_mask = htons(0); - wc->tp_dst_mask = htons(0); - memset(wc->dl_src_mask, 0, ETH_ADDR_LEN); - memset(wc->dl_dst_mask, 0, ETH_ADDR_LEN); - memset(wc->arp_sha_mask, 0, ETH_ADDR_LEN); - memset(wc->arp_tha_mask, 0, ETH_ADDR_LEN); - wc->nw_proto_mask = 0; - wc->nw_tos_mask = 0; - wc->nw_ttl_mask = 0; - memset(wc->zeros, 0, sizeof wc->zeros); + wc->masks.tun_id = htonll(0); + wc->masks.nw_src = htonl(0); + wc->masks.nw_dst = htonl(0); + wc->masks.ipv6_src = in6addr_any; + wc->masks.ipv6_dst = in6addr_any; + wc->masks.ipv6_label = htonl(0); + wc->masks.nd_target = in6addr_any; + memset(wc->masks.regs, 0, sizeof wc->masks.regs); + wc->masks.metadata = htonll(0); + wc->masks.in_port = 0; + wc->masks.vlan_tci = htons(0); + wc->masks.nw_frag = 0; + wc->masks.dl_type = htons(0); + wc->masks.tp_src = htons(0); + wc->masks.tp_dst = htons(0); + memset(wc->masks.dl_src, 0, ETH_ADDR_LEN); + memset(wc->masks.dl_dst, 0, ETH_ADDR_LEN); + memset(wc->masks.arp_sha, 0, ETH_ADDR_LEN); + memset(wc->masks.arp_tha, 0, ETH_ADDR_LEN); + wc->masks.nw_proto = 0; + wc->masks.nw_tos = 0; + wc->masks.nw_ttl = 0; + memset(wc->masks.zeros, 0, sizeof wc->masks.zeros); } /* Initializes 'wc' as an exact-match set of wildcards; that is, 'wc' does not @@ -602,29 +602,29 @@ flow_wildcards_init_exact(struct flow_wildcards *wc) { BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17); - wc->tun_id_mask = htonll(UINT64_MAX); - wc->nw_src_mask = htonl(UINT32_MAX); - wc->nw_dst_mask = htonl(UINT32_MAX); - wc->ipv6_src_mask = in6addr_exact; - wc->ipv6_dst_mask = in6addr_exact; - wc->ipv6_label_mask = htonl(UINT32_MAX); - wc->nd_target_mask = in6addr_exact; - memset(wc->reg_masks, 0xff, sizeof wc->reg_masks); - wc->metadata_mask = htonll(UINT64_MAX); - wc->in_port_mask = UINT16_MAX; - wc->vlan_tci_mask = htons(UINT16_MAX); - wc->nw_frag_mask = UINT8_MAX; - wc->dl_type_mask = htons(UINT16_MAX); - wc->tp_src_mask = htons(UINT16_MAX); - wc->tp_dst_mask = htons(UINT16_MAX); - memset(wc->dl_src_mask, 0xff, ETH_ADDR_LEN); - memset(wc->dl_dst_mask, 0xff, ETH_ADDR_LEN); - memset(wc->arp_sha_mask, 0xff, ETH_ADDR_LEN); - memset(wc->arp_tha_mask, 0xff, ETH_ADDR_LEN); - wc->nw_proto_mask = UINT8_MAX; - wc->nw_tos_mask = UINT8_MAX; - wc->nw_ttl_mask = UINT8_MAX; - memset(wc->zeros, 0, sizeof wc->zeros); + wc->masks.tun_id = htonll(UINT64_MAX); + wc->masks.nw_src = htonl(UINT32_MAX); + wc->masks.nw_dst = htonl(UINT32_MAX); + wc->masks.ipv6_src = in6addr_exact; + wc->masks.ipv6_dst = in6addr_exact; + wc->masks.ipv6_label = htonl(UINT32_MAX); + wc->masks.nd_target = in6addr_exact; + memset(wc->masks.regs, 0xff, sizeof wc->masks.regs); + wc->masks.metadata = htonll(UINT64_MAX); + wc->masks.in_port = UINT16_MAX; + wc->masks.vlan_tci = htons(UINT16_MAX); + wc->masks.nw_frag = UINT8_MAX; + wc->masks.dl_type = htons(UINT16_MAX); + wc->masks.tp_src = htons(UINT16_MAX); + wc->masks.tp_dst = htons(UINT16_MAX); + memset(wc->masks.dl_src, 0xff, ETH_ADDR_LEN); + memset(wc->masks.dl_dst, 0xff, ETH_ADDR_LEN); + memset(wc->masks.arp_sha, 0xff, ETH_ADDR_LEN); + memset(wc->masks.arp_tha, 0xff, ETH_ADDR_LEN); + wc->masks.nw_proto = UINT8_MAX; + wc->masks.nw_tos = UINT8_MAX; + wc->masks.nw_ttl = UINT8_MAX; + memset(wc->masks.zeros, 0, sizeof wc->masks.zeros); } /* Returns true if 'wc' is exact-match, false if 'wc' wildcards any bits or @@ -636,32 +636,32 @@ flow_wildcards_is_exact(const struct flow_wildcards *wc) BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17); - if (wc->tun_id_mask != htonll(UINT64_MAX) - || wc->nw_src_mask != htonl(UINT32_MAX) - || wc->nw_dst_mask != htonl(UINT32_MAX) - || wc->tp_src_mask != htons(UINT16_MAX) - || wc->tp_dst_mask != htons(UINT16_MAX) - || wc->in_port_mask != UINT16_MAX - || wc->vlan_tci_mask != htons(UINT16_MAX) - || wc->metadata_mask != htonll(UINT64_MAX) - || wc->dl_type_mask != htons(UINT16_MAX) - || !eth_mask_is_exact(wc->dl_src_mask) - || !eth_mask_is_exact(wc->dl_dst_mask) - || !eth_mask_is_exact(wc->arp_sha_mask) - || !eth_mask_is_exact(wc->arp_tha_mask) - || !ipv6_mask_is_exact(&wc->ipv6_src_mask) - || !ipv6_mask_is_exact(&wc->ipv6_dst_mask) - || wc->ipv6_label_mask != htonl(UINT32_MAX) - || !ipv6_mask_is_exact(&wc->nd_target_mask) - || wc->nw_proto_mask != UINT8_MAX - || wc->nw_frag_mask != UINT8_MAX - || wc->nw_tos_mask != UINT8_MAX - || wc->nw_ttl_mask != UINT8_MAX) { + if (wc->masks.tun_id != htonll(UINT64_MAX) + || wc->masks.nw_src != htonl(UINT32_MAX) + || wc->masks.nw_dst != htonl(UINT32_MAX) + || wc->masks.tp_src != htons(UINT16_MAX) + || wc->masks.tp_dst != htons(UINT16_MAX) + || wc->masks.in_port != UINT16_MAX + || wc->masks.vlan_tci != htons(UINT16_MAX) + || wc->masks.metadata != htonll(UINT64_MAX) + || wc->masks.dl_type != htons(UINT16_MAX) + || !eth_mask_is_exact(wc->masks.dl_src) + || !eth_mask_is_exact(wc->masks.dl_dst) + || !eth_mask_is_exact(wc->masks.arp_sha) + || !eth_mask_is_exact(wc->masks.arp_tha) + || !ipv6_mask_is_exact(&wc->masks.ipv6_src) + || !ipv6_mask_is_exact(&wc->masks.ipv6_dst) + || wc->masks.ipv6_label != htonl(UINT32_MAX) + || !ipv6_mask_is_exact(&wc->masks.nd_target) + || wc->masks.nw_proto != UINT8_MAX + || wc->masks.nw_frag != UINT8_MAX + || wc->masks.nw_tos != UINT8_MAX + || wc->masks.nw_ttl != UINT8_MAX) { return false; } for (i = 0; i < FLOW_N_REGS; i++) { - if (wc->reg_masks[i] != UINT32_MAX) { + if (wc->masks.regs[i] != UINT32_MAX) { return false; } } @@ -678,32 +678,32 @@ flow_wildcards_is_catchall(const struct flow_wildcards *wc) BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17); - if (wc->tun_id_mask != htonll(0) - || wc->nw_src_mask != htonl(0) - || wc->nw_dst_mask != htonl(0) - || wc->tp_src_mask != htons(0) - || wc->tp_dst_mask != htons(0) - || wc->in_port_mask != 0 - || wc->vlan_tci_mask != htons(0) - || wc->metadata_mask != htonll(0) - || wc->dl_type_mask != htons(0) - || !eth_addr_is_zero(wc->dl_src_mask) - || !eth_addr_is_zero(wc->dl_dst_mask) - || !eth_addr_is_zero(wc->arp_sha_mask) - || !eth_addr_is_zero(wc->arp_tha_mask) - || !ipv6_mask_is_any(&wc->ipv6_src_mask) - || !ipv6_mask_is_any(&wc->ipv6_dst_mask) - || wc->ipv6_label_mask != htonl(0) - || !ipv6_mask_is_any(&wc->nd_target_mask) - || wc->nw_proto_mask != 0 - || wc->nw_frag_mask != 0 - || wc->nw_tos_mask != 0 - || wc->nw_ttl_mask != 0) { + if (wc->masks.tun_id != htonll(0) + || wc->masks.nw_src != htonl(0) + || wc->masks.nw_dst != htonl(0) + || wc->masks.tp_src != htons(0) + || wc->masks.tp_dst != htons(0) + || wc->masks.in_port != 0 + || wc->masks.vlan_tci != htons(0) + || wc->masks.metadata != htonll(0) + || wc->masks.dl_type != htons(0) + || !eth_addr_is_zero(wc->masks.dl_src) + || !eth_addr_is_zero(wc->masks.dl_dst) + || !eth_addr_is_zero(wc->masks.arp_sha) + || !eth_addr_is_zero(wc->masks.arp_tha) + || !ipv6_mask_is_any(&wc->masks.ipv6_src) + || !ipv6_mask_is_any(&wc->masks.ipv6_dst) + || wc->masks.ipv6_label != htonl(0) + || !ipv6_mask_is_any(&wc->masks.nd_target) + || wc->masks.nw_proto != 0 + || wc->masks.nw_frag != 0 + || wc->masks.nw_tos != 0 + || wc->masks.nw_ttl != 0) { return false; } for (i = 0; i < FLOW_N_REGS; i++) { - if (wc->reg_masks[i] != 0) { + if (wc->masks.regs[i] != 0) { return false; } } @@ -723,33 +723,35 @@ flow_wildcards_combine(struct flow_wildcards *dst, BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17); - dst->tun_id_mask = src1->tun_id_mask & src2->tun_id_mask; - dst->nw_src_mask = src1->nw_src_mask & src2->nw_src_mask; - dst->nw_dst_mask = src1->nw_dst_mask & src2->nw_dst_mask; - dst->ipv6_src_mask = ipv6_addr_bitand(&src1->ipv6_src_mask, - &src2->ipv6_src_mask); - dst->ipv6_dst_mask = ipv6_addr_bitand(&src1->ipv6_dst_mask, - &src2->ipv6_dst_mask); - dst->ipv6_label_mask = src1->ipv6_label_mask & src2->ipv6_label_mask; - dst->nd_target_mask = ipv6_addr_bitand(&src1->nd_target_mask, - &src2->nd_target_mask); + dst->masks.tun_id = src1->masks.tun_id & src2->masks.tun_id; + dst->masks.nw_src = src1->masks.nw_src & src2->masks.nw_src; + dst->masks.nw_dst = src1->masks.nw_dst & src2->masks.nw_dst; + dst->masks.ipv6_src = ipv6_addr_bitand(&src1->masks.ipv6_src, + &src2->masks.ipv6_src); + dst->masks.ipv6_dst = ipv6_addr_bitand(&src1->masks.ipv6_dst, + &src2->masks.ipv6_dst); + dst->masks.ipv6_label = src1->masks.ipv6_label & src2->masks.ipv6_label; + dst->masks.nd_target = ipv6_addr_bitand(&src1->masks.nd_target, + &src2->masks.nd_target); for (i = 0; i < FLOW_N_REGS; i++) { - dst->reg_masks[i] = src1->reg_masks[i] & src2->reg_masks[i]; + dst->masks.regs[i] = src1->masks.regs[i] & src2->masks.regs[i]; } - dst->metadata_mask = src1->metadata_mask & src2->metadata_mask; - dst->in_port_mask = src1->in_port_mask & src2->in_port_mask; - dst->vlan_tci_mask = src1->vlan_tci_mask & src2->vlan_tci_mask; - dst->dl_type_mask = src1->dl_type_mask & src2->dl_type_mask; - dst->tp_src_mask = src1->tp_src_mask & src2->tp_src_mask; - dst->tp_dst_mask = src1->tp_dst_mask & src2->tp_dst_mask; - dst->nw_frag_mask = src1->nw_frag_mask & src2->nw_frag_mask; - eth_addr_bitand(src1->dl_src_mask, src2->dl_src_mask, dst->dl_src_mask); - eth_addr_bitand(src1->dl_dst_mask, src2->dl_dst_mask, dst->dl_dst_mask); - eth_addr_bitand(src1->arp_sha_mask, src2->arp_sha_mask, dst->arp_sha_mask); - eth_addr_bitand(src1->arp_tha_mask, src2->arp_tha_mask, dst->arp_tha_mask); - dst->nw_proto_mask = src1->nw_proto_mask & src2->nw_proto_mask; - dst->nw_tos_mask = src1->nw_tos_mask & src2->nw_tos_mask; - dst->nw_ttl_mask = src1->nw_ttl_mask & src2->nw_ttl_mask; + dst->masks.metadata = src1->masks.metadata & src2->masks.metadata; + dst->masks.in_port = src1->masks.in_port & src2->masks.in_port; + dst->masks.vlan_tci = src1->masks.vlan_tci & src2->masks.vlan_tci; + dst->masks.dl_type = src1->masks.dl_type & src2->masks.dl_type; + dst->masks.tp_src = src1->masks.tp_src & src2->masks.tp_src; + dst->masks.tp_dst = src1->masks.tp_dst & src2->masks.tp_dst; + dst->masks.nw_frag = src1->masks.nw_frag & src2->masks.nw_frag; + eth_addr_bitand(src1->masks.dl_src, src2->masks.dl_src, dst->masks.dl_src); + eth_addr_bitand(src1->masks.dl_dst, src2->masks.dl_dst, dst->masks.dl_dst); + eth_addr_bitand(src1->masks.arp_sha, src2->masks.arp_sha, + dst->masks.arp_sha); + eth_addr_bitand(src1->masks.arp_tha, src2->masks.arp_tha, + dst->masks.arp_tha); + dst->masks.nw_proto = src1->masks.nw_proto & src2->masks.nw_proto; + dst->masks.nw_tos = src1->masks.nw_tos & src2->masks.nw_tos; + dst->masks.nw_ttl = src1->masks.nw_ttl & src2->masks.nw_ttl; } /* Returns a hash of the wildcards in 'wc'. */ @@ -769,32 +771,32 @@ flow_wildcards_equal(const struct flow_wildcards *a, BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17); - if (a->tun_id_mask != b->tun_id_mask - || a->nw_src_mask != b->nw_src_mask - || a->nw_dst_mask != b->nw_dst_mask - || a->in_port_mask != b->in_port_mask - || a->vlan_tci_mask != b->vlan_tci_mask - || a->metadata_mask != b->metadata_mask - || a->dl_type_mask != b->dl_type_mask - || !ipv6_addr_equals(&a->ipv6_src_mask, &b->ipv6_src_mask) - || !ipv6_addr_equals(&a->ipv6_dst_mask, &b->ipv6_dst_mask) - || a->ipv6_label_mask != b->ipv6_label_mask - || !ipv6_addr_equals(&a->nd_target_mask, &b->nd_target_mask) - || a->tp_src_mask != b->tp_src_mask - || a->tp_dst_mask != b->tp_dst_mask - || a->nw_frag_mask != b->nw_frag_mask - || !eth_addr_equals(a->dl_src_mask, b->dl_src_mask) - || !eth_addr_equals(a->dl_dst_mask, b->dl_dst_mask) - || !eth_addr_equals(a->arp_sha_mask, b->arp_sha_mask) - || !eth_addr_equals(a->arp_tha_mask, b->arp_tha_mask) - || a->nw_proto_mask != b->nw_proto_mask - || a->nw_tos_mask != b->nw_tos_mask - || a->nw_ttl_mask != b->nw_ttl_mask) { + if (a->masks.tun_id != b->masks.tun_id + || a->masks.nw_src != b->masks.nw_src + || a->masks.nw_dst != b->masks.nw_dst + || a->masks.in_port != b->masks.in_port + || a->masks.vlan_tci != b->masks.vlan_tci + || a->masks.metadata != b->masks.metadata + || a->masks.dl_type != b->masks.dl_type + || !ipv6_addr_equals(&a->masks.ipv6_src, &b->masks.ipv6_src) + || !ipv6_addr_equals(&a->masks.ipv6_dst, &b->masks.ipv6_dst) + || a->masks.ipv6_label != b->masks.ipv6_label + || !ipv6_addr_equals(&a->masks.nd_target, &b->masks.nd_target) + || a->masks.tp_src != b->masks.tp_src + || a->masks.tp_dst != b->masks.tp_dst + || a->masks.nw_frag != b->masks.nw_frag + || !eth_addr_equals(a->masks.dl_src, b->masks.dl_src) + || !eth_addr_equals(a->masks.dl_dst, b->masks.dl_dst) + || !eth_addr_equals(a->masks.arp_sha, b->masks.arp_sha) + || !eth_addr_equals(a->masks.arp_tha, b->masks.arp_tha) + || a->masks.nw_proto != b->masks.nw_proto + || a->masks.nw_tos != b->masks.nw_tos + || a->masks.nw_ttl != b->masks.nw_ttl) { return false; } for (i = 0; i < FLOW_N_REGS; i++) { - if (a->reg_masks[i] != b->reg_masks[i]) { + if (a->masks.regs[i] != b->masks.regs[i]) { return false; } } @@ -815,60 +817,62 @@ flow_wildcards_has_extra(const struct flow_wildcards *a, BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17); for (i = 0; i < FLOW_N_REGS; i++) { - if ((a->reg_masks[i] & b->reg_masks[i]) != b->reg_masks[i]) { + if ((a->masks.regs[i] & b->masks.regs[i]) != b->masks.regs[i]) { return true; } } - eth_addr_bitand(a->dl_src_mask, b->dl_src_mask, eth_masked); - if (!eth_addr_equals(eth_masked, b->dl_src_mask)) { + eth_addr_bitand(a->masks.dl_src, b->masks.dl_src, eth_masked); + if (!eth_addr_equals(eth_masked, b->masks.dl_src)) { return true; } - eth_addr_bitand(a->dl_dst_mask, b->dl_dst_mask, eth_masked); - if (!eth_addr_equals(eth_masked, b->dl_dst_mask)) { + eth_addr_bitand(a->masks.dl_dst, b->masks.dl_dst, eth_masked); + if (!eth_addr_equals(eth_masked, b->masks.dl_dst)) { return true; } - eth_addr_bitand(a->arp_sha_mask, b->arp_sha_mask, eth_masked); - if (!eth_addr_equals(eth_masked, b->arp_sha_mask)) { + eth_addr_bitand(a->masks.arp_sha, b->masks.arp_sha, eth_masked); + if (!eth_addr_equals(eth_masked, b->masks.arp_sha)) { return true; } - eth_addr_bitand(a->arp_tha_mask, b->arp_tha_mask, eth_masked); - if (!eth_addr_equals(eth_masked, b->arp_tha_mask)) { + eth_addr_bitand(a->masks.arp_tha, b->masks.arp_tha, eth_masked); + if (!eth_addr_equals(eth_masked, b->masks.arp_tha)) { return true; } - ipv6_masked = ipv6_addr_bitand(&a->ipv6_src_mask, &b->ipv6_src_mask); - if (!ipv6_addr_equals(&ipv6_masked, &b->ipv6_src_mask)) { + ipv6_masked = ipv6_addr_bitand(&a->masks.ipv6_src, &b->masks.ipv6_src); + if (!ipv6_addr_equals(&ipv6_masked, &b->masks.ipv6_src)) { return true; } - ipv6_masked = ipv6_addr_bitand(&a->ipv6_dst_mask, &b->ipv6_dst_mask); - if (!ipv6_addr_equals(&ipv6_masked, &b->ipv6_dst_mask)) { + ipv6_masked = ipv6_addr_bitand(&a->masks.ipv6_dst, &b->masks.ipv6_dst); + if (!ipv6_addr_equals(&ipv6_masked, &b->masks.ipv6_dst)) { return true; } - ipv6_masked = ipv6_addr_bitand(&a->nd_target_mask, &b->nd_target_mask); - if (!ipv6_addr_equals(&ipv6_masked, &b->nd_target_mask)) { + ipv6_masked = ipv6_addr_bitand(&a->masks.nd_target, &b->masks.nd_target); + if (!ipv6_addr_equals(&ipv6_masked, &b->masks.nd_target)) { return true; } - return ((a->tun_id_mask & b->tun_id_mask) != b->tun_id_mask - || (a->nw_src_mask & b->nw_src_mask) != b->nw_src_mask - || (a->nw_dst_mask & b->nw_dst_mask) != b->nw_dst_mask - || (a->ipv6_label_mask & b->ipv6_label_mask) != b->ipv6_label_mask - || (a->in_port_mask & b->in_port_mask) != b->in_port_mask - || (a->vlan_tci_mask & b->vlan_tci_mask) != b->vlan_tci_mask - || (a->metadata_mask & b->metadata_mask) != b->metadata_mask - || (a->dl_type_mask & b->dl_type_mask) != b->dl_type_mask - || (a->tp_src_mask & b->tp_src_mask) != b->tp_src_mask - || (a->tp_dst_mask & b->tp_dst_mask) != b->tp_dst_mask - || (a->nw_proto_mask & b->nw_proto_mask) != b->nw_proto_mask - || (a->nw_frag_mask & b->nw_frag_mask) != b->nw_frag_mask - || (a->nw_tos_mask & b->nw_tos_mask) != b->nw_tos_mask - || (a->nw_ttl_mask & b->nw_ttl_mask) != b->nw_ttl_mask); + return ((a->masks.tun_id & b->masks.tun_id) != b->masks.tun_id + || (a->masks.nw_src & b->masks.nw_src) != b->masks.nw_src + || (a->masks.nw_dst & b->masks.nw_dst) != b->masks.nw_dst + || ((a->masks.ipv6_label & b->masks.ipv6_label) + != b->masks.ipv6_label) + || (a->masks.in_port & b->masks.in_port) != b->masks.in_port + || (a->masks.vlan_tci & b->masks.vlan_tci) != b->masks.vlan_tci + || (a->masks.metadata & b->masks.metadata) != b->masks.metadata + || (a->masks.dl_type & b->masks.dl_type) != b->masks.dl_type + || (a->masks.dl_type & b->masks.dl_type) != b->masks.dl_type + || (a->masks.tp_src & b->masks.tp_src) != b->masks.tp_src + || (a->masks.tp_dst & b->masks.tp_dst) != b->masks.tp_dst + || (a->masks.nw_proto & b->masks.nw_proto) != b->masks.nw_proto + || (a->masks.nw_frag & b->masks.nw_frag) != b->masks.nw_frag + || (a->masks.nw_tos & b->masks.nw_tos) != b->masks.nw_tos + || (a->masks.nw_ttl & b->masks.nw_ttl) != b->masks.nw_ttl); } /* Sets the wildcard mask for register 'idx' in 'wc' to 'mask'. @@ -876,7 +880,7 @@ flow_wildcards_has_extra(const struct flow_wildcards *a, void flow_wildcards_set_reg_mask(struct flow_wildcards *wc, int idx, uint32_t mask) { - wc->reg_masks[idx] = mask; + wc->masks.regs[idx] = mask; } /* Hashes 'flow' based on its L2 through L4 protocol information. */ diff --git a/lib/flow.h b/lib/flow.h index 3534fb48..d12a62bf 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -126,37 +126,14 @@ flow_hash(const struct flow *flow, uint32_t basis) return hash_words((const uint32_t *) flow, sizeof *flow / 4, basis); } -/* Information on wildcards for a flow, as a supplement to "struct flow". */ +/* Wildcards for a flow. + * + * A 1-bit in each bit in 'masks' indicates that the corresponding bit of + * the flow is significant (must match). A 0-bit indicates that the + * corresponding bit of the flow is wildcarded (need not match). */ struct flow_wildcards { - ovs_be64 tun_id_mask; /* 1-bit in each significant tun_id bit. */ - ovs_be64 metadata_mask; /* 1-bit in each significant metadata bit. */ - uint32_t reg_masks[FLOW_N_REGS]; /* 1-bit in each significant regs bit. */ - ovs_be32 nw_src_mask; /* 1-bit in each significant nw_src bit. */ - ovs_be32 nw_dst_mask; /* 1-bit in each significant nw_dst bit. */ - struct in6_addr ipv6_src_mask; /* 1-bit in each signficant ipv6_src bit. */ - struct in6_addr ipv6_dst_mask; /* 1-bit in each signficant ipv6_dst bit. */ - struct in6_addr nd_target_mask; /* 1-bit in each significant - nd_target bit. */ - ovs_be32 ipv6_label_mask; /* 1 bit in each significant ipv6_label bit. */ - uint16_t in_port_mask; /* 1-bit in each significant in_port bit. */ - ovs_be16 vlan_tci_mask; /* 1-bit in each significant vlan_tci bit. */ - ovs_be16 dl_type_mask; /* 1-bit in each significant dl_type bit. */ - ovs_be16 tp_src_mask; /* 1-bit in each significant tp_src bit. */ - ovs_be16 tp_dst_mask; /* 1-bit in each significant tp_dst bit. */ - uint8_t nw_proto_mask; /* 1-bit in each significant nw_proto bit. */ - uint8_t nw_frag_mask; /* 1-bit in each significant nw_frag bit. */ - uint8_t dl_src_mask[6]; /* 1-bit in each significant dl_src bit. */ - uint8_t dl_dst_mask[6]; /* 1-bit in each significant dl_dst bit. */ - uint8_t arp_sha_mask[6]; /* 1-bit in each significant dl_dst bit. */ - uint8_t arp_tha_mask[6]; /* 1-bit in each significant dl_dst bit. */ - uint8_t nw_tos_mask; /* 1-bit in each significant nw_tos bit. */ - uint8_t nw_ttl_mask; /* 1-bit in each significant nw_ttl bit. */ - uint8_t zeros[6]; /* Padding field set to zero. */ + struct flow masks; }; -BUILD_ASSERT_DECL(sizeof(struct flow_wildcards) % 8 == 0); - -/* Remember to update FLOW_WC_SEQ when updating struct flow_wildcards. */ -BUILD_ASSERT_DECL(sizeof(struct flow_wildcards) == 152 && FLOW_WC_SEQ == 17); void flow_wildcards_init_catchall(struct flow_wildcards *); void flow_wildcards_init_exact(struct flow_wildcards *); diff --git a/lib/meta-flow.c b/lib/meta-flow.c index 7306df0d..8d64aa91 100644 --- a/lib/meta-flow.c +++ b/lib/meta-flow.c @@ -574,84 +574,84 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc) { switch (mf->id) { case MFF_TUN_ID: - return !wc->tun_id_mask; + return !wc->masks.tun_id; case MFF_METADATA: - return !wc->metadata_mask; + return !wc->masks.metadata; case MFF_IN_PORT: - return !wc->in_port_mask; + return !wc->masks.in_port; CASE_MFF_REGS: - return !wc->reg_masks[mf->id - MFF_REG0]; + return !wc->masks.regs[mf->id - MFF_REG0]; case MFF_ETH_SRC: - return eth_addr_is_zero(wc->dl_src_mask); + return eth_addr_is_zero(wc->masks.dl_src); case MFF_ETH_DST: - return eth_addr_is_zero(wc->dl_dst_mask); + return eth_addr_is_zero(wc->masks.dl_dst); case MFF_ETH_TYPE: - return !wc->dl_type_mask; + return !wc->masks.dl_type; case MFF_ARP_SHA: case MFF_ND_SLL: - return eth_addr_is_zero(wc->arp_sha_mask); + return eth_addr_is_zero(wc->masks.arp_sha); case MFF_ARP_THA: case MFF_ND_TLL: - return eth_addr_is_zero(wc->arp_tha_mask); + return eth_addr_is_zero(wc->masks.arp_tha); case MFF_VLAN_TCI: - return !wc->vlan_tci_mask; + return !wc->masks.vlan_tci; case MFF_DL_VLAN: - return !(wc->vlan_tci_mask & htons(VLAN_VID_MASK)); + return !(wc->masks.vlan_tci & htons(VLAN_VID_MASK)); case MFF_VLAN_VID: - return !(wc->vlan_tci_mask & htons(VLAN_VID_MASK | VLAN_CFI)); + return !(wc->masks.vlan_tci & htons(VLAN_VID_MASK | VLAN_CFI)); case MFF_DL_VLAN_PCP: case MFF_VLAN_PCP: - return !(wc->vlan_tci_mask & htons(VLAN_PCP_MASK)); + return !(wc->masks.vlan_tci & htons(VLAN_PCP_MASK)); case MFF_IPV4_SRC: - return !wc->nw_src_mask; + return !wc->masks.nw_src; case MFF_IPV4_DST: - return !wc->nw_dst_mask; + return !wc->masks.nw_dst; case MFF_IPV6_SRC: - return ipv6_mask_is_any(&wc->ipv6_src_mask); + return ipv6_mask_is_any(&wc->masks.ipv6_src); case MFF_IPV6_DST: - return ipv6_mask_is_any(&wc->ipv6_dst_mask); + return ipv6_mask_is_any(&wc->masks.ipv6_dst); case MFF_IPV6_LABEL: - return !wc->ipv6_label_mask; + return !wc->masks.ipv6_label; case MFF_IP_PROTO: - return !wc->nw_proto_mask; + return !wc->masks.nw_proto; case MFF_IP_DSCP: - return !(wc->nw_tos_mask & IP_DSCP_MASK); + return !(wc->masks.nw_tos & IP_DSCP_MASK); case MFF_IP_ECN: - return !(wc->nw_tos_mask & IP_ECN_MASK); + return !(wc->masks.nw_tos & IP_ECN_MASK); case MFF_IP_TTL: - return !wc->nw_ttl_mask; + return !wc->masks.nw_ttl; case MFF_ND_TARGET: - return ipv6_mask_is_any(&wc->nd_target_mask); + return ipv6_mask_is_any(&wc->masks.nd_target); case MFF_IP_FRAG: - return !(wc->nw_frag_mask & FLOW_NW_FRAG_MASK); + return !(wc->masks.nw_frag & FLOW_NW_FRAG_MASK); case MFF_ARP_OP: - return !wc->nw_proto_mask; + return !wc->masks.nw_proto; case MFF_ARP_SPA: - return !wc->nw_src_mask; + return !wc->masks.nw_src; case MFF_ARP_TPA: - return !wc->nw_dst_mask; + return !wc->masks.nw_dst; case MFF_TCP_SRC: case MFF_UDP_SRC: case MFF_ICMPV4_TYPE: case MFF_ICMPV6_TYPE: - return !wc->tp_src_mask; + return !wc->masks.tp_src; case MFF_TCP_DST: case MFF_UDP_DST: case MFF_ICMPV4_CODE: case MFF_ICMPV6_CODE: - return !wc->tp_dst_mask; + return !wc->masks.tp_dst; case MFF_N_IDS: default: @@ -671,114 +671,114 @@ mf_get_mask(const struct mf_field *mf, const struct flow_wildcards *wc, { switch (mf->id) { case MFF_TUN_ID: - mask->be64 = wc->tun_id_mask; + mask->be64 = wc->masks.tun_id; break; case MFF_METADATA: - mask->be64 = wc->metadata_mask; + mask->be64 = wc->masks.metadata; break; case MFF_IN_PORT: - mask->be16 = htons(wc->in_port_mask); + mask->be16 = htons(wc->masks.in_port); break; CASE_MFF_REGS: - mask->be32 = htonl(wc->reg_masks[mf->id - MFF_REG0]); + mask->be32 = htonl(wc->masks.regs[mf->id - MFF_REG0]); break; case MFF_ETH_DST: - memcpy(mask->mac, wc->dl_dst_mask, ETH_ADDR_LEN); + memcpy(mask->mac, wc->masks.dl_dst, ETH_ADDR_LEN); break; case MFF_ETH_SRC: - memcpy(mask->mac, wc->dl_src_mask, ETH_ADDR_LEN); + memcpy(mask->mac, wc->masks.dl_src, ETH_ADDR_LEN); break; case MFF_ETH_TYPE: - mask->be16 = wc->dl_type_mask; + mask->be16 = wc->masks.dl_type; break; case MFF_VLAN_TCI: - mask->be16 = wc->vlan_tci_mask; + mask->be16 = wc->masks.vlan_tci; break; case MFF_DL_VLAN: - mask->be16 = wc->vlan_tci_mask & htons(VLAN_VID_MASK); + mask->be16 = wc->masks.vlan_tci & htons(VLAN_VID_MASK); break; case MFF_VLAN_VID: - mask->be16 = wc->vlan_tci_mask & htons(VLAN_VID_MASK | VLAN_CFI); + mask->be16 = wc->masks.vlan_tci & htons(VLAN_VID_MASK | VLAN_CFI); break; case MFF_DL_VLAN_PCP: case MFF_VLAN_PCP: - mask->u8 = vlan_tci_to_pcp(wc->vlan_tci_mask); + mask->u8 = vlan_tci_to_pcp(wc->masks.vlan_tci); break; case MFF_IPV4_SRC: - mask->be32 = wc->nw_src_mask; + mask->be32 = wc->masks.nw_src; break; case MFF_IPV4_DST: - mask->be32 = wc->nw_dst_mask; + mask->be32 = wc->masks.nw_dst; break; case MFF_IPV6_SRC: - mask->ipv6 = wc->ipv6_src_mask; + mask->ipv6 = wc->masks.ipv6_src; break; case MFF_IPV6_DST: - mask->ipv6 = wc->ipv6_dst_mask; + mask->ipv6 = wc->masks.ipv6_dst; break; case MFF_IPV6_LABEL: - mask->be32 = wc->ipv6_label_mask; + mask->be32 = wc->masks.ipv6_label; break; case MFF_IP_PROTO: - mask->u8 = wc->nw_proto_mask; + mask->u8 = wc->masks.nw_proto; break; case MFF_IP_DSCP: - mask->u8 = wc->nw_tos_mask & IP_DSCP_MASK; + mask->u8 = wc->masks.nw_tos & IP_DSCP_MASK; break; case MFF_IP_ECN: - mask->u8 = wc->nw_tos_mask & IP_ECN_MASK; + mask->u8 = wc->masks.nw_tos & IP_ECN_MASK; break; case MFF_ND_TARGET: - mask->ipv6 = wc->nd_target_mask; + mask->ipv6 = wc->masks.nd_target; break; case MFF_IP_TTL: - mask->u8 = wc->nw_ttl_mask; + mask->u8 = wc->masks.nw_ttl; break; case MFF_IP_FRAG: - mask->u8 = wc->nw_frag_mask & FLOW_NW_FRAG_MASK; + mask->u8 = wc->masks.nw_frag & FLOW_NW_FRAG_MASK; break; case MFF_ARP_OP: - mask->u8 = wc->nw_proto_mask; + mask->u8 = wc->masks.nw_proto; break; case MFF_ARP_SPA: - mask->be32 = wc->nw_src_mask; + mask->be32 = wc->masks.nw_src; break; case MFF_ARP_TPA: - mask->be32 = wc->nw_dst_mask; + mask->be32 = wc->masks.nw_dst; break; case MFF_ARP_SHA: case MFF_ND_SLL: - memcpy(mask->mac, wc->arp_sha_mask, ETH_ADDR_LEN); + memcpy(mask->mac, wc->masks.arp_sha, ETH_ADDR_LEN); break; case MFF_ARP_THA: case MFF_ND_TLL: - memcpy(mask->mac, wc->arp_tha_mask, ETH_ADDR_LEN); + memcpy(mask->mac, wc->masks.arp_tha, ETH_ADDR_LEN); break; case MFF_TCP_SRC: case MFF_UDP_SRC: - mask->be16 = wc->tp_src_mask; + mask->be16 = wc->masks.tp_src; break; case MFF_TCP_DST: case MFF_UDP_DST: - mask->be16 = wc->tp_dst_mask; + mask->be16 = wc->masks.tp_dst; break; case MFF_ICMPV4_TYPE: case MFF_ICMPV6_TYPE: - mask->u8 = ntohs(wc->tp_src_mask); + mask->u8 = ntohs(wc->masks.tp_src); break; case MFF_ICMPV4_CODE: case MFF_ICMPV6_CODE: - mask->u8 = ntohs(wc->tp_dst_mask); + mask->u8 = ntohs(wc->masks.tp_dst); break; case MFF_N_IDS: @@ -1403,7 +1403,7 @@ mf_set_wild(const struct mf_field *mf, struct cls_rule *rule) case MFF_IN_PORT: rule->flow.in_port = 0; - rule->wc.in_port_mask = 0; + rule->wc.masks.in_port = 0; break; CASE_MFF_REGS: @@ -1412,17 +1412,17 @@ mf_set_wild(const struct mf_field *mf, struct cls_rule *rule) case MFF_ETH_SRC: memset(rule->flow.dl_src, 0, ETH_ADDR_LEN); - memset(rule->wc.dl_src_mask, 0, ETH_ADDR_LEN); + memset(rule->wc.masks.dl_src, 0, ETH_ADDR_LEN); break; case MFF_ETH_DST: memset(rule->flow.dl_dst, 0, ETH_ADDR_LEN); - memset(rule->wc.dl_dst_mask, 0, ETH_ADDR_LEN); + memset(rule->wc.masks.dl_dst, 0, ETH_ADDR_LEN); break; case MFF_ETH_TYPE: rule->flow.dl_type = htons(0); - rule->wc.dl_type_mask = htons(0); + rule->wc.masks.dl_type = htons(0); break; case MFF_VLAN_TCI: @@ -1450,67 +1450,67 @@ mf_set_wild(const struct mf_field *mf, struct cls_rule *rule) break; case MFF_IPV6_SRC: - memset(&rule->wc.ipv6_src_mask, 0, sizeof rule->wc.ipv6_src_mask); + memset(&rule->wc.masks.ipv6_src, 0, sizeof rule->wc.masks.ipv6_src); memset(&rule->flow.ipv6_src, 0, sizeof rule->flow.ipv6_src); break; case MFF_IPV6_DST: - memset(&rule->wc.ipv6_dst_mask, 0, sizeof rule->wc.ipv6_dst_mask); + memset(&rule->wc.masks.ipv6_dst, 0, sizeof rule->wc.masks.ipv6_dst); memset(&rule->flow.ipv6_dst, 0, sizeof rule->flow.ipv6_dst); break; case MFF_IPV6_LABEL: - rule->wc.ipv6_label_mask = 0; - rule->flow.ipv6_label = 0; + rule->wc.masks.ipv6_label = htonl(0); + rule->flow.ipv6_label = htonl(0); break; case MFF_IP_PROTO: - rule->wc.nw_proto_mask = 0; + rule->wc.masks.nw_proto = 0; rule->flow.nw_proto = 0; break; case MFF_IP_DSCP: - rule->wc.nw_tos_mask &= ~IP_DSCP_MASK; + rule->wc.masks.nw_tos &= ~IP_DSCP_MASK; rule->flow.nw_tos &= ~IP_DSCP_MASK; break; case MFF_IP_ECN: - rule->wc.nw_tos_mask &= ~IP_ECN_MASK; + rule->wc.masks.nw_tos &= ~IP_ECN_MASK; rule->flow.nw_tos &= ~IP_ECN_MASK; break; case MFF_IP_TTL: - rule->wc.nw_ttl_mask = 0; + rule->wc.masks.nw_ttl = 0; rule->flow.nw_ttl = 0; break; case MFF_IP_FRAG: - rule->wc.nw_frag_mask |= FLOW_NW_FRAG_MASK; + rule->wc.masks.nw_frag |= FLOW_NW_FRAG_MASK; rule->flow.nw_frag &= ~FLOW_NW_FRAG_MASK; break; case MFF_ARP_OP: - rule->wc.nw_proto_mask = 0; + rule->wc.masks.nw_proto = 0; rule->flow.nw_proto = 0; break; case MFF_ARP_SHA: case MFF_ND_SLL: memset(rule->flow.arp_sha, 0, ETH_ADDR_LEN); - memset(rule->wc.arp_sha_mask, 0, ETH_ADDR_LEN); + memset(rule->wc.masks.arp_sha, 0, ETH_ADDR_LEN); break; case MFF_ARP_THA: case MFF_ND_TLL: memset(rule->flow.arp_tha, 0, ETH_ADDR_LEN); - memset(rule->wc.arp_tha_mask, 0, ETH_ADDR_LEN); + memset(rule->wc.masks.arp_tha, 0, ETH_ADDR_LEN); break; case MFF_TCP_SRC: case MFF_UDP_SRC: case MFF_ICMPV4_TYPE: case MFF_ICMPV6_TYPE: - rule->wc.tp_src_mask = htons(0); + rule->wc.masks.tp_src = htons(0); rule->flow.tp_src = htons(0); break; @@ -1518,12 +1518,12 @@ mf_set_wild(const struct mf_field *mf, struct cls_rule *rule) case MFF_UDP_DST: case MFF_ICMPV4_CODE: case MFF_ICMPV6_CODE: - rule->wc.tp_dst_mask = htons(0); + rule->wc.masks.tp_dst = htons(0); rule->flow.tp_dst = htons(0); break; case MFF_ND_TARGET: - memset(&rule->wc.nd_target_mask, 0, sizeof rule->wc.nd_target_mask); + memset(&rule->wc.masks.nd_target, 0, sizeof rule->wc.masks.nd_target); memset(&rule->flow.nd_target, 0, sizeof rule->flow.nd_target); break; diff --git a/lib/nx-match.c b/lib/nx-match.c index 732d33e1..37410a05 100644 --- a/lib/nx-match.c +++ b/lib/nx-match.c @@ -473,7 +473,7 @@ static void nxm_put_frag(struct ofpbuf *b, const struct cls_rule *cr) { uint8_t nw_frag = cr->flow.nw_frag; - uint8_t nw_frag_mask = cr->wc.nw_frag_mask; + uint8_t nw_frag_mask = cr->wc.masks.nw_frag; switch (nw_frag_mask) { case 0: @@ -499,38 +499,38 @@ nxm_put_ip(struct ofpbuf *b, const struct cls_rule *cr, nxm_put_frag(b, cr); - if (cr->wc.nw_tos_mask & IP_DSCP_MASK) { + if (cr->wc.masks.nw_tos & IP_DSCP_MASK) { nxm_put_8(b, oxm ? OXM_OF_IP_DSCP : NXM_OF_IP_TOS, flow->nw_tos & IP_DSCP_MASK); } - if (cr->wc.nw_tos_mask & IP_ECN_MASK) { + if (cr->wc.masks.nw_tos & IP_ECN_MASK) { nxm_put_8(b, oxm ? OXM_OF_IP_ECN : NXM_NX_IP_ECN, flow->nw_tos & IP_ECN_MASK); } - if (!oxm && cr->wc.nw_ttl_mask) { + if (!oxm && cr->wc.masks.nw_ttl) { nxm_put_8(b, NXM_NX_IP_TTL, flow->nw_ttl); } - if (cr->wc.nw_proto_mask) { + if (cr->wc.masks.nw_proto) { nxm_put_8(b, oxm ? OXM_OF_IP_PROTO : NXM_OF_IP_PROTO, flow->nw_proto); if (flow->nw_proto == IPPROTO_TCP) { nxm_put_16m(b, oxm ? OXM_OF_TCP_SRC : NXM_OF_TCP_SRC, - flow->tp_src, cr->wc.tp_src_mask); + flow->tp_src, cr->wc.masks.tp_src); nxm_put_16m(b, oxm ? OXM_OF_TCP_DST : NXM_OF_TCP_DST, - flow->tp_dst, cr->wc.tp_dst_mask); + flow->tp_dst, cr->wc.masks.tp_dst); } else if (flow->nw_proto == IPPROTO_UDP) { nxm_put_16m(b, oxm ? OXM_OF_UDP_SRC : NXM_OF_UDP_SRC, - flow->tp_src, cr->wc.tp_src_mask); + flow->tp_src, cr->wc.masks.tp_src); nxm_put_16m(b, oxm ? OXM_OF_UDP_DST : NXM_OF_UDP_DST, - flow->tp_dst, cr->wc.tp_dst_mask); + flow->tp_dst, cr->wc.masks.tp_dst); } else if (flow->nw_proto == icmp_proto) { - if (cr->wc.tp_src_mask) { + if (cr->wc.masks.tp_src) { nxm_put_8(b, icmp_type, ntohs(flow->tp_src)); } - if (cr->wc.tp_dst_mask) { + if (cr->wc.masks.tp_dst) { nxm_put_8(b, icmp_code, ntohs(flow->tp_dst)); } } @@ -560,7 +560,7 @@ nx_put_raw(struct ofpbuf *b, bool oxm, const struct cls_rule *cr, BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17); /* Metadata. */ - if (cr->wc.in_port_mask) { + if (cr->wc.masks.in_port) { uint16_t in_port = flow->in_port; if (oxm) { nxm_put_32(b, OXM_OF_IN_PORT, ofputil_port_to_ofp11(in_port)); @@ -571,17 +571,18 @@ nx_put_raw(struct ofpbuf *b, bool oxm, const struct cls_rule *cr, /* Ethernet. */ nxm_put_eth_masked(b, oxm ? OXM_OF_ETH_SRC : NXM_OF_ETH_SRC, - flow->dl_src, cr->wc.dl_src_mask); + flow->dl_src, cr->wc.masks.dl_src); nxm_put_eth_masked(b, oxm ? OXM_OF_ETH_DST : NXM_OF_ETH_DST, - flow->dl_dst, cr->wc.dl_dst_mask); + flow->dl_dst, cr->wc.masks.dl_dst); nxm_put_16m(b, oxm ? OXM_OF_ETH_TYPE : NXM_OF_ETH_TYPE, ofputil_dl_type_to_openflow(flow->dl_type), - cr->wc.dl_type_mask); + cr->wc.masks.dl_type); /* 802.1Q. */ if (oxm) { - ovs_be16 vid = flow->vlan_tci & htons(VLAN_VID_MASK | VLAN_CFI); - ovs_be16 mask = cr->wc.vlan_tci_mask & htons(VLAN_VID_MASK | VLAN_CFI); + ovs_be16 VID_CFI_MASK = htons(VLAN_VID_MASK | VLAN_CFI); + ovs_be16 vid = flow->vlan_tci & VID_CFI_MASK; + ovs_be16 mask = cr->wc.masks.vlan_tci & VID_CFI_MASK; if (mask == htons(VLAN_VID_MASK | VLAN_CFI)) { nxm_put_16(b, OXM_OF_VLAN_VID, vid); @@ -589,78 +590,78 @@ nx_put_raw(struct ofpbuf *b, bool oxm, const struct cls_rule *cr, nxm_put_16m(b, OXM_OF_VLAN_VID, vid, mask); } - if (vid && vlan_tci_to_pcp(cr->wc.vlan_tci_mask)) { + if (vid && vlan_tci_to_pcp(cr->wc.masks.vlan_tci)) { nxm_put_8(b, OXM_OF_VLAN_PCP, vlan_tci_to_pcp(flow->vlan_tci)); } } else { - nxm_put_16m(b, NXM_OF_VLAN_TCI, flow->vlan_tci, cr->wc.vlan_tci_mask); + nxm_put_16m(b, NXM_OF_VLAN_TCI, flow->vlan_tci, cr->wc.masks.vlan_tci); } /* L3. */ if (flow->dl_type == htons(ETH_TYPE_IP)) { /* IP. */ nxm_put_32m(b, oxm ? OXM_OF_IPV4_SRC : NXM_OF_IP_SRC, - flow->nw_src, cr->wc.nw_src_mask); + flow->nw_src, cr->wc.masks.nw_src); nxm_put_32m(b, oxm ? OXM_OF_IPV4_DST : NXM_OF_IP_DST, - flow->nw_dst, cr->wc.nw_dst_mask); + flow->nw_dst, cr->wc.masks.nw_dst); nxm_put_ip(b, cr, IPPROTO_ICMP, oxm ? OXM_OF_ICMPV4_TYPE : NXM_OF_ICMP_TYPE, oxm ? OXM_OF_ICMPV4_CODE : NXM_OF_ICMP_CODE, oxm); } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) { /* IPv6. */ nxm_put_ipv6(b, oxm ? OXM_OF_IPV6_SRC : NXM_NX_IPV6_SRC, - &flow->ipv6_src, &cr->wc.ipv6_src_mask); + &flow->ipv6_src, &cr->wc.masks.ipv6_src); nxm_put_ipv6(b, oxm ? OXM_OF_IPV6_DST : NXM_NX_IPV6_DST, - &flow->ipv6_dst, &cr->wc.ipv6_dst_mask); + &flow->ipv6_dst, &cr->wc.masks.ipv6_dst); nxm_put_ip(b, cr, IPPROTO_ICMPV6, oxm ? OXM_OF_ICMPV6_TYPE : NXM_NX_ICMPV6_TYPE, oxm ? OXM_OF_ICMPV6_CODE : NXM_NX_ICMPV6_CODE, oxm); nxm_put_32m(b, oxm ? OXM_OF_IPV6_FLABEL : NXM_NX_IPV6_LABEL, - flow->ipv6_label, cr->wc.ipv6_label_mask); + flow->ipv6_label, cr->wc.masks.ipv6_label); if (flow->nw_proto == IPPROTO_ICMPV6 && (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT) || flow->tp_src == htons(ND_NEIGHBOR_ADVERT))) { nxm_put_ipv6(b, oxm ? OXM_OF_IPV6_ND_TARGET : NXM_NX_ND_TARGET, - &flow->nd_target, &cr->wc.nd_target_mask); + &flow->nd_target, &cr->wc.masks.nd_target); if (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT)) { nxm_put_eth_masked(b, oxm ? OXM_OF_IPV6_ND_SLL : NXM_NX_ND_SLL, - flow->arp_sha, cr->wc.arp_sha_mask); + flow->arp_sha, cr->wc.masks.arp_sha); } if (flow->tp_src == htons(ND_NEIGHBOR_ADVERT)) { nxm_put_eth_masked(b, oxm ? OXM_OF_IPV6_ND_TLL : NXM_NX_ND_TLL, - flow->arp_tha, cr->wc.arp_tha_mask); + flow->arp_tha, cr->wc.masks.arp_tha); } } } else if (flow->dl_type == htons(ETH_TYPE_ARP)) { /* ARP. */ - if (cr->wc.nw_proto_mask) { + if (cr->wc.masks.nw_proto) { nxm_put_16(b, oxm ? OXM_OF_ARP_OP : NXM_OF_ARP_OP, htons(flow->nw_proto)); } nxm_put_32m(b, oxm ? OXM_OF_ARP_SPA : NXM_OF_ARP_SPA, - flow->nw_src, cr->wc.nw_src_mask); + flow->nw_src, cr->wc.masks.nw_src); nxm_put_32m(b, oxm ? OXM_OF_ARP_TPA : NXM_OF_ARP_TPA, - flow->nw_dst, cr->wc.nw_dst_mask); + flow->nw_dst, cr->wc.masks.nw_dst); nxm_put_eth_masked(b, oxm ? OXM_OF_ARP_SHA : NXM_NX_ARP_SHA, - flow->arp_sha, cr->wc.arp_sha_mask); + flow->arp_sha, cr->wc.masks.arp_sha); nxm_put_eth_masked(b, oxm ? OXM_OF_ARP_THA : NXM_NX_ARP_THA, - flow->arp_tha, cr->wc.arp_tha_mask); + flow->arp_tha, cr->wc.masks.arp_tha); } /* Tunnel ID. */ - nxm_put_64m(b, NXM_NX_TUN_ID, flow->tun_id, cr->wc.tun_id_mask); + nxm_put_64m(b, NXM_NX_TUN_ID, flow->tun_id, cr->wc.masks.tun_id); /* Registers. */ for (i = 0; i < FLOW_N_REGS; i++) { nxm_put_32m(b, NXM_NX_REG(i), - htonl(flow->regs[i]), htonl(cr->wc.reg_masks[i])); + htonl(flow->regs[i]), htonl(cr->wc.masks.regs[i])); } /* OpenFlow 1.1+ Metadata. */ - nxm_put_64m(b, OXM_OF_METADATA, flow->metadata, cr->wc.metadata_mask); + nxm_put_64m(b, OXM_OF_METADATA, flow->metadata, cr->wc.masks.metadata); /* Cookie. */ nxm_put_64m(b, NXM_NX_COOKIE, cookie, cookie_mask); diff --git a/lib/ofp-util.c b/lib/ofp-util.c index c120e0b6..1a8ecb76 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -90,42 +90,44 @@ ofputil_wildcard_from_ofpfw10(uint32_t ofpfw, struct flow_wildcards *wc) flow_wildcards_init_catchall(wc); if (!(ofpfw & OFPFW10_IN_PORT)) { - wc->in_port_mask = UINT16_MAX; + wc->masks.in_port = UINT16_MAX; } if (!(ofpfw & OFPFW10_NW_TOS)) { - wc->nw_tos_mask |= IP_DSCP_MASK; + wc->masks.nw_tos |= IP_DSCP_MASK; } if (!(ofpfw & OFPFW10_NW_PROTO)) { - wc->nw_proto_mask = UINT8_MAX; + wc->masks.nw_proto = UINT8_MAX; } - wc->nw_src_mask = ofputil_wcbits_to_netmask(ofpfw >> OFPFW10_NW_SRC_SHIFT); - wc->nw_dst_mask = ofputil_wcbits_to_netmask(ofpfw >> OFPFW10_NW_DST_SHIFT); + wc->masks.nw_src = ofputil_wcbits_to_netmask(ofpfw + >> OFPFW10_NW_SRC_SHIFT); + wc->masks.nw_dst = ofputil_wcbits_to_netmask(ofpfw + >> OFPFW10_NW_DST_SHIFT); if (!(ofpfw & OFPFW10_TP_SRC)) { - wc->tp_src_mask = htons(UINT16_MAX); + wc->masks.tp_src = htons(UINT16_MAX); } if (!(ofpfw & OFPFW10_TP_DST)) { - wc->tp_dst_mask = htons(UINT16_MAX); + wc->masks.tp_dst = htons(UINT16_MAX); } if (!(ofpfw & OFPFW10_DL_SRC)) { - memset(wc->dl_src_mask, 0xff, ETH_ADDR_LEN); + memset(wc->masks.dl_src, 0xff, ETH_ADDR_LEN); } if (!(ofpfw & OFPFW10_DL_DST)) { - memset(wc->dl_dst_mask, 0xff, ETH_ADDR_LEN); + memset(wc->masks.dl_dst, 0xff, ETH_ADDR_LEN); } if (!(ofpfw & OFPFW10_DL_TYPE)) { - wc->dl_type_mask = htons(UINT16_MAX); + wc->masks.dl_type = htons(UINT16_MAX); } /* VLAN TCI mask. */ if (!(ofpfw & OFPFW10_DL_VLAN_PCP)) { - wc->vlan_tci_mask |= htons(VLAN_PCP_MASK | VLAN_CFI); + wc->masks.vlan_tci |= htons(VLAN_PCP_MASK | VLAN_CFI); } if (!(ofpfw & OFPFW10_DL_VLAN)) { - wc->vlan_tci_mask |= htons(VLAN_VID_MASK | VLAN_CFI); + wc->masks.vlan_tci |= htons(VLAN_VID_MASK | VLAN_CFI); } } @@ -166,14 +168,14 @@ ofputil_cls_rule_from_ofp10_match(const struct ofp10_match *match, * However, older versions of OVS treated this as matching packets * withut an 802.1Q header, so we do here too. */ rule->flow.vlan_tci = htons(0); - rule->wc.vlan_tci_mask = htons(0xffff); + rule->wc.masks.vlan_tci = htons(0xffff); } else { ovs_be16 vid, pcp, tci; vid = match->dl_vlan & htons(VLAN_VID_MASK); pcp = htons((match->dl_vlan_pcp << VLAN_PCP_SHIFT) & VLAN_PCP_MASK); tci = vid | pcp | htons(VLAN_CFI); - rule->flow.vlan_tci = tci & rule->wc.vlan_tci_mask; + rule->flow.vlan_tci = tci & rule->wc.masks.vlan_tci; } /* Clean up. */ @@ -190,52 +192,52 @@ ofputil_cls_rule_to_ofp10_match(const struct cls_rule *rule, /* Figure out most OpenFlow wildcards. */ ofpfw = 0; - if (!wc->in_port_mask) { + if (!wc->masks.in_port) { ofpfw |= OFPFW10_IN_PORT; } - if (!wc->dl_type_mask) { + if (!wc->masks.dl_type) { ofpfw |= OFPFW10_DL_TYPE; } - if (!wc->nw_proto_mask) { + if (!wc->masks.nw_proto) { ofpfw |= OFPFW10_NW_PROTO; } - ofpfw |= (ofputil_netmask_to_wcbits(wc->nw_src_mask) + ofpfw |= (ofputil_netmask_to_wcbits(wc->masks.nw_src) << OFPFW10_NW_SRC_SHIFT); - ofpfw |= (ofputil_netmask_to_wcbits(wc->nw_dst_mask) + ofpfw |= (ofputil_netmask_to_wcbits(wc->masks.nw_dst) << OFPFW10_NW_DST_SHIFT); - if (!(wc->nw_tos_mask & IP_DSCP_MASK)) { + if (!(wc->masks.nw_tos & IP_DSCP_MASK)) { ofpfw |= OFPFW10_NW_TOS; } - if (!wc->tp_src_mask) { + if (!wc->masks.tp_src) { ofpfw |= OFPFW10_TP_SRC; } - if (!wc->tp_dst_mask) { + if (!wc->masks.tp_dst) { ofpfw |= OFPFW10_TP_DST; } - if (eth_addr_is_zero(wc->dl_src_mask)) { + if (eth_addr_is_zero(wc->masks.dl_src)) { ofpfw |= OFPFW10_DL_SRC; } - if (eth_addr_is_zero(wc->dl_dst_mask)) { + if (eth_addr_is_zero(wc->masks.dl_dst)) { ofpfw |= OFPFW10_DL_DST; } /* Translate VLANs. */ match->dl_vlan = htons(0); match->dl_vlan_pcp = 0; - if (rule->wc.vlan_tci_mask == htons(0)) { + if (rule->wc.masks.vlan_tci == htons(0)) { ofpfw |= OFPFW10_DL_VLAN | OFPFW10_DL_VLAN_PCP; - } else if (rule->wc.vlan_tci_mask & htons(VLAN_CFI) + } else if (rule->wc.masks.vlan_tci & htons(VLAN_CFI) && !(rule->flow.vlan_tci & htons(VLAN_CFI))) { match->dl_vlan = htons(OFP10_VLAN_NONE); ofpfw |= OFPFW10_DL_VLAN_PCP; } else { - if (!(rule->wc.vlan_tci_mask & htons(VLAN_VID_MASK))) { + if (!(rule->wc.masks.vlan_tci & htons(VLAN_VID_MASK))) { ofpfw |= OFPFW10_DL_VLAN; } else { match->dl_vlan = htons(vlan_tci_to_vid(rule->flow.vlan_tci)); } - if (!(rule->wc.vlan_tci_mask & htons(VLAN_PCP_MASK))) { + if (!(rule->wc.masks.vlan_tci & htons(VLAN_PCP_MASK))) { ofpfw |= OFPFW10_DL_VLAN_PCP; } else { match->dl_vlan_pcp = vlan_tci_to_pcp(rule->flow.vlan_tci); @@ -336,16 +338,16 @@ ofputil_cls_rule_from_ofp11_match(const struct ofp11_match *match, if (match->dl_vlan == htons(OFPVID11_NONE)) { /* Match only packets without a VLAN tag. */ rule->flow.vlan_tci = htons(0); - rule->wc.vlan_tci_mask = htons(UINT16_MAX); + rule->wc.masks.vlan_tci = htons(UINT16_MAX); } else { if (match->dl_vlan == htons(OFPVID11_ANY)) { /* Match any packet with a VLAN tag regardless of VID. */ rule->flow.vlan_tci = htons(VLAN_CFI); - rule->wc.vlan_tci_mask = htons(VLAN_CFI); + rule->wc.masks.vlan_tci = htons(VLAN_CFI); } else if (ntohs(match->dl_vlan) < 4096) { /* Match only packets with the specified VLAN VID. */ rule->flow.vlan_tci = htons(VLAN_CFI) | match->dl_vlan; - rule->wc.vlan_tci_mask = htons(VLAN_CFI | VLAN_VID_MASK); + rule->wc.masks.vlan_tci = htons(VLAN_CFI | VLAN_VID_MASK); } else { /* Invalid VID. */ return OFPERR_OFPBMC_BAD_VALUE; @@ -355,7 +357,7 @@ ofputil_cls_rule_from_ofp11_match(const struct ofp11_match *match, if (match->dl_vlan_pcp <= 7) { rule->flow.vlan_tci |= htons(match->dl_vlan_pcp << VLAN_PCP_SHIFT); - rule->wc.vlan_tci_mask |= htons(VLAN_PCP_MASK); + rule->wc.masks.vlan_tci |= htons(VLAN_PCP_MASK); } else { /* Invalid PCP. */ return OFPERR_OFPBMC_BAD_VALUE; @@ -469,7 +471,7 @@ ofputil_cls_rule_to_ofp11_match(const struct cls_rule *rule, match->omh.type = htons(OFPMT_STANDARD); match->omh.length = htons(OFPMT11_STANDARD_LENGTH); - if (!rule->wc.in_port_mask) { + if (!rule->wc.masks.in_port) { wc |= OFPFW11_IN_PORT; } else { match->in_port = ofputil_port_to_ofp11(rule->flow.in_port); @@ -477,64 +479,64 @@ ofputil_cls_rule_to_ofp11_match(const struct cls_rule *rule, memcpy(match->dl_src, rule->flow.dl_src, ETH_ADDR_LEN); for (i = 0; i < ETH_ADDR_LEN; i++) { - match->dl_src_mask[i] = ~rule->wc.dl_src_mask[i]; + match->dl_src_mask[i] = ~rule->wc.masks.dl_src[i]; } memcpy(match->dl_dst, rule->flow.dl_dst, ETH_ADDR_LEN); for (i = 0; i < ETH_ADDR_LEN; i++) { - match->dl_dst_mask[i] = ~rule->wc.dl_dst_mask[i]; + match->dl_dst_mask[i] = ~rule->wc.masks.dl_dst[i]; } - if (rule->wc.vlan_tci_mask == htons(0)) { + if (rule->wc.masks.vlan_tci == htons(0)) { wc |= OFPFW11_DL_VLAN | OFPFW11_DL_VLAN_PCP; - } else if (rule->wc.vlan_tci_mask & htons(VLAN_CFI) + } else if (rule->wc.masks.vlan_tci & htons(VLAN_CFI) && !(rule->flow.vlan_tci & htons(VLAN_CFI))) { match->dl_vlan = htons(OFPVID11_NONE); wc |= OFPFW11_DL_VLAN_PCP; } else { - if (!(rule->wc.vlan_tci_mask & htons(VLAN_VID_MASK))) { + if (!(rule->wc.masks.vlan_tci & htons(VLAN_VID_MASK))) { match->dl_vlan = htons(OFPVID11_ANY); } else { match->dl_vlan = htons(vlan_tci_to_vid(rule->flow.vlan_tci)); } - if (!(rule->wc.vlan_tci_mask & htons(VLAN_PCP_MASK))) { + if (!(rule->wc.masks.vlan_tci & htons(VLAN_PCP_MASK))) { wc |= OFPFW11_DL_VLAN_PCP; } else { match->dl_vlan_pcp = vlan_tci_to_pcp(rule->flow.vlan_tci); } } - if (!rule->wc.dl_type_mask) { + if (!rule->wc.masks.dl_type) { wc |= OFPFW11_DL_TYPE; } else { match->dl_type = ofputil_dl_type_to_openflow(rule->flow.dl_type); } - if (!(rule->wc.nw_tos_mask & IP_DSCP_MASK)) { + if (!(rule->wc.masks.nw_tos & IP_DSCP_MASK)) { wc |= OFPFW11_NW_TOS; } else { match->nw_tos = rule->flow.nw_tos & IP_DSCP_MASK; } - if (!rule->wc.nw_proto_mask) { + if (!rule->wc.masks.nw_proto) { wc |= OFPFW11_NW_PROTO; } else { match->nw_proto = rule->flow.nw_proto; } match->nw_src = rule->flow.nw_src; - match->nw_src_mask = ~rule->wc.nw_src_mask; + match->nw_src_mask = ~rule->wc.masks.nw_src; match->nw_dst = rule->flow.nw_dst; - match->nw_dst_mask = ~rule->wc.nw_dst_mask; + match->nw_dst_mask = ~rule->wc.masks.nw_dst; - if (!rule->wc.tp_src_mask) { + if (!rule->wc.masks.tp_src) { wc |= OFPFW11_TP_SRC; } else { match->tp_src = rule->flow.tp_src; } - if (!rule->wc.tp_dst_mask) { + if (!rule->wc.masks.tp_dst) { wc |= OFPFW11_TP_DST; } else { match->tp_dst = rule->flow.tp_dst; @@ -545,7 +547,7 @@ ofputil_cls_rule_to_ofp11_match(const struct cls_rule *rule, wc |= OFPFW11_MPLS_TC; match->metadata = rule->flow.metadata; - match->metadata_mask = ~rule->wc.metadata_mask; + match->metadata_mask = ~rule->wc.masks.metadata; match->wildcards = htonl(wc); } @@ -887,7 +889,7 @@ regs_fully_wildcarded(const struct flow_wildcards *wc) int i; for (i = 0; i < FLOW_N_REGS; i++) { - if (wc->reg_masks[i] != 0) { + if (wc->masks.regs[i] != 0) { return false; } } @@ -906,23 +908,23 @@ ofputil_usable_protocols(const struct cls_rule *rule) BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17); /* NXM and OF1.1+ supports bitwise matching on ethernet addresses. */ - if (!eth_mask_is_exact(wc->dl_src_mask) - && !eth_addr_is_zero(wc->dl_src_mask)) { + if (!eth_mask_is_exact(wc->masks.dl_src) + && !eth_addr_is_zero(wc->masks.dl_src)) { return OFPUTIL_P_NXM_ANY; } - if (!eth_mask_is_exact(wc->dl_dst_mask) - && !eth_addr_is_zero(wc->dl_dst_mask)) { + if (!eth_mask_is_exact(wc->masks.dl_dst) + && !eth_addr_is_zero(wc->masks.dl_dst)) { return OFPUTIL_P_NXM_ANY; } /* NXM and OF1.1+ support matching metadata. */ - if (wc->metadata_mask != htonll(0)) { + if (wc->masks.metadata != htonll(0)) { return OFPUTIL_P_NXM_ANY; } /* Only NXM supports matching ARP hardware addresses. */ - if (!eth_addr_is_zero(wc->arp_sha_mask) || - !eth_addr_is_zero(wc->arp_tha_mask)) { + if (!eth_addr_is_zero(wc->masks.arp_sha) || + !eth_addr_is_zero(wc->masks.arp_tha)) { return OFPUTIL_P_NXM_ANY; } @@ -937,38 +939,38 @@ ofputil_usable_protocols(const struct cls_rule *rule) } /* Only NXM supports matching tun_id. */ - if (wc->tun_id_mask != htonll(0)) { + if (wc->masks.tun_id != htonll(0)) { return OFPUTIL_P_NXM_ANY; } /* Only NXM supports matching fragments. */ - if (wc->nw_frag_mask) { + if (wc->masks.nw_frag) { return OFPUTIL_P_NXM_ANY; } /* Only NXM supports matching IPv6 flow label. */ - if (wc->ipv6_label_mask) { + if (wc->masks.ipv6_label) { return OFPUTIL_P_NXM_ANY; } /* Only NXM supports matching IP ECN bits. */ - if (wc->nw_tos_mask & IP_ECN_MASK) { + if (wc->masks.nw_tos & IP_ECN_MASK) { return OFPUTIL_P_NXM_ANY; } /* Only NXM supports matching IP TTL/hop limit. */ - if (wc->nw_ttl_mask) { + if (wc->masks.nw_ttl) { return OFPUTIL_P_NXM_ANY; } /* Only NXM supports non-CIDR IPv4 address masks. */ - if (!ip_is_cidr(wc->nw_src_mask) || !ip_is_cidr(wc->nw_dst_mask)) { + if (!ip_is_cidr(wc->masks.nw_src) || !ip_is_cidr(wc->masks.nw_dst)) { return OFPUTIL_P_NXM_ANY; } /* Only NXM supports bitwise matching on transport port. */ - if ((wc->tp_src_mask && wc->tp_src_mask != htons(UINT16_MAX)) || - (wc->tp_dst_mask && wc->tp_dst_mask != htons(UINT16_MAX))) { + if ((wc->masks.tp_src && wc->masks.tp_src != htons(UINT16_MAX)) || + (wc->masks.tp_dst && wc->masks.tp_dst != htons(UINT16_MAX))) { return OFPUTIL_P_NXM_ANY; } @@ -3625,30 +3627,30 @@ ofputil_normalize_rule__(struct cls_rule *rule, bool may_log) /* Clear the fields that may not be matched. */ wc = rule->wc; if (!(may_match & MAY_NW_ADDR)) { - wc.nw_src_mask = wc.nw_dst_mask = htonl(0); + wc.masks.nw_src = wc.masks.nw_dst = htonl(0); } if (!(may_match & MAY_TP_ADDR)) { - wc.tp_src_mask = wc.tp_dst_mask = htons(0); + wc.masks.tp_src = wc.masks.tp_dst = htons(0); } if (!(may_match & MAY_NW_PROTO)) { - wc.nw_proto_mask = 0; + wc.masks.nw_proto = 0; } if (!(may_match & MAY_IPVx)) { - wc.nw_tos_mask = 0; - wc.nw_ttl_mask = 0; + wc.masks.nw_tos = 0; + wc.masks.nw_ttl = 0; } if (!(may_match & MAY_ARP_SHA)) { - memset(wc.arp_sha_mask, 0, ETH_ADDR_LEN); + memset(wc.masks.arp_sha, 0, ETH_ADDR_LEN); } if (!(may_match & MAY_ARP_THA)) { - memset(wc.arp_tha_mask, 0, ETH_ADDR_LEN); + memset(wc.masks.arp_tha, 0, ETH_ADDR_LEN); } if (!(may_match & MAY_IPV6)) { - wc.ipv6_src_mask = wc.ipv6_dst_mask = in6addr_any; - wc.ipv6_label_mask = htonl(0); + wc.masks.ipv6_src = wc.masks.ipv6_dst = in6addr_any; + wc.masks.ipv6_label = htonl(0); } if (!(may_match & MAY_ND_TARGET)) { - wc.nd_target_mask = in6addr_any; + wc.masks.nd_target = in6addr_any; } /* Log any changes. */ diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index d773c91c..83843081 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -3992,7 +3992,7 @@ ofopgroup_complete(struct ofopgroup *group) case OFOPERATION_ADD: if (!op->error) { ofproto_rule_destroy__(op->victim); - if ((rule->cr.wc.vlan_tci_mask & htons(VLAN_VID_MASK)) + if ((rule->cr.wc.masks.vlan_tci & htons(VLAN_VID_MASK)) == htons(VLAN_VID_MASK)) { if (ofproto->vlan_bitmap) { uint16_t vid = vlan_tci_to_vid(rule->cr.flow.vlan_tci); @@ -4646,7 +4646,7 @@ ofproto_get_vlan_usage(struct ofproto *ofproto, unsigned long int *vlan_bitmap) const struct cls_table *table; HMAP_FOR_EACH (table, hmap_node, &oftable->cls.tables) { - if ((table->wc.vlan_tci_mask & htons(VLAN_VID_MASK)) + if ((table->wc.masks.vlan_tci & htons(VLAN_VID_MASK)) == htons(VLAN_VID_MASK)) { const struct cls_rule *rule; diff --git a/tests/test-classifier.c b/tests/test-classifier.c index da72d910..ae1d81f2 100644 --- a/tests/test-classifier.c +++ b/tests/test-classifier.c @@ -188,39 +188,44 @@ match(const struct cls_rule *wild, const struct flow *fixed) bool eq; if (f_idx == CLS_F_IDX_NW_SRC) { - eq = !((fixed->nw_src ^ wild->flow.nw_src) & wild->wc.nw_src_mask); + eq = !((fixed->nw_src ^ wild->flow.nw_src) + & wild->wc.masks.nw_src); } else if (f_idx == CLS_F_IDX_NW_DST) { - eq = !((fixed->nw_dst ^ wild->flow.nw_dst) & wild->wc.nw_dst_mask); + eq = !((fixed->nw_dst ^ wild->flow.nw_dst) + & wild->wc.masks.nw_dst); } else if (f_idx == CLS_F_IDX_TP_SRC) { - eq = !((fixed->tp_src ^ wild->flow.tp_src) & wild->wc.tp_src_mask); + eq = !((fixed->tp_src ^ wild->flow.tp_src) + & wild->wc.masks.tp_src); } else if (f_idx == CLS_F_IDX_TP_DST) { - eq = !((fixed->tp_dst ^ wild->flow.tp_dst) & wild->wc.tp_dst_mask); + eq = !((fixed->tp_dst ^ wild->flow.tp_dst) + & wild->wc.masks.tp_dst); } else if (f_idx == CLS_F_IDX_DL_SRC) { eq = eth_addr_equal_except(fixed->dl_src, wild->flow.dl_src, - wild->wc.dl_src_mask); + wild->wc.masks.dl_src); } else if (f_idx == CLS_F_IDX_DL_DST) { eq = eth_addr_equal_except(fixed->dl_dst, wild->flow.dl_dst, - wild->wc.dl_dst_mask); + wild->wc.masks.dl_dst); } else if (f_idx == CLS_F_IDX_VLAN_TCI) { eq = !((fixed->vlan_tci ^ wild->flow.vlan_tci) - & wild->wc.vlan_tci_mask); + & wild->wc.masks.vlan_tci); } else if (f_idx == CLS_F_IDX_TUN_ID) { - eq = !((fixed->tun_id ^ wild->flow.tun_id) & wild->wc.tun_id_mask); + eq = !((fixed->tun_id ^ wild->flow.tun_id) + & wild->wc.masks.tun_id); } else if (f_idx == CLS_F_IDX_METADATA) { eq = !((fixed->metadata ^ wild->flow.metadata) - & wild->wc.metadata_mask); + & wild->wc.masks.metadata); } else if (f_idx == CLS_F_IDX_NW_DSCP) { eq = !((fixed->nw_tos ^ wild->flow.nw_tos) & - (wild->wc.nw_tos_mask & IP_DSCP_MASK)); + (wild->wc.masks.nw_tos & IP_DSCP_MASK)); } else if (f_idx == CLS_F_IDX_NW_PROTO) { eq = !((fixed->nw_proto ^ wild->flow.nw_proto) - & wild->wc.nw_proto_mask); + & wild->wc.masks.nw_proto); } else if (f_idx == CLS_F_IDX_DL_TYPE) { eq = !((fixed->dl_type ^ wild->flow.dl_type) - & wild->wc.dl_type_mask); + & wild->wc.masks.dl_type); } else if (f_idx == CLS_F_IDX_IN_PORT) { eq = !((fixed->in_port ^ wild->flow.in_port) - & wild->wc.in_port_mask); + & wild->wc.masks.in_port); } else { NOT_REACHED(); } @@ -483,31 +488,31 @@ make_rule(int wc_fields, unsigned int priority, int value_pat) values[f_idx][value_idx], f->len); if (f_idx == CLS_F_IDX_NW_SRC) { - rule->cls_rule.wc.nw_src_mask = htonl(UINT32_MAX); + rule->cls_rule.wc.masks.nw_src = htonl(UINT32_MAX); } else if (f_idx == CLS_F_IDX_NW_DST) { - rule->cls_rule.wc.nw_dst_mask = htonl(UINT32_MAX); + rule->cls_rule.wc.masks.nw_dst = htonl(UINT32_MAX); } else if (f_idx == CLS_F_IDX_TP_SRC) { - rule->cls_rule.wc.tp_src_mask = htons(UINT16_MAX); + rule->cls_rule.wc.masks.tp_src = htons(UINT16_MAX); } else if (f_idx == CLS_F_IDX_TP_DST) { - rule->cls_rule.wc.tp_dst_mask = htons(UINT16_MAX); + rule->cls_rule.wc.masks.tp_dst = htons(UINT16_MAX); } else if (f_idx == CLS_F_IDX_DL_SRC) { - memset(rule->cls_rule.wc.dl_src_mask, 0xff, ETH_ADDR_LEN); + memset(rule->cls_rule.wc.masks.dl_src, 0xff, ETH_ADDR_LEN); } else if (f_idx == CLS_F_IDX_DL_DST) { - memset(rule->cls_rule.wc.dl_dst_mask, 0xff, ETH_ADDR_LEN); + memset(rule->cls_rule.wc.masks.dl_dst, 0xff, ETH_ADDR_LEN); } else if (f_idx == CLS_F_IDX_VLAN_TCI) { - rule->cls_rule.wc.vlan_tci_mask = htons(UINT16_MAX); + rule->cls_rule.wc.masks.vlan_tci = htons(UINT16_MAX); } else if (f_idx == CLS_F_IDX_TUN_ID) { - rule->cls_rule.wc.tun_id_mask = htonll(UINT64_MAX); + rule->cls_rule.wc.masks.tun_id = htonll(UINT64_MAX); } else if (f_idx == CLS_F_IDX_METADATA) { - rule->cls_rule.wc.metadata_mask = htonll(UINT64_MAX); + rule->cls_rule.wc.masks.metadata = htonll(UINT64_MAX); } else if (f_idx == CLS_F_IDX_NW_DSCP) { - rule->cls_rule.wc.nw_tos_mask |= IP_DSCP_MASK; + rule->cls_rule.wc.masks.nw_tos |= IP_DSCP_MASK; } else if (f_idx == CLS_F_IDX_NW_PROTO) { - rule->cls_rule.wc.nw_proto_mask = UINT8_MAX; + rule->cls_rule.wc.masks.nw_proto = UINT8_MAX; } else if (f_idx == CLS_F_IDX_DL_TYPE) { - rule->cls_rule.wc.dl_type_mask = htons(UINT16_MAX); + rule->cls_rule.wc.masks.dl_type = htons(UINT16_MAX); } else if (f_idx == CLS_F_IDX_IN_PORT) { - rule->cls_rule.wc.in_port_mask = UINT16_MAX; + rule->cls_rule.wc.masks.in_port = UINT16_MAX; } else { NOT_REACHED(); } diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 5d10b378..126c7204 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -2606,7 +2606,7 @@ ofctl_check_vlan(int argc OVS_UNUSED, char *argv[]) cls_rule_init_catchall(&rule, OFP_DEFAULT_PRIORITY); rule.flow.vlan_tci = htons(strtoul(argv[1], NULL, 16)); - rule.wc.vlan_tci_mask = htons(strtoul(argv[2], NULL, 16)); + rule.wc.masks.vlan_tci = htons(strtoul(argv[2], NULL, 16)); /* Convert to and from string. */ string_s = cls_rule_to_string(&rule); @@ -2615,7 +2615,7 @@ ofctl_check_vlan(int argc OVS_UNUSED, char *argv[]) parse_ofp_str(&fm, -1, string_s, false); printf("%04"PRIx16"/%04"PRIx16"\n", ntohs(fm.cr.flow.vlan_tci), - ntohs(fm.cr.wc.vlan_tci_mask)); + ntohs(fm.cr.wc.masks.vlan_tci)); free(string_s); /* Convert to and from NXM. */ @@ -2629,7 +2629,7 @@ ofctl_check_vlan(int argc OVS_UNUSED, char *argv[]) } else { printf("%04"PRIx16"/%04"PRIx16"\n", ntohs(nxm_rule.flow.vlan_tci), - ntohs(nxm_rule.wc.vlan_tci_mask)); + ntohs(nxm_rule.wc.masks.vlan_tci)); } free(nxm_s); ofpbuf_uninit(&nxm); @@ -2645,11 +2645,11 @@ ofctl_check_vlan(int argc OVS_UNUSED, char *argv[]) } else { uint16_t vid = ntohs(nxm_rule.flow.vlan_tci) & (VLAN_VID_MASK | VLAN_CFI); - uint16_t mask = ntohs(nxm_rule.wc.vlan_tci_mask) & + uint16_t mask = ntohs(nxm_rule.wc.masks.vlan_tci) & (VLAN_VID_MASK | VLAN_CFI); printf("%04"PRIx16"/%04"PRIx16",", vid, mask); - if (vid && vlan_tci_to_pcp(nxm_rule.wc.vlan_tci_mask)) { + if (vid && vlan_tci_to_pcp(nxm_rule.wc.masks.vlan_tci)) { printf("%02"PRIx8"\n", vlan_tci_to_pcp(nxm_rule.flow.vlan_tci)); } else { printf("--\n"); @@ -2667,7 +2667,7 @@ ofctl_check_vlan(int argc OVS_UNUSED, char *argv[]) of10_match.dl_vlan_pcp, (of10_match.wildcards & htonl(OFPFW10_DL_VLAN_PCP)) != 0, ntohs(of10_rule.flow.vlan_tci), - ntohs(of10_rule.wc.vlan_tci_mask)); + ntohs(of10_rule.wc.masks.vlan_tci)); /* Convert to and from OpenFlow 1.1. */ ofputil_cls_rule_to_ofp11_match(&rule, &of11_match); @@ -2678,7 +2678,7 @@ ofctl_check_vlan(int argc OVS_UNUSED, char *argv[]) of11_match.dl_vlan_pcp, (of11_match.wildcards & htonl(OFPFW11_DL_VLAN_PCP)) != 0, ntohs(of11_rule.flow.vlan_tci), - ntohs(of11_rule.wc.vlan_tci_mask)); + ntohs(of11_rule.wc.masks.vlan_tci)); } /* "print-error ENUM": Prints the type and code of ENUM for every OpenFlow -- 2.30.2