NXFMFC_HARDWARE = 0x100,
/* A nonexistent table ID was specified in the "command" field of struct
- * ofp_flow_mod, when the nxt_flow_mod_table_id extension is enabled.
- * (This extension is not yet implemented on this branch of Open
- * vSwitch.) */
+ * ofp_flow_mod, when the nxt_flow_mod_table_id extension is enabled. */
NXFMFC_BAD_TABLE_ID = 0x101
};
\f
/* Values for the 'subtype' member of struct nicira_header. */
enum nicira_type {
- /* Switch status request. The request body is an ASCII string that
- * specifies a prefix of the key names to include in the output; if it is
- * the null string, then all key-value pairs are included. */
- NXT_STATUS_REQUEST,
-
- /* Switch status reply. The reply body is an ASCII string of key-value
- * pairs in the form "key=value\n". */
- NXT_STATUS_REPLY,
-
/* No longer used. */
- NXT_ACT_SET_CONFIG__OBSOLETE,
- NXT_ACT_GET_CONFIG__OBSOLETE,
- NXT_COMMAND_REQUEST__OBSOLETE,
- NXT_COMMAND_REPLY__OBSOLETE,
- NXT_FLOW_END_CONFIG__OBSOLETE,
- NXT_FLOW_END__OBSOLETE,
- NXT_MGMT__OBSOLETE,
-
- /* Use the high 32 bits of the cookie field as the tunnel ID in the flow
- * match. */
- NXT_TUN_ID_FROM_COOKIE,
+ NXT_STATUS_REQUEST__OBSOLETE = 0,
+ NXT_STATUS_REPLY__OBSOLETE = 1,
+ NXT_ACT_SET_CONFIG__OBSOLETE = 2,
+ NXT_ACT_GET_CONFIG__OBSOLETE = 3,
+ NXT_COMMAND_REQUEST__OBSOLETE = 4,
+ NXT_COMMAND_REPLY__OBSOLETE = 5,
+ NXT_FLOW_END_CONFIG__OBSOLETE = 6,
+ NXT_FLOW_END__OBSOLETE = 7,
+ NXT_MGMT__OBSOLETE = 8,
+ NXT_TUN_ID_FROM_COOKIE__OBSOLETE = 9,
/* Controller role support. The request body is struct nx_role_request.
* The reply echos the request. */
- NXT_ROLE_REQUEST,
- NXT_ROLE_REPLY,
+ NXT_ROLE_REQUEST = 10,
+ NXT_ROLE_REPLY = 11,
/* Flexible flow specification (aka NXM = Nicira Extended Match). */
- NXT_SET_FLOW_FORMAT, /* Set flow format. */
- NXT_FLOW_MOD, /* Analogous to OFPT_FLOW_MOD. */
- NXT_FLOW_REMOVED /* Analogous to OFPT_FLOW_REMOVED. */
+ NXT_SET_FLOW_FORMAT = 12, /* Set flow format. */
+ NXT_FLOW_MOD = 13, /* Analogous to OFPT_FLOW_MOD. */
+ NXT_FLOW_REMOVED = 14, /* Analogous to OFPT_FLOW_REMOVED. */
+
+ /* Use the upper 8 bits of the 'command' member in struct ofp_flow_mod to
+ * designate the table to which a flow is to be added? See the big comment
+ * on struct nxt_flow_mod_table_id for more information. */
+ NXT_FLOW_MOD_TABLE_ID = 15
};
/* Header for Nicira vendor stats request and reply messages. */
struct nicira_stats_msg {
- struct ofp_header header; /* OFPT_STATS_REQUEST or OFPT_STATS_REPLY. */
- ovs_be16 type; /* OFPST_VENDOR. */
- ovs_be16 flags; /* OFPSF_{REQ,REPLY}_*. */
- ovs_be32 vendor; /* NX_VENDOR_ID. */
+ struct ofp_vendor_stats_msg vsm; /* Vendor NX_VENDOR_ID. */
ovs_be32 subtype; /* One of NXST_* below. */
uint8_t pad[4]; /* Align to 64-bits. */
};
NXST_AGGREGATE /* Analogous to OFPST_AGGREGATE. */
};
-/* NXT_TUN_ID_FROM_COOKIE request. */
-struct nxt_tun_id_cookie {
+/* This command enables or disables an Open vSwitch extension that allows a
+ * controller to specify the OpenFlow table to which a flow should be added,
+ * instead of having the switch decide which table is most appropriate as
+ * required by OpenFlow 1.0. By default, the extension is disabled.
+ *
+ * When this feature is enabled, Open vSwitch treats struct ofp_flow_mod's
+ * 16-bit 'command' member as two separate fields. The upper 8 bits are used
+ * as the table ID, the lower 8 bits specify the command as usual. A table ID
+ * of 0xff is treated like a wildcarded table ID.
+ *
+ * The specific treatment of the table ID depends on the type of flow mod:
+ *
+ * - OFPFC_ADD: Given a specific table ID, the flow is always placed in that
+ * table. If an identical flow already exists in that table only, then it
+ * is replaced. If the flow cannot be placed in the specified table,
+ * either because the table is full or because the table cannot support
+ * flows of the given type, the switch replies with an
+ * OFPFMFC_ALL_TABLES_FULL error. (A controller can distinguish these
+ * cases by comparing the current and maximum number of entries reported
+ * in ofp_table_stats.)
+ *
+ * If the table ID is wildcarded, the switch picks an appropriate table
+ * itself. If an identical flow already exist in the selected flow table,
+ * then it is replaced. The choice of table might depend on the flows
+ * that are already in the switch; for example, if one table fills up then
+ * the switch might fall back to another one.
+ *
+ * - OFPFC_MODIFY, OFPFC_DELETE: Given a specific table ID, only flows
+ * within that table are matched and modified or deleted. If the table ID
+ * is wildcarded, flows within any table may be matched and modified or
+ * deleted.
+ *
+ * - OFPFC_MODIFY_STRICT, OFPFC_DELETE_STRICT: Given a specific table ID,
+ * only a flow within that table may be matched and modified or deleted.
+ * If the table ID is wildcarded and exactly one flow within any table
+ * matches, then it is modified or deleted; if flows in more than one
+ * table match, then none is modified or deleted.
+ */
+struct nxt_flow_mod_table_id {
struct ofp_header header;
- ovs_be32 vendor; /* NX_VENDOR_ID. */
- ovs_be32 subtype; /* NXT_TUN_ID_FROM_COOKIE */
+ uint32_t vendor; /* NX_VENDOR_ID. */
+ uint32_t subtype; /* NXT_FLOW_MOD_TABLE_ID. */
uint8_t set; /* Nonzero to enable, zero to disable. */
uint8_t pad[7];
};
-OFP_ASSERT(sizeof(struct nxt_tun_id_cookie) == 24);
+OFP_ASSERT(sizeof(struct nxt_flow_mod_table_id) == 24);
/* Configures the "role" of the sending controller. The default role is:
*
NXAST_SNAT__OBSOLETE, /* No longer used. */
NXAST_RESUBMIT, /* struct nx_action_resubmit */
NXAST_SET_TUNNEL, /* struct nx_action_set_tunnel */
- NXAST_DROP_SPOOFED_ARP, /* struct nx_action_drop_spoofed_arp */
+ NXAST_DROP_SPOOFED_ARP__OBSOLETE,
NXAST_SET_QUEUE, /* struct nx_action_set_queue */
NXAST_POP_QUEUE, /* struct nx_action_pop_queue */
NXAST_REG_MOVE, /* struct nx_action_reg_move */
NXAST_REG_LOAD, /* struct nx_action_reg_load */
NXAST_NOTE, /* struct nx_action_note */
NXAST_SET_TUNNEL64, /* struct nx_action_set_tunnel64 */
- NXAST_MULTIPATH /* struct nx_action_multipath */
+ NXAST_MULTIPATH, /* struct nx_action_multipath */
+ NXAST_AUTOPATH /* struct nx_action_autopath */
};
/* Header for Nicira-defined actions. */
};
OFP_ASSERT(sizeof(struct nx_action_set_tunnel64) == 24);
-/* Action structure for NXAST_DROP_SPOOFED_ARP.
- *
- * Stops processing further actions, if the packet being processed is an
- * Ethernet+IPv4 ARP packet for which the source Ethernet address inside the
- * ARP packet differs from the source Ethernet address in the Ethernet header.
- *
- * This is useful because OpenFlow does not provide a way to match on the
- * Ethernet addresses inside ARP packets, so there is no other way to drop
- * spoofed ARPs other than sending every ARP packet to a controller. */
-struct nx_action_drop_spoofed_arp {
- ovs_be16 type; /* OFPAT_VENDOR. */
- ovs_be16 len; /* Length is 16. */
- ovs_be32 vendor; /* NX_VENDOR_ID. */
- ovs_be16 subtype; /* NXAST_DROP_SPOOFED_ARP. */
- uint8_t pad[6];
-};
-OFP_ASSERT(sizeof(struct nx_action_drop_spoofed_arp) == 16);
-
/* Action structure for NXAST_SET_QUEUE.
*
* Set the queue that should be used when packets are output. This is similar
* - NXM_OF_ARP_SPA
* - NXM_OF_ARP_TPA
* - NXM_NX_TUN_ID
+ * - NXM_NX_ARP_SHA
+ * - NXM_NX_ARP_THA
+ * - NXM_NX_ICMPV6_TYPE
+ * - NXM_NX_ICMPV6_CODE
+ * - NXM_NX_ND_SLL
+ * - NXM_NX_ND_TLL
* - NXM_NX_REG(idx) for idx in the switch's accepted range.
*
* The following nxm_header values are potentially acceptable as 'dst':
* Some algorithms use 'arg' as an additional argument.
*
* 3. Stores 'link' in dst[ofs:ofs+n_bits]. The format and semantics of
- * 'dst' and 'ofs_nbits' are identical to those for the NXAST_REG_LOAD
- * action; refer to the description of that action for details.
+ * 'dst' and 'ofs_nbits' are similar to those for the NXAST_REG_LOAD
+ * action, except that 'dst' must be NXM_NX_REG(idx) for 'idx' in the
+ * switch's supported range.
*
* The switch will reject actions that have an unknown 'fields', or an unknown
* 'algorithm', or in which ofs+n_bits is greater than the width of 'dst', or
*/
NX_MP_ALG_ITER_HASH /* Iterative Hash. */
};
+\f
+/* Action structure for NXAST_AUTOPATH.
+ *
+ * This action performs the following steps in sequence:
+ *
+ * 1. Hashes the flow using an implementation-defined hash function.
+ *
+ * The hashed fields' values are drawn from the current state of the
+ * flow, including all modifications that have been made by actions up to
+ * this point.
+ *
+ * 2. Selects an OpenFlow 'port'.
+ *
+ * 'port' is selected in an implementation-defined manner, taking into
+ * account 'id' and the hash value calculated in step 1.
+ *
+ * Generally a switch will have been configured with a set of ports that
+ * may be chosen given 'id'. The switch may take into account any number
+ * of factors when choosing 'port' from its configured set. Factors may
+ * include carrier, load, and the results of configuration protocols such
+ * as LACP.
+ *
+ * 3. Stores 'port' in dst[ofs:ofs+n_bits].
+ *
+ * The format and semantics of 'dst' and 'ofs_nbits' are similar to those
+ * for the NXAST_REG_LOAD action, except that 'dst' must be
+ * NXM_NX_REG(idx) for 'idx' in the switch's supported range.
+ *
+ * The switch will reject actions in which ofs+n_bits is greater than the width
+ * of 'dst', with error type OFPET_BAD_ACTION, code OFPBAC_BAD_ARGUMENT.
+ */
+struct nx_action_autopath {
+ ovs_be16 type; /* OFPAT_VENDOR. */
+ ovs_be16 len; /* Length is 20. */
+ ovs_be32 vendor; /* NX_VENDOR_ID. */
+ ovs_be16 subtype; /* NXAST_MULTIPATH. */
-/* Wildcard for tunnel ID. */
-#define NXFW_TUN_ID (1 << 25)
+ /* Where to store the result. */
+ ovs_be16 ofs_nbits; /* (ofs << 6) | (n_bits - 1). */
+ ovs_be32 dst; /* Destination register. */
-#define NXFW_ALL NXFW_TUN_ID
-#define OVSFW_ALL (OFPFW_ALL | NXFW_ALL)
+ ovs_be32 id; /* Autopath ID. */
+ ovs_be32 pad;
+};
+OFP_ASSERT(sizeof(struct nx_action_autopath) == 24);
\f
/* Flexible flow specifications (aka NXM = Nicira Extended Match).
*
/* The "type of service" byte of the IP header, with the ECN bits forced to 0.
*
- * Prereqs: NXM_OF_ETH_TYPE must match 0x0800 exactly.
+ * Prereqs: NXM_OF_ETH_TYPE must be either 0x0800 or 0x86dd.
*
* Format: 8-bit integer with 2 least-significant bits forced to 0.
*
/* The "protocol" byte in the IP header.
*
- * Prereqs: NXM_OF_ETH_TYPE must match 0x0800 exactly.
+ * Prereqs: NXM_OF_ETH_TYPE must be either 0x0800 or 0x86dd.
*
* Format: 8-bit integer.
*
/* The source or destination port in the TCP header.
*
* Prereqs:
- * NXM_OF_ETH_TYPE must match 0x0800 exactly.
+ * 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.
/* The source or destination port in the UDP header.
*
* Prereqs:
- * NXM_OF_ETH_TYPE must match 0x0800 exactly.
+ * 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.
#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)
+
+
/* ## --------------------- ## */
/* ## Requests and replies. ## */
/* ## --------------------- ## */
enum nx_flow_format {
NXFF_OPENFLOW10 = 0, /* Standard OpenFlow 1.0 compatible. */
- NXFF_TUN_ID_FROM_COOKIE = 1, /* OpenFlow 1.0, plus obtain tunnel ID from
- * cookie. */
NXFF_NXM = 2 /* Nicira extended match. */
};
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 in flow. */
- ovs_be64 byte_count; /* Number of bytes in flow. */
+ 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
OFP_ASSERT(sizeof(struct nx_aggregate_stats_request) == 32);
/* Body for nicira_stats_msg reply of type NXST_AGGREGATE (analogous to
- * OFPST_AGGREGATE reply).
- *
- * ofp_aggregate_stats_reply does not contain an ofp_match structure, so we
- * reuse it entirely. (It would be very odd to use OFPST_AGGREGATE to reply to
- * an NXST_AGGREGATE request, so we don't do that.) */
+ * OFPST_AGGREGATE reply). */
struct nx_aggregate_stats_reply {
struct nicira_stats_msg nsm;
- struct ofp_aggregate_stats_reply asr;
+ 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);