/*
- * Copyright (c) 2008, 2009, 2010 Nicira Networks
+ * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include "openflow/openflow.h"
#include "openvswitch/types.h"
-#define NICIRA_OUI_STR "002320"
-
/* The following vendor extensions, proposed by Nicira Networks, are not yet
* standardized, so they are not included in openflow.h. Some of them may be
* suitable for standardization; others we never expect to standardize. */
*
* This extension attempts to address the problem by adding a generic "error
* vendor extension". The extension works as follows: use NXET_VENDOR as type
- * and NXVC_VENDOR_CODE as code, followed by struct nx_vendor_error with
+ * and NXVC_VENDOR_ERROR as code, followed by struct nx_vendor_error with
* vendor-specific details, followed by at least 64 bytes of the failed
* request.
*
* that duplicate the current ones' meanings. */
/* Additional "code" values for OFPET_BAD_REQUEST. */
-enum {
+enum nx_bad_request_code {
/* Nicira Extended Match (NXM) errors. */
/* Generic error code used when there is an error in an NXM sent to the
};
/* Additional "code" values for OFPET_FLOW_MOD_FAILED. */
-enum {
+enum nx_flow_mod_failed_code {
/* Generic hardware error. */
NXFMFC_HARDWARE = 0x100,
/* NXT_TUN_ID_FROM_COOKIE request. */
struct nxt_tun_id_cookie {
struct ofp_header header;
- uint32_t vendor; /* NX_VENDOR_ID. */
- uint32_t subtype; /* NXT_TUN_ID_FROM_COOKIE */
+ ovs_be32 vendor; /* NX_VENDOR_ID. */
+ ovs_be32 subtype; /* NXT_TUN_ID_FROM_COOKIE */
uint8_t set; /* Nonzero to enable, zero to disable. */
uint8_t pad[7];
};
*/
struct nx_role_request {
struct nicira_header nxh;
- uint32_t role; /* One of NX_ROLE_*. */
+ ovs_be32 role; /* One of NX_ROLE_*. */
};
enum nx_role {
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_NOTE, /* struct nx_action_note */
+ NXAST_SET_TUNNEL64, /* struct nx_action_set_tunnel64 */
+ NXAST_MULTIPATH /* struct nx_action_multipath */
};
/* Header for Nicira-defined actions. */
struct nx_action_header {
- uint16_t type; /* OFPAT_VENDOR. */
- uint16_t len; /* Length is 16. */
- uint32_t vendor; /* NX_VENDOR_ID. */
- uint16_t subtype; /* NXAST_*. */
+ ovs_be16 type; /* OFPAT_VENDOR. */
+ ovs_be16 len; /* Length is 16. */
+ ovs_be32 vendor; /* NX_VENDOR_ID. */
+ ovs_be16 subtype; /* NXAST_*. */
uint8_t pad[6];
};
OFP_ASSERT(sizeof(struct nx_action_header) == 16);
* ignored. (Open vSwitch 1.0.1 and earlier did not support recursion.)
*/
struct nx_action_resubmit {
- uint16_t type; /* OFPAT_VENDOR. */
- uint16_t len; /* Length is 16. */
- uint32_t vendor; /* NX_VENDOR_ID. */
- uint16_t subtype; /* NXAST_RESUBMIT. */
- uint16_t in_port; /* New in_port for checking flow table. */
+ ovs_be16 type; /* OFPAT_VENDOR. */
+ ovs_be16 len; /* Length is 16. */
+ ovs_be32 vendor; /* NX_VENDOR_ID. */
+ ovs_be16 subtype; /* NXAST_RESUBMIT. */
+ ovs_be16 in_port; /* New in_port for checking flow table. */
uint8_t pad[4];
};
OFP_ASSERT(sizeof(struct nx_action_resubmit) == 16);
/* Action structure for NXAST_SET_TUNNEL.
*
- * Sets the encapsulating tunnel ID. */
+ * Sets the encapsulating tunnel ID to a 32-bit value. The most-significant 32
+ * bits of the tunnel ID are set to 0. */
struct nx_action_set_tunnel {
- uint16_t type; /* OFPAT_VENDOR. */
- uint16_t len; /* Length is 16. */
- uint32_t vendor; /* NX_VENDOR_ID. */
- uint16_t subtype; /* NXAST_SET_TUNNEL. */
+ ovs_be16 type; /* OFPAT_VENDOR. */
+ ovs_be16 len; /* Length is 16. */
+ ovs_be32 vendor; /* NX_VENDOR_ID. */
+ ovs_be16 subtype; /* NXAST_SET_TUNNEL. */
uint8_t pad[2];
- uint32_t tun_id; /* Tunnel ID. */
+ ovs_be32 tun_id; /* Tunnel ID. */
};
OFP_ASSERT(sizeof(struct nx_action_set_tunnel) == 16);
+/* Action structure for NXAST_SET_TUNNEL64.
+ *
+ * Sets the encapsulating tunnel ID to a 64-bit value. */
+struct nx_action_set_tunnel64 {
+ ovs_be16 type; /* OFPAT_VENDOR. */
+ ovs_be16 len; /* Length is 16. */
+ ovs_be32 vendor; /* NX_VENDOR_ID. */
+ ovs_be16 subtype; /* NXAST_SET_TUNNEL64. */
+ uint8_t pad[6];
+ ovs_be64 tun_id; /* Tunnel ID. */
+};
+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. */
+ * (This action is deprecated in favor of defining flows using the
+ * NXM_NX_ARP_SHA flow match and will likely be removed in a future version
+ * of Open vSwitch.) */
struct nx_action_drop_spoofed_arp {
- uint16_t type; /* OFPAT_VENDOR. */
- uint16_t len; /* Length is 16. */
- uint32_t vendor; /* NX_VENDOR_ID. */
- uint16_t subtype; /* NXAST_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);
* an argument. This allows the queue to be defined before the port is
* known. */
struct nx_action_set_queue {
- uint16_t type; /* OFPAT_VENDOR. */
- uint16_t len; /* Length is 16. */
- uint32_t vendor; /* NX_VENDOR_ID. */
- uint16_t subtype; /* NXAST_SET_QUEUE. */
+ ovs_be16 type; /* OFPAT_VENDOR. */
+ ovs_be16 len; /* Length is 16. */
+ ovs_be32 vendor; /* NX_VENDOR_ID. */
+ ovs_be16 subtype; /* NXAST_SET_QUEUE. */
uint8_t pad[2];
- uint32_t queue_id; /* Where to enqueue packets. */
+ ovs_be32 queue_id; /* Where to enqueue packets. */
};
OFP_ASSERT(sizeof(struct nx_action_set_queue) == 16);
* were used. Only the original queue can be restored this way; no stack is
* maintained. */
struct nx_action_pop_queue {
- uint16_t type; /* OFPAT_VENDOR. */
- uint16_t len; /* Length is 16. */
- uint32_t vendor; /* NX_VENDOR_ID. */
- uint16_t subtype; /* NXAST_POP_QUEUE. */
+ ovs_be16 type; /* OFPAT_VENDOR. */
+ ovs_be16 len; /* Length is 16. */
+ ovs_be32 vendor; /* NX_VENDOR_ID. */
+ ovs_be16 subtype; /* NXAST_POP_QUEUE. */
uint8_t pad[6];
};
OFP_ASSERT(sizeof(struct nx_action_pop_queue) == 16);
* bit 'c'). Bit numbering starts at 0 for the least-significant bit, 1 for
* the next most significant bit, and so on.
*
- * 'src' and 'dst' are nxm_header values with nxm_hasmask=0. The following
- * nxm_header values are potentially acceptable as 'src':
+ * 'src' and 'dst' are nxm_header values with nxm_hasmask=0. (It doesn't make
+ * sense to use nxm_hasmask=1 because the action does not do any kind of
+ * matching; it uses the actual value of a field.)
+ *
+ * The following nxm_header values are potentially acceptable as 'src':
*
* - NXM_OF_IN_PORT
* - NXM_OF_ETH_DST
* - NXM_OF_ARP_SPA
* - NXM_OF_ARP_TPA
* - NXM_NX_TUN_ID
+ * - NXM_NX_ARP_SHA
+ * - NXM_NX_ARP_THA
* - NXM_NX_REG(idx) for idx in the switch's accepted range.
*
* The following nxm_header values are potentially acceptable as 'dst':
* starts at 0 for the least-significant bit, 1 for the next most significant
* bit, and so on.
*
- * 'dst' must be one of the following:
- *
- * - NXM_NX_REG(idx) for idx in the switch's accepted range.
+ * 'dst' is an nxm_header with nxm_hasmask=0. See the documentation for
+ * NXAST_REG_MOVE, above, for the permitted fields and for the side effects of
+ * loading them.
*
* The 'ofs' and 'n_bits' fields are combined into a single 'ofs_nbits' field
* to avoid enlarging the structure by another 8 bytes. To allow 'n_bits' to
* This action might go away in the future.
*/
struct nx_action_note {
- uint16_t type; /* OFPAT_VENDOR. */
- uint16_t len; /* A multiple of 8, but at least 16. */
- uint32_t vendor; /* NX_VENDOR_ID. */
- uint16_t subtype; /* NXAST_NOTE. */
+ ovs_be16 type; /* OFPAT_VENDOR. */
+ ovs_be16 len; /* A multiple of 8, but at least 16. */
+ ovs_be32 vendor; /* NX_VENDOR_ID. */
+ ovs_be16 subtype; /* NXAST_NOTE. */
uint8_t note[6]; /* Start of user-defined data. */
/* Possibly followed by additional user-defined data. */
};
OFP_ASSERT(sizeof(struct nx_action_note) == 16);
+/* Action structure for NXAST_MULTIPATH.
+ *
+ * This action performs the following steps in sequence:
+ *
+ * 1. Hashes the fields designated by 'fields', one of NX_MP_FIELDS_*.
+ * Refer to the definition of "enum nx_mp_fields" for details.
+ *
+ * The 'basis' value is used as a universal hash parameter, that is,
+ * different values of 'basis' yield different hash functions. The
+ * particular universal hash function used is implementation-defined.
+ *
+ * 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. Applies the multipath link choice algorithm specified by 'algorithm',
+ * one of NX_MP_ALG_*. Refer to the definition of "enum nx_mp_algorithm"
+ * for details.
+ *
+ * The output of the algorithm is 'link', an unsigned integer less than
+ * or equal to 'max_link'.
+ *
+ * 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.
+ *
+ * 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
+ * in which 'max_link' is greater than or equal to 2**n_bits, with error type
+ * OFPET_BAD_ACTION, code OFPBAC_BAD_ARGUMENT.
+ */
+struct nx_action_multipath {
+ ovs_be16 type; /* OFPAT_VENDOR. */
+ ovs_be16 len; /* Length is 32. */
+ ovs_be32 vendor; /* NX_VENDOR_ID. */
+ ovs_be16 subtype; /* NXAST_MULTIPATH. */
+
+ /* What fields to hash and how. */
+ ovs_be16 fields; /* One of NX_MP_FIELDS_*. */
+ ovs_be16 basis; /* Universal hash parameter. */
+ ovs_be16 pad0;
+
+ /* Multipath link choice algorithm to apply to hash value. */
+ ovs_be16 algorithm; /* One of NX_MP_ALG_*. */
+ ovs_be16 max_link; /* Number of output links, minus 1. */
+ ovs_be32 arg; /* Algorithm-specific argument. */
+ ovs_be16 pad1;
+
+ /* Where to store the result. */
+ ovs_be16 ofs_nbits; /* (ofs << 6) | (n_bits - 1). */
+ ovs_be32 dst; /* Destination register. */
+};
+OFP_ASSERT(sizeof(struct nx_action_multipath) == 32);
+
+/* NXAST_MULTIPATH: Fields to hash. */
+enum nx_mp_fields {
+ /* Ethernet source address (NXM_OF_ETH_SRC) only. */
+ NX_MP_FIELDS_ETH_SRC,
+
+ /* L2 through L4, symmetric across src/dst. Specifically, each of the
+ * following fields, if present, is hashed (slashes separate symmetric
+ * pairs):
+ *
+ * - NXM_OF_ETH_DST / NXM_OF_ETH_SRC
+ * - NXM_OF_ETH_TYPE
+ * - The VID bits from NXM_OF_VLAN_TCI, ignoring PCP and CFI.
+ * - NXM_OF_IP_PROTO
+ * - NXM_OF_IP_SRC / NXM_OF_IP_DST
+ * - NXM_OF_TCP_SRC / NXM_OF_TCP_DST
+ * - NXM_OF_UDP_SRC / NXM_OF_UDP_DST
+ */
+ NX_MP_FIELDS_SYMMETRIC_L4
+};
+
+/* NXAST_MULTIPATH: Multipath link choice algorithm to apply.
+ *
+ * In the descriptions below, 'n_links' is max_link + 1. */
+enum nx_mp_algorithm {
+ /* link = hash(flow) % n_links.
+ *
+ * Redistributes all traffic when n_links changes. O(1) performance. See
+ * RFC 2992.
+ *
+ * Use UINT16_MAX for max_link to get a raw hash value. */
+ NX_MP_ALG_MODULO_N,
+
+ /* link = hash(flow) / (MAX_HASH / n_links).
+ *
+ * Redistributes between one-quarter and one-half of traffic when n_links
+ * changes. O(1) performance. See RFC 2992.
+ */
+ NX_MP_ALG_HASH_THRESHOLD,
+
+ /* for i in [0,n_links):
+ * weights[i] = hash(flow, i)
+ * link = { i such that weights[i] >= weights[j] for all j != i }
+ *
+ * Redistributes 1/n_links of traffic when n_links changes. O(n_links)
+ * performance. If n_links is greater than a threshold (currently 64, but
+ * subject to change), Open vSwitch will substitute another algorithm
+ * automatically. See RFC 2992. */
+ NX_MP_ALG_HRW, /* Highest Random Weight. */
+
+ /* i = 0
+ * repeat:
+ * i = i + 1
+ * link = hash(flow, i) % arg
+ * while link > max_link
+ *
+ * Redistributes 1/n_links of traffic when n_links changes. O(1)
+ * performance when arg/max_link is bounded by a constant.
+ *
+ * Redistributes all traffic when arg changes.
+ *
+ * arg must be greater than max_link and for best performance should be no
+ * more than approximately max_link * 2. If arg is outside the acceptable
+ * range, Open vSwitch will automatically substitute the least power of 2
+ * greater than max_link.
+ *
+ * This algorithm is specific to Open vSwitch.
+ */
+ NX_MP_ALG_ITER_HASH /* Iterative Hash. */
+};
+
/* Wildcard for tunnel ID. */
#define NXFW_TUN_ID (1 << 25)
* - 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=0xe000 matches packets with no 802.1Q
+ * - 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)
#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_REG(0))) & 0xffffe0ff))
+#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_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)
+
/* ## --------------------- ## */
/* ## Requests and replies. ## */
/* ## --------------------- ## */