+/* OXM headers.
+ *
+ *
+ * Standard OXM/NXM
+ * ================
+ *
+ * The header is 32 bits long. It looks like this:
+ *
+ * |31 16 15 9| 8 7 0
+ * +----------------------------------+---------------+--+------------------+
+ * | oxm_class | oxm_field |hm| oxm_length |
+ * +----------------------------------+---------------+--+------------------+
+ *
+ * where hm stands for oxm_hasmask. It is followed by oxm_length bytes of
+ * payload. When oxm_hasmask is 0, the payload is the value of the field
+ * identified by the header; when oxm_hasmask is 1, the payload is a value for
+ * the field followed by a mask of equal length.
+ *
+ * Internally, we represent a standard OXM header as a 64-bit integer with the
+ * above information in the most-significant bits.
+ *
+ *
+ * Experimenter OXM
+ * ================
+ *
+ * The header is 64 bits long. It looks like the diagram above except that a
+ * 32-bit experimenter ID, which we call oxm_vendor and which identifies a
+ * vendor, is inserted just before the payload. Experimenter OXMs are
+ * identified by an all-1-bits oxm_class (OFPXMC12_EXPERIMENTER). The
+ * oxm_length value *includes* the experimenter ID, so that the real payload is
+ * only oxm_length - 4 bytes long.
+ *
+ * Internally, we represent an experimenter OXM header as a 64-bit integer with
+ * the standard header in the upper 32 bits and the experimenter ID in the
+ * lower 32 bits. (It would be more convenient to swap the positions of the
+ * two 32-bit words, but this would be more error-prone because experimenter
+ * OXMs are very rarely used, so accidentally passing one through a 32-bit type
+ * somewhere in the OVS code would be hard to find.)
+ */
+
+/*
+ * OXM Class IDs.
+ * The high order bit differentiate reserved classes from member classes.
+ * Classes 0x0000 to 0x7FFF are member classes, allocated by ONF.
+ * Classes 0x8000 to 0xFFFE are reserved classes, reserved for standardisation.
+ */
+enum ofp12_oxm_class {
+ OFPXMC12_NXM_0 = 0x0000, /* Backward compatibility with NXM */
+ OFPXMC12_NXM_1 = 0x0001, /* Backward compatibility with NXM */
+ OFPXMC12_OPENFLOW_BASIC = 0x8000, /* Basic class for OpenFlow */
+ OFPXMC15_PACKET_REGS = 0x8001, /* Packet registers (pipeline fields). */
+ OFPXMC12_EXPERIMENTER = 0xffff, /* Experimenter class */
+};
+
+/* Functions for extracting raw field values from OXM/NXM headers. */
+static uint32_t nxm_vendor(uint64_t header) { return header; }
+static int nxm_class(uint64_t header) { return header >> 48; }
+static int nxm_field(uint64_t header) { return (header >> 41) & 0x7f; }
+static bool nxm_hasmask(uint64_t header) { return (header >> 40) & 1; }
+static int nxm_length(uint64_t header) { return (header >> 32) & 0xff; }
+
+static bool
+is_experimenter_oxm(uint64_t header)
+{
+ return nxm_class(header) == OFPXMC12_EXPERIMENTER;
+}
+
+/* The OXM header "length" field is somewhat tricky:
+ *
+ * - For a standard OXM header, the length is the number of bytes of the
+ * payload, and the payload consists of just the value (and mask, if
+ * present).
+ *
+ * - For an experimenter OXM header, the length is the number of bytes in
+ * the payload plus 4 (the length of the experimenter ID). That is, the
+ * experimenter ID is included in oxm_length.
+ *
+ * This function returns the length of the experimenter ID field in 'header'.
+ * That is, for an experimenter OXM (when an experimenter ID is present), it
+ * returns 4, and for a standard OXM (when no experimenter ID is present), it
+ * returns 0. */
+static int
+nxm_experimenter_len(uint64_t header)
+{
+ return is_experimenter_oxm(header) ? 4 : 0;
+}
+
+/* Returns the number of bytes that follow the header for an NXM/OXM entry
+ * with the given 'header'. */
+static int
+nxm_payload_len(uint64_t header)
+{
+ return nxm_length(header) - nxm_experimenter_len(header);
+}
+
+/* Returns the number of bytes in the header for an NXM/OXM entry with the
+ * given 'header'. */
+static int
+nxm_header_len(uint64_t header)
+{
+ return 4 + nxm_experimenter_len(header);
+}
+
+#define NXM_HEADER(VENDOR, CLASS, FIELD, HASMASK, LENGTH) \
+ (((uint64_t) (CLASS) << 48) | \
+ ((uint64_t) (FIELD) << 41) | \
+ ((uint64_t) (HASMASK) << 40) | \
+ ((uint64_t) (LENGTH) << 32) | \
+ (VENDOR))
+
+#define NXM_HEADER_FMT "%#"PRIx32":%d:%d:%d:%d"
+#define NXM_HEADER_ARGS(HEADER) \
+ nxm_vendor(HEADER), nxm_class(HEADER), nxm_field(HEADER), \
+ nxm_hasmask(HEADER), nxm_length(HEADER)
+
+/* Functions for turning the "hasmask" bit on or off. (This also requires
+ * adjusting the length.) */
+static uint64_t
+nxm_make_exact_header(uint64_t header)
+{
+ int new_len = nxm_payload_len(header) / 2 + nxm_experimenter_len(header);
+ return NXM_HEADER(nxm_vendor(header), nxm_class(header),
+ nxm_field(header), 0, new_len);
+}
+static uint64_t
+nxm_make_wild_header(uint64_t header)
+{
+ int new_len = nxm_payload_len(header) * 2 + nxm_experimenter_len(header);
+ return NXM_HEADER(nxm_vendor(header), nxm_class(header),
+ nxm_field(header), 1, new_len);
+}
+
+/* Flow cookie.
+ *
+ * This may be used to gain the OpenFlow 1.1-like ability to restrict
+ * certain NXM-based Flow Mod and Flow Stats Request messages to flows
+ * with specific cookies. See the "nx_flow_mod" and "nx_flow_stats_request"
+ * structure definitions for more details. This match is otherwise not
+ * allowed. */
+#define NXM_NX_COOKIE NXM_HEADER (0, 0x0001, 30, 0, 8)
+#define NXM_NX_COOKIE_W nxm_make_wild_header(NXM_NX_COOKIE)
+
+struct nxm_field {
+ uint64_t header;
+ enum ofp_version version;
+ const char *name; /* e.g. "NXM_OF_IN_PORT". */
+
+ enum mf_field_id id;
+};
+
+static const struct nxm_field *nxm_field_by_header(uint64_t header);
+static const struct nxm_field *nxm_field_by_name(const char *name, size_t len);
+static const struct nxm_field *nxm_field_by_mf_id(enum mf_field_id,
+ enum ofp_version);
+
+static void nx_put_header__(struct ofpbuf *, uint64_t header, bool masked);
+