-enum {
- NXM_INVALID = OFP_MKERR_NICIRA(OFPET_BAD_REQUEST, NXBRC_NXM_INVALID),
- NXM_BAD_TYPE = OFP_MKERR_NICIRA(OFPET_BAD_REQUEST, NXBRC_NXM_BAD_TYPE),
- NXM_BAD_VALUE = OFP_MKERR_NICIRA(OFPET_BAD_REQUEST, NXBRC_NXM_BAD_VALUE),
- NXM_BAD_MASK = OFP_MKERR_NICIRA(OFPET_BAD_REQUEST, NXBRC_NXM_BAD_MASK),
- NXM_BAD_PREREQ = OFP_MKERR_NICIRA(OFPET_BAD_REQUEST, NXBRC_NXM_BAD_PREREQ),
- NXM_DUP_TYPE = OFP_MKERR_NICIRA(OFPET_BAD_REQUEST, NXBRC_NXM_DUP_TYPE),
- 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, WILDCARD, DL_TYPES, NW_PROTO, 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. */
- flow_wildcards_t wildcard; /* FWW_* bit, if exactly one. */
- ovs_be16 dl_type[N_NXM_DL_TYPES]; /* dl_type prerequisites. */
- uint8_t nw_proto; /* nw_proto prerequisite, if nonzero. */
- 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, WILDCARD, DL_TYPES, NW_PROTO, WRITABLE) \
- { HMAP_NODE_NULL_INITIALIZER, NFI_NXM_##HEADER, NXM_##HEADER, WILDCARD, \
- DL_CONVERT DL_TYPES, NW_PROTO, "NXM_" #HEADER, WRITABLE },
-#define DL_CONVERT(T1, T2) { CONSTANT_HTONS(T1), CONSTANT_HTONS(T2) }
-#include "nx-match.def"
-};
-
-/* Hash table of 'nxm_fields'. */
-static struct hmap all_nxm_fields = HMAP_INITIALIZER(&all_nxm_fields);
-
-/* Possible masks for NXM_OF_ETH_DST_W. */
-static const uint8_t eth_all_0s[ETH_ADDR_LEN]
- = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-static const uint8_t eth_all_1s[ETH_ADDR_LEN]
- = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-static const uint8_t eth_mcast_1[ETH_ADDR_LEN]
- = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
-static const uint8_t eth_mcast_0[ETH_ADDR_LEN]
- = {0xfe, 0xff, 0xff, 0xff, 0xff, 0xff};
-
-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));
- }
-
- /* Verify that the header values are unique (duplicate "case" values
- * cause a compile error). */
- switch (0) {
-#define DEFINE_FIELD(HEADER, WILDCARD, DL_TYPE, NW_PROTO, 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;
-}
-