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;
}
{
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;
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) {
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);
&& !((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)
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);
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;
{
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);
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);
{
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);
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);
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)
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)
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;
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;
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
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
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. */
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. */
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. */
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);
{
MFF_TUN_ID, "tun_id", NULL,
MF_FIELD_SIZES(be64),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_HEXADECIMAL,
MFP_NONE,
true,
}, {
MFF_METADATA, "metadata", NULL,
MF_FIELD_SIZES(be64),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_HEXADECIMAL,
MFP_NONE,
true,
}, {
MFF_IN_PORT, "in_port", NULL,
MF_FIELD_SIZES(be16),
- MFM_NONE, FWW_IN_PORT,
+ MFM_NONE,
MFS_OFP_PORT,
MFP_NONE,
false,
{ \
MFF_REG##IDX, "reg" #IDX, NULL, \
MF_FIELD_SIZES(be32), \
- MFM_FULLY, 0, \
+ MFM_FULLY, \
MFS_HEXADECIMAL, \
MFP_NONE, \
true, \
{
MFF_ETH_SRC, "eth_src", "dl_src",
MF_FIELD_SIZES(mac),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_ETHERNET,
MFP_NONE,
true,
}, {
MFF_ETH_DST, "eth_dst", "dl_dst",
MF_FIELD_SIZES(mac),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_ETHERNET,
MFP_NONE,
true,
}, {
MFF_ETH_TYPE, "eth_type", "dl_type",
MF_FIELD_SIZES(be16),
- MFM_NONE, 0,
+ MFM_NONE,
MFS_HEXADECIMAL,
MFP_NONE,
false,
{
MFF_VLAN_TCI, "vlan_tci", NULL,
MF_FIELD_SIZES(be16),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_HEXADECIMAL,
MFP_NONE,
true,
}, {
MFF_DL_VLAN, "dl_vlan", NULL,
sizeof(ovs_be16), 12,
- MFM_NONE, 0,
+ MFM_NONE,
MFS_DECIMAL,
MFP_NONE,
true,
}, {
MFF_VLAN_VID, "vlan_vid", NULL,
sizeof(ovs_be16), 12,
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_DECIMAL,
MFP_NONE,
true,
}, {
MFF_DL_VLAN_PCP, "dl_vlan_pcp", NULL,
1, 3,
- MFM_NONE, 0,
+ MFM_NONE,
MFS_DECIMAL,
MFP_NONE,
true,
}, {
MFF_VLAN_PCP, "vlan_pcp", NULL,
1, 3,
- MFM_NONE, 0,
+ MFM_NONE,
MFS_DECIMAL,
MFP_VLAN_VID,
true,
{
MFF_IPV4_SRC, "ip_src", "nw_src",
MF_FIELD_SIZES(be32),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_IPV4,
MFP_IPV4,
true,
}, {
MFF_IPV4_DST, "ip_dst", "nw_dst",
MF_FIELD_SIZES(be32),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_IPV4,
MFP_IPV4,
true,
{
MFF_IPV6_SRC, "ipv6_src", NULL,
MF_FIELD_SIZES(ipv6),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_IPV6,
MFP_IPV6,
true,
}, {
MFF_IPV6_DST, "ipv6_dst", NULL,
MF_FIELD_SIZES(ipv6),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_IPV6,
MFP_IPV6,
true,
{
MFF_IPV6_LABEL, "ipv6_label", NULL,
4, 20,
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_HEXADECIMAL,
MFP_IPV6,
false,
{
MFF_IP_PROTO, "nw_proto", NULL,
MF_FIELD_SIZES(u8),
- MFM_NONE, 0,
+ MFM_NONE,
MFS_DECIMAL,
MFP_IP_ANY,
false,
}, {
MFF_IP_DSCP, "nw_tos", NULL,
MF_FIELD_SIZES(u8),
- MFM_NONE, 0,
+ MFM_NONE,
MFS_DECIMAL,
MFP_IP_ANY,
true,
}, {
MFF_IP_ECN, "nw_ecn", NULL,
1, 2,
- MFM_NONE, 0,
+ MFM_NONE,
MFS_DECIMAL,
MFP_IP_ANY,
true,
}, {
MFF_IP_TTL, "nw_ttl", NULL,
MF_FIELD_SIZES(u8),
- MFM_NONE, 0,
+ MFM_NONE,
MFS_DECIMAL,
MFP_IP_ANY,
true,
}, {
MFF_IP_FRAG, "ip_frag", NULL,
1, 2,
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_FRAG,
MFP_IP_ANY,
false,
{
MFF_ARP_OP, "arp_op", NULL,
MF_FIELD_SIZES(be16),
- MFM_NONE, 0,
+ MFM_NONE,
MFS_DECIMAL,
MFP_ARP,
false,
}, {
MFF_ARP_SPA, "arp_spa", NULL,
MF_FIELD_SIZES(be32),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_IPV4,
MFP_ARP,
false,
}, {
MFF_ARP_TPA, "arp_tpa", NULL,
MF_FIELD_SIZES(be32),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_IPV4,
MFP_ARP,
false,
}, {
MFF_ARP_SHA, "arp_sha", NULL,
MF_FIELD_SIZES(mac),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_ETHERNET,
MFP_ARP,
false,
}, {
MFF_ARP_THA, "arp_tha", NULL,
MF_FIELD_SIZES(mac),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_ETHERNET,
MFP_ARP,
false,
{
MFF_TCP_SRC, "tcp_src", "tp_src",
MF_FIELD_SIZES(be16),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_DECIMAL,
MFP_TCP,
true,
}, {
MFF_TCP_DST, "tcp_dst", "tp_dst",
MF_FIELD_SIZES(be16),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_DECIMAL,
MFP_TCP,
true,
{
MFF_UDP_SRC, "udp_src", NULL,
MF_FIELD_SIZES(be16),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_DECIMAL,
MFP_UDP,
true,
}, {
MFF_UDP_DST, "udp_dst", NULL,
MF_FIELD_SIZES(be16),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_DECIMAL,
MFP_UDP,
true,
{
MFF_ICMPV4_TYPE, "icmp_type", NULL,
MF_FIELD_SIZES(u8),
- MFM_NONE, 0,
+ MFM_NONE,
MFS_DECIMAL,
MFP_ICMPV4,
false,
}, {
MFF_ICMPV4_CODE, "icmp_code", NULL,
MF_FIELD_SIZES(u8),
- MFM_NONE, 0,
+ MFM_NONE,
MFS_DECIMAL,
MFP_ICMPV4,
false,
{
MFF_ICMPV6_TYPE, "icmpv6_type", NULL,
MF_FIELD_SIZES(u8),
- MFM_NONE, 0,
+ MFM_NONE,
MFS_DECIMAL,
MFP_ICMPV6,
false,
}, {
MFF_ICMPV6_CODE, "icmpv6_code", NULL,
MF_FIELD_SIZES(u8),
- MFM_NONE, 0,
+ MFM_NONE,
MFS_DECIMAL,
MFP_ICMPV6,
false,
{
MFF_ND_TARGET, "nd_target", NULL,
MF_FIELD_SIZES(ipv6),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_IPV6,
MFP_ND,
false,
}, {
MFF_ND_SLL, "nd_sll", NULL,
MF_FIELD_SIZES(mac),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_ETHERNET,
MFP_ND_SOLICIT,
false,
}, {
MFF_ND_TLL, "nd_tll", NULL,
MF_FIELD_SIZES(mac),
- MFM_FULLY, 0,
+ MFM_FULLY,
MFS_ETHERNET,
MFP_ND_ADVERT,
false,
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];
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;
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:
/* 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? */
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;
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));
/* 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)) {
/* 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) {
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);
/* 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
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
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);
} 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();
}
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);
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();
}