From 28da1f8f725fc2a797174df18a7b3e31ef49ede0 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 12 Oct 2011 17:04:13 -0700 Subject: [PATCH] nx-match: Fold all of its data structures into mf_field. This is less redundant. --- lib/automake.mk | 1 - lib/classifier.c | 10 +- lib/learn.c | 18 +- lib/meta-flow.c | 331 +++++++++++++++++++++++++++---- lib/meta-flow.h | 11 ++ lib/nx-match.c | 496 ++++++++++++----------------------------------- lib/nx-match.def | 74 ------- lib/nx-match.h | 1 - 8 files changed, 448 insertions(+), 494 deletions(-) delete mode 100644 lib/nx-match.def diff --git a/lib/automake.mk b/lib/automake.mk index 64845188..da95acb9 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -88,7 +88,6 @@ lib_libopenvswitch_a_SOURCES = \ lib/netlink.c \ lib/netlink.h \ lib/nx-match.c \ - lib/nx-match.def \ lib/nx-match.h \ lib/odp-util.c \ lib/odp-util.h \ diff --git a/lib/classifier.c b/lib/classifier.c index 26d45fc3..dab8f620 100644 --- a/lib/classifier.c +++ b/lib/classifier.c @@ -218,12 +218,10 @@ cls_rule_set_any_vid(struct cls_rule *rule) void cls_rule_set_dl_vlan(struct cls_rule *rule, ovs_be16 dl_vlan) { + flow_set_vlan_vid(&rule->flow, dl_vlan); if (dl_vlan == htons(OFP_VLAN_NONE)) { - cls_rule_set_dl_tci(rule, htons(0)); + rule->wc.vlan_tci_mask = htons(UINT16_MAX); } else { - dl_vlan &= htons(VLAN_VID_MASK); - rule->flow.vlan_tci &= ~htons(VLAN_VID_MASK); - rule->flow.vlan_tci |= htons(VLAN_CFI) | dl_vlan; rule->wc.vlan_tci_mask |= htons(VLAN_VID_MASK | VLAN_CFI); } } @@ -247,9 +245,7 @@ cls_rule_set_any_pcp(struct cls_rule *rule) void cls_rule_set_dl_vlan_pcp(struct cls_rule *rule, uint8_t dl_vlan_pcp) { - dl_vlan_pcp &= 0x07; - rule->flow.vlan_tci &= ~htons(VLAN_PCP_MASK); - rule->flow.vlan_tci |= htons((dl_vlan_pcp << VLAN_PCP_SHIFT) | VLAN_CFI); + flow_set_vlan_pcp(&rule->flow, dl_vlan_pcp); rule->wc.vlan_tci_mask |= htons(VLAN_CFI | VLAN_PCP_MASK); } diff --git a/lib/learn.c b/lib/learn.c index 9f95a131..19a0e009 100644 --- a/lib/learn.c +++ b/lib/learn.c @@ -169,7 +169,7 @@ learn_check(const struct nx_action_learn *learn, const struct flow *flow) if (dst_type == NX_LEARN_DST_MATCH && src_type == NX_LEARN_SRC_IMMEDIATE) { - mf_set_subfield(nxm_field_to_mf_field(ntohl(dst_field)), value, + mf_set_subfield(mf_from_nxm_header(ntohl(dst_field)), value, dst_ofs, n_bits, &rule); } } @@ -232,7 +232,7 @@ learn_execute(const struct nx_action_learn *learn, const struct flow *flow, case NX_LEARN_DST_MATCH: dst_field = get_be32(&p); dst_ofs = ntohs(get_be16(&p)); - mf_set_subfield(nxm_field_to_mf_field(ntohl(dst_field)), value, + mf_set_subfield(mf_from_nxm_header(ntohl(dst_field)), value, dst_ofs, n_bits, &fm->cr); break; @@ -346,10 +346,10 @@ learn_parse_spec(const char *orig, char *name, char *value, spec->n_bits = n_bits; spec->src_type = NX_LEARN_SRC_FIELD; - spec->src = nxm_field_to_mf_field(src_header); + spec->src = mf_from_nxm_header(src_header); spec->src_ofs = src_ofs; spec->dst_type = NX_LEARN_DST_MATCH; - spec->dst = nxm_field_to_mf_field(dst_header); + spec->dst = mf_from_nxm_header(dst_header); spec->dst_ofs = 0; } else if (!strcmp(name, "load")) { if (value[strcspn(value, "[-")] == '-') { @@ -371,7 +371,7 @@ learn_parse_spec(const char *orig, char *name, char *value, spec->src_imm[i] = imm >> ((imm_bytes - i - 1) * 8); } spec->dst_type = NX_LEARN_DST_LOAD; - spec->dst = nxm_field_to_mf_field(ntohl(load.dst)); + spec->dst = mf_from_nxm_header(ntohl(load.dst)); spec->dst_ofs = nxm_decode_ofs(load.ofs_nbits); } else { struct nx_action_reg_move move; @@ -380,10 +380,10 @@ learn_parse_spec(const char *orig, char *name, char *value, spec->n_bits = ntohs(move.n_bits); spec->src_type = NX_LEARN_SRC_FIELD; - spec->src = nxm_field_to_mf_field(ntohl(move.src)); + spec->src = mf_from_nxm_header(ntohl(move.src)); spec->src_ofs = ntohs(move.src_ofs); spec->dst_type = NX_LEARN_DST_LOAD; - spec->dst = nxm_field_to_mf_field(ntohl(move.dst)); + spec->dst = mf_from_nxm_header(ntohl(move.dst)); spec->dst_ofs = ntohs(move.dst_ofs); } } else if (!strcmp(name, "output")) { @@ -397,7 +397,7 @@ learn_parse_spec(const char *orig, char *name, char *value, spec->n_bits = n_bits; spec->src_type = NX_LEARN_SRC_FIELD; - spec->src = nxm_field_to_mf_field(header); + spec->src = mf_from_nxm_header(header); spec->src_ofs = ofs; spec->dst_type = NX_LEARN_DST_OUTPUT; spec->dst = NULL; @@ -605,7 +605,7 @@ learn_format(const struct nx_action_learn *learn, struct ds *s) /* Get the destination. */ if (dst_type == NX_LEARN_DST_MATCH || dst_type == NX_LEARN_DST_LOAD) { dst_header = ntohl(get_be32(&p)); - dst_field = nxm_field_to_mf_field(dst_header); + dst_field = mf_from_nxm_header(dst_header); dst_ofs = ntohs(get_be16(&p)); } else { dst_header = 0; diff --git a/lib/meta-flow.c b/lib/meta-flow.c index 483fff4f..41cbf494 100644 --- a/lib/meta-flow.c +++ b/lib/meta-flow.c @@ -48,14 +48,16 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { MFM_FULLY, 0, MFS_HEXADECIMAL, MFP_NONE, - NXM_NX_TUN_ID, + true, + NXM_NX_TUN_ID, "NXM_NX_TUN_ID", }, { MFF_IN_PORT, "in_port", NULL, MF_FIELD_SIZES(be16), MFM_NONE, FWW_IN_PORT, MFS_OFP_PORT, MFP_NONE, - NXM_OF_IN_PORT, + false, + NXM_OF_IN_PORT, "NXM_OF_IN_PORT", }, #define REGISTER(IDX) \ @@ -65,7 +67,9 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { MFM_FULLY, 0, \ MFS_HEXADECIMAL, \ MFP_NONE, \ + true, \ NXM_NX_REG(IDX), \ + "NXM_NX_REG" #IDX \ } #if FLOW_N_REGS > 0 REGISTER(0), @@ -96,21 +100,24 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { MFM_NONE, FWW_DL_SRC, MFS_ETHERNET, MFP_NONE, - NXM_OF_ETH_SRC, + true, + NXM_OF_ETH_SRC, "NXM_OF_ETH_SRC", }, { MFF_ETH_DST, "eth_dst", "dl_dst", MF_FIELD_SIZES(mac), MFM_MCAST, 0, MFS_ETHERNET, MFP_NONE, - NXM_OF_ETH_DST, + true, + NXM_OF_ETH_DST, "NXM_OF_ETH_DST", }, { MFF_ETH_TYPE, "eth_type", "dl_type", MF_FIELD_SIZES(be16), MFM_NONE, FWW_DL_TYPE, MFS_HEXADECIMAL, MFP_NONE, - NXM_OF_ETH_TYPE, + false, + NXM_OF_ETH_TYPE, "NXM_OF_ETH_TYPE", }, { @@ -119,21 +126,24 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { MFM_FULLY, 0, MFS_HEXADECIMAL, MFP_NONE, - NXM_OF_VLAN_TCI, + true, + NXM_OF_VLAN_TCI, "NXM_OF_VLAN_TCI", }, { MFF_VLAN_VID, "dl_vlan", NULL, sizeof(ovs_be16), 12, MFM_NONE, 0, MFS_DECIMAL, MFP_NONE, - 0, + true, + 0, NULL }, { MFF_VLAN_PCP, "dl_vlan_pcp", NULL, 1, 3, MFM_NONE, 0, MFS_DECIMAL, MFP_NONE, - 0, + true, + 0, NULL }, /* ## -- ## */ @@ -146,14 +156,16 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { MFM_CIDR, 0, MFS_IPV4, MFP_IPV4, - NXM_OF_IP_SRC, + true, + NXM_OF_IP_SRC, "NXM_OF_IP_SRC", }, { MFF_IPV4_DST, "ip_dst", "nw_dst", MF_FIELD_SIZES(be32), MFM_CIDR, 0, MFS_IPV4, MFP_IPV4, - NXM_OF_IP_DST, + true, + NXM_OF_IP_DST, "NXM_OF_IP_DST", }, { @@ -162,14 +174,16 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { MFM_CIDR, 0, MFS_IPV6, MFP_IPV6, - NXM_NX_IPV6_SRC, + true, + NXM_NX_IPV6_SRC, "NXM_NX_IPV6_SRC", }, { MFF_IPV6_DST, "ipv6_dst", NULL, MF_FIELD_SIZES(ipv6), MFM_CIDR, 0, MFS_IPV6, MFP_IPV6, - NXM_NX_IPV6_DST, + true, + NXM_NX_IPV6_DST, "NXM_NX_IPV6_DST", }, { MFF_IPV6_LABEL, "ipv6_label", NULL, @@ -177,7 +191,8 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { MFM_NONE, FWW_IPV6_LABEL, MFS_HEXADECIMAL, MFP_IPV6, - NXM_NX_IPV6_LABEL, + false, + NXM_NX_IPV6_LABEL, "NXM_NX_IPV6_LABEL", }, { @@ -186,35 +201,40 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { MFM_NONE, FWW_NW_PROTO, MFS_DECIMAL, MFP_IP_ANY, - NXM_OF_IP_PROTO, + false, + NXM_OF_IP_PROTO, "NXM_OF_IP_PROTO", }, { MFF_IP_DSCP, "nw_tos", NULL, MF_FIELD_SIZES(u8), MFM_NONE, FWW_NW_DSCP, MFS_DECIMAL, MFP_IP_ANY, - NXM_OF_IP_TOS, + true, + NXM_OF_IP_TOS, "NXM_OF_IP_TOS" }, { MFF_IP_ECN, "nw_ecn", NULL, 1, 2, MFM_NONE, FWW_NW_ECN, MFS_DECIMAL, MFP_IP_ANY, - NXM_NX_IP_ECN, + true, + NXM_NX_IP_ECN, "NXM_NX_IP_ECN", }, { MFF_IP_TTL, "nw_ttl", NULL, MF_FIELD_SIZES(u8), MFM_NONE, FWW_NW_TTL, MFS_DECIMAL, MFP_IP_ANY, - NXM_NX_IP_TTL, + true, + NXM_NX_IP_TTL, "NXM_NX_IP_TTL" }, { MFF_IP_FRAG, "ip_frag", NULL, 1, 2, MFM_FULLY, 0, MFS_FRAG, MFP_IP_ANY, - NXM_NX_IP_FRAG, + false, + NXM_NX_IP_FRAG, "NXM_NX_IP_FRAG" }, { @@ -223,35 +243,40 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { MFM_NONE, FWW_NW_PROTO, MFS_DECIMAL, MFP_ARP, - NXM_OF_ARP_OP, + false, + NXM_OF_ARP_OP, "NXM_OF_ARP_OP", }, { MFF_ARP_SPA, "arp_spa", NULL, MF_FIELD_SIZES(be32), MFM_CIDR, 0, MFS_IPV4, MFP_ARP, - NXM_OF_ARP_SPA, + false, + NXM_OF_ARP_SPA, "NXM_OF_ARP_SPA", }, { MFF_ARP_TPA, "arp_tpa", NULL, MF_FIELD_SIZES(be32), MFM_CIDR, 0, MFS_IPV4, MFP_ARP, - NXM_OF_ARP_TPA, + false, + NXM_OF_ARP_TPA, "NXM_OF_ARP_TPA", }, { MFF_ARP_SHA, "arp_sha", NULL, MF_FIELD_SIZES(mac), MFM_NONE, FWW_ARP_SHA, MFS_ETHERNET, MFP_ARP, - NXM_NX_ARP_SHA, + false, + NXM_NX_ARP_SHA, "NXM_NX_ARP_SHA", }, { MFF_ARP_THA, "arp_tha", NULL, MF_FIELD_SIZES(mac), MFM_NONE, FWW_ARP_THA, MFS_ETHERNET, MFP_ARP, - NXM_NX_ARP_THA, + false, + NXM_NX_ARP_THA, "NXM_NX_ARP_THA", }, /* ## -- ## */ @@ -264,14 +289,16 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { MFM_NONE, FWW_TP_SRC, MFS_DECIMAL, MFP_TCP, - NXM_OF_TCP_SRC, + true, + NXM_OF_TCP_SRC, "NXM_OF_TCP_SRC", }, { MFF_TCP_DST, "tcp_dst", "tp_dst", MF_FIELD_SIZES(be16), MFM_NONE, FWW_TP_DST, MFS_DECIMAL, MFP_TCP, - NXM_OF_TCP_DST, + true, + NXM_OF_TCP_DST, "NXM_OF_TCP_DST", }, { @@ -280,14 +307,16 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { MFM_NONE, FWW_TP_SRC, MFS_DECIMAL, MFP_UDP, - NXM_OF_UDP_SRC, + true, + NXM_OF_UDP_SRC, "NXM_OF_UDP_SRC", }, { MFF_UDP_DST, "udp_dst", NULL, MF_FIELD_SIZES(be16), MFM_NONE, FWW_TP_DST, MFS_DECIMAL, MFP_UDP, - NXM_OF_UDP_DST, + true, + NXM_OF_UDP_DST, "NXM_OF_UDP_DST", }, { @@ -296,28 +325,34 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { MFM_NONE, FWW_TP_SRC, MFS_DECIMAL, MFP_ICMPV4, - NXM_OF_ICMP_TYPE, + false, + NXM_OF_ICMP_TYPE, "NXM_OF_ICMP_TYPE", }, { MFF_ICMPV4_CODE, "icmp_code", NULL, MF_FIELD_SIZES(u8), MFM_NONE, FWW_TP_DST, MFS_DECIMAL, MFP_ICMPV4, - NXM_OF_ICMP_CODE, - }, { + false, + NXM_OF_ICMP_CODE, "NXM_OF_ICMP_CODE", + }, + + { MFF_ICMPV6_TYPE, "icmpv6_type", NULL, MF_FIELD_SIZES(u8), MFM_NONE, FWW_TP_SRC, MFS_DECIMAL, MFP_ICMPV6, - NXM_NX_ICMPV6_TYPE, + false, + NXM_NX_ICMPV6_TYPE, "NXM_NX_ICMPV6_TYPE", }, { MFF_ICMPV6_CODE, "icmpv6_code", NULL, MF_FIELD_SIZES(u8), MFM_NONE, FWW_TP_DST, MFS_DECIMAL, MFP_ICMPV6, - NXM_NX_ICMPV6_CODE, + false, + NXM_NX_ICMPV6_CODE, "NXM_NX_ICMPV6_CODE", }, /* ## ---- ## */ @@ -330,24 +365,35 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { MFM_NONE, FWW_ND_TARGET, MFS_IPV6, MFP_ND, - NXM_NX_ND_TARGET, + false, + NXM_NX_ND_TARGET, "NXM_NX_ND_TARGET", }, { MFF_ND_SLL, "nd_sll", NULL, MF_FIELD_SIZES(mac), MFM_NONE, FWW_ARP_SHA, MFS_ETHERNET, MFP_ND_SOLICIT, - NXM_NX_ND_SLL, + false, + NXM_NX_ND_SLL, "NXM_NX_ND_SLL", }, { MFF_ND_TLL, "nd_tll", NULL, MF_FIELD_SIZES(mac), MFM_NONE, FWW_ARP_THA, MFS_ETHERNET, MFP_ND_ADVERT, - NXM_NX_ND_TLL, + false, + NXM_NX_ND_TLL, "NXM_NX_ND_TLL", } }; +struct nxm_field { + struct hmap_node hmap_node; + uint32_t nxm_header; + const struct mf_field *mf; +}; + +static struct hmap all_nxm_fields = HMAP_INITIALIZER(&all_nxm_fields); + /* Returns the field with the given 'id'. */ const struct mf_field * mf_from_id(enum mf_field_id id) @@ -377,6 +423,64 @@ mf_from_name(const char *name) return shash_find_data(&mf_by_name, name); } +static void +add_nxm_field(uint32_t nxm_header, const struct mf_field *mf) +{ + struct nxm_field *f; + + f = xmalloc(sizeof *f); + hmap_insert(&all_nxm_fields, &f->hmap_node, hash_int(nxm_header, 0)); + f->nxm_header = nxm_header; + f->mf = mf; +} + +static void +nxm_init(void) +{ + const struct mf_field *mf; + + for (mf = mf_fields; mf < &mf_fields[MFF_N_IDS]; mf++) { + if (mf->nxm_header) { + add_nxm_field(mf->nxm_header, mf); + if (mf->maskable != MFM_NONE) { + add_nxm_field(NXM_MAKE_WILD_HEADER(mf->nxm_header), mf); + } + } + } + +#ifndef NDEBUG + /* Verify that the header values are unique. */ + for (mf = mf_fields; mf < &mf_fields[MFF_N_IDS]; mf++) { + if (mf->nxm_header) { + assert(mf_from_nxm_header(mf->nxm_header) == mf); + if (mf->maskable != MFM_NONE) { + assert(mf_from_nxm_header(NXM_MAKE_WILD_HEADER(mf->nxm_header)) + == mf); + } + } + } +#endif +} + +const struct mf_field * +mf_from_nxm_header(uint32_t header) +{ + const struct nxm_field *f; + + if (hmap_is_empty(&all_nxm_fields)) { + nxm_init(); + } + + HMAP_FOR_EACH_IN_BUCKET (f, hmap_node, hash_int(header, 0), + &all_nxm_fields) { + if (f->nxm_header == header) { + return f->mf; + } + } + + return NULL; +} + /* Returns true if 'wc' wildcards all the bits in field 'mf', false if 'wc' * specifies at least one bit in the field. * @@ -1072,6 +1176,163 @@ mf_set_value(const struct mf_field *mf, } } +/* Makes 'rule' match field 'mf' exactly, with the value matched taken from + * 'value'. The caller is responsible for ensuring that 'rule' meets 'mf''s + * prerequisites. */ +void +mf_set_flow_value(const struct mf_field *mf, + const union mf_value *value, struct flow *flow) +{ + switch (mf->id) { + case MFF_TUN_ID: + flow->tun_id = value->be64; + break; + + case MFF_IN_PORT: + flow->in_port = ntohs(value->be16); + break; + +#if FLOW_N_REGS > 0 + case MFF_REG0: +#endif +#if FLOW_N_REGS > 1 + case MFF_REG1: +#endif +#if FLOW_N_REGS > 2 + case MFF_REG2: +#endif +#if FLOW_N_REGS > 3 + case MFF_REG3: +#endif +#if FLOW_N_REGS > 4 + case MFF_REG4: +#endif +#if FLOW_N_REGS > 5 +#error +#endif +#if FLOW_N_REGS > 0 + flow->regs[mf->id - MFF_REG0] = ntohl(value->be32); + break; +#endif + + case MFF_ETH_SRC: + memcpy(flow->dl_src, value->mac, ETH_ADDR_LEN); + break; + + case MFF_ETH_DST: + memcpy(flow->dl_src, value->mac, ETH_ADDR_LEN); + break; + + case MFF_ETH_TYPE: + flow->dl_type = value->be16; + break; + + case MFF_VLAN_TCI: + flow->vlan_tci = value->be16; + break; + + case MFF_VLAN_VID: + flow_set_vlan_vid(flow, value->be16); + break; + + case MFF_VLAN_PCP: + flow_set_vlan_pcp(flow, value->u8); + break; + + case MFF_IPV4_SRC: + flow->nw_src = value->be32; + break; + + case MFF_IPV4_DST: + flow->nw_dst = value->be32; + break; + + case MFF_IPV6_SRC: + flow->ipv6_src = value->ipv6; + break; + + case MFF_IPV6_DST: + flow->ipv6_dst = value->ipv6; + break; + + case MFF_IPV6_LABEL: + flow->ipv6_label = value->be32 & ~htonl(IPV6_LABEL_MASK); + break; + + case MFF_IP_PROTO: + flow->nw_proto = value->u8; + break; + + case MFF_IP_DSCP: + flow->nw_tos &= ~IP_DSCP_MASK; + flow->nw_tos |= value->u8 & IP_DSCP_MASK; + break; + + case MFF_IP_ECN: + flow->nw_tos &= ~IP_ECN_MASK; + flow->nw_tos |= value->u8 & IP_ECN_MASK; + break; + + case MFF_IP_TTL: + flow->nw_ttl = value->u8; + break; + + case MFF_IP_FRAG: + flow->nw_frag &= value->u8; + break; + + case MFF_ARP_OP: + flow->nw_proto = ntohs(value->be16); + break; + + case MFF_ARP_SPA: + flow->nw_src = value->be32; + break; + + case MFF_ARP_TPA: + flow->nw_dst = value->be32; + break; + + case MFF_ARP_SHA: + case MFF_ND_SLL: + memcpy(flow->arp_sha, value->mac, ETH_ADDR_LEN); + break; + + case MFF_ARP_THA: + case MFF_ND_TLL: + memcpy(flow->arp_tha, value->mac, ETH_ADDR_LEN); + break; + + case MFF_TCP_SRC: + case MFF_UDP_SRC: + flow->tp_src = value->be16; + break; + + case MFF_TCP_DST: + case MFF_UDP_DST: + flow->tp_dst = value->be16; + break; + + case MFF_ICMPV4_TYPE: + case MFF_ICMPV6_TYPE: + flow->tp_src = htons(value->u8); + break; + + case MFF_ICMPV4_CODE: + case MFF_ICMPV6_CODE: + flow->tp_dst = htons(value->u8); + break; + + case MFF_ND_TARGET: + flow->nd_target = value->ipv6; + break; + + case MFF_N_IDS: + default: + NOT_REACHED(); + } +} + /* Makes 'rule' wildcard field 'mf'. * * The caller is responsible for ensuring that 'rule' meets 'mf''s diff --git a/lib/meta-flow.h b/lib/meta-flow.h index 79907132..a552e3ce 100644 --- a/lib/meta-flow.h +++ b/lib/meta-flow.h @@ -178,7 +178,14 @@ struct mf_field { 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? */ + + /* NXM properties. + * + * A few "mf_field"s don't correspond to NXM fields. Those have 0 and + * NULL for the following members, respectively. */ uint32_t nxm_header; /* An NXM_* constant (a few fields have 0). */ + const char *nxm_name; /* The "NXM_*" constant's name. */ }; /* The representation of a field's value. */ @@ -194,6 +201,8 @@ union mf_value { /* Finding mf_fields. */ const struct mf_field *mf_from_id(enum mf_field_id); const struct mf_field *mf_from_name(const char *name); +const struct mf_field *mf_from_nxm_header(uint32_t nxm_header); +const struct mf_field *mf_from_nxm_name(const char *nxm_name); /* Inspecting wildcarded bits. */ bool mf_is_all_wild(const struct mf_field *, const struct flow_wildcards *); @@ -213,6 +222,8 @@ void mf_get_value(const struct mf_field *, const struct flow *, union mf_value *value); void mf_set_value(const struct mf_field *, const union mf_value *value, struct cls_rule *); +void mf_set_flow_value(const struct mf_field *, const union mf_value *value, + struct flow *); void mf_get(const struct mf_field *, const struct cls_rule *, union mf_value *value, union mf_value *mask); diff --git a/lib/nx-match.c b/lib/nx-match.c index 8c4bf509..9b3c1e05 100644 --- a/lib/nx-match.c +++ b/lib/nx-match.c @@ -46,76 +46,6 @@ enum { BAD_ARGUMENT = OFP_MKERR(OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT) }; -/* For each NXM_* field, define NFI_NXM_* as consecutive integers starting from - * zero. */ -enum nxm_field_index { -#define DEFINE_FIELD(HEADER, MFF_ID, WRITABLE) \ - NFI_NXM_##HEADER, -#include "nx-match.def" - N_NXM_FIELDS -}; - -struct nxm_field { - struct hmap_node hmap_node; - enum nxm_field_index index; /* NFI_* value. */ - uint32_t header; /* NXM_* value. */ - enum mf_field_id mf_id; /* MFF_* value. */ - const struct mf_field *mf; - const char *name; /* "NXM_*" string. */ - bool writable; /* Writable with NXAST_REG_{MOVE,LOAD}? */ -}; - -/* All the known fields. */ -static struct nxm_field nxm_fields[N_NXM_FIELDS] = { -#define DEFINE_FIELD(HEADER, MFF_ID, WRITABLE) \ - { HMAP_NODE_NULL_INITIALIZER, NFI_NXM_##HEADER, NXM_##HEADER, \ - MFF_ID, NULL, "NXM_" #HEADER, WRITABLE }, -#include "nx-match.def" -}; - -/* Hash table of 'nxm_fields'. */ -static struct hmap all_nxm_fields = HMAP_INITIALIZER(&all_nxm_fields); - -static void -nxm_init(void) -{ - if (hmap_is_empty(&all_nxm_fields)) { - int i; - - for (i = 0; i < N_NXM_FIELDS; i++) { - struct nxm_field *f = &nxm_fields[i]; - hmap_insert(&all_nxm_fields, &f->hmap_node, - hash_int(f->header, 0)); - f->mf = mf_from_id(f->mf_id); - } - - /* Verify that the header values are unique (duplicate "case" values - * cause a compile error). */ - switch (0) { -#define DEFINE_FIELD(HEADER, MFF_ID, WRITABLE) \ - case NXM_##HEADER: break; -#include "nx-match.def" - } - } -} - -static const struct nxm_field * -nxm_field_lookup(uint32_t header) -{ - struct nxm_field *f; - - nxm_init(); - - HMAP_FOR_EACH_WITH_HASH (f, hmap_node, hash_int(header, 0), - &all_nxm_fields) { - if (f->header == header) { - return f; - } - } - - return NULL; -} - /* Returns the width of the data for a field with the given 'header', in * bytes. */ int @@ -132,13 +62,6 @@ nxm_field_bits(uint32_t header) { return nxm_field_bytes(header) * 8; } - -const struct mf_field * -nxm_field_to_mf_field(uint32_t header) -{ - const struct nxm_field *f = nxm_field_lookup(header); - return f ? f->mf : NULL; -} /* nx_pull_match() and helpers. */ @@ -191,46 +114,46 @@ nx_pull_match(struct ofpbuf *b, unsigned int match_len, uint16_t priority, cls_rule_init_catchall(rule, priority); while ((header = nx_entry_ok(p, match_len)) != 0) { unsigned length = NXM_LENGTH(header); - const struct nxm_field *f; + const struct mf_field *mf; int error; - f = nxm_field_lookup(header); - if (!f) { + mf = mf_from_nxm_header(header); + if (!mf) { error = NXM_BAD_TYPE; - } else if (!mf_are_prereqs_ok(f->mf, &rule->flow)) { + } else if (!mf_are_prereqs_ok(mf, &rule->flow)) { error = NXM_BAD_PREREQ; - } else if (!mf_is_all_wild(f->mf, &rule->wc)) { + } else if (!mf_is_all_wild(mf, &rule->wc)) { error = NXM_DUP_TYPE; } else { - unsigned int width = f->mf->n_bytes; + unsigned int width = mf->n_bytes; union mf_value value; memcpy(&value, p + 4, width); - if (!mf_is_value_valid(f->mf, &value)) { + if (!mf_is_value_valid(mf, &value)) { error = NXM_BAD_VALUE; } else if (!NXM_HASMASK(header)) { error = 0; - mf_set_value(f->mf, &value, rule); + mf_set_value(mf, &value, rule); } else { union mf_value mask; memcpy(&mask, p + 4 + width, width); - if (!mf_is_mask_valid(f->mf, &mask)) { + if (!mf_is_mask_valid(mf, &mask)) { error = NXM_BAD_MASK; } else { error = 0; - mf_set(f->mf, &value, &mask, rule); + mf_set(mf, &value, &mask, rule); } } } if (error) { char *msg = ofputil_error_to_string(error); - VLOG_DBG_RL(&rl, "bad nxm_entry with vendor=%"PRIu32", " - "field=%"PRIu32", hasmask=%"PRIu32", type=%"PRIu32" " - "(%s)", + VLOG_DBG_RL(&rl, "bad nxm_entry %#08"PRIx32" (vendor=%"PRIu32", " + "field=%"PRIu32", hasmask=%"PRIu32", len=%"PRIu32"), " + "(%s)", header, NXM_VENDOR(header), NXM_FIELD(header), - NXM_HASMASK(header), NXM_TYPE(header), + NXM_HASMASK(header), NXM_LENGTH(header), msg); free(msg); @@ -696,9 +619,12 @@ nx_match_to_string(const uint8_t *p, unsigned int match_len) static void format_nxm_field_name(struct ds *s, uint32_t header) { - const struct nxm_field *f = nxm_field_lookup(header); - if (f) { - ds_put_cstr(s, f->name); + const struct mf_field *mf = mf_from_nxm_header(header); + if (mf) { + ds_put_cstr(s, mf->nxm_name); + if (NXM_HASMASK(header)) { + ds_put_cstr(s, "_W"); + } } else { ds_put_format(s, "%d:%d", NXM_VENDOR(header), NXM_FIELD(header)); } @@ -707,12 +633,25 @@ format_nxm_field_name(struct ds *s, uint32_t header) static uint32_t parse_nxm_field_name(const char *name, int name_len) { - const struct nxm_field *f; + bool wild; + int i; /* Check whether it's a field name. */ - for (f = nxm_fields; f < &nxm_fields[ARRAY_SIZE(nxm_fields)]; f++) { - if (!strncmp(f->name, name, name_len) && f->name[name_len] == '\0') { - return f->header; + wild = name_len > 2 && !memcmp(&name[name_len - 2], "_W", 2); + if (wild) { + name_len -= 2; + } + for (i = 0; i < MFF_N_IDS; i++) { + const struct mf_field *mf = mf_from_id(i); + + if (mf->nxm_name + && !strncmp(mf->nxm_name, name, name_len) + && mf->nxm_name[name_len] == '\0') { + if (!wild) { + return mf->nxm_header; + } else if (mf->maskable != MFM_NONE) { + return NXM_MAKE_WILD_HEADER(mf->nxm_header); + } } } @@ -951,12 +890,11 @@ nxm_format_reg_load(const struct nx_action_reg_load *load, struct ds *s) /* nxm_check_reg_move(), nxm_check_reg_load(). */ static bool -field_ok(const struct nxm_field *f, const struct flow *flow, int size) +field_ok(const struct mf_field *mf, const struct flow *flow, int size) { - return (f - && !NXM_HASMASK(f->header) - && mf_are_prereqs_ok(f->mf, flow) - && size <= nxm_field_bits(f->header)); + return (mf + && mf_are_prereqs_ok(mf, flow) + && size <= nxm_field_bits(mf->nxm_header)); } int @@ -981,14 +919,15 @@ nxm_check_reg_move(const struct nx_action_reg_move *action, /* Given a flow, checks that the source field represented by 'src_header' * in the range ['ofs', 'ofs' + 'n_bits') is valid. */ int -nxm_src_check(ovs_be32 src_header, unsigned int ofs, unsigned int n_bits, +nxm_src_check(ovs_be32 src_header_, unsigned int ofs, unsigned int n_bits, const struct flow *flow) { - const struct nxm_field *src = nxm_field_lookup(ntohl(src_header)); + uint32_t src_header = ntohl(src_header_); + const struct mf_field *src = mf_from_nxm_header(src_header); if (!n_bits) { VLOG_WARN_RL(&rl, "zero bit source field"); - } else if (!field_ok(src, flow, ofs + n_bits)) { + } else if (NXM_HASMASK(src_header) || !field_ok(src, flow, ofs + n_bits)) { VLOG_WARN_RL(&rl, "invalid source field"); } else { return 0; @@ -1000,14 +939,15 @@ nxm_src_check(ovs_be32 src_header, unsigned int ofs, unsigned int n_bits, /* Given a flow, checks that the destination field represented by 'dst_header' * in the range ['ofs', 'ofs' + 'n_bits') is valid. */ int -nxm_dst_check(ovs_be32 dst_header, unsigned int ofs, unsigned int n_bits, +nxm_dst_check(ovs_be32 dst_header_, unsigned int ofs, unsigned int n_bits, const struct flow *flow) { - const struct nxm_field *dst = nxm_field_lookup(ntohl(dst_header)); + uint32_t dst_header = ntohl(dst_header_); + const struct mf_field *dst = mf_from_nxm_header(dst_header); if (!n_bits) { VLOG_WARN_RL(&rl, "zero bit destination field"); - } else if (!field_ok(dst, flow, ofs + n_bits)) { + } else if (NXM_HASMASK(dst_header) || !field_ok(dst, flow, ofs + n_bits)) { VLOG_WARN_RL(&rl, "invalid destination field"); } else if (!dst->writable) { VLOG_WARN_RL(&rl, "destination field is not writable"); @@ -1042,120 +982,57 @@ nxm_check_reg_load(const struct nx_action_reg_load *action, /* nxm_execute_reg_move(), nxm_execute_reg_load(). */ -static uint64_t -nxm_read_field(const struct nxm_field *src, const struct flow *flow) +static void +bitwise_copy(const void *src_, unsigned int src_len, unsigned int src_ofs, + void *dst_, unsigned int dst_len, unsigned int dst_ofs, + unsigned int n_bits) { - switch (src->index) { - case NFI_NXM_OF_IN_PORT: - return flow->in_port; - - case NFI_NXM_OF_ETH_DST: - return eth_addr_to_uint64(flow->dl_dst); - - case NFI_NXM_OF_ETH_SRC: - return eth_addr_to_uint64(flow->dl_src); - - case NFI_NXM_OF_ETH_TYPE: - return ntohs(ofputil_dl_type_to_openflow(flow->dl_type)); - - case NFI_NXM_OF_VLAN_TCI: - return ntohs(flow->vlan_tci); - - case NFI_NXM_OF_IP_TOS: - return flow->nw_tos & IP_DSCP_MASK; - - case NFI_NXM_NX_IP_ECN: - return flow->nw_tos & IP_ECN_MASK; - - case NFI_NXM_NX_IP_TTL: - return flow->nw_ttl; - - case NFI_NXM_NX_IP_FRAG: - return flow->nw_frag; - - case NFI_NXM_OF_IP_PROTO: - case NFI_NXM_OF_ARP_OP: - return flow->nw_proto; - - case NFI_NXM_OF_IP_SRC: - case NFI_NXM_OF_ARP_SPA: - return ntohl(flow->nw_src); - - case NFI_NXM_OF_IP_DST: - case NFI_NXM_OF_ARP_TPA: - return ntohl(flow->nw_dst); - - case NFI_NXM_OF_TCP_SRC: - case NFI_NXM_OF_UDP_SRC: - return ntohs(flow->tp_src); - - case NFI_NXM_OF_TCP_DST: - case NFI_NXM_OF_UDP_DST: - return ntohs(flow->tp_dst); - - case NFI_NXM_OF_ICMP_TYPE: - case NFI_NXM_NX_ICMPV6_TYPE: - return ntohs(flow->tp_src) & 0xff; - - case NFI_NXM_OF_ICMP_CODE: - case NFI_NXM_NX_ICMPV6_CODE: - return ntohs(flow->tp_dst) & 0xff; - - case NFI_NXM_NX_TUN_ID: - return ntohll(flow->tun_id); - - case NFI_NXM_NX_IPV6_LABEL: - return ntohl(flow->ipv6_label); - -#define NXM_READ_REGISTER(IDX) \ - case NFI_NXM_NX_REG##IDX: \ - return flow->regs[IDX]; \ - case NFI_NXM_NX_REG##IDX##_W: \ - NOT_REACHED(); - - NXM_READ_REGISTER(0); -#if FLOW_N_REGS >= 2 - NXM_READ_REGISTER(1); -#endif -#if FLOW_N_REGS >= 3 - NXM_READ_REGISTER(2); -#endif -#if FLOW_N_REGS >= 4 - NXM_READ_REGISTER(3); -#endif -#if FLOW_N_REGS >= 5 - NXM_READ_REGISTER(4); -#endif -#if FLOW_N_REGS > 5 -#error -#endif - - case NFI_NXM_NX_ARP_SHA: - case NFI_NXM_NX_ND_SLL: - return eth_addr_to_uint64(flow->arp_sha); - - case NFI_NXM_NX_ARP_THA: - case NFI_NXM_NX_ND_TLL: - return eth_addr_to_uint64(flow->arp_tha); - - case NFI_NXM_NX_TUN_ID_W: - case NFI_NXM_OF_ETH_DST_W: - case NFI_NXM_OF_VLAN_TCI_W: - case NFI_NXM_OF_IP_SRC_W: - case NFI_NXM_OF_IP_DST_W: - case NFI_NXM_OF_ARP_SPA_W: - case NFI_NXM_OF_ARP_TPA_W: - case NFI_NXM_NX_IPV6_SRC: - case NFI_NXM_NX_IPV6_SRC_W: - case NFI_NXM_NX_IPV6_DST: - case NFI_NXM_NX_IPV6_DST_W: - case NFI_NXM_NX_IP_FRAG_W: - case NFI_NXM_NX_ND_TARGET: - case N_NXM_FIELDS: - NOT_REACHED(); - } + const uint8_t *src = src_; + uint8_t *dst = dst_; + + src += src_len - (src_ofs / 8 + 1); + src_ofs %= 8; + + dst += dst_len - (dst_ofs / 8 + 1); + dst_ofs %= 8; - NOT_REACHED(); + if (src_ofs == 0 && dst_ofs == 0) { + unsigned int n_bytes = n_bits / 8; + if (n_bytes) { + dst -= n_bytes - 1; + src -= n_bytes - 1; + memcpy(dst, src, n_bytes); + + n_bits %= 8; + src--; + dst--; + } + if (n_bits) { + uint8_t mask = (1 << n_bits) - 1; + *dst = (*dst & ~mask) | (*src & mask); + } + } else { + while (n_bits > 0) { + unsigned int max_copy = 8 - MAX(src_ofs, dst_ofs); + unsigned int chunk = MIN(n_bits, max_copy); + uint8_t mask = ((1 << chunk) - 1) << dst_ofs; + + *dst &= ~mask; + *dst |= ((*src >> src_ofs) << dst_ofs) & mask; + + src_ofs += chunk; + if (src_ofs == 8) { + src--; + src_ofs = 0; + } + dst_ofs += chunk; + if (dst_ofs == 8) { + dst--; + dst_ofs = 0; + } + n_bits -= chunk; + } + } } /* Returns the value of the NXM field corresponding to 'header' at 'ofs_nbits' @@ -1164,148 +1041,33 @@ uint64_t nxm_read_field_bits(ovs_be32 header, ovs_be16 ofs_nbits, const struct flow *flow) { - int n_bits = nxm_decode_n_bits(ofs_nbits); - int ofs = nxm_decode_ofs(ofs_nbits); - uint64_t mask, data; - - mask = n_bits == 64 ? UINT64_MAX : (UINT64_C(1) << n_bits) - 1; - data = nxm_read_field(nxm_field_lookup(ntohl(header)), flow); - data = (data >> ofs) & mask; - - return data; -} - -static void -nxm_write_field(const struct nxm_field *dst, struct flow *flow, - uint64_t new_value) -{ - switch (dst->index) { - case NFI_NXM_OF_ETH_DST: - eth_addr_from_uint64(new_value, flow->dl_dst); - break; - - case NFI_NXM_OF_ETH_SRC: - eth_addr_from_uint64(new_value, flow->dl_src); - break; - - case NFI_NXM_OF_VLAN_TCI: - flow->vlan_tci = htons(new_value); - break; - - case NFI_NXM_NX_TUN_ID: - flow->tun_id = htonll(new_value); - break; - -#define NXM_WRITE_REGISTER(IDX) \ - case NFI_NXM_NX_REG##IDX: \ - flow->regs[IDX] = new_value; \ - break; \ - case NFI_NXM_NX_REG##IDX##_W: \ - NOT_REACHED(); - - NXM_WRITE_REGISTER(0); -#if FLOW_N_REGS >= 2 - NXM_WRITE_REGISTER(1); -#endif -#if FLOW_N_REGS >= 3 - NXM_WRITE_REGISTER(2); -#endif -#if FLOW_N_REGS >= 4 - NXM_WRITE_REGISTER(3); -#endif -#if FLOW_N_REGS >= 5 - NXM_WRITE_REGISTER(4); -#endif -#if FLOW_N_REGS > 5 -#error -#endif - - case NFI_NXM_OF_IP_TOS: - flow->nw_tos &= ~IP_DSCP_MASK; - flow->nw_tos |= new_value & IP_DSCP_MASK; - break; - - case NFI_NXM_NX_IP_ECN: - flow->nw_tos &= ~IP_ECN_MASK; - flow->nw_tos |= new_value & IP_ECN_MASK; - break; - - case NFI_NXM_NX_IP_TTL: - flow->nw_ttl = new_value; - break; - - case NFI_NXM_NX_IP_FRAG: - flow->nw_frag = new_value; - break; - - case NFI_NXM_OF_IP_SRC: - flow->nw_src = htonl(new_value); - break; - - case NFI_NXM_OF_IP_DST: - flow->nw_dst = htonl(new_value); - break; - - case NFI_NXM_NX_IPV6_LABEL: - flow->ipv6_label = htonl(new_value); - break; - - case NFI_NXM_OF_TCP_SRC: - case NFI_NXM_OF_UDP_SRC: - flow->tp_src = htons(new_value); - break; - - case NFI_NXM_OF_TCP_DST: - case NFI_NXM_OF_UDP_DST: - flow->tp_dst = htons(new_value); - break; - - case NFI_NXM_OF_IN_PORT: - case NFI_NXM_OF_ETH_TYPE: - case NFI_NXM_OF_IP_PROTO: - case NFI_NXM_OF_ARP_OP: - case NFI_NXM_OF_ARP_SPA: - case NFI_NXM_OF_ARP_TPA: - case NFI_NXM_OF_ICMP_TYPE: - case NFI_NXM_OF_ICMP_CODE: - case NFI_NXM_NX_TUN_ID_W: - case NFI_NXM_OF_ETH_DST_W: - case NFI_NXM_OF_VLAN_TCI_W: - case NFI_NXM_OF_IP_SRC_W: - case NFI_NXM_OF_IP_DST_W: - case NFI_NXM_OF_ARP_SPA_W: - case NFI_NXM_OF_ARP_TPA_W: - case NFI_NXM_NX_ARP_SHA: - case NFI_NXM_NX_ARP_THA: - case NFI_NXM_NX_IPV6_SRC: - case NFI_NXM_NX_IPV6_SRC_W: - case NFI_NXM_NX_IPV6_DST: - case NFI_NXM_NX_IPV6_DST_W: - case NFI_NXM_NX_IP_FRAG_W: - case NFI_NXM_NX_ICMPV6_TYPE: - case NFI_NXM_NX_ICMPV6_CODE: - case NFI_NXM_NX_ND_TARGET: - case NFI_NXM_NX_ND_SLL: - case NFI_NXM_NX_ND_TLL: - case N_NXM_FIELDS: - NOT_REACHED(); - } + const struct mf_field *field = mf_from_nxm_header(ntohl(header)); + union mf_value value; + union mf_value bits; + + mf_get_value(field, flow, &value); + bits.be64 = htonll(0); + bitwise_copy(&value, field->n_bytes, nxm_decode_ofs(ofs_nbits), + &bits, sizeof bits.be64, 0, + nxm_decode_n_bits(ofs_nbits)); + return ntohll(bits.be64); } void nxm_execute_reg_move(const struct nx_action_reg_move *action, struct flow *flow) { - ovs_be16 src_ofs_nbits, dst_ofs_nbits; - uint64_t src_data; - int n_bits; - - n_bits = ntohs(action->n_bits); - src_ofs_nbits = nxm_encode_ofs_nbits(ntohs(action->src_ofs), n_bits); - dst_ofs_nbits = nxm_encode_ofs_nbits(ntohs(action->dst_ofs), n_bits); - - src_data = nxm_read_field_bits(action->src, src_ofs_nbits, flow); - nxm_reg_load(action->dst, dst_ofs_nbits, src_data, flow); + const struct mf_field *src = mf_from_nxm_header(ntohl(action->src)); + const struct mf_field *dst = mf_from_nxm_header(ntohl(action->dst)); + union mf_value src_value; + union mf_value dst_value; + + mf_get_value(dst, flow, &dst_value); + mf_get_value(src, flow, &src_value); + bitwise_copy(&src_value, src->n_bytes, ntohs(action->src_ofs), + &dst_value, dst->n_bytes, ntohs(action->dst_ofs), + ntohs(action->n_bits)); + mf_set_flow_value(dst, &dst_value, flow); } void @@ -1321,16 +1083,16 @@ void nxm_reg_load(ovs_be32 dst_header, ovs_be16 ofs_nbits, uint64_t src_data, struct flow *flow) { + const struct mf_field *dst = mf_from_nxm_header(ntohl(dst_header)); int n_bits = nxm_decode_n_bits(ofs_nbits); int dst_ofs = nxm_decode_ofs(ofs_nbits); - uint64_t mask = n_bits == 64 ? UINT64_MAX : (UINT64_C(1) << n_bits) - 1; - - /* Get remaining bits of the destination field. */ - const struct nxm_field *dst = nxm_field_lookup(ntohl(dst_header)); - uint64_t dst_data = nxm_read_field(dst, flow) & ~(mask << dst_ofs); - - /* Get the final value. */ - uint64_t new_data = dst_data | (src_data << dst_ofs); - - nxm_write_field(dst, flow, new_data); + union mf_value dst_value; + union mf_value src_value; + + mf_get_value(dst, flow, &dst_value); + src_value.be64 = htonll(src_data); + bitwise_copy(&src_value, sizeof src_value.be64, 0, + &dst_value, dst->n_bytes, dst_ofs, + n_bits); + mf_set_flow_value(dst, &dst_value, flow); } diff --git a/lib/nx-match.def b/lib/nx-match.def deleted file mode 100644 index 0426edf8..00000000 --- a/lib/nx-match.def +++ /dev/null @@ -1,74 +0,0 @@ -/* -*- c -*- - * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define DEFINE_FIELD_M(HEADER, MFF_ID, WRITABLE) \ - DEFINE_FIELD(HEADER, MFF_ID, WRITABLE) \ - DEFINE_FIELD(HEADER##_W, MFF_ID, false) - -/* NXM_ suffix MFF_ field ID rw? */ -/* ------------ ------------ ----- */ -DEFINE_FIELD_M(NX_TUN_ID, MFF_TUN_ID, true) -DEFINE_FIELD (OF_IN_PORT, MFF_IN_PORT, false) -DEFINE_FIELD_M(OF_ETH_DST, MFF_ETH_DST, true) -DEFINE_FIELD (OF_ETH_SRC, MFF_ETH_SRC, true) -DEFINE_FIELD (OF_ETH_TYPE, MFF_ETH_TYPE, false) -DEFINE_FIELD_M(OF_VLAN_TCI, MFF_VLAN_TCI, true) -DEFINE_FIELD (OF_IP_TOS, MFF_IP_DSCP, true) -DEFINE_FIELD (OF_IP_PROTO, MFF_IP_PROTO, false) -DEFINE_FIELD_M(OF_IP_SRC, MFF_IPV4_SRC, true) -DEFINE_FIELD_M(OF_IP_DST, MFF_IPV4_DST, true) -DEFINE_FIELD_M(NX_IP_FRAG, MFF_IP_FRAG, false) -DEFINE_FIELD (OF_TCP_SRC, MFF_TCP_SRC, true) -DEFINE_FIELD (OF_TCP_DST, MFF_TCP_DST, true) -DEFINE_FIELD (OF_UDP_SRC, MFF_UDP_SRC, true) -DEFINE_FIELD (OF_UDP_DST, MFF_UDP_DST, true) -DEFINE_FIELD (OF_ICMP_TYPE, MFF_ICMPV4_TYPE, false) -DEFINE_FIELD (OF_ICMP_CODE, MFF_ICMPV4_CODE, false) -DEFINE_FIELD (OF_ARP_OP, MFF_ARP_OP, false) -DEFINE_FIELD_M(OF_ARP_SPA, MFF_ARP_SPA, false) -DEFINE_FIELD_M(OF_ARP_TPA, MFF_ARP_TPA, false) -DEFINE_FIELD (NX_ARP_SHA, MFF_ARP_SHA, false) -DEFINE_FIELD (NX_ARP_THA, MFF_ARP_THA, false) -DEFINE_FIELD_M(NX_IPV6_SRC, MFF_IPV6_SRC, false) -DEFINE_FIELD_M(NX_IPV6_DST, MFF_IPV6_DST, false) -DEFINE_FIELD (NX_IPV6_LABEL, MFF_IPV6_LABEL,false) -DEFINE_FIELD (NX_IP_ECN, MFF_IP_ECN, true) -DEFINE_FIELD (NX_IP_TTL, MFF_IP_TTL, true) -/* XXX should we have MFF_ICMPV4_TYPE and MFF_ICMPV6_TYPE? */ -DEFINE_FIELD (NX_ICMPV6_TYPE,MFF_ICMPV6_TYPE, false) -DEFINE_FIELD (NX_ICMPV6_CODE,MFF_ICMPV6_CODE, false) -DEFINE_FIELD (NX_ND_TARGET, MFF_ND_TARGET, false) -DEFINE_FIELD (NX_ND_SLL, MFF_ND_SLL, false) -DEFINE_FIELD (NX_ND_TLL, MFF_ND_TLL, false) - -DEFINE_FIELD_M(NX_REG0, MFF_REG0, true) -#if FLOW_N_REGS >= 2 -DEFINE_FIELD_M(NX_REG1, MFF_REG1, true) -#endif -#if FLOW_N_REGS >= 3 -DEFINE_FIELD_M(NX_REG2, MFF_REG2, true) -#endif -#if FLOW_N_REGS >= 4 -DEFINE_FIELD_M(NX_REG3, MFF_REG3, true) -#endif -#if FLOW_N_REGS >= 5 -DEFINE_FIELD_M(NX_REG4, MFF_REG4, true) -#endif -#if FLOW_N_REGS > 5 -#error -#endif - -#undef DEFINE_FIELD diff --git a/lib/nx-match.h b/lib/nx-match.h index 0b9a437d..faeacd6c 100644 --- a/lib/nx-match.h +++ b/lib/nx-match.h @@ -64,7 +64,6 @@ void nxm_reg_load(ovs_be32 dst, ovs_be16 ofs_nbits, uint64_t src_data, int nxm_field_bytes(uint32_t header); int nxm_field_bits(uint32_t header); -const struct mf_field *nxm_field_to_mf_field(uint32_t header); const char *nxm_parse_field_bits(const char *s, uint32_t *headerp, int *ofsp, int *n_bitsp); -- 2.30.2