X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=include%2Fopenflow%2Fnicira-ext.h;h=5cf02e7c58a1b4fe6dac19b18c14104f503cbeee;hb=d5e1e5ede31ea213d1dea2f865a1b679b7f1bed2;hp=3a4a694016bb0bc0a5880aae37276da10b1ef386;hpb=b6c9e612fa0801037c60339a931d29413e8fa08f;p=openvswitch diff --git a/include/openflow/nicira-ext.h b/include/openflow/nicira-ext.h index 3a4a6940..5cf02e7c 100644 --- a/include/openflow/nicira-ext.h +++ b/include/openflow/nicira-ext.h @@ -1,5 +1,5 @@ /* - * 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. @@ -20,8 +20,6 @@ #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. */ @@ -38,7 +36,7 @@ * * 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. * @@ -78,7 +76,7 @@ struct nx_vendor_error { * 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 @@ -105,14 +103,12 @@ enum { }; /* Additional "code" values for OFPET_FLOW_MOD_FAILED. */ -enum { +enum nx_flow_mod_failed_code { /* Generic hardware error. */ 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 }; @@ -128,45 +124,37 @@ OFP_ASSERT(sizeof(struct nicira_header) == 16); /* 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. */ }; @@ -179,15 +167,71 @@ enum nicira_stats_type { NXST_AGGREGATE /* Analogous to OFPST_AGGREGATE. */ }; -/* NXT_TUN_ID_FROM_COOKIE request. */ -struct nxt_tun_id_cookie { +/* Fields to use when hashing flows. */ +enum nx_hash_fields { + /* Ethernet source address (NXM_OF_ETH_SRC) only. */ + NX_HASH_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 + */ + NX_HASH_FIELDS_SYMMETRIC_L4 +}; + +/* 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; uint32_t vendor; /* NX_VENDOR_ID. */ - uint32_t subtype; /* NXT_TUN_ID_FROM_COOKIE */ + 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: * @@ -205,12 +249,12 @@ OFP_ASSERT(sizeof(struct nxt_tun_id_cookie) == 24); * OpenFlow features. In particular attempts to modify the flow table * will be rejected with an OFPBRC_EPERM error. * - * Slave controllers also do not receive asynchronous messages - * (OFPT_PACKET_IN, OFPT_FLOW_REMOVED, OFPT_PORT_STATUS). + * Slave controllers do not receive OFPT_PACKET_IN or OFPT_FLOW_REMOVED + * messages, but they do receive OFPT_PORT_STATUS messages. */ 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 { @@ -225,19 +269,25 @@ enum nx_action_subtype { 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_AUTOPATH, /* struct nx_action_autopath */ + NXAST_BUNDLE, /* struct nx_action_bundle */ + NXAST_BUNDLE_LOAD /* struct nx_action_bundle */ }; /* 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); @@ -269,45 +319,41 @@ 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_DROP_SPOOFED_ARP. +/* Action structure for NXAST_SET_TUNNEL64. * - * 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 { - uint16_t type; /* OFPAT_VENDOR. */ - uint16_t len; /* Length is 16. */ - uint32_t vendor; /* NX_VENDOR_ID. */ - uint16_t subtype; /* NXAST_DROP_SPOOFED_ARP. */ + * 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_drop_spoofed_arp) == 16); +OFP_ASSERT(sizeof(struct nx_action_set_tunnel64) == 24); /* Action structure for NXAST_SET_QUEUE. * @@ -316,12 +362,12 @@ 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); @@ -331,10 +377,10 @@ 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); @@ -346,8 +392,11 @@ 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 @@ -368,10 +417,28 @@ OFP_ASSERT(sizeof(struct nx_action_pop_queue) == 16); * - 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': * + * - NXM_OF_ETH_DST + * - NXM_OF_ETH_SRC + * - NXM_OF_IP_TOS + * - NXM_OF_IP_SRC + * - NXM_OF_IP_DST + * - NXM_OF_TCP_SRC + * - NXM_OF_TCP_DST + * - NXM_OF_UDP_SRC + * - NXM_OF_UDP_DST + * Modifying any of the above fields changes the corresponding packet + * header. + * * - NXM_NX_REG(idx) for idx in the switch's accepted range. * * - NXM_OF_VLAN_TCI. Modifying this field's value has side effects on the @@ -412,9 +479,9 @@ OFP_ASSERT(sizeof(struct nx_action_reg_move) == 24); * 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 @@ -442,11 +509,255 @@ struct nx_action_reg_load { }; OFP_ASSERT(sizeof(struct nx_action_reg_load) == 24); -/* Wildcard for tunnel ID. */ -#define NXFW_TUN_ID (1 << 25) +/* Action structure for NXAST_NOTE. + * + * This action has no effect. It is variable length. The switch does not + * attempt to interpret the user-defined 'note' data in any way. A controller + * can use this action to attach arbitrary metadata to a flow. + * + * This action might go away in the future. + */ +struct nx_action_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_HASH_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 similar to those for the NXAST_REG_LOAD + * action. + * + * 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_HASH_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. */ +}; +OFP_ASSERT(sizeof(struct nx_action_multipath) == 32); + +/* 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. */ +}; + +/* 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. + * + * 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_AUTOPATH. */ + + /* Where to store the result. */ + ovs_be16 ofs_nbits; /* (ofs << 6) | (n_bits - 1). */ + ovs_be32 dst; /* Destination. */ -#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); + +/* Action structure for NXAST_BUNDLE and NXAST_BUNDLE_LOAD. + * + * The bundle actions choose a slave from a supplied list of options. + * NXAST_BUNDLE outputs to its selection. NXAST_BUNDLE_LOAD writes its + * selection to a register. + * + * The list of possible slaves follows the nx_action_bundle structure. The size + * of each slave is governed by its type as indicated by the 'slave_type' + * parameter. The list of slaves should be padded at its end with zeros to make + * the total length of the action a multiple of 8. + * + * Switches infer from the 'slave_type' parameter the size of each slave. All + * implementations must support the NXM_OF_IN_PORT 'slave_type' which indicates + * that the slaves are OpenFlow port numbers with NXM_LENGTH(NXM_OF_IN_PORT) == + * 2 byte width. Switches should reject actions which indicate unknown or + * unsupported slave types. + * + * Switches use a strategy dictated by the 'algorithm' parameter to choose a + * slave. If the switch does not support the specified 'algorithm' parameter, + * it should reject the action. + * + * Some slave selection strategies require the use of a hash function, in which + * case the 'fields' and 'basis' parameters should be populated. The 'fields' + * parameter (one of NX_HASH_FIELDS_*) designates which parts of the flow to + * hash. Refer to the definition of "enum nx_hash_fields" for details. The + * 'basis' parameter is used as a universal hash parameter. Different values + * of 'basis' yield different hash results. + * + * The 'zero' parameter at the end of the action structure is reserved for + * future use. Switches are required to reject actions which have nonzero + * bytes in the 'zero' field. + * + * NXAST_BUNDLE actions should have 'ofs_nbits' and 'dst' zeroed. Switches + * should reject actions which have nonzero bytes in either of these fields. + * + * NXAST_BUNDLE_LOAD stores the OpenFlow port number of the selected slave 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. */ +struct nx_action_bundle { + ovs_be16 type; /* OFPAT_VENDOR. */ + ovs_be16 len; /* Length including slaves. */ + ovs_be32 vendor; /* NX_VENDOR_ID. */ + ovs_be16 subtype; /* NXAST_BUNDLE. */ + + /* Slave choice algorithm to apply to hash value. */ + ovs_be16 algorithm; /* One of NX_BD_ALG_*. */ + + /* What fields to hash and how. */ + ovs_be16 fields; /* One of NX_BD_FIELDS_*. */ + ovs_be16 basis; /* Universal hash parameter. */ + + ovs_be32 slave_type; /* NXM_OF_IN_PORT. */ + ovs_be16 n_slaves; /* Number of slaves. */ + + ovs_be16 ofs_nbits; /* (ofs << 6) | (n_bits - 1). */ + ovs_be32 dst; /* Destination. */ + + uint8_t zero[4]; /* Reserved. Must be zero. */ +}; +OFP_ASSERT(sizeof(struct nx_action_bundle) == 32); + +/* NXAST_BUNDLE: Bundle slave choice algorithm to apply. + * + * In the descriptions below, 'slaves' is the list of possible slaves in the + * order they appear in the OpenFlow action. */ +enum nx_bd_algorithm { + /* Chooses the first live slave listed in the bundle. + * + * O(n_slaves) performance. */ + NX_BD_ALG_ACTIVE_BACKUP, + + /* for i in [0,n_slaves): + * weights[i] = hash(flow, i) + * slave = { slaves[i] such that weights[i] >= weights[j] for all j != i } + * + * Redistributes 1/n_slaves of traffic when a slave's liveness changes. + * O(n_slaves) performance. + * + * Uses the 'fields' and 'basis' parameters. */ + NX_BD_ALG_HRW /* Highest Random Weight. */ +}; /* Flexible flow specifications (aka NXM = Nicira Extended Match). * @@ -669,8 +980,12 @@ OFP_ASSERT(sizeof(struct nx_action_reg_load) == 24); * * Format: 48-bit Ethernet MAC address. * - * Masking: Not maskable. */ + * Masking: The nxm_mask patterns 01:00:00:00:00:00 and FE:FF:FF:FF:FF:FF must + * be supported for NXM_OF_ETH_DST_W (as well as the trivial patterns that + * are all-0-bits or all-1-bits). Support for other patterns and for masking + * of NXM_OF_ETH_SRC is optional. */ #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) /* Packet's Ethernet type. @@ -722,15 +1037,21 @@ OFP_ASSERT(sizeof(struct nx_action_reg_load) == 24); * - 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) /* 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. * @@ -739,7 +1060,7 @@ OFP_ASSERT(sizeof(struct nx_action_reg_load) == 24); /* 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. * @@ -762,7 +1083,7 @@ OFP_ASSERT(sizeof(struct nx_action_reg_load) == 24); /* 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. @@ -774,7 +1095,7 @@ OFP_ASSERT(sizeof(struct nx_action_reg_load) == 24); /* 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. @@ -841,7 +1162,8 @@ OFP_ASSERT(sizeof(struct nx_action_reg_load) == 24); #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) @@ -865,14 +1187,87 @@ OFP_ASSERT(sizeof(struct nx_action_reg_load) == 24); #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 { +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. */ }; @@ -969,8 +1364,8 @@ struct nx_flow_stats { 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 @@ -1002,14 +1397,13 @@ struct nx_aggregate_stats_request { 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);