+ ovs_be16 max_len; /* Max length to send to controller. */
+
+ uint8_t zero[6]; /* Reserved, must be zero. */
+};
+OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24);
+\f
+/* NXAST_EXIT
+ *
+ * Discontinues action processing.
+ *
+ * The NXAST_EXIT action causes the switch to immediately halt processing
+ * actions for the flow. Any actions which have already been processed are
+ * executed by the switch. However, any further actions, including those which
+ * may be in different tables, or different levels of the NXAST_RESUBMIT
+ * hierarchy, will be ignored.
+ *
+ * Uses the nx_action_header structure. */
+\f
+/* Flexible flow specifications (aka NXM = Nicira Extended Match).
+ *
+ * OpenFlow 1.0 has "struct ofp10_match" for specifying flow matches. This
+ * structure is fixed-length and hence difficult to extend. This section
+ * describes a more flexible, variable-length flow match, called "nx_match" for
+ * short, that is also supported by Open vSwitch. This section also defines a
+ * replacement for each OpenFlow message that includes struct ofp10_match.
+ *
+ *
+ * Format
+ * ======
+ *
+ * An nx_match is a sequence of zero or more "nxm_entry"s, which are
+ * type-length-value (TLV) entries, each 5 to 259 (inclusive) bytes long.
+ * "nxm_entry"s are not aligned on or padded to any multibyte boundary. The
+ * first 4 bytes of an nxm_entry are its "header", followed by the entry's
+ * "body".
+ *
+ * An nxm_entry's header is interpreted as a 32-bit word in network byte order:
+ *
+ * |<-------------------- nxm_type ------------------>|
+ * | |
+ * |31 16 15 9| 8 7 0
+ * +----------------------------------+---------------+--+------------------+
+ * | nxm_vendor | nxm_field |hm| nxm_length |
+ * +----------------------------------+---------------+--+------------------+
+ *
+ * The most-significant 23 bits of the header are collectively "nxm_type".
+ * Bits 16...31 are "nxm_vendor", one of the NXM_VENDOR_* values below. Bits
+ * 9...15 are "nxm_field", which is a vendor-specific value. nxm_type normally
+ * designates a protocol header, such as the Ethernet type, but it can also
+ * refer to packet metadata, such as the switch port on which a packet arrived.
+ *
+ * Bit 8 is "nxm_hasmask" (labeled "hm" above for space reasons). The meaning
+ * of this bit is explained later.
+ *
+ * The least-significant 8 bits are "nxm_length", a positive integer. The
+ * length of the nxm_entry, including the header, is exactly 4 + nxm_length
+ * bytes.
+ *
+ * For a given nxm_vendor, nxm_field, and nxm_hasmask value, nxm_length is a
+ * constant. It is included only to allow software to minimally parse
+ * "nxm_entry"s of unknown types. (Similarly, for a given nxm_vendor,
+ * nxm_field, and nxm_length, nxm_hasmask is a constant.)
+ *
+ *
+ * Semantics
+ * =========
+ *
+ * A zero-length nx_match (one with no "nxm_entry"s) matches every packet.
+ *
+ * An nxm_entry places a constraint on the packets matched by the nx_match:
+ *
+ * - If nxm_hasmask is 0, the nxm_entry's body contains a value for the
+ * field, called "nxm_value". The nx_match matches only packets in which
+ * the field equals nxm_value.
+ *
+ * - If nxm_hasmask is 1, then the nxm_entry's body contains a value for the
+ * field (nxm_value), followed by a bitmask of the same length as the
+ * value, called "nxm_mask". For each 1-bit in position J in nxm_mask, the
+ * nx_match matches only packets for which bit J in the given field's value
+ * matches bit J in nxm_value. A 0-bit in nxm_mask causes the
+ * corresponding bits in nxm_value and the field's value to be ignored.
+ * (The sense of the nxm_mask bits is the opposite of that used by the
+ * "wildcards" member of struct ofp10_match.)
+ *
+ * When nxm_hasmask is 1, nxm_length is always even.
+ *
+ * An all-zero-bits nxm_mask is equivalent to omitting the nxm_entry
+ * entirely. An all-one-bits nxm_mask is equivalent to specifying 0 for
+ * nxm_hasmask.
+ *
+ * When there are multiple "nxm_entry"s, all of the constraints must be met.
+ *
+ *
+ * Mask Restrictions
+ * =================
+ *
+ * Masks may be restricted:
+ *
+ * - Some nxm_types may not support masked wildcards, that is, nxm_hasmask
+ * must always be 0 when these fields are specified. For example, the
+ * field that identifies the port on which a packet was received may not be
+ * masked.
+ *
+ * - Some nxm_types that do support masked wildcards may only support certain
+ * nxm_mask patterns. For example, fields that have IPv4 address values
+ * may be restricted to CIDR masks.
+ *
+ * These restrictions should be noted in specifications for individual fields.
+ * A switch may accept an nxm_hasmask or nxm_mask value that the specification
+ * disallows, if the switch correctly implements support for that nxm_hasmask
+ * or nxm_mask value. A switch must reject an attempt to set up a flow that
+ * contains a nxm_hasmask or nxm_mask value that it does not support.
+ *
+ *
+ * Prerequisite Restrictions
+ * =========================
+ *
+ * The presence of an nxm_entry with a given nxm_type may be restricted based
+ * on the presence of or values of other "nxm_entry"s. For example:
+ *
+ * - An nxm_entry for nxm_type=NXM_OF_IP_TOS is allowed only if it is
+ * preceded by another entry with nxm_type=NXM_OF_ETH_TYPE, nxm_hasmask=0,
+ * and nxm_value=0x0800. That is, matching on the IP source address is
+ * allowed only if the Ethernet type is explicitly set to IP.
+ *
+ * - An nxm_entry for nxm_type=NXM_OF_TCP_SRC is allowed only if it is
+ * preceded by an entry with nxm_type=NXM_OF_ETH_TYPE, nxm_hasmask=0, and
+ * nxm_value either 0x0800 or 0x86dd, and another with
+ * nxm_type=NXM_OF_IP_PROTO, nxm_hasmask=0, nxm_value=6, in that order.
+ * That is, matching on the TCP source port is allowed only if the Ethernet
+ * type is IP or IPv6 and the IP protocol is TCP.
+ *
+ * These restrictions should be noted in specifications for individual fields.
+ * A switch may implement relaxed versions of these restrictions. A switch
+ * must reject an attempt to set up a flow that violates its restrictions.
+ *
+ *
+ * Ordering Restrictions
+ * =====================
+ *
+ * An nxm_entry that has prerequisite restrictions must appear after the
+ * "nxm_entry"s for its prerequisites. Ordering of "nxm_entry"s within an
+ * nx_match is not otherwise constrained.
+ *
+ * Any given nxm_type may appear in an nx_match at most once.
+ *
+ *
+ * nxm_entry Examples
+ * ==================
+ *
+ * These examples show the format of a single nxm_entry with particular
+ * nxm_hasmask and nxm_length values. The diagrams are labeled with field
+ * numbers and byte indexes.
+ *
+ *
+ * 8-bit nxm_value, nxm_hasmask=1, nxm_length=2:
+ *
+ * 0 3 4 5
+ * +------------+---+---+
+ * | header | v | m |
+ * +------------+---+---+
+ *
+ *
+ * 16-bit nxm_value, nxm_hasmask=0, nxm_length=2:
+ *
+ * 0 3 4 5
+ * +------------+------+
+ * | header | value|
+ * +------------+------+
+ *
+ *
+ * 32-bit nxm_value, nxm_hasmask=0, nxm_length=4:
+ *
+ * 0 3 4 7
+ * +------------+-------------+
+ * | header | nxm_value |
+ * +------------+-------------+
+ *
+ *
+ * 48-bit nxm_value, nxm_hasmask=0, nxm_length=6:
+ *
+ * 0 3 4 9
+ * +------------+------------------+
+ * | header | nxm_value |
+ * +------------+------------------+
+ *
+ *
+ * 48-bit nxm_value, nxm_hasmask=1, nxm_length=12:
+ *
+ * 0 3 4 9 10 15
+ * +------------+------------------+------------------+
+ * | header | nxm_value | nxm_mask |
+ * +------------+------------------+------------------+
+ *
+ *
+ * Error Reporting
+ * ===============
+ *
+ * A switch should report an error in an nx_match using error type
+ * OFPET_BAD_REQUEST and one of the NXBRC_NXM_* codes. Ideally the switch
+ * should report a specific error code, if one is assigned for the particular
+ * problem, but NXBRC_NXM_INVALID is also available to report a generic
+ * nx_match error.
+ */
+
+#define NXM_HEADER__(VENDOR, FIELD, HASMASK, LENGTH) \
+ (((VENDOR) << 16) | ((FIELD) << 9) | ((HASMASK) << 8) | (LENGTH))
+#define NXM_HEADER(VENDOR, FIELD, LENGTH) \
+ NXM_HEADER__(VENDOR, FIELD, 0, LENGTH)
+#define NXM_HEADER_W(VENDOR, FIELD, LENGTH) \
+ NXM_HEADER__(VENDOR, FIELD, 1, (LENGTH) * 2)
+#define NXM_VENDOR(HEADER) ((HEADER) >> 16)
+#define NXM_FIELD(HEADER) (((HEADER) >> 9) & 0x7f)
+#define NXM_TYPE(HEADER) (((HEADER) >> 9) & 0x7fffff)
+#define NXM_HASMASK(HEADER) (((HEADER) >> 8) & 1)
+#define NXM_LENGTH(HEADER) ((HEADER) & 0xff)
+
+#define NXM_MAKE_WILD_HEADER(HEADER) \
+ NXM_HEADER_W(NXM_VENDOR(HEADER), NXM_FIELD(HEADER), NXM_LENGTH(HEADER))
+
+/* ## ------------------------------- ## */
+/* ## OpenFlow 1.0-compatible fields. ## */
+/* ## ------------------------------- ## */
+
+/* Physical or virtual port on which the packet was received.
+ *
+ * Prereqs: None.
+ *
+ * Format: 16-bit integer in network byte order.
+ *
+ * Masking: Not maskable. */
+#define NXM_OF_IN_PORT NXM_HEADER (0x0000, 0, 2)
+
+/* Source or destination address in Ethernet header.
+ *
+ * Prereqs: None.
+ *
+ * Format: 48-bit Ethernet MAC address.
+ *
+ * Masking: Fully maskable, in versions 1.8 and later. Earlier versions only
+ * supported the following masks for NXM_OF_ETH_DST_W: 00:00:00:00:00:00,
+ * fe:ff:ff:ff:ff:ff, 01:00:00:00:00:00, ff:ff:ff:ff:ff:ff. */
+#define NXM_OF_ETH_DST NXM_HEADER (0x0000, 1, 6)
+#define NXM_OF_ETH_DST_W NXM_HEADER_W(0x0000, 1, 6)
+#define NXM_OF_ETH_SRC NXM_HEADER (0x0000, 2, 6)
+#define NXM_OF_ETH_SRC_W NXM_HEADER_W(0x0000, 2, 6)
+
+/* Packet's Ethernet type.
+ *
+ * For an Ethernet II packet this is taken from the Ethernet header. For an
+ * 802.2 LLC+SNAP header with OUI 00-00-00 this is taken from the SNAP header.
+ * A packet that has neither format has value 0x05ff
+ * (OFP_DL_TYPE_NOT_ETH_TYPE).
+ *
+ * For a packet with an 802.1Q header, this is the type of the encapsulated
+ * frame.
+ *
+ * Prereqs: None.
+ *
+ * Format: 16-bit integer in network byte order.
+ *
+ * Masking: Not maskable. */
+#define NXM_OF_ETH_TYPE NXM_HEADER (0x0000, 3, 2)
+
+/* 802.1Q TCI.
+ *
+ * For a packet with an 802.1Q header, this is the Tag Control Information
+ * (TCI) field, with the CFI bit forced to 1. For a packet with no 802.1Q
+ * header, this has value 0.
+ *
+ * Prereqs: None.
+ *
+ * Format: 16-bit integer in network byte order.
+ *
+ * Masking: Arbitrary masks.
+ *
+ * This field can be used in various ways:
+ *
+ * - If it is not constrained at all, the nx_match matches packets without
+ * an 802.1Q header or with an 802.1Q header that has any TCI value.
+ *
+ * - Testing for an exact match with 0 matches only packets without an
+ * 802.1Q header.
+ *
+ * - Testing for an exact match with a TCI value with CFI=1 matches packets
+ * that have an 802.1Q header with a specified VID and PCP.
+ *
+ * - Testing for an exact match with a nonzero TCI value with CFI=0 does
+ * not make sense. The switch may reject this combination.
+ *
+ * - Testing with a specific VID and CFI=1, with nxm_mask=0x1fff, matches
+ * packets that have an 802.1Q header with that VID (and any PCP).
+ *
+ * - Testing with a specific PCP and CFI=1, with nxm_mask=0xf000, matches
+ * packets that have an 802.1Q header with that PCP (and any VID).
+ *
+ * - Testing with nxm_value=0, nxm_mask=0x0fff matches packets with no 802.1Q
+ * header or with an 802.1Q header with a VID of 0.
+ *
+ * - Testing with nxm_value=0, nxm_mask=0xe000 matches packets with no 802.1Q
+ * header or with an 802.1Q header with a PCP of 0.
+ *
+ * - Testing with nxm_value=0, nxm_mask=0xefff matches packets with no 802.1Q
+ * header or with an 802.1Q header with both VID and PCP of 0.
+ */
+#define NXM_OF_VLAN_TCI NXM_HEADER (0x0000, 4, 2)
+#define NXM_OF_VLAN_TCI_W NXM_HEADER_W(0x0000, 4, 2)
+
+/* The "type of service" byte of the IP header, with the ECN bits forced to 0.
+ *
+ * Prereqs: NXM_OF_ETH_TYPE must be either 0x0800 or 0x86dd.
+ *
+ * Format: 8-bit integer with 2 least-significant bits forced to 0.
+ *
+ * Masking: Not maskable. */
+#define NXM_OF_IP_TOS NXM_HEADER (0x0000, 5, 1)
+
+/* The "protocol" byte in the IP header.
+ *
+ * Prereqs: NXM_OF_ETH_TYPE must be either 0x0800 or 0x86dd.
+ *
+ * Format: 8-bit integer.
+ *
+ * Masking: Not maskable. */
+#define NXM_OF_IP_PROTO NXM_HEADER (0x0000, 6, 1)
+
+/* The source or destination address in the IP header.
+ *
+ * Prereqs: NXM_OF_ETH_TYPE must match 0x0800 exactly.
+ *
+ * Format: 32-bit integer in network byte order.
+ *
+ * Masking: Fully maskable, in Open vSwitch 1.8 and later. In earlier
+ * versions, 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_IP_SRC NXM_HEADER (0x0000, 7, 4)
+#define NXM_OF_IP_SRC_W NXM_HEADER_W(0x0000, 7, 4)
+#define NXM_OF_IP_DST NXM_HEADER (0x0000, 8, 4)
+#define NXM_OF_IP_DST_W NXM_HEADER_W(0x0000, 8, 4)
+
+/* 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: Fully maskable, in Open vSwitch 1.6 and later. Not maskable, in
+ * earlier versions. */
+#define NXM_OF_TCP_SRC NXM_HEADER (0x0000, 9, 2)
+#define NXM_OF_TCP_SRC_W NXM_HEADER_W(0x0000, 9, 2)
+#define NXM_OF_TCP_DST NXM_HEADER (0x0000, 10, 2)
+#define NXM_OF_TCP_DST_W NXM_HEADER_W(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: Fully maskable, in Open vSwitch 1.6 and later. Not maskable, in
+ * earlier versions. */
+#define NXM_OF_UDP_SRC NXM_HEADER (0x0000, 11, 2)
+#define NXM_OF_UDP_SRC_W NXM_HEADER_W(0x0000, 11, 2)
+#define NXM_OF_UDP_DST NXM_HEADER (0x0000, 12, 2)
+#define NXM_OF_UDP_DST_W NXM_HEADER_W(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: Fully maskable, in Open vSwitch 1.8 and later. In earlier
+ * versions, 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)
+#define NXM_NX_REG5 NXM_HEADER (0x0001, 5, 4)
+#define NXM_NX_REG5_W NXM_HEADER_W(0x0001, 5, 4)
+#define NXM_NX_REG6 NXM_HEADER (0x0001, 6, 4)
+#define NXM_NX_REG6_W NXM_HEADER_W(0x0001, 6, 4)
+#define NXM_NX_REG7 NXM_HEADER (0x0001, 7, 4)
+#define NXM_NX_REG7_W NXM_HEADER_W(0x0001, 7, 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: Fully maskable, in Open vSwitch 1.8 and later. In previous
+ * versions, 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: Fully maskable, in Open vSwitch 1.8 and later. In previous
+ * versions, 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_ND_TARGET NXM_HEADER (0x0001, 23, 16)
+#define NXM_NX_ND_TARGET_W NXM_HEADER_W (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. */
+ NXFF_OPENFLOW12 = 3 /* OpenFlow 1.2 format. */
+};
+
+/* NXT_SET_FLOW_FORMAT request. */
+struct nx_set_flow_format {
+ struct nicira_header nxh;
+ 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(_W) matches. The "cookie" field
+ * is used only to add or modify flow cookies.
+ */
+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).
+ *
+ * The values of 'idle_age' and 'hard_age' are only meaningful when talking to
+ * a switch that implements the NXT_FLOW_AGE extension. Zero means that the
+ * true value is unknown, perhaps because hardware does not track the value.
+ * (Zero is also the value that one should ordinarily expect to see talking to
+ * a switch that does not implement NXT_FLOW_AGE, since those switches zero the
+ * padding bytes that these fields replaced.) A nonzero value X represents X-1
+ * seconds. A value of 65535 represents 65534 or more seconds.
+ *
+ * 'idle_age' is the number of seconds that the flow has been idle, that is,
+ * the number of seconds since a packet passed through the flow. 'hard_age' is
+ * the number of seconds since the flow was last modified (e.g. OFPFC_MODIFY or
+ * OFPFC_MODIFY_STRICT). (The 'duration_*' fields are the elapsed time since
+ * the flow was added, regardless of subsequent modifications.)
+ *
+ * For a flow with an idle or hard timeout, 'idle_age' or 'hard_age',
+ * respectively, will ordinarily be smaller than the timeout, but flow
+ * expiration times are only approximate and so one must be prepared to
+ * tolerate expirations that occur somewhat early or late.
+ */
+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. */
+ 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. */
+ ovs_be16 idle_age; /* Seconds since last packet, plus one. */
+ ovs_be16 hard_age; /* Seconds since last modification, plus one. */
+ 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);
+\f
+/* NXT_SET_CONTROLLER_ID.
+ *
+ * Each OpenFlow controller connection has a 16-bit identifier that is
+ * initially 0. This message changes the connection's ID to 'id'.
+ *
+ * Controller connection IDs need not be unique.
+ *
+ * The NXAST_CONTROLLER action is the only current user of controller
+ * connection IDs. */
+struct nx_controller_id {
+ struct nicira_header nxh;
+ uint8_t zero[6]; /* Must be zero. */
+ ovs_be16 controller_id; /* New controller connection ID. */
+};
+OFP_ASSERT(sizeof(struct nx_controller_id) == 24);
+
+/* Action structure for NXAST_CONTROLLER.
+ *
+ * This generalizes using OFPAT_OUTPUT to send a packet to OFPP_CONTROLLER. In
+ * addition to the 'max_len' that OFPAT_OUTPUT supports, it also allows
+ * specifying:
+ *
+ * - 'reason': The reason code to use in the ofp_packet_in or nx_packet_in.
+ *
+ * - 'controller_id': The ID of the controller connection to which the
+ * ofp_packet_in should be sent. The ofp_packet_in or nx_packet_in is
+ * sent only to controllers that have the specified controller connection
+ * ID. See "struct nx_controller_id" for more information. */
+struct nx_action_controller {
+ ovs_be16 type; /* OFPAT_VENDOR. */
+ ovs_be16 len; /* Length is 16. */
+ ovs_be32 vendor; /* NX_VENDOR_ID. */
+ ovs_be16 subtype; /* NXAST_CONTROLLER. */
+ ovs_be16 max_len; /* Maximum length to send to controller. */
+ ovs_be16 controller_id; /* Controller ID to send packet-in. */
+ uint8_t reason; /* enum ofp_packet_in_reason (OFPR_*). */
+ uint8_t zero; /* Must be zero. */
+};
+OFP_ASSERT(sizeof(struct nx_action_controller) == 16);
+\f
+/* Flow Table Monitoring
+ * =====================
+ *
+ * NXST_FLOW_MONITOR allows a controller to keep track of changes to OpenFlow
+ * flow table(s) or subsets of them, with the following workflow:
+ *
+ * 1. The controller sends an NXST_FLOW_MONITOR request to begin monitoring
+ * flows. The 'id' in the request must be unique among all monitors that
+ * the controller has started and not yet canceled on this OpenFlow
+ * connection.
+ *
+ * 2. The switch responds with an NXST_FLOW_MONITOR reply. If the request's
+ * 'flags' included NXFMF_INITIAL, the reply includes all the flows that
+ * matched the request at the time of the request (with event NXFME_ADDED).
+ * If 'flags' did not include NXFMF_INITIAL, the reply is empty.
+ *
+ * The reply uses the xid of the request (as do all replies to OpenFlow
+ * requests).
+ *
+ * 3. Whenever a change to a flow table entry matches some outstanding monitor
+ * request's criteria and flags, the switch sends a notification to the
+ * controller as an additional NXST_FLOW_MONITOR reply with xid 0.
+ *
+ * When multiple outstanding monitors match a single change, only a single
+ * notification is sent. This merged notification includes the information
+ * requested in any of the individual monitors. That is, if any of the
+ * matching monitors requests actions (NXFMF_ACTIONS), the notification
+ * includes actions, and if any of the monitors request full changes for the
+ * controller's own changes (NXFMF_OWN), the controller's own changes will
+ * be included in full.
+ *
+ * 4. The controller may cancel a monitor with NXT_FLOW_MONITOR_CANCEL. No
+ * further notifications will be sent on the basis of the canceled monitor
+ * afterward.
+ *
+ *
+ * Buffer Management
+ * =================
+ *
+ * OpenFlow messages for flow monitor notifications can overflow the buffer
+ * space available to the switch, either temporarily (e.g. due to network
+ * conditions slowing OpenFlow traffic) or more permanently (e.g. the sustained
+ * rate of flow table change exceeds the network bandwidth between switch and
+ * controller).
+ *
+ * When Open vSwitch's notification buffer space reaches a limiting threshold,
+ * OVS reacts as follows:
+ *
+ * 1. OVS sends an NXT_FLOW_MONITOR_PAUSED message to the controller, following
+ * all the already queued notifications. After it receives this message,
+ * the controller knows that its view of the flow table, as represented by
+ * flow monitor notifications, is incomplete.
+ *
+ * 2. As long as the notification buffer is not empty:
+ *
+ * - NXMFE_ADD and NXFME_MODIFIED notifications will not be sent.
+ *
+ * - NXFME_DELETED notifications will still be sent, but only for flows
+ * that existed before OVS sent NXT_FLOW_MONITOR_PAUSED.
+ *
+ * - NXFME_ABBREV notifications will not be sent. They are treated as
+ * the expanded version (and therefore only the NXFME_DELETED
+ * components, if any, are sent).
+ *
+ * 3. When the notification buffer empties, OVS sends NXFME_ADD notifications
+ * for flows added since the buffer reached its limit and NXFME_MODIFIED
+ * notifications for flows that existed before the limit was reached and
+ * changed after the limit was reached.
+ *
+ * 4. OVS sends an NXT_FLOW_MONITOR_RESUMED message to the controller. After
+ * it receives this message, the controller knows that its view of the flow
+ * table, as represented by flow monitor notifications, is again complete.
+ *
+ * This allows the maximum buffer space requirement for notifications to be
+ * bounded by the limit plus the maximum number of supported flows.
+ *
+ *
+ * "Flow Removed" messages
+ * =======================
+ *
+ * The flow monitor mechanism is independent of OFPT_FLOW_REMOVED and
+ * NXT_FLOW_REMOVED. Flow monitor updates for deletion are sent if
+ * NXFMF_DELETE is set on a monitor, regardless of whether the
+ * OFPFF_SEND_FLOW_REM flag was set when the flow was added. */
+
+/* NXST_FLOW_MONITOR request.
+ *
+ * The NXST_FLOW_MONITOR request's body consists of an array of zero or more
+ * instances of this structure. The request arranges to monitor the flows
+ * that match the specified criteria, which are interpreted in the same way as
+ * for NXST_FLOW.
+ *
+ * 'id' identifies a particular monitor for the purpose of allowing it to be
+ * canceled later with NXT_FLOW_MONITOR_CANCEL. 'id' must be unique among
+ * existing monitors that have not already been canceled.
+ *
+ * The reply includes the initial flow matches for monitors that have the
+ * NXFMF_INITIAL flag set. No single flow will be included in the reply more
+ * than once, even if more than one requested monitor matches that flow. The
+ * reply will be empty if none of the monitors has NXFMF_INITIAL set or if none
+ * of the monitors initially matches any flows.
+ *
+ * For NXFMF_ADD, an event will be reported if 'out_port' matches against the
+ * actions of the flow being added or, for a flow that is replacing an existing
+ * flow, if 'out_port' matches against the actions of the flow being replaced.
+ * For NXFMF_DELETE, 'out_port' matches against the actions of a flow being
+ * deleted. For NXFMF_MODIFY, an event will be reported if 'out_port' matches
+ * either the old or the new actions. */
+struct nx_flow_monitor_request {
+ ovs_be32 id; /* Controller-assigned ID for this monitor. */
+ ovs_be16 flags; /* NXFMF_*. */
+ ovs_be16 out_port; /* Required output port, if not OFPP_NONE. */
+ ovs_be16 match_len; /* Length of nx_match. */
+ uint8_t table_id; /* One table's ID or 0xff for all tables. */
+ uint8_t zeros[5]; /* Align to 64 bits (must be zero). */
+ /* 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_monitor_request) == 16);
+
+/* 'flags' bits in struct nx_flow_monitor_request. */
+enum nx_flow_monitor_flags {
+ /* When to send updates. */
+ NXFMF_INITIAL = 1 << 0, /* Initially matching flows. */
+ NXFMF_ADD = 1 << 1, /* New matching flows as they are added. */
+ NXFMF_DELETE = 1 << 2, /* Old matching flows as they are removed. */
+ NXFMF_MODIFY = 1 << 3, /* Matching flows as they are changed. */
+
+ /* What to include in updates. */
+ NXFMF_ACTIONS = 1 << 4, /* If set, actions are included. */
+ NXFMF_OWN = 1 << 5, /* If set, include own changes in full. */
+};
+
+/* NXST_FLOW_MONITOR reply header.
+ *
+ * The body of an NXST_FLOW_MONITOR reply is an array of variable-length
+ * structures, each of which begins with this header. The 'length' member may
+ * be used to traverse the array, and the 'event' member may be used to
+ * determine the particular structure.
+ *
+ * Every instance is a multiple of 8 bytes long. */
+struct nx_flow_update_header {
+ ovs_be16 length; /* Length of this entry. */
+ ovs_be16 event; /* One of NXFME_*. */
+ /* ...other data depending on 'event'... */
+};
+OFP_ASSERT(sizeof(struct nx_flow_update_header) == 4);
+
+/* 'event' values in struct nx_flow_update_header. */
+enum nx_flow_update_event {
+ /* struct nx_flow_update_full. */
+ NXFME_ADDED = 0, /* Flow was added. */
+ NXFME_DELETED = 1, /* Flow was deleted. */
+ NXFME_MODIFIED = 2, /* Flow (generally its actions) was changed. */
+
+ /* struct nx_flow_update_abbrev. */
+ NXFME_ABBREV = 3, /* Abbreviated reply. */
+};
+
+/* NXST_FLOW_MONITOR reply for NXFME_ADDED, NXFME_DELETED, and
+ * NXFME_MODIFIED. */
+struct nx_flow_update_full {
+ ovs_be16 length; /* Length is 24. */
+ ovs_be16 event; /* One of NXFME_*. */
+ ovs_be16 reason; /* OFPRR_* for NXFME_DELETED, else zero. */
+ ovs_be16 priority; /* Priority of the 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 table_id; /* ID of flow's table. */
+ uint8_t pad; /* Reserved, currently zeroed. */
+ ovs_be64 cookie; /* Opaque controller-issued identifier. */
+ /* 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). If NXFMF_ACTIONS was not specified, or 'event' is
+ * NXFME_DELETED, no actions are included.
+ */
+};
+OFP_ASSERT(sizeof(struct nx_flow_update_full) == 24);
+
+/* NXST_FLOW_MONITOR reply for NXFME_ABBREV.
+ *
+ * When the controller does not specify NXFMF_OWN in a monitor request, any
+ * flow tables changes due to the controller's own requests (on the same
+ * OpenFlow channel) will be abbreviated, when possible, to this form, which
+ * simply specifies the 'xid' of the OpenFlow request (e.g. an OFPT_FLOW_MOD or
+ * NXT_FLOW_MOD) that caused the change.
+ *
+ * Some changes cannot be abbreviated and will be sent in full:
+ *
+ * - Changes that only partially succeed. This can happen if, for example,
+ * a flow_mod with type OFPFC_MODIFY affects multiple flows, but only some
+ * of those modifications succeed (e.g. due to hardware limitations).
+ *
+ * This cannot occur with the current implementation of the Open vSwitch
+ * software datapath. It could happen with other datapath implementations.
+ *
+ * - Changes that race with conflicting changes made by other controllers or
+ * other flow_mods (not separated by barriers) by the same controller.
+ *
+ * This cannot occur with the current Open vSwitch implementation
+ * (regardless of datapath) because Open vSwitch internally serializes
+ * potentially conflicting changes.
+ *
+ * A flow_mod that does not change the flow table will not trigger any
+ * notification, even an abbreviated one. For example, a "modify" or "delete"
+ * flow_mod that does not match any flows will not trigger a notification.
+ * Whether an "add" or "modify" that specifies all the same parameters that a
+ * flow already has triggers a notification is unspecified and subject to
+ * change in future versions of Open vSwitch.
+ *
+ * OVS will always send the notifications for a given flow table change before
+ * the reply to a OFPT_BARRIER_REQUEST request that precedes the flow table
+ * change. Thus, if the controller does not receive an abbreviated
+ * notification for a flow_mod before the next OFPT_BARRIER_REPLY, it will
+ * never receive one. */
+struct nx_flow_update_abbrev {
+ ovs_be16 length; /* Length is 8. */
+ ovs_be16 event; /* NXFME_ABBREV. */
+ ovs_be32 xid; /* Controller-specified xid from flow_mod. */
+};
+OFP_ASSERT(sizeof(struct nx_flow_update_abbrev) == 8);
+
+/* Used by a controller to cancel an outstanding monitor. */
+struct nx_flow_monitor_cancel {
+ struct nicira_header nxh; /* Type NXT_FLOW_MONITOR_CANCEL. */
+ ovs_be32 id; /* 'id' from nx_flow_monitor_request. */
+};
+OFP_ASSERT(sizeof(struct nx_flow_monitor_cancel) == 20);