From 0bdc4bec4fd00e8140c16915e2aa817a18ea166d Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 3 Aug 2012 13:27:15 -0700 Subject: [PATCH] flow: Use bit-mask for in_port match, instead of FWW_* flag. Signed-off-by: Ben Pfaff --- lib/classifier.c | 8 ++-- lib/flow.c | 27 ++++++------ lib/flow.h | 27 ++---------- lib/meta-flow.c | 94 +++++++++++++++++++---------------------- lib/meta-flow.h | 1 - lib/nx-match.c | 3 +- lib/ofp-util.c | 9 ++-- tests/test-classifier.c | 55 +++++++++++------------- 8 files changed, 92 insertions(+), 132 deletions(-) diff --git a/lib/classifier.c b/lib/classifier.c index af715d34..d5e383f1 100644 --- a/lib/classifier.c +++ b/lib/classifier.c @@ -149,7 +149,7 @@ cls_rule_set_tun_id_masked(struct cls_rule *rule, void cls_rule_set_in_port(struct cls_rule *rule, uint16_t ofp_port) { - rule->wc.wildcards &= ~FWW_IN_PORT; + rule->wc.in_port_mask = UINT16_MAX; rule->flow.in_port = ofp_port; } @@ -600,7 +600,6 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s) { const struct flow_wildcards *wc = &rule->wc; size_t start_len = s->length; - flow_wildcards_t w = wc->wildcards; const struct flow *f = &rule->flow; bool skip_type = false; bool skip_proto = false; @@ -688,7 +687,7 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s) ntohll(f->metadata), ntohll(wc->metadata_mask)); break; } - if (!(w & FWW_IN_PORT)) { + if (wc->in_port_mask) { ds_put_format(s, "in_port=%"PRIu16",", f->in_port); } if (wc->vlan_tci_mask) { @@ -1288,7 +1287,6 @@ static bool flow_equal_except(const struct flow *a, const struct flow *b, const struct flow_wildcards *wildcards) { - const flow_wildcards_t wc = wildcards->wildcards; int i; BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17); @@ -1303,7 +1301,7 @@ flow_equal_except(const struct flow *a, const struct flow *b, && !((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) - && (wc & FWW_IN_PORT || a->in_port == b->in_port) + && !((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) diff --git a/lib/flow.c b/lib/flow.c index 5f4cdcd3..c414e812 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -442,7 +442,6 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority, ovs_be64 tun_id, void flow_zero_wildcards(struct flow *flow, const struct flow_wildcards *wildcards) { - const flow_wildcards_t wc = wildcards->wildcards; int i; BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17); @@ -454,9 +453,7 @@ flow_zero_wildcards(struct flow *flow, const struct flow_wildcards *wildcards) flow->metadata &= wildcards->metadata_mask; flow->nw_src &= wildcards->nw_src_mask; flow->nw_dst &= wildcards->nw_dst_mask; - if (wc & FWW_IN_PORT) { - flow->in_port = 0; - } + 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; @@ -573,7 +570,6 @@ flow_wildcards_init_catchall(struct flow_wildcards *wc) { BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17); - wc->wildcards = FWW_ALL; wc->tun_id_mask = htonll(0); wc->nw_src_mask = htonl(0); wc->nw_dst_mask = htonl(0); @@ -583,6 +579,7 @@ flow_wildcards_init_catchall(struct flow_wildcards *wc) 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); @@ -605,7 +602,6 @@ flow_wildcards_init_exact(struct flow_wildcards *wc) { BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17); - wc->wildcards = 0; wc->tun_id_mask = htonll(UINT64_MAX); wc->nw_src_mask = htonl(UINT32_MAX); wc->nw_dst_mask = htonl(UINT32_MAX); @@ -615,6 +611,7 @@ flow_wildcards_init_exact(struct flow_wildcards *wc) 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); @@ -639,12 +636,12 @@ flow_wildcards_is_exact(const struct flow_wildcards *wc) BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17); - if (wc->wildcards - || wc->tun_id_mask != htonll(UINT64_MAX) + 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) @@ -681,12 +678,12 @@ flow_wildcards_is_catchall(const struct flow_wildcards *wc) BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17); - if (wc->wildcards != FWW_ALL - || wc->tun_id_mask != htonll(0) + 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) @@ -726,7 +723,6 @@ flow_wildcards_combine(struct flow_wildcards *dst, BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17); - dst->wildcards = src1->wildcards | src2->wildcards; 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; @@ -741,6 +737,7 @@ flow_wildcards_combine(struct flow_wildcards *dst, dst->reg_masks[i] = src1->reg_masks[i] & src2->reg_masks[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; @@ -776,10 +773,10 @@ flow_wildcards_equal(const struct flow_wildcards *a, BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17); - if (a->wildcards != b->wildcards - || a->tun_id_mask != b->tun_id_mask + 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 @@ -862,11 +859,11 @@ flow_wildcards_has_extra(const struct flow_wildcards *a, return true; } - return (a->wildcards & ~b->wildcards - || (a->tun_id_mask & b->tun_id_mask) != b->tun_id_mask + 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 diff --git a/lib/flow.h b/lib/flow.h index 4320bd6d..406324ad 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -133,28 +133,10 @@ flow_hash(const struct flow *flow, uint32_t basis) return hash_bytes(flow, FLOW_SIG_SIZE, basis); } -/* Open vSwitch flow wildcard bits. - * - * These are used only internally to Open vSwitch, in the 'wildcards' member of - * struct flow_wildcards. They never appear in the wire protocol in this - * form. */ - -typedef unsigned int OVS_BITWISE flow_wildcards_t; - -#define FWW_IN_PORT ((OVS_FORCE flow_wildcards_t) (1 << 0)) -#define FWW_ALL ((OVS_FORCE flow_wildcards_t) (((1 << 1)) - 1)) - -/* Remember to update FLOW_WC_SEQ when adding or removing FWW_*. */ -BUILD_ASSERT_DECL(FWW_ALL == ((1 << 1) - 1) && FLOW_WC_SEQ == 17); - -/* Information on wildcards for a flow, as a supplement to "struct flow". - * - * Note that the meaning of 1-bits in 'wildcards' is opposite that of 1-bits in - * the rest of the members. */ +/* Information on wildcards for a flow, as a supplement to "struct flow". */ 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. */ - flow_wildcards_t wildcards; /* 1-bit in each FWW_* wildcarded field. */ 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. */ @@ -163,6 +145,7 @@ struct flow_wildcards { 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. */ @@ -175,7 +158,7 @@ struct flow_wildcards { 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[4]; /* Padding field set to zero. */ + uint8_t zeros[6]; /* Padding field set to zero. */ }; /* Remember to update FLOW_WC_SEQ when updating struct flow_wildcards. */ @@ -201,10 +184,6 @@ bool flow_wildcards_equal(const struct flow_wildcards *, const struct flow_wildcards *); uint32_t flow_hash_symmetric_l4(const struct flow *flow, uint32_t basis); -const uint8_t *flow_wildcards_to_dl_dst_mask(flow_wildcards_t); -bool flow_wildcards_is_dl_dst_mask_valid(const uint8_t[6]); -flow_wildcards_t flow_wildcards_set_dl_dst_mask(flow_wildcards_t, - const uint8_t mask[6]); uint32_t flow_hash_fields(const struct flow *, enum nx_hash_fields, uint16_t basis); const char *flow_hash_fields_to_str(enum nx_hash_fields); diff --git a/lib/meta-flow.c b/lib/meta-flow.c index 99a97726..7306df0d 100644 --- a/lib/meta-flow.c +++ b/lib/meta-flow.c @@ -49,7 +49,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { { MFF_TUN_ID, "tun_id", NULL, MF_FIELD_SIZES(be64), - MFM_FULLY, 0, + MFM_FULLY, MFS_HEXADECIMAL, MFP_NONE, true, @@ -58,7 +58,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_METADATA, "metadata", NULL, MF_FIELD_SIZES(be64), - MFM_FULLY, 0, + MFM_FULLY, MFS_HEXADECIMAL, MFP_NONE, true, @@ -67,7 +67,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_IN_PORT, "in_port", NULL, MF_FIELD_SIZES(be16), - MFM_NONE, FWW_IN_PORT, + MFM_NONE, MFS_OFP_PORT, MFP_NONE, false, @@ -79,7 +79,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { { \ MFF_REG##IDX, "reg" #IDX, NULL, \ MF_FIELD_SIZES(be32), \ - MFM_FULLY, 0, \ + MFM_FULLY, \ MFS_HEXADECIMAL, \ MFP_NONE, \ true, \ @@ -121,7 +121,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { { MFF_ETH_SRC, "eth_src", "dl_src", MF_FIELD_SIZES(mac), - MFM_FULLY, 0, + MFM_FULLY, MFS_ETHERNET, MFP_NONE, true, @@ -130,7 +130,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_ETH_DST, "eth_dst", "dl_dst", MF_FIELD_SIZES(mac), - MFM_FULLY, 0, + MFM_FULLY, MFS_ETHERNET, MFP_NONE, true, @@ -139,7 +139,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_ETH_TYPE, "eth_type", "dl_type", MF_FIELD_SIZES(be16), - MFM_NONE, 0, + MFM_NONE, MFS_HEXADECIMAL, MFP_NONE, false, @@ -150,7 +150,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { { MFF_VLAN_TCI, "vlan_tci", NULL, MF_FIELD_SIZES(be16), - MFM_FULLY, 0, + MFM_FULLY, MFS_HEXADECIMAL, MFP_NONE, true, @@ -159,7 +159,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_DL_VLAN, "dl_vlan", NULL, sizeof(ovs_be16), 12, - MFM_NONE, 0, + MFM_NONE, MFS_DECIMAL, MFP_NONE, true, @@ -168,7 +168,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_VLAN_VID, "vlan_vid", NULL, sizeof(ovs_be16), 12, - MFM_FULLY, 0, + MFM_FULLY, MFS_DECIMAL, MFP_NONE, true, @@ -177,7 +177,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_DL_VLAN_PCP, "dl_vlan_pcp", NULL, 1, 3, - MFM_NONE, 0, + MFM_NONE, MFS_DECIMAL, MFP_NONE, true, @@ -186,7 +186,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_VLAN_PCP, "vlan_pcp", NULL, 1, 3, - MFM_NONE, 0, + MFM_NONE, MFS_DECIMAL, MFP_VLAN_VID, true, @@ -201,7 +201,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { { MFF_IPV4_SRC, "ip_src", "nw_src", MF_FIELD_SIZES(be32), - MFM_FULLY, 0, + MFM_FULLY, MFS_IPV4, MFP_IPV4, true, @@ -210,7 +210,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_IPV4_DST, "ip_dst", "nw_dst", MF_FIELD_SIZES(be32), - MFM_FULLY, 0, + MFM_FULLY, MFS_IPV4, MFP_IPV4, true, @@ -221,7 +221,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { { MFF_IPV6_SRC, "ipv6_src", NULL, MF_FIELD_SIZES(ipv6), - MFM_FULLY, 0, + MFM_FULLY, MFS_IPV6, MFP_IPV6, true, @@ -230,7 +230,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_IPV6_DST, "ipv6_dst", NULL, MF_FIELD_SIZES(ipv6), - MFM_FULLY, 0, + MFM_FULLY, MFS_IPV6, MFP_IPV6, true, @@ -240,7 +240,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { { MFF_IPV6_LABEL, "ipv6_label", NULL, 4, 20, - MFM_FULLY, 0, + MFM_FULLY, MFS_HEXADECIMAL, MFP_IPV6, false, @@ -251,7 +251,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { { MFF_IP_PROTO, "nw_proto", NULL, MF_FIELD_SIZES(u8), - MFM_NONE, 0, + MFM_NONE, MFS_DECIMAL, MFP_IP_ANY, false, @@ -260,7 +260,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_IP_DSCP, "nw_tos", NULL, MF_FIELD_SIZES(u8), - MFM_NONE, 0, + MFM_NONE, MFS_DECIMAL, MFP_IP_ANY, true, @@ -269,7 +269,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_IP_ECN, "nw_ecn", NULL, 1, 2, - MFM_NONE, 0, + MFM_NONE, MFS_DECIMAL, MFP_IP_ANY, true, @@ -278,7 +278,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_IP_TTL, "nw_ttl", NULL, MF_FIELD_SIZES(u8), - MFM_NONE, 0, + MFM_NONE, MFS_DECIMAL, MFP_IP_ANY, true, @@ -287,7 +287,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_IP_FRAG, "ip_frag", NULL, 1, 2, - MFM_FULLY, 0, + MFM_FULLY, MFS_FRAG, MFP_IP_ANY, false, @@ -298,7 +298,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { { MFF_ARP_OP, "arp_op", NULL, MF_FIELD_SIZES(be16), - MFM_NONE, 0, + MFM_NONE, MFS_DECIMAL, MFP_ARP, false, @@ -307,7 +307,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_ARP_SPA, "arp_spa", NULL, MF_FIELD_SIZES(be32), - MFM_FULLY, 0, + MFM_FULLY, MFS_IPV4, MFP_ARP, false, @@ -316,7 +316,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_ARP_TPA, "arp_tpa", NULL, MF_FIELD_SIZES(be32), - MFM_FULLY, 0, + MFM_FULLY, MFS_IPV4, MFP_ARP, false, @@ -325,7 +325,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_ARP_SHA, "arp_sha", NULL, MF_FIELD_SIZES(mac), - MFM_FULLY, 0, + MFM_FULLY, MFS_ETHERNET, MFP_ARP, false, @@ -334,7 +334,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_ARP_THA, "arp_tha", NULL, MF_FIELD_SIZES(mac), - MFM_FULLY, 0, + MFM_FULLY, MFS_ETHERNET, MFP_ARP, false, @@ -349,7 +349,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { { MFF_TCP_SRC, "tcp_src", "tp_src", MF_FIELD_SIZES(be16), - MFM_FULLY, 0, + MFM_FULLY, MFS_DECIMAL, MFP_TCP, true, @@ -358,7 +358,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_TCP_DST, "tcp_dst", "tp_dst", MF_FIELD_SIZES(be16), - MFM_FULLY, 0, + MFM_FULLY, MFS_DECIMAL, MFP_TCP, true, @@ -369,7 +369,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { { MFF_UDP_SRC, "udp_src", NULL, MF_FIELD_SIZES(be16), - MFM_FULLY, 0, + MFM_FULLY, MFS_DECIMAL, MFP_UDP, true, @@ -378,7 +378,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_UDP_DST, "udp_dst", NULL, MF_FIELD_SIZES(be16), - MFM_FULLY, 0, + MFM_FULLY, MFS_DECIMAL, MFP_UDP, true, @@ -389,7 +389,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { { MFF_ICMPV4_TYPE, "icmp_type", NULL, MF_FIELD_SIZES(u8), - MFM_NONE, 0, + MFM_NONE, MFS_DECIMAL, MFP_ICMPV4, false, @@ -398,7 +398,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_ICMPV4_CODE, "icmp_code", NULL, MF_FIELD_SIZES(u8), - MFM_NONE, 0, + MFM_NONE, MFS_DECIMAL, MFP_ICMPV4, false, @@ -409,7 +409,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { { MFF_ICMPV6_TYPE, "icmpv6_type", NULL, MF_FIELD_SIZES(u8), - MFM_NONE, 0, + MFM_NONE, MFS_DECIMAL, MFP_ICMPV6, false, @@ -418,7 +418,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_ICMPV6_CODE, "icmpv6_code", NULL, MF_FIELD_SIZES(u8), - MFM_NONE, 0, + MFM_NONE, MFS_DECIMAL, MFP_ICMPV6, false, @@ -433,7 +433,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { { MFF_ND_TARGET, "nd_target", NULL, MF_FIELD_SIZES(ipv6), - MFM_FULLY, 0, + MFM_FULLY, MFS_IPV6, MFP_ND, false, @@ -442,7 +442,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_ND_SLL, "nd_sll", NULL, MF_FIELD_SIZES(mac), - MFM_FULLY, 0, + MFM_FULLY, MFS_ETHERNET, MFP_ND_SOLICIT, false, @@ -451,7 +451,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { }, { MFF_ND_TLL, "nd_tll", NULL, MF_FIELD_SIZES(mac), - MFM_FULLY, 0, + MFM_FULLY, MFS_ETHERNET, MFP_ND_ADVERT, false, @@ -573,15 +573,12 @@ bool mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc) { switch (mf->id) { - case MFF_IN_PORT: - assert(mf->fww_bit != 0); - return (wc->wildcards & mf->fww_bit) != 0; - case MFF_TUN_ID: return !wc->tun_id_mask; case MFF_METADATA: return !wc->metadata_mask; - + case MFF_IN_PORT: + return !wc->in_port_mask; CASE_MFF_REGS: return !wc->reg_masks[mf->id - MFF_REG0]; @@ -673,18 +670,15 @@ mf_get_mask(const struct mf_field *mf, const struct flow_wildcards *wc, union mf_value *mask) { switch (mf->id) { - case MFF_IN_PORT: - assert(mf->fww_bit != 0); - memset(mask, wc->wildcards & mf->fww_bit ? 0x00 : 0xff, mf->n_bytes); - break; - case MFF_TUN_ID: mask->be64 = wc->tun_id_mask; break; case MFF_METADATA: mask->be64 = wc->metadata_mask; break; - + case MFF_IN_PORT: + mask->be16 = htons(wc->in_port_mask); + break; CASE_MFF_REGS: mask->be32 = htonl(wc->reg_masks[mf->id - MFF_REG0]); break; @@ -1408,8 +1402,8 @@ mf_set_wild(const struct mf_field *mf, struct cls_rule *rule) cls_rule_set_metadata_masked(rule, htonll(0), htonll(0)); case MFF_IN_PORT: - rule->wc.wildcards |= FWW_IN_PORT; rule->flow.in_port = 0; + rule->wc.in_port_mask = 0; break; CASE_MFF_REGS: diff --git a/lib/meta-flow.h b/lib/meta-flow.h index 12a4baa2..db3ac7ad 100644 --- a/lib/meta-flow.h +++ b/lib/meta-flow.h @@ -218,7 +218,6 @@ struct mf_field { /* Properties. */ enum mf_maskable maskable; - flow_wildcards_t fww_bit; /* Either 0 or exactly one FWW_* bit. */ enum mf_string string; enum mf_prereqs prereqs; bool writable; /* May be written by actions? */ diff --git a/lib/nx-match.c b/lib/nx-match.c index 511cd7c1..732d33e1 100644 --- a/lib/nx-match.c +++ b/lib/nx-match.c @@ -552,7 +552,6 @@ static int nx_put_raw(struct ofpbuf *b, bool oxm, const struct cls_rule *cr, ovs_be64 cookie, ovs_be64 cookie_mask) { - const flow_wildcards_t wc = cr->wc.wildcards; const struct flow *flow = &cr->flow; const size_t start_len = b->size; int match_len; @@ -561,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 (!(wc & FWW_IN_PORT)) { + if (cr->wc.in_port_mask) { uint16_t in_port = flow->in_port; if (oxm) { nxm_put_32(b, OXM_OF_IN_PORT, ofputil_port_to_ofp11(in_port)); diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 8413c378..02615292 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -89,9 +89,8 @@ ofputil_wildcard_from_ofpfw10(uint32_t ofpfw, struct flow_wildcards *wc) /* Initialize most of rule->wc. */ flow_wildcards_init_catchall(wc); - wc->wildcards = 0; - if (ofpfw & OFPFW10_IN_PORT) { - wc->wildcards |= FWW_IN_PORT; + if (!(ofpfw & OFPFW10_IN_PORT)) { + wc->in_port_mask = UINT16_MAX; } if (!(ofpfw & OFPFW10_NW_TOS)) { @@ -190,7 +189,7 @@ ofputil_cls_rule_to_ofp10_match(const struct cls_rule *rule, /* Figure out most OpenFlow wildcards. */ ofpfw = 0; - if (wc->wildcards & FWW_IN_PORT) { + if (!wc->in_port_mask) { ofpfw |= OFPFW10_IN_PORT; } if (!wc->dl_type_mask) { @@ -469,7 +468,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.wildcards & FWW_IN_PORT) { + if (!rule->wc.in_port_mask) { wc |= OFPFW11_IN_PORT; } else { match->in_port = ofputil_port_to_ofp11(rule->flow.in_port); diff --git a/tests/test-classifier.c b/tests/test-classifier.c index 97e8f3fe..baa4cc1a 100644 --- a/tests/test-classifier.c +++ b/tests/test-classifier.c @@ -41,28 +41,28 @@ /* Fields in a rule. */ #define CLS_FIELDS \ - /* struct flow all-caps */ \ - /* FWW_* bit(s) member name name */ \ - /* -------------------------- ----------- -------- */ \ - CLS_FIELD(0, tun_id, TUN_ID) \ - CLS_FIELD(0, metadata, METADATA) \ - CLS_FIELD(0, nw_src, NW_SRC) \ - CLS_FIELD(0, nw_dst, NW_DST) \ - CLS_FIELD(FWW_IN_PORT, in_port, IN_PORT) \ - CLS_FIELD(0, vlan_tci, VLAN_TCI) \ - CLS_FIELD(0, dl_type, DL_TYPE) \ - CLS_FIELD(0, tp_src, TP_SRC) \ - CLS_FIELD(0, tp_dst, TP_DST) \ - CLS_FIELD(0, dl_src, DL_SRC) \ - CLS_FIELD(0, dl_dst, DL_DST) \ - CLS_FIELD(0, nw_proto, NW_PROTO) \ - CLS_FIELD(0, nw_tos, NW_DSCP) + /* struct flow all-caps */ \ + /* member name name */ \ + /* ----------- -------- */ \ + CLS_FIELD(tun_id, TUN_ID) \ + CLS_FIELD(metadata, METADATA) \ + CLS_FIELD(nw_src, NW_SRC) \ + CLS_FIELD(nw_dst, NW_DST) \ + CLS_FIELD(in_port, IN_PORT) \ + CLS_FIELD(vlan_tci, VLAN_TCI) \ + CLS_FIELD(dl_type, DL_TYPE) \ + CLS_FIELD(tp_src, TP_SRC) \ + CLS_FIELD(tp_dst, TP_DST) \ + CLS_FIELD(dl_src, DL_SRC) \ + CLS_FIELD(dl_dst, DL_DST) \ + CLS_FIELD(nw_proto, NW_PROTO) \ + CLS_FIELD(nw_tos, NW_DSCP) /* Field indexes. * * (These are also indexed into struct classifier's 'tables' array.) */ enum { -#define CLS_FIELD(WILDCARDS, MEMBER, NAME) CLS_F_IDX_##NAME, +#define CLS_FIELD(MEMBER, NAME) CLS_F_IDX_##NAME, CLS_FIELDS #undef CLS_FIELD CLS_N_FIELDS @@ -72,15 +72,13 @@ enum { struct cls_field { int ofs; /* Offset in struct flow. */ int len; /* Length in bytes. */ - flow_wildcards_t wildcards; /* FWW_* bit or bits for this field. */ const char *name; /* Name (for debugging). */ }; static const struct cls_field cls_fields[CLS_N_FIELDS] = { -#define CLS_FIELD(WILDCARDS, MEMBER, NAME) \ +#define CLS_FIELD(MEMBER, NAME) \ { offsetof(struct flow, MEMBER), \ sizeof ((struct flow *)0)->MEMBER, \ - WILDCARDS, \ #NAME }, CLS_FIELDS #undef CLS_FIELD @@ -187,15 +185,9 @@ match(const struct cls_rule *wild, const struct flow *fixed) int f_idx; for (f_idx = 0; f_idx < CLS_N_FIELDS; f_idx++) { - const struct cls_field *f = &cls_fields[f_idx]; bool eq; - if (f->wildcards) { - void *wild_field = (char *) &wild->flow + f->ofs; - void *fixed_field = (char *) fixed + f->ofs; - eq = ((wild->wc.wildcards & f->wildcards) == f->wildcards - || !memcmp(wild_field, fixed_field, f->len)); - } else if (f_idx == CLS_F_IDX_NW_SRC) { + if (f_idx == CLS_F_IDX_NW_SRC) { eq = !((fixed->nw_src ^ wild->flow.nw_src) & wild->wc.nw_src_mask); } else if (f_idx == CLS_F_IDX_NW_DST) { eq = !((fixed->nw_dst ^ wild->flow.nw_dst) & wild->wc.nw_dst_mask); @@ -226,6 +218,9 @@ match(const struct cls_rule *wild, const struct flow *fixed) } else if (f_idx == CLS_F_IDX_DL_TYPE) { eq = !((fixed->dl_type ^ wild->flow.dl_type) & wild->wc.dl_type_mask); + } else if (f_idx == CLS_F_IDX_IN_PORT) { + eq = !((fixed->in_port ^ wild->flow.in_port) + & wild->wc.in_port_mask); } else { NOT_REACHED(); } @@ -486,9 +481,7 @@ make_rule(int wc_fields, unsigned int priority, int value_pat) memcpy((char *) &rule->cls_rule.flow + f->ofs, values[f_idx][value_idx], f->len); - if (f->wildcards) { - rule->cls_rule.wc.wildcards &= ~f->wildcards; - } else if (f_idx == CLS_F_IDX_NW_SRC) { + if (f_idx == CLS_F_IDX_NW_SRC) { rule->cls_rule.wc.nw_src_mask = htonl(UINT32_MAX); } else if (f_idx == CLS_F_IDX_NW_DST) { rule->cls_rule.wc.nw_dst_mask = htonl(UINT32_MAX); @@ -512,6 +505,8 @@ make_rule(int wc_fields, unsigned int priority, int value_pat) rule->cls_rule.wc.nw_proto_mask = UINT8_MAX; } else if (f_idx == CLS_F_IDX_DL_TYPE) { rule->cls_rule.wc.dl_type_mask = htons(UINT16_MAX); + } else if (f_idx == CLS_F_IDX_IN_PORT) { + rule->cls_rule.wc.in_port_mask = UINT16_MAX; } else { NOT_REACHED(); } -- 2.30.2