+/* The source or destination port in the TCP header.
+ *
+ * Prereqs:
+ * NXM_OF_ETH_TYPE must be either 0x0800 or 0x86dd.
+ * NXM_OF_IP_PROTO must match 6 exactly.
+ *
+ * Format: 16-bit integer in network byte order.
+ *
+ * Masking: Not maskable. */
+#define NXM_OF_TCP_SRC NXM_HEADER (0x0000, 9, 2)
+#define NXM_OF_TCP_DST NXM_HEADER (0x0000, 10, 2)
+
+/* The source or destination port in the UDP header.
+ *
+ * Prereqs:
+ * NXM_OF_ETH_TYPE must match either 0x0800 or 0x86dd.
+ * NXM_OF_IP_PROTO must match 17 exactly.
+ *
+ * Format: 16-bit integer in network byte order.
+ *
+ * Masking: Not maskable. */
+#define NXM_OF_UDP_SRC NXM_HEADER (0x0000, 11, 2)
+#define NXM_OF_UDP_DST NXM_HEADER (0x0000, 12, 2)
+
+/* The type or code in the ICMP header.
+ *
+ * Prereqs:
+ * NXM_OF_ETH_TYPE must match 0x0800 exactly.
+ * NXM_OF_IP_PROTO must match 1 exactly.
+ *
+ * Format: 8-bit integer.
+ *
+ * Masking: Not maskable. */
+#define NXM_OF_ICMP_TYPE NXM_HEADER (0x0000, 13, 1)
+#define NXM_OF_ICMP_CODE NXM_HEADER (0x0000, 14, 1)
+
+/* ARP opcode.
+ *
+ * For an Ethernet+IP ARP packet, the opcode in the ARP header. Always 0
+ * otherwise. Only ARP opcodes between 1 and 255 should be specified for
+ * matching.
+ *
+ * Prereqs: NXM_OF_ETH_TYPE must match 0x0806 exactly.
+ *
+ * Format: 16-bit integer in network byte order.
+ *
+ * Masking: Not maskable. */
+#define NXM_OF_ARP_OP NXM_HEADER (0x0000, 15, 2)
+
+/* For an Ethernet+IP ARP packet, the source or target protocol address
+ * in the ARP header. Always 0 otherwise.
+ *
+ * Prereqs: NXM_OF_ETH_TYPE must match 0x0806 exactly.
+ *
+ * Format: 32-bit integer in network byte order.
+ *
+ * Masking: Only CIDR masks are allowed, that is, masks that consist of N
+ * high-order bits set to 1 and the other 32-N bits set to 0. */
+#define NXM_OF_ARP_SPA NXM_HEADER (0x0000, 16, 4)
+#define NXM_OF_ARP_SPA_W NXM_HEADER_W(0x0000, 16, 4)
+#define NXM_OF_ARP_TPA NXM_HEADER (0x0000, 17, 4)
+#define NXM_OF_ARP_TPA_W NXM_HEADER_W(0x0000, 17, 4)
+
+/* ## ------------------------ ## */
+/* ## Nicira match extensions. ## */
+/* ## ------------------------ ## */
+
+/* Metadata registers.
+ *
+ * Registers initially have value 0. Actions allow register values to be
+ * manipulated.
+ *
+ * Prereqs: None.
+ *
+ * Format: Array of 32-bit integer registers. Space is reserved for up to
+ * NXM_NX_MAX_REGS registers, but switches may implement fewer.
+ *
+ * Masking: Arbitrary masks. */
+#define NXM_NX_MAX_REGS 16
+#define NXM_NX_REG(IDX) NXM_HEADER (0x0001, IDX, 4)
+#define NXM_NX_REG_W(IDX) NXM_HEADER_W(0x0001, IDX, 4)
+#define NXM_NX_REG_IDX(HEADER) NXM_FIELD(HEADER)
+#define NXM_IS_NX_REG(HEADER) (!((((HEADER) ^ NXM_NX_REG0)) & 0xffffe1ff))
+#define NXM_IS_NX_REG_W(HEADER) (!((((HEADER) ^ NXM_NX_REG0_W)) & 0xffffe1ff))
+#define NXM_NX_REG0 NXM_HEADER (0x0001, 0, 4)
+#define NXM_NX_REG0_W NXM_HEADER_W(0x0001, 0, 4)
+#define NXM_NX_REG1 NXM_HEADER (0x0001, 1, 4)
+#define NXM_NX_REG1_W NXM_HEADER_W(0x0001, 1, 4)
+#define NXM_NX_REG2 NXM_HEADER (0x0001, 2, 4)
+#define NXM_NX_REG2_W NXM_HEADER_W(0x0001, 2, 4)
+#define NXM_NX_REG3 NXM_HEADER (0x0001, 3, 4)
+#define NXM_NX_REG3_W NXM_HEADER_W(0x0001, 3, 4)
+#define NXM_NX_REG4 NXM_HEADER (0x0001, 4, 4)
+#define NXM_NX_REG4_W NXM_HEADER_W(0x0001, 4, 4)
+
+/* Tunnel ID.
+ *
+ * For a packet received via GRE tunnel including a (32-bit) key, the key is
+ * stored in the low 32-bits and the high bits are zeroed. For other packets,
+ * the value is 0.
+ *
+ * Prereqs: None.
+ *
+ * Format: 64-bit integer in network byte order.
+ *
+ * Masking: Arbitrary masks. */
+#define NXM_NX_TUN_ID NXM_HEADER (0x0001, 16, 8)
+#define NXM_NX_TUN_ID_W NXM_HEADER_W(0x0001, 16, 8)
+
+/* For an Ethernet+IP ARP packet, the source or target hardware address
+ * in the ARP header. Always 0 otherwise.
+ *
+ * Prereqs: NXM_OF_ETH_TYPE must match 0x0806 exactly.
+ *
+ * Format: 48-bit Ethernet MAC address.
+ *
+ * Masking: Not maskable. */
+#define NXM_NX_ARP_SHA NXM_HEADER (0x0001, 17, 6)
+#define NXM_NX_ARP_THA NXM_HEADER (0x0001, 18, 6)
+
+/* The source or destination address in the IPv6 header.
+ *
+ * Prereqs: NXM_OF_ETH_TYPE must match 0x86dd exactly.
+ *
+ * Format: 128-bit IPv6 address.
+ *
+ * Masking: Only CIDR masks are allowed, that is, masks that consist of N
+ * high-order bits set to 1 and the other 128-N bits set to 0. */
+#define NXM_NX_IPV6_SRC NXM_HEADER (0x0001, 19, 16)
+#define NXM_NX_IPV6_SRC_W NXM_HEADER_W(0x0001, 19, 16)
+#define NXM_NX_IPV6_DST NXM_HEADER (0x0001, 20, 16)
+#define NXM_NX_IPV6_DST_W NXM_HEADER_W(0x0001, 20, 16)
+
+/* The type or code in the ICMPv6 header.
+ *
+ * Prereqs:
+ * NXM_OF_ETH_TYPE must match 0x86dd exactly.
+ * NXM_OF_IP_PROTO must match 58 exactly.
+ *
+ * Format: 8-bit integer.
+ *
+ * Masking: Not maskable. */
+#define NXM_NX_ICMPV6_TYPE NXM_HEADER (0x0001, 21, 1)
+#define NXM_NX_ICMPV6_CODE NXM_HEADER (0x0001, 22, 1)
+
+/* The target address in an IPv6 Neighbor Discovery message.
+ *
+ * Prereqs:
+ * NXM_OF_ETH_TYPE must match 0x86dd exactly.
+ * NXM_OF_IP_PROTO must match 58 exactly.
+ * NXM_OF_ICMPV6_TYPE must be either 135 or 136.
+ *
+ * Format: 128-bit IPv6 address.
+ *
+ * Masking: Not maskable. */
+#define NXM_NX_ND_TARGET NXM_HEADER (0x0001, 23, 16)
+
+/* The source link-layer address option in an IPv6 Neighbor Discovery
+ * message.
+ *
+ * Prereqs:
+ * NXM_OF_ETH_TYPE must match 0x86dd exactly.
+ * NXM_OF_IP_PROTO must match 58 exactly.
+ * NXM_OF_ICMPV6_TYPE must be exactly 135.
+ *
+ * Format: 48-bit Ethernet MAC address.
+ *
+ * Masking: Not maskable. */
+#define NXM_NX_ND_SLL NXM_HEADER (0x0001, 24, 6)
+
+/* The target link-layer address option in an IPv6 Neighbor Discovery
+ * message.
+ *
+ * Prereqs:
+ * NXM_OF_ETH_TYPE must match 0x86dd exactly.
+ * NXM_OF_IP_PROTO must match 58 exactly.
+ * NXM_OF_ICMPV6_TYPE must be exactly 136.
+ *
+ * Format: 48-bit Ethernet MAC address.
+ *
+ * Masking: Not maskable. */
+#define NXM_NX_ND_TLL NXM_HEADER (0x0001, 25, 6)
+
+/* IP fragment information.
+ *
+ * Prereqs:
+ * NXM_OF_ETH_TYPE must be either 0x0800 or 0x86dd.
+ *
+ * Format: 8-bit value with one of the values 0, 1, or 3, as described below.
+ *
+ * Masking: Fully maskable.
+ *
+ * This field has three possible values:
+ *
+ * - A packet that is not an IP fragment has value 0.
+ *
+ * - A packet that is an IP fragment with offset 0 (the first fragment) has
+ * bit 0 set and thus value 1.
+ *
+ * - A packet that is an IP fragment with nonzero offset has bits 0 and 1 set
+ * and thus value 3.
+ *
+ * NX_IP_FRAG_ANY and NX_IP_FRAG_LATER are declared to symbolically represent
+ * the meanings of bits 0 and 1.
+ *
+ * The switch may reject matches against values that can never appear.
+ *
+ * It is important to understand how this field interacts with the OpenFlow IP
+ * fragment handling mode:
+ *
+ * - In OFPC_FRAG_DROP mode, the OpenFlow switch drops all IP fragments
+ * before they reach the flow table, so every packet that is available for
+ * matching will have value 0 in this field.
+ *
+ * - Open vSwitch does not implement OFPC_FRAG_REASM mode, but if it did then
+ * IP fragments would be reassembled before they reached the flow table and
+ * again every packet available for matching would always have value 0.
+ *
+ * - In OFPC_FRAG_NORMAL mode, all three values are possible, but OpenFlow
+ * 1.0 says that fragments' transport ports are always 0, even for the
+ * first fragment, so this does not provide much extra information.
+ *
+ * - In OFPC_FRAG_NX_MATCH mode, all three values are possible. For
+ * fragments with offset 0, Open vSwitch makes L4 header information
+ * available.
+ */
+#define NXM_NX_IP_FRAG NXM_HEADER (0x0001, 26, 1)
+#define NXM_NX_IP_FRAG_W NXM_HEADER_W(0x0001, 26, 1)
+
+/* Bits in the value of NXM_NX_IP_FRAG. */
+#define NX_IP_FRAG_ANY (1 << 0) /* Is this a fragment? */
+#define NX_IP_FRAG_LATER (1 << 1) /* Is this a fragment with nonzero offset? */
+
+/* The flow label in the IPv6 header.
+ *
+ * Prereqs: NXM_OF_ETH_TYPE must match 0x86dd exactly.
+ *
+ * Format: 20-bit IPv6 flow label in least-significant bits.
+ *
+ * Masking: Not maskable. */
+#define NXM_NX_IPV6_LABEL NXM_HEADER (0x0001, 27, 4)
+
+/* The ECN of the IP header.
+ *
+ * Prereqs: NXM_OF_ETH_TYPE must be either 0x0800 or 0x86dd.
+ *
+ * Format: ECN in the low-order 2 bits.
+ *
+ * Masking: Not maskable. */
+#define NXM_NX_IP_ECN NXM_HEADER (0x0001, 28, 1)
+
+/* The time-to-live/hop limit of the IP header.
+ *
+ * Prereqs: NXM_OF_ETH_TYPE must be either 0x0800 or 0x86dd.
+ *
+ * Format: 8-bit integer.
+ *
+ * Masking: Not maskable. */
+#define NXM_NX_IP_TTL NXM_HEADER (0x0001, 29, 1)
+
+/* 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.
+ *
+ * Prereqs: None.
+ *
+ * Format: 64-bit integer in network byte order.
+ *
+ * Masking: Arbitrary masks. */
+#define NXM_NX_COOKIE NXM_HEADER (0x0001, 30, 8)
+#define NXM_NX_COOKIE_W NXM_HEADER_W(0x0001, 30, 8)
+
+/* ## --------------------- ## */
+/* ## Requests and replies. ## */
+/* ## --------------------- ## */
+
+enum nx_flow_format {
+ NXFF_OPENFLOW10 = 0, /* Standard OpenFlow 1.0 compatible. */
+ NXFF_NXM = 2 /* Nicira extended match. */
+};
+
+/* NXT_SET_FLOW_FORMAT request. */
+struct nx_set_flow_format {
+ struct ofp_header header;
+ ovs_be32 vendor; /* NX_VENDOR_ID. */
+ ovs_be32 subtype; /* NXT_SET_FLOW_FORMAT. */
+ ovs_be32 format; /* One of NXFF_*. */
+};
+OFP_ASSERT(sizeof(struct nx_set_flow_format) == 20);
+
+/* NXT_FLOW_MOD (analogous to OFPT_FLOW_MOD).
+ *
+ * It is possible to limit flow deletions and modifications to certain
+ * cookies by using the NXM_NX_COOKIE and NXM_NX_COOKIE_W matches. For
+ * these commands, the "cookie" field is always ignored. Flow additions
+ * make use of the "cookie" field and ignore any NXM_NX_COOKIE*
+ * definitions.
+ */
+struct nx_flow_mod {
+ struct nicira_header nxh;
+ ovs_be64 cookie; /* Opaque controller-issued identifier. */
+ ovs_be16 command; /* One of OFPFC_*. */
+ ovs_be16 idle_timeout; /* Idle time before discarding (seconds). */
+ ovs_be16 hard_timeout; /* Max time before discarding (seconds). */
+ ovs_be16 priority; /* Priority level of flow entry. */
+ ovs_be32 buffer_id; /* Buffered packet to apply to (or -1).
+ Not meaningful for OFPFC_DELETE*. */
+ ovs_be16 out_port; /* For OFPFC_DELETE* commands, require
+ matching entries to include this as an
+ output port. A value of OFPP_NONE
+ indicates no restriction. */
+ ovs_be16 flags; /* One of OFPFF_*. */
+ ovs_be16 match_len; /* Size of nx_match. */
+ uint8_t pad[6]; /* Align to 64-bits. */
+ /* Followed by:
+ * - Exactly match_len (possibly 0) bytes containing the nx_match, then
+ * - Exactly (match_len + 7)/8*8 - match_len (between 0 and 7) bytes of
+ * all-zero bytes, then
+ * - Actions to fill out the remainder of the message length (always a
+ * multiple of 8).
+ */
+};
+OFP_ASSERT(sizeof(struct nx_flow_mod) == 48);
+
+/* NXT_FLOW_REMOVED (analogous to OFPT_FLOW_REMOVED). */
+struct nx_flow_removed {
+ struct nicira_header nxh;
+ ovs_be64 cookie; /* Opaque controller-issued identifier. */
+ ovs_be16 priority; /* Priority level of flow entry. */
+ uint8_t reason; /* One of OFPRR_*. */
+ uint8_t pad[1]; /* Align to 32-bits. */
+ ovs_be32 duration_sec; /* Time flow was alive in seconds. */
+ ovs_be32 duration_nsec; /* Time flow was alive in nanoseconds beyond
+ duration_sec. */
+ ovs_be16 idle_timeout; /* Idle timeout from original flow mod. */
+ ovs_be16 match_len; /* Size of nx_match. */
+ ovs_be64 packet_count;
+ ovs_be64 byte_count;
+ /* Followed by:
+ * - Exactly match_len (possibly 0) bytes containing the nx_match, then
+ * - Exactly (match_len + 7)/8*8 - match_len (between 0 and 7) bytes of
+ * all-zero bytes. */
+};
+OFP_ASSERT(sizeof(struct nx_flow_removed) == 56);
+
+/* Nicira vendor stats request of type NXST_FLOW (analogous to OFPST_FLOW
+ * request).
+ *
+ * It is possible to limit matches to certain cookies by using the
+ * NXM_NX_COOKIE and NXM_NX_COOKIE_W matches.
+ */
+struct nx_flow_stats_request {
+ struct nicira_stats_msg nsm;
+ ovs_be16 out_port; /* Require matching entries to include this
+ as an output port. A value of OFPP_NONE
+ indicates no restriction. */
+ ovs_be16 match_len; /* Length of nx_match. */
+ uint8_t table_id; /* ID of table to read (from ofp_table_stats)
+ or 0xff for all tables. */
+ uint8_t pad[3]; /* Align to 64 bits. */
+ /* Followed by:
+ * - Exactly match_len (possibly 0) bytes containing the nx_match, then
+ * - Exactly (match_len + 7)/8*8 - match_len (between 0 and 7) bytes of
+ * all-zero bytes, which must also exactly fill out the length of the
+ * message.
+ */
+};
+OFP_ASSERT(sizeof(struct nx_flow_stats_request) == 32);
+
+/* Body for Nicira vendor stats reply of type NXST_FLOW (analogous to
+ * OFPST_FLOW reply). */
+struct nx_flow_stats {
+ ovs_be16 length; /* Length of this entry. */
+ uint8_t table_id; /* ID of table flow came from. */
+ uint8_t pad;
+ ovs_be32 duration_sec; /* Time flow has been alive in seconds. */
+ ovs_be32 duration_nsec; /* Time flow has been alive in nanoseconds
+ beyond duration_sec. */
+ ovs_be16 priority; /* Priority of the entry. Only meaningful
+ when this is not an exact-match entry. */
+ ovs_be16 idle_timeout; /* Number of seconds idle before expiration. */
+ ovs_be16 hard_timeout; /* Number of seconds before expiration. */
+ ovs_be16 match_len; /* Length of nx_match. */
+ uint8_t pad2[4]; /* Align to 64 bits. */
+ ovs_be64 cookie; /* Opaque controller-issued identifier. */
+ ovs_be64 packet_count; /* Number of packets, UINT64_MAX if unknown. */
+ ovs_be64 byte_count; /* Number of bytes, UINT64_MAX if unknown. */
+ /* Followed by:
+ * - Exactly match_len (possibly 0) bytes containing the nx_match, then
+ * - Exactly (match_len + 7)/8*8 - match_len (between 0 and 7) bytes of
+ * all-zero bytes, then
+ * - Actions to fill out the remainder 'length' bytes (always a multiple
+ * of 8).
+ */
+};
+OFP_ASSERT(sizeof(struct nx_flow_stats) == 48);
+
+/* Nicira vendor stats request of type NXST_AGGREGATE (analogous to
+ * OFPST_AGGREGATE request). */
+struct nx_aggregate_stats_request {
+ struct nicira_stats_msg nsm;
+ ovs_be16 out_port; /* Require matching entries to include this
+ as an output port. A value of OFPP_NONE
+ indicates no restriction. */
+ ovs_be16 match_len; /* Length of nx_match. */
+ uint8_t table_id; /* ID of table to read (from ofp_table_stats)
+ or 0xff for all tables. */
+ uint8_t pad[3]; /* Align to 64 bits. */
+ /* Followed by:
+ * - Exactly match_len (possibly 0) bytes containing the nx_match, then
+ * - Exactly (match_len + 7)/8*8 - match_len (between 0 and 7) bytes of
+ * all-zero bytes, which must also exactly fill out the length of the
+ * message.
+ */
+};
+OFP_ASSERT(sizeof(struct nx_aggregate_stats_request) == 32);
+
+/* Body for nicira_stats_msg reply of type NXST_AGGREGATE (analogous to
+ * OFPST_AGGREGATE reply). */
+struct nx_aggregate_stats_reply {
+ struct nicira_stats_msg nsm;
+ ovs_be64 packet_count; /* Number of packets, UINT64_MAX if unknown. */
+ ovs_be64 byte_count; /* Number of bytes, UINT64_MAX if unknown. */
+ ovs_be32 flow_count; /* Number of flows. */
+ uint8_t pad[4]; /* Align to 64 bits. */
+};
+OFP_ASSERT(sizeof(struct nx_aggregate_stats_reply) == 48);