};
OFP_ASSERT(sizeof(struct nx_flow_monitor_cancel) == 4);
-/* Geneve option table maintenance commands.
- *
- * In order to work with Geneve options, we need to maintain a mapping
- * table between an option (defined by <class, type, length>) and
- * an NXM field that can be operated on for the purposes of matches,
- * actions, etc. This mapping must be explicitly specified by the
- * user.
+/* Variable-length option TLV table maintenance commands.
+ *
+ * The option in Type-Length-Value format is widely used in tunnel options,
+ * e.g., the base Geneve header is followed by zero or more options in TLV
+ * format. Each option consists of a four byte option header and a variable
+ * amount of option data interpreted according to the type. The generic TLV
+ * format in tunnel options is as following:
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Option Class | Type |R|R|R| Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Variable Option Data |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * In order to work with this variable-length options in TLV format in
+ * tunnel options, we need to maintain a mapping table between an option
+ * TLV (defined by <class, type, length>) and an NXM field that can be
+ * operated on for the purposes of matches, actions, etc. This mapping
+ * must be explicitly specified by the user.
*
* There are two primary groups of OpenFlow messages that are introduced
* as Nicira extensions: modification commands (add, delete, clear mappings)
* Note that mappings should not be changed while they are in active use by
* a flow. The result of doing so is undefined. */
-/* Geneve table commands */
-enum nx_geneve_table_mod_command {
- NXGTMC_ADD, /* New mappings (fails if an option is already
+/* TLV table commands */
+enum nx_tlv_table_mod_command {
+ NXTTMC_ADD, /* New mappings (fails if an option is already
mapped). */
- NXGTMC_DELETE, /* Delete mappings, identified by index
+ NXTTMC_DELETE, /* Delete mappings, identified by index
* (unmapped options are ignored). */
- NXGTMC_CLEAR, /* Clear all mappings. Additional information
+ NXTTMC_CLEAR, /* Clear all mappings. Additional information
in this command is ignored. */
};
-/* Map between a Geneve option and an NXM field. */
-struct nx_geneve_map {
- ovs_be16 option_class; /* Geneve option class. */
- uint8_t option_type; /* Geneve option type. */
- uint8_t option_len; /* Geneve option length (multiple of 4). */
+/* Map between an option TLV and an NXM field. */
+struct nx_tlv_map {
+ ovs_be16 option_class; /* TLV class. */
+ uint8_t option_type; /* TLV type. */
+ uint8_t option_len; /* TLV length (multiple of 4). */
ovs_be16 index; /* NXM_NX_TUN_METADATA<n> index */
uint8_t pad[2];
};
-OFP_ASSERT(sizeof(struct nx_geneve_map) == 8);
+OFP_ASSERT(sizeof(struct nx_tlv_map) == 8);
-/* NXT_GENEVE_TABLE_MOD.
+/* NXT_TLV_TABLE_MOD.
*
- * Use to configure a mapping between Geneve options (class, type, length)
+ * Use to configure a mapping between option TLVs (class, type, length)
* and NXM fields (NXM_NX_TUN_METADATA<n> where 'index' is <n>).
*
* This command is atomic: all operations on different options will
* either succeed or fail. */
-struct nx_geneve_table_mod {
- ovs_be16 command; /* One of NTGTMC_* */
+struct nx_tlv_table_mod {
+ ovs_be16 command; /* One of NTTTMC_* */
uint8_t pad[6];
- /* struct nx_geneve_map[0]; Array of maps between indicies and Geneve
- options. The number of elements is
- inferred from the length field in the
- header. */
+ /* struct nx_tlv_map[0]; Array of maps between indicies and option
+ TLVs. The number of elements is inferred
+ from the length field in the header. */
};
-OFP_ASSERT(sizeof(struct nx_geneve_table_mod) == 8);
+OFP_ASSERT(sizeof(struct nx_tlv_table_mod) == 8);
-/* NXT_GENEVE_TABLE_REPLY.
+/* NXT_TLV_TABLE_REPLY.
*
- * Issued in reponse to an NXT_GENEVE_TABLE_REQUEST to give information
- * about the current status of the Geneve table in the switch. Provides
+ * Issued in reponse to an NXT_TLV_TABLE_REQUEST to give information
+ * about the current status of the TLV table in the switch. Provides
* both static information about the switch's capabilities as well as
- * the configured Geneve option table. */
-struct nx_geneve_table_reply {
+ * the configured TLV table. */
+struct nx_tlv_table_reply {
ovs_be32 max_option_space; /* Maximum total of option sizes supported. */
ovs_be16 max_fields; /* Maximum number of match fields supported. */
uint8_t reserved[10];
- /* struct nx_geneve_map[0]; Array of maps between indicies and Geneve
- options. The number of elements is
- inferred from the length field in the
- header. */
+ /* struct nx_tlv_map[0]; Array of maps between indicies and option
+ TLVs. The number of elements is inferred
+ from the length field in the header. */
};
-OFP_ASSERT(sizeof(struct nx_geneve_table_reply) == 16);
+OFP_ASSERT(sizeof(struct nx_tlv_table_reply) == 16);
#endif /* openflow/nicira-ext.h */
/* Translate tunnel metadata masks to datapath format. */
if (wc) {
if (wc->masks.tunnel.metadata.present.map) {
- struct geneve_opt opts[GENEVE_TOT_OPT_SIZE /
+ struct geneve_opt opts[TLV_TOT_OPT_SIZE /
sizeof(struct geneve_opt)];
tun_metadata_to_geneve_udpif_mask(&flow->tunnel,
#include "openvswitch/types.h"
-#define GENEVE_MAX_OPT_SIZE 124
-#define GENEVE_TOT_OPT_SIZE 252
+#define TLV_MAX_OPT_SIZE 124
+#define TLV_TOT_OPT_SIZE 252
#define GENEVE_CRIT_OPT_TYPE (1 << 7)
case OFPTYPE_TABLE_DESC_REPLY:
case OFPTYPE_BUNDLE_CONTROL:
case OFPTYPE_BUNDLE_ADD_MESSAGE:
- case OFPTYPE_NXT_GENEVE_TABLE_MOD:
- case OFPTYPE_NXT_GENEVE_TABLE_REQUEST:
- case OFPTYPE_NXT_GENEVE_TABLE_REPLY:
+ case OFPTYPE_NXT_TLV_TABLE_MOD:
+ case OFPTYPE_NXT_TLV_TABLE_REQUEST:
+ case OFPTYPE_NXT_TLV_TABLE_REPLY:
default:
if (VLOG_IS_DBG_ENABLED()) {
char *s = ofp_to_string(msg->data, msg->size, 2);
uint8_t u8;
};
BUILD_ASSERT_DECL(sizeof(union mf_value) == 128);
-BUILD_ASSERT_DECL(sizeof(union mf_value) >= GENEVE_MAX_OPT_SIZE);
+BUILD_ASSERT_DECL(sizeof(union mf_value) >= TLV_MAX_OPT_SIZE);
/* A const mf_value with all bits initialized to ones. */
extern const union mf_value exact_match_mask;
OFPERR_OFPMOFC_BAD_OUT,
/* ## ----------------------------- ## */
-/* ## OFPET_GENEVE_TABLE_MOD_FAILED ## */
+/* ## OFPET_TLV_TABLE_MOD_FAILED ## */
/* ## ----------------------------- ## */
- /* NX1.0-1.1(1,527), NX1.2+(16). The Geneve table mod command is not
+ /* NX1.0-1.1(1,527), NX1.2+(16). The TLV table mod command is not
* recognized as a valid operation. */
- OFPERR_NXGTMFC_BAD_COMMAND,
+ OFPERR_NXTTMFC_BAD_COMMAND,
/* NX1.0-1.1(1,528), NX1.2+(17). The option length is not a valid
- * option size for Geneve. */
- OFPERR_NXGTMFC_BAD_OPT_LEN,
+ * option size for TLVs. */
+ OFPERR_NXTTMFC_BAD_OPT_LEN,
/* NX1.0-1.1(1,529), NX1.2+(18). The field index is out of range for
* the supported NX_TUN_METADATA<n> match. */
- OFPERR_NXGTMFC_BAD_FIELD_IDX,
+ OFPERR_NXTTMFC_BAD_FIELD_IDX,
/* NX1.0-1.1(1,530), NX1.2+(19). The total set of configured options
* exceeds the maximum supported by the switch. */
- OFPERR_NXGTMFC_TABLE_FULL,
+ OFPERR_NXTTMFC_TABLE_FULL,
- /* NX1.0-1.1(1,531), NX1.2+(20). The controller issued an NXGTMC_ADD
+ /* NX1.0-1.1(1,531), NX1.2+(20). The controller issued an NXTTMC_ADD
* command for a field index that is already mapped. */
- OFPERR_NXGTMFC_ALREADY_MAPPED,
+ OFPERR_NXTTMFC_ALREADY_MAPPED,
- /* NX1.0-1.1(1,532), NX1.2+(21). The Geneve option that is attempting
+ /* NX1.0-1.1(1,532), NX1.2+(21). The option TLV that is attempting
* to be mapped is the same as one assigned to a different field. */
- OFPERR_NXGTMFC_DUP_ENTRY,
+ OFPERR_NXTTMFC_DUP_ENTRY,
/* ## ------------------ ## */
/* ## OFPET_EXPERIMENTER ## */
/* NXT 1.0+ (23): void. */
OFPRAW_NXT_FLOW_MONITOR_RESUMED,
- /* NXT 1.0+ (24): struct nx_geneve_table_mod, struct nx_geneve_map[]. */
- OFPRAW_NXT_GENEVE_TABLE_MOD,
+ /* NXT 1.0+ (24): struct nx_tlv_table_mod, struct nx_tlv_map[]. */
+ OFPRAW_NXT_TLV_TABLE_MOD,
/* NXT 1.0+ (25): void. */
- OFPRAW_NXT_GENEVE_TABLE_REQUEST,
+ OFPRAW_NXT_TLV_TABLE_REQUEST,
- /* NXT 1.0+ (26): struct nx_geneve_table_reply, struct nx_geneve_map[]. */
- OFPRAW_NXT_GENEVE_TABLE_REPLY,
+ /* NXT 1.0+ (26): struct nx_tlv_table_reply, struct nx_tlv_map[]. */
+ OFPRAW_NXT_TLV_TABLE_REPLY,
};
/* Decoding messages into OFPRAW_* values. */
OFPTYPE_SET_PACKET_IN_FORMAT, /* OFPRAW_NXT_SET_PACKET_IN_FORMAT. */
OFPTYPE_FLOW_AGE, /* OFPRAW_NXT_FLOW_AGE. */
OFPTYPE_SET_CONTROLLER_ID, /* OFPRAW_NXT_SET_CONTROLLER_ID. */
- OFPTYPE_NXT_GENEVE_TABLE_MOD, /* OFPRAW_NXT_GENEVE_TABLE_MOD. */
- OFPTYPE_NXT_GENEVE_TABLE_REQUEST, /* OFPRAW_NXT_GENEVE_TABLE_REQUEST. */
- OFPTYPE_NXT_GENEVE_TABLE_REPLY, /* OFPRAW_NXT_GENEVE_TABLE_REPLY. */
+ OFPTYPE_NXT_TLV_TABLE_MOD, /* OFPRAW_NXT_TLV_TABLE_MOD. */
+ OFPTYPE_NXT_TLV_TABLE_REQUEST, /* OFPRAW_NXT_TLV_TABLE_REQUEST. */
+ OFPTYPE_NXT_TLV_TABLE_REPLY, /* OFPRAW_NXT_TLV_TABLE_REPLY. */
/* Flow monitor extension. */
OFPTYPE_FLOW_MONITOR_CANCEL, /* OFPRAW_NXT_FLOW_MONITOR_CANCEL. */
}
char * OVS_WARN_UNUSED_RESULT
-parse_ofp_geneve_table_mod_str(struct ofputil_geneve_table_mod *gtm,
+parse_ofp_tlv_table_mod_str(struct ofputil_tlv_table_mod *ttm,
uint16_t command, const char *s,
enum ofputil_protocol *usable_protocols)
{
*usable_protocols = OFPUTIL_P_NXM_OXM_ANY;
- gtm->command = command;
- list_init(>m->mappings);
+ ttm->command = command;
+ list_init(&ttm->mappings);
while (*s) {
- struct ofputil_geneve_map *map = xmalloc(sizeof *map);
+ struct ofputil_tlv_map *map = xmalloc(sizeof *map);
int n;
if (*s == ',') {
s++;
}
- list_push_back(>m->mappings, &map->list_node);
+ list_push_back(&ttm->mappings, &map->list_node);
if (!ovs_scan(s, "{class=%"SCNi16",type=%"SCNi8",len=%"SCNi8"}->tun_metadata%"SCNi16"%n",
&map->option_class, &map->option_type, &map->option_len,
&map->index, &n)) {
- ofputil_uninit_geneve_table(>m->mappings);
- return xstrdup("invalid geneve mapping");
+ ofputil_uninit_tlv_table(&ttm->mappings);
+ return xstrdup("invalid tlv mapping");
}
s += n;
struct ofputil_group_mod;
struct ofputil_meter_mod;
struct ofputil_table_mod;
-struct ofputil_geneve_table_mod;
+struct ofputil_tlv_table_mod;
struct simap;
enum ofputil_protocol;
enum ofputil_protocol *usable_protocols)
OVS_WARN_UNUSED_RESULT;
-char *parse_ofp_geneve_table_mod_str(struct ofputil_geneve_table_mod *,
+char *parse_ofp_tlv_table_mod_str(struct ofputil_tlv_table_mod *,
uint16_t command, const char *string,
enum ofputil_protocol *usable_protocols)
OVS_WARN_UNUSED_RESULT;
}
static void
-print_geneve_table(struct ds *s, struct ovs_list *mappings)
+print_tlv_table(struct ds *s, struct ovs_list *mappings)
{
- struct ofputil_geneve_map *map;
+ struct ofputil_tlv_map *map;
ds_put_cstr(s, " mapping table:\n");
ds_put_cstr(s, " class\ttype\tlength\tmatch field\n");
}
static void
-ofp_print_geneve_table_mod(struct ds *s, const struct ofp_header *oh)
+ofp_print_tlv_table_mod(struct ds *s, const struct ofp_header *oh)
{
int error;
- struct ofputil_geneve_table_mod gtm;
+ struct ofputil_tlv_table_mod ttm;
- error = ofputil_decode_geneve_table_mod(oh, >m);
+ error = ofputil_decode_tlv_table_mod(oh, &ttm);
if (error) {
ofp_print_error(s, error);
return;
ds_put_cstr(s, "\n ");
- switch (gtm.command) {
- case NXGTMC_ADD:
+ switch (ttm.command) {
+ case NXTTMC_ADD:
ds_put_cstr(s, "ADD");
break;
- case NXGTMC_DELETE:
+ case NXTTMC_DELETE:
ds_put_cstr(s, "DEL");
break;
- case NXGTMC_CLEAR:
+ case NXTTMC_CLEAR:
ds_put_cstr(s, "CLEAR");
break;
}
- if (gtm.command != NXGTMC_CLEAR) {
- print_geneve_table(s, >m.mappings);
+ if (ttm.command != NXTTMC_CLEAR) {
+ print_tlv_table(s, &ttm.mappings);
}
- ofputil_uninit_geneve_table(>m.mappings);
+ ofputil_uninit_tlv_table(&ttm.mappings);
}
static void
-ofp_print_geneve_table_reply(struct ds *s, const struct ofp_header *oh)
+ofp_print_tlv_table_reply(struct ds *s, const struct ofp_header *oh)
{
int error;
- struct ofputil_geneve_table_reply gtr;
- struct ofputil_geneve_map *map;
+ struct ofputil_tlv_table_reply ttr;
+ struct ofputil_tlv_map *map;
int allocated_space = 0;
- error = ofputil_decode_geneve_table_reply(oh, >r);
+ error = ofputil_decode_tlv_table_reply(oh, &ttr);
if (error) {
ofp_print_error(s, error);
return;
ds_put_char(s, '\n');
- LIST_FOR_EACH (map, list_node, >r.mappings) {
+ LIST_FOR_EACH (map, list_node, &ttr.mappings) {
allocated_space += map->option_len;
}
ds_put_format(s, " max option space=%"PRIu32" max fields=%"PRIu16"\n",
- gtr.max_option_space, gtr.max_fields);
+ ttr.max_option_space, ttr.max_fields);
ds_put_format(s, " allocated option space=%d\n", allocated_space);
ds_put_char(s, '\n');
- print_geneve_table(s, >r.mappings);
+ print_tlv_table(s, &ttr.mappings);
- ofputil_uninit_geneve_table(>r.mappings);
+ ofputil_uninit_tlv_table(&ttr.mappings);
}
/* This function will print the request forward message. The reason for
ofp_print_bundle_add(string, msg, verbosity);
break;
- case OFPTYPE_NXT_GENEVE_TABLE_MOD:
- ofp_print_geneve_table_mod(string, msg);
+ case OFPTYPE_NXT_TLV_TABLE_MOD:
+ ofp_print_tlv_table_mod(string, msg);
break;
- case OFPTYPE_NXT_GENEVE_TABLE_REQUEST:
+ case OFPTYPE_NXT_TLV_TABLE_REQUEST:
break;
- case OFPTYPE_NXT_GENEVE_TABLE_REPLY:
- ofp_print_geneve_table_reply(string, msg);
+ case OFPTYPE_NXT_TLV_TABLE_REPLY:
+ ofp_print_tlv_table_reply(string, msg);
break;
}
case OFPTYPE_TABLE_MOD:
case OFPTYPE_METER_MOD:
case OFPTYPE_PACKET_OUT:
- case OFPTYPE_NXT_GENEVE_TABLE_MOD:
+ case OFPTYPE_NXT_TLV_TABLE_MOD:
/* Not to be bundlable. */
case OFPTYPE_ECHO_REQUEST:
case OFPTYPE_TABLE_DESC_REPLY:
case OFPTYPE_ROLE_STATUS:
case OFPTYPE_REQUESTFORWARD:
- case OFPTYPE_NXT_GENEVE_TABLE_REQUEST:
- case OFPTYPE_NXT_GENEVE_TABLE_REPLY:
+ case OFPTYPE_NXT_TLV_TABLE_REQUEST:
+ case OFPTYPE_NXT_TLV_TABLE_REPLY:
break;
}
}
static void
-encode_geneve_table_mappings(struct ofpbuf *b, struct ovs_list *mappings)
+encode_tlv_table_mappings(struct ofpbuf *b, struct ovs_list *mappings)
{
- struct ofputil_geneve_map *map;
+ struct ofputil_tlv_map *map;
LIST_FOR_EACH (map, list_node, mappings) {
- struct nx_geneve_map *nx_map;
+ struct nx_tlv_map *nx_map;
nx_map = ofpbuf_put_zeros(b, sizeof *nx_map);
nx_map->option_class = htons(map->option_class);
}
struct ofpbuf *
-ofputil_encode_geneve_table_mod(enum ofp_version ofp_version,
- struct ofputil_geneve_table_mod *gtm)
+ofputil_encode_tlv_table_mod(enum ofp_version ofp_version,
+ struct ofputil_tlv_table_mod *ttm)
{
struct ofpbuf *b;
- struct nx_geneve_table_mod *nx_gtm;
+ struct nx_tlv_table_mod *nx_ttm;
- b = ofpraw_alloc(OFPRAW_NXT_GENEVE_TABLE_MOD, ofp_version, 0);
- nx_gtm = ofpbuf_put_zeros(b, sizeof *nx_gtm);
- nx_gtm->command = htons(gtm->command);
- encode_geneve_table_mappings(b, >m->mappings);
+ b = ofpraw_alloc(OFPRAW_NXT_TLV_TABLE_MOD, ofp_version, 0);
+ nx_ttm = ofpbuf_put_zeros(b, sizeof *nx_ttm);
+ nx_ttm->command = htons(ttm->command);
+ encode_tlv_table_mappings(b, &ttm->mappings);
return b;
}
static enum ofperr
-decode_geneve_table_mappings(struct ofpbuf *msg, unsigned int max_fields,
+decode_tlv_table_mappings(struct ofpbuf *msg, unsigned int max_fields,
struct ovs_list *mappings)
{
list_init(mappings);
while (msg->size) {
- struct nx_geneve_map *nx_map;
- struct ofputil_geneve_map *map;
+ struct nx_tlv_map *nx_map;
+ struct ofputil_tlv_map *map;
nx_map = ofpbuf_pull(msg, sizeof *nx_map);
map = xmalloc(sizeof *map);
map->option_type = nx_map->option_type;
map->option_len = nx_map->option_len;
- if (map->option_len % 4 || map->option_len > GENEVE_MAX_OPT_SIZE) {
+ if (map->option_len % 4 || map->option_len > TLV_MAX_OPT_SIZE) {
VLOG_WARN_RL(&bad_ofmsg_rl,
- "geneve table option length (%u) is not a valid option size",
+ "tlv table option length (%u) is not a valid option size",
map->option_len);
- ofputil_uninit_geneve_table(mappings);
- return OFPERR_NXGTMFC_BAD_OPT_LEN;
+ ofputil_uninit_tlv_table(mappings);
+ return OFPERR_NXTTMFC_BAD_OPT_LEN;
}
map->index = ntohs(nx_map->index);
if (map->index >= max_fields) {
VLOG_WARN_RL(&bad_ofmsg_rl,
- "geneve table field index (%u) is too large (max %u)",
+ "tlv table field index (%u) is too large (max %u)",
map->index, max_fields - 1);
- ofputil_uninit_geneve_table(mappings);
- return OFPERR_NXGTMFC_BAD_FIELD_IDX;
+ ofputil_uninit_tlv_table(mappings);
+ return OFPERR_NXTTMFC_BAD_FIELD_IDX;
}
}
}
enum ofperr
-ofputil_decode_geneve_table_mod(const struct ofp_header *oh,
- struct ofputil_geneve_table_mod *gtm)
+ofputil_decode_tlv_table_mod(const struct ofp_header *oh,
+ struct ofputil_tlv_table_mod *ttm)
{
struct ofpbuf msg;
- struct nx_geneve_table_mod *nx_gtm;
+ struct nx_tlv_table_mod *nx_ttm;
ofpbuf_use_const(&msg, oh, ntohs(oh->length));
ofpraw_pull_assert(&msg);
- nx_gtm = ofpbuf_pull(&msg, sizeof *nx_gtm);
- gtm->command = ntohs(nx_gtm->command);
- if (gtm->command > NXGTMC_CLEAR) {
+ nx_ttm = ofpbuf_pull(&msg, sizeof *nx_ttm);
+ ttm->command = ntohs(nx_ttm->command);
+ if (ttm->command > NXTTMC_CLEAR) {
VLOG_WARN_RL(&bad_ofmsg_rl,
- "geneve table mod command (%u) is out of range",
- gtm->command);
- return OFPERR_NXGTMFC_BAD_COMMAND;
+ "tlv table mod command (%u) is out of range",
+ ttm->command);
+ return OFPERR_NXTTMFC_BAD_COMMAND;
}
- return decode_geneve_table_mappings(&msg, TUN_METADATA_NUM_OPTS,
- >m->mappings);
+ return decode_tlv_table_mappings(&msg, TUN_METADATA_NUM_OPTS,
+ &ttm->mappings);
}
struct ofpbuf *
-ofputil_encode_geneve_table_reply(const struct ofp_header *oh,
- struct ofputil_geneve_table_reply *gtr)
+ofputil_encode_tlv_table_reply(const struct ofp_header *oh,
+ struct ofputil_tlv_table_reply *ttr)
{
struct ofpbuf *b;
- struct nx_geneve_table_reply *nx_gtr;
+ struct nx_tlv_table_reply *nx_ttr;
- b = ofpraw_alloc_reply(OFPRAW_NXT_GENEVE_TABLE_REPLY, oh, 0);
- nx_gtr = ofpbuf_put_zeros(b, sizeof *nx_gtr);
- nx_gtr->max_option_space = htonl(gtr->max_option_space);
- nx_gtr->max_fields = htons(gtr->max_fields);
+ b = ofpraw_alloc_reply(OFPRAW_NXT_TLV_TABLE_REPLY, oh, 0);
+ nx_ttr = ofpbuf_put_zeros(b, sizeof *nx_ttr);
+ nx_ttr->max_option_space = htonl(ttr->max_option_space);
+ nx_ttr->max_fields = htons(ttr->max_fields);
- encode_geneve_table_mappings(b, >r->mappings);
+ encode_tlv_table_mappings(b, &ttr->mappings);
return b;
}
-/* Decodes the NXT_GENEVE_TABLE_REPLY message in 'oh' into '*gtr'. Returns 0
+/* Decodes the NXT_TLV_TABLE_REPLY message in 'oh' into '*ttr'. Returns 0
* if successful, otherwise an ofperr.
*
- * The decoder verifies that the indexes in 'gtr->mappings' are less than
- * 'gtr->max_fields', but the caller must ensure, if necessary, that they are
+ * The decoder verifies that the indexes in 'ttr->mappings' are less than
+ * 'ttr->max_fields', but the caller must ensure, if necessary, that they are
* less than TUN_METADATA_NUM_OPTS. */
enum ofperr
-ofputil_decode_geneve_table_reply(const struct ofp_header *oh,
- struct ofputil_geneve_table_reply *gtr)
+ofputil_decode_tlv_table_reply(const struct ofp_header *oh,
+ struct ofputil_tlv_table_reply *ttr)
{
struct ofpbuf msg;
- struct nx_geneve_table_reply *nx_gtr;
+ struct nx_tlv_table_reply *nx_ttr;
ofpbuf_use_const(&msg, oh, ntohs(oh->length));
ofpraw_pull_assert(&msg);
- nx_gtr = ofpbuf_pull(&msg, sizeof *nx_gtr);
- gtr->max_option_space = ntohl(nx_gtr->max_option_space);
- gtr->max_fields = ntohs(nx_gtr->max_fields);
+ nx_ttr = ofpbuf_pull(&msg, sizeof *nx_ttr);
+ ttr->max_option_space = ntohl(nx_ttr->max_option_space);
+ ttr->max_fields = ntohs(nx_ttr->max_fields);
- return decode_geneve_table_mappings(&msg, gtr->max_fields, >r->mappings);
+ return decode_tlv_table_mappings(&msg, ttr->max_fields, &ttr->mappings);
}
void
-ofputil_uninit_geneve_table(struct ovs_list *mappings)
+ofputil_uninit_tlv_table(struct ovs_list *mappings)
{
- struct ofputil_geneve_map *map;
+ struct ofputil_tlv_map *map;
LIST_FOR_EACH_POP (map, list_node, mappings) {
free(map);
struct ofputil_bundle_add_msg *,
enum ofptype *type);
-struct ofputil_geneve_map {
+struct ofputil_tlv_map {
struct ovs_list list_node;
uint16_t option_class;
uint16_t index;
};
-struct ofputil_geneve_table_mod {
+struct ofputil_tlv_table_mod {
uint16_t command;
- struct ovs_list mappings; /* Contains "struct ofputil_geneve_map"s. */
+ struct ovs_list mappings; /* Contains "struct ofputil_tlv_map"s. */
};
-struct ofputil_geneve_table_reply {
+struct ofputil_tlv_table_reply {
uint32_t max_option_space;
uint16_t max_fields;
- struct ovs_list mappings; /* Contains "struct ofputil_geneve_map"s. */
+ struct ovs_list mappings; /* Contains "struct ofputil_tlv_map"s. */
};
-struct ofpbuf *ofputil_encode_geneve_table_mod(enum ofp_version ofp_version,
- struct ofputil_geneve_table_mod *);
-enum ofperr ofputil_decode_geneve_table_mod(const struct ofp_header *,
- struct ofputil_geneve_table_mod *);
-struct ofpbuf *ofputil_encode_geneve_table_reply(const struct ofp_header *,
- struct ofputil_geneve_table_reply *);
-enum ofperr ofputil_decode_geneve_table_reply(const struct ofp_header *,
- struct ofputil_geneve_table_reply *);
-void ofputil_uninit_geneve_table(struct ovs_list *mappings);
+struct ofpbuf *ofputil_encode_tlv_table_mod(enum ofp_version ofp_version,
+ struct ofputil_tlv_table_mod *);
+enum ofperr ofputil_decode_tlv_table_mod(const struct ofp_header *,
+ struct ofputil_tlv_table_mod *);
+struct ofpbuf *ofputil_encode_tlv_table_reply(const struct ofp_header *,
+ struct ofputil_tlv_table_reply *);
+enum ofperr ofputil_decode_tlv_table_reply(const struct ofp_header *,
+ struct ofputil_tlv_table_reply *);
+void ofputil_uninit_tlv_table(struct ovs_list *mappings);
enum ofputil_async_msg_type {
OAM_PACKET_IN, /* OFPT_PACKET_IN or NXT_PACKET_IN. */
case OFPTYPE_FLOW_MONITOR_RESUMED:
case OFPTYPE_BUNDLE_CONTROL:
case OFPTYPE_BUNDLE_ADD_MESSAGE:
- case OFPTYPE_NXT_GENEVE_TABLE_MOD:
- case OFPTYPE_NXT_GENEVE_TABLE_REQUEST:
- case OFPTYPE_NXT_GENEVE_TABLE_REPLY:
+ case OFPTYPE_NXT_TLV_TABLE_MOD:
+ case OFPTYPE_NXT_TLV_TABLE_REQUEST:
+ case OFPTYPE_NXT_TLV_TABLE_REPLY:
default:
return true;
}
bool valid; /* True if allocated to a class and type. */
};
-/* Maps from Geneve option class+type to positions in a struct tun_metadata's
+/* Maps from TLV option class+type to positions in a struct tun_metadata's
* 'opts' array. */
struct tun_table {
/* TUN_METADATA<i> is stored in element <i>. */
}
enum ofperr
-tun_metadata_table_mod(struct ofputil_geneve_table_mod *gtm)
+tun_metadata_table_mod(struct ofputil_tlv_table_mod *ttm)
{
struct tun_table *old_map, *new_map;
- struct ofputil_geneve_map *ofp_map;
+ struct ofputil_tlv_map *ofp_map;
enum ofperr err = 0;
ovs_mutex_lock(&tab_mutex);
old_map = ovsrcu_get_protected(struct tun_table *, &metadata_tab);
- switch (gtm->command) {
- case NXGTMC_ADD:
+ switch (ttm->command) {
+ case NXTTMC_ADD:
new_map = table_alloc(old_map);
- LIST_FOR_EACH (ofp_map, list_node, >m->mappings) {
+ LIST_FOR_EACH (ofp_map, list_node, &ttm->mappings) {
err = tun_metadata_add_entry(new_map, ofp_map->index,
ofp_map->option_class,
ofp_map->option_type,
}
break;
- case NXGTMC_DELETE:
+ case NXTTMC_DELETE:
new_map = table_alloc(old_map);
- LIST_FOR_EACH (ofp_map, list_node, >m->mappings) {
+ LIST_FOR_EACH (ofp_map, list_node, &ttm->mappings) {
tun_metadata_del_entry(new_map, ofp_map->index);
}
break;
- case NXGTMC_CLEAR:
+ case NXTTMC_CLEAR:
new_map = table_alloc(NULL);
break;
}
void
-tun_metadata_table_request(struct ofputil_geneve_table_reply *gtr)
+tun_metadata_table_request(struct ofputil_tlv_table_reply *ttr)
{
struct tun_table *map = ovsrcu_get(struct tun_table *, &metadata_tab);
int i;
- gtr->max_option_space = TUN_METADATA_TOT_OPT_SIZE;
- gtr->max_fields = TUN_METADATA_NUM_OPTS;
- list_init(>r->mappings);
+ ttr->max_option_space = TUN_METADATA_TOT_OPT_SIZE;
+ ttr->max_fields = TUN_METADATA_NUM_OPTS;
+ list_init(&ttr->mappings);
for (i = 0; i < TUN_METADATA_NUM_OPTS; i++) {
struct tun_meta_entry *entry = &map->entries[i];
- struct ofputil_geneve_map *map;
+ struct ofputil_tlv_map *map;
if (!entry->valid) {
continue;
map->option_len = entry->loc.len;
map->index = i;
- list_push_back(>r->mappings, &map->list_node);
+ list_push_back(&ttr->mappings, &map->list_node);
}
}
entry = &map->entries[idx];
if (entry->valid) {
- return OFPERR_NXGTMFC_ALREADY_MAPPED;
+ return OFPERR_NXTTMFC_ALREADY_MAPPED;
}
entry->key = tun_meta_key(htons(opt_class), type);
if (tun_meta_find_key(&map->key_hmap, entry->key)) {
- return OFPERR_NXGTMFC_DUP_ENTRY;
+ return OFPERR_NXTTMFC_DUP_ENTRY;
}
entry->valid = true;
err = tun_metadata_alloc_chain(map, len, cur_chain);
if (err) {
tun_metadata_del_entry(map, idx);
- return OFPERR_NXGTMFC_TABLE_FULL;
+ return OFPERR_NXTTMFC_TABLE_FULL;
}
len -= cur_chain->len;
ovs_assert(!(flow->flags & FLOW_TNL_F_UDPIF));
- ofpbuf_use_stack(&b, opts, GENEVE_TOT_OPT_SIZE);
+ ofpbuf_use_stack(&b, opts, TLV_TOT_OPT_SIZE);
tun_metadata_to_geneve__(&flow->metadata, &b, crit_opt);
return b.size;
struct match;
struct mf_field;
union mf_value;
-struct ofputil_geneve_table_mod;
-struct ofputil_geneve_table_reply;
+struct ofputil_tlv_table_mod;
+struct ofputil_tlv_table_reply;
struct tun_table;
#define TUN_METADATA_NUM_OPTS 64
union {
uint8_t u8[TUN_METADATA_TOT_OPT_SIZE]; /* Values from tunnel TLVs. */
- struct geneve_opt gnv[GENEVE_TOT_OPT_SIZE / sizeof(struct geneve_opt)];
+ struct geneve_opt gnv[TLV_TOT_OPT_SIZE / sizeof(struct geneve_opt)];
} opts;
};
BUILD_ASSERT_DECL(offsetof(struct tun_metadata, opts) % 8 == 0);
void tun_metadata_init(void);
-enum ofperr tun_metadata_table_mod(struct ofputil_geneve_table_mod *);
-void tun_metadata_table_request(struct ofputil_geneve_table_reply *);
+enum ofperr tun_metadata_table_mod(struct ofputil_tlv_table_mod *);
+void tun_metadata_table_request(struct ofputil_tlv_table_reply *);
void tun_metadata_read(const struct flow_tnl *,
const struct mf_field *, union mf_value *);
}
static enum ofperr
-handle_geneve_table_mod(struct ofconn *ofconn, const struct ofp_header *oh)
+handle_tlv_table_mod(struct ofconn *ofconn, const struct ofp_header *oh)
{
- struct ofputil_geneve_table_mod gtm;
+ struct ofputil_tlv_table_mod ttm;
enum ofperr error;
error = reject_slave_controller(ofconn);
return error;
}
- error = ofputil_decode_geneve_table_mod(oh, >m);
+ error = ofputil_decode_tlv_table_mod(oh, &ttm);
if (error) {
return error;
}
- error = tun_metadata_table_mod(>m);
+ error = tun_metadata_table_mod(&ttm);
- ofputil_uninit_geneve_table(>m.mappings);
+ ofputil_uninit_tlv_table(&ttm.mappings);
return error;
}
static enum ofperr
-handle_geneve_table_request(struct ofconn *ofconn, const struct ofp_header *oh)
+handle_tlv_table_request(struct ofconn *ofconn, const struct ofp_header *oh)
{
- struct ofputil_geneve_table_reply gtr;
+ struct ofputil_tlv_table_reply ttr;
struct ofpbuf *b;
- tun_metadata_table_request(>r);
- b = ofputil_encode_geneve_table_reply(oh, >r);
- ofputil_uninit_geneve_table(>r.mappings);
+ tun_metadata_table_request(&ttr);
+ b = ofputil_encode_tlv_table_reply(oh, &ttr);
+ ofputil_uninit_tlv_table(&ttr.mappings);
ofconn_send_reply(ofconn, b);
return 0;
case OFPTYPE_BUNDLE_ADD_MESSAGE:
return handle_bundle_add(ofconn, oh);
- case OFPTYPE_NXT_GENEVE_TABLE_MOD:
- return handle_geneve_table_mod(ofconn, oh);
+ case OFPTYPE_NXT_TLV_TABLE_MOD:
+ return handle_tlv_table_mod(ofconn, oh);
- case OFPTYPE_NXT_GENEVE_TABLE_REQUEST:
- return handle_geneve_table_request(ofconn, oh);
+ case OFPTYPE_NXT_TLV_TABLE_REQUEST:
+ return handle_tlv_table_request(ofconn, oh);
case OFPTYPE_HELLO:
case OFPTYPE_ERROR:
case OFPTYPE_TABLE_DESC_REPLY:
case OFPTYPE_ROLE_STATUS:
case OFPTYPE_REQUESTFORWARD:
- case OFPTYPE_NXT_GENEVE_TABLE_REPLY:
+ case OFPTYPE_NXT_TLV_TABLE_REPLY:
default:
if (ofpmsg_is_stat_request(oh)) {
return OFPERR_OFPBRC_BAD_STAT;
/* Connection state machine. */
#define STATES \
STATE(S_NEW) \
- STATE(S_GENEVE_TABLE_REQUESTED) \
- STATE(S_GENEVE_TABLE_MOD_SENT) \
+ STATE(S_TLV_TABLE_REQUESTED) \
+ STATE(S_TLV_TABLE_MOD_SENT) \
STATE(S_CLEAR_FLOWS) \
STATE(S_UPDATE_FLOWS)
enum ofctrl_state {
* installed in the switch. */
static struct hmap installed_flows;
-/* MFF_* field ID for our Geneve option. In S_GENEVE_TABLE_MOD_SENT, this is
+/* MFF_* field ID for our Geneve option. In S_TLV_TABLE_MOD_SENT, this is
* the option we requested (we don't know whether we obtained it yet). In
* S_CLEAR_FLOWS or S_UPDATE_FLOWS, this is really the option we have. */
static enum mf_field_id mff_ovn_geneve;
\f
/* S_NEW, for a new connection.
*
- * Sends NXT_GENEVE_TABLE_REQUEST and transitions to
- * S_GENEVE_TABLE_REQUESTED. */
+ * Sends NXT_TLV_TABLE_REQUEST and transitions to
+ * S_TLV_TABLE_REQUESTED. */
static void
run_S_NEW(void)
{
- struct ofpbuf *buf = ofpraw_alloc(OFPRAW_NXT_GENEVE_TABLE_REQUEST,
+ struct ofpbuf *buf = ofpraw_alloc(OFPRAW_NXT_TLV_TABLE_REQUEST,
rconn_get_version(swconn), 0);
xid = queue_msg(buf);
- state = S_GENEVE_TABLE_REQUESTED;
+ state = S_TLV_TABLE_REQUESTED;
}
static void
OVS_NOT_REACHED();
}
\f
-/* S_GENEVE_TABLE_REQUESTED, when NXT_GENEVE_TABLE_REQUEST has been sent
+/* S_TLV_TABLE_REQUESTED, when NXT_TLV_TABLE_REQUEST has been sent
* and we're waiting for a reply.
*
- * If we receive an NXT_GENEVE_TABLE_REPLY:
+ * If we receive an NXT_TLV_TABLE_REPLY:
*
* - If it contains our tunnel metadata option, assign its field ID to
* mff_ovn_geneve and transition to S_CLEAR_FLOWS.
*
* - Otherwise, if there is an unused tunnel metadata field ID, send
- * NXT_GENEVE_TABLE_MOD and OFPT_BARRIER_REQUEST, and transition to
- * S_GENEVE_TABLE_MOD_SENT.
+ * NXT_TLV_TABLE_MOD and OFPT_BARRIER_REQUEST, and transition to
+ * S_TLV_TABLE_MOD_SENT.
*
* - Otherwise, log an error, disable Geneve, and transition to
* S_CLEAR_FLOWS.
* - Log an error, disable Geneve, and transition to S_CLEAR_FLOWS. */
static void
-run_S_GENEVE_TABLE_REQUESTED(void)
+run_S_TLV_TABLE_REQUESTED(void)
{
}
static void
-recv_S_GENEVE_TABLE_REQUESTED(const struct ofp_header *oh, enum ofptype type)
+recv_S_TLV_TABLE_REQUESTED(const struct ofp_header *oh, enum ofptype type)
{
if (oh->xid != xid) {
ofctrl_recv(oh, type);
- } else if (type == OFPTYPE_NXT_GENEVE_TABLE_REPLY) {
- struct ofputil_geneve_table_reply reply;
- enum ofperr error = ofputil_decode_geneve_table_reply(oh, &reply);
+ } else if (type == OFPTYPE_NXT_TLV_TABLE_REPLY) {
+ struct ofputil_tlv_table_reply reply;
+ enum ofperr error = ofputil_decode_tlv_table_reply(oh, &reply);
if (error) {
- VLOG_ERR("failed to decode Geneve table request (%s)",
+ VLOG_ERR("failed to decode TLV table request (%s)",
ofperr_to_string(error));
goto error;
}
- const struct ofputil_geneve_map *map;
+ const struct ofputil_tlv_map *map;
uint64_t md_free = UINT64_MAX;
BUILD_ASSERT(TUN_METADATA_NUM_OPTS == 64);
unsigned int index = rightmost_1bit_idx(md_free);
mff_ovn_geneve = MFF_TUN_METADATA0 + index;
- struct ofputil_geneve_map gm;
- gm.option_class = OVN_GENEVE_CLASS;
- gm.option_type = OVN_GENEVE_TYPE;
- gm.option_len = OVN_GENEVE_LEN;
- gm.index = index;
-
- struct ofputil_geneve_table_mod gtm;
- gtm.command = NXGTMC_ADD;
- list_init(>m.mappings);
- list_push_back(>m.mappings, &gm.list_node);
-
- xid = queue_msg(ofputil_encode_geneve_table_mod(OFP13_VERSION, >m));
+ struct ofputil_tlv_map tm;
+ tm.option_class = OVN_GENEVE_CLASS;
+ tm.option_type = OVN_GENEVE_TYPE;
+ tm.option_len = OVN_GENEVE_LEN;
+ tm.index = index;
+
+ struct ofputil_tlv_table_mod ttm;
+ ttm.command = NXTTMC_ADD;
+ list_init(&ttm.mappings);
+ list_push_back(&ttm.mappings, &tm.list_node);
+
+ xid = queue_msg(ofputil_encode_tlv_table_mod(OFP13_VERSION, &ttm));
xid2 = queue_msg(ofputil_encode_barrier_request(OFP13_VERSION));
- state = S_GENEVE_TABLE_MOD_SENT;
+ state = S_TLV_TABLE_MOD_SENT;
} else if (type == OFPTYPE_ERROR) {
VLOG_ERR("switch refused to allocate Geneve option (%s)",
ofperr_to_string(ofperr_decode_msg(oh, NULL)));
goto error;
} else {
char *s = ofp_to_string(oh, ntohs(oh->length), 1);
- VLOG_ERR("unexpected reply to Geneve table request (%s)",
+ VLOG_ERR("unexpected reply to TLV table request (%s)",
s);
free(s);
goto error;
state = S_CLEAR_FLOWS;
}
\f
-/* S_GENEVE_TABLE_MOD_SENT, when NXT_GENEVE_TABLE_MOD and OFPT_BARRIER_REQUEST
+/* S_TLV_TABLE_MOD_SENT, when NXT_TLV_TABLE_MOD and OFPT_BARRIER_REQUEST
* have been sent and we're waiting for a reply to one or the other.
*
* If we receive an OFPT_ERROR:
*
- * - If the error is NXGTMFC_ALREADY_MAPPED or NXGTMFC_DUP_ENTRY, we
+ * - If the error is NXTTMFC_ALREADY_MAPPED or NXTTMFC_DUP_ENTRY, we
* raced with some other controller. Transition to S_NEW.
*
* - Otherwise, log an error, disable Geneve, and transition to
*/
static void
-run_S_GENEVE_TABLE_MOD_SENT(void)
+run_S_TLV_TABLE_MOD_SENT(void)
{
}
static void
-recv_S_GENEVE_TABLE_MOD_SENT(const struct ofp_header *oh, enum ofptype type)
+recv_S_TLV_TABLE_MOD_SENT(const struct ofp_header *oh, enum ofptype type)
{
if (oh->xid != xid && oh->xid != xid2) {
ofctrl_recv(oh, type);
state = S_CLEAR_FLOWS;
} else if (oh->xid == xid && type == OFPTYPE_ERROR) {
enum ofperr error = ofperr_decode_msg(oh, NULL);
- if (error == OFPERR_NXGTMFC_ALREADY_MAPPED ||
- error == OFPERR_NXGTMFC_DUP_ENTRY) {
+ if (error == OFPERR_NXTTMFC_ALREADY_MAPPED ||
+ error == OFPERR_NXTTMFC_DUP_ENTRY) {
VLOG_INFO("raced with another controller adding "
"Geneve option (%s); trying again",
ofperr_to_string(error));
])
dnl Check Geneve tunnel push with options
-AT_CHECK([ovs-ofctl add-geneve-map int-br "{class=0xffff,type=0x80,len=4}->tun_metadata0"])
+AT_CHECK([ovs-ofctl add-tlv-map int-br "{class=0xffff,type=0x80,len=4}->tun_metadata0"])
AT_CHECK([ovs-ofctl add-flow int-br "actions=set_field:2001:cafe::92->tun_ipv6_dst,set_field:0xa->tun_metadata0,5"])
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=47,tos=0,ttl=64,frag=no)'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
])
dnl Check Geneve tunnel push with options
-AT_CHECK([ovs-ofctl add-geneve-map int-br "{class=0xffff,type=0x80,len=4}->tun_metadata0"])
+AT_CHECK([ovs-ofctl add-tlv-map int-br "{class=0xffff,type=0x80,len=4}->tun_metadata0"])
AT_CHECK([ovs-ofctl add-flow int-br "actions=set_field:1.1.2.92->tun_dst,set_field:0xa->tun_metadata0,5"])
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.112,proto=47,tos=0,ttl=64,frag=no)'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
ofport_request=2 ofport_request=2])
OVS_VSWITCHD_DISABLE_TUNNEL_PUSH_POP
-AT_CHECK([ovs-ofctl add-geneve-map br0 "{class=0xffff,type=0,len=4}->tun_metadata0,{class=0xffff,type=1,len=8}->tun_metadata1"])
+AT_CHECK([ovs-ofctl add-tlv-map br0 "{class=0xffff,type=0,len=4}->tun_metadata0,{class=0xffff,type=1,len=8}->tun_metadata1"])
AT_DATA([flows.txt], [dnl
in_port=2,actions=set_field:0xa->tun_metadata0,set_field:0x1234567890abcdef->tun_metadata1,1
dnl Check mapping table constraints
AT_CHECK([ovs-ofctl del-flows br0])
-AT_CHECK([ovs-ofctl add-geneve-map br0 "{class=0xffff,type=2,len=124}->tun_metadata2,{class=0xffff,type=3,len=124}->tun_metadata3"], [1], [ignore],
-[OFPT_ERROR (xid=0x4): NXGTMFC_TABLE_FULL
-NXT_GENEVE_TABLE_MOD (xid=0x4):
+AT_CHECK([ovs-ofctl add-tlv-map br0 "{class=0xffff,type=2,len=124}->tun_metadata2,{class=0xffff,type=3,len=124}->tun_metadata3"], [1], [ignore],
+[OFPT_ERROR (xid=0x4): NXTTMFC_TABLE_FULL
+NXT_TLV_TABLE_MOD (xid=0x4):
ADD mapping table:
class type length match field
----- ---- ------ -----------
])
dnl Allocation and match with fragmented address space
-AT_CHECK([ovs-ofctl add-geneve-map br0 "{class=0xffff,type=2,len=124}->tun_metadata2"])
-AT_CHECK([ovs-ofctl add-geneve-map br0 "{class=0xffff,type=3,len=4}->tun_metadata3"])
-AT_CHECK([ovs-ofctl add-geneve-map br0 "{class=0xffff,type=4,len=112}->tun_metadata4"])
-AT_CHECK([ovs-ofctl del-geneve-map br0 "{class=0xffff,type=3,len=4}->tun_metadata3"])
-AT_CHECK([ovs-ofctl add-geneve-map br0 "{class=0xffff,type=3,len=8}->tun_metadata3"])
+AT_CHECK([ovs-ofctl add-tlv-map br0 "{class=0xffff,type=2,len=124}->tun_metadata2"])
+AT_CHECK([ovs-ofctl add-tlv-map br0 "{class=0xffff,type=3,len=4}->tun_metadata3"])
+AT_CHECK([ovs-ofctl add-tlv-map br0 "{class=0xffff,type=4,len=112}->tun_metadata4"])
+AT_CHECK([ovs-ofctl del-tlv-map br0 "{class=0xffff,type=3,len=4}->tun_metadata3"])
+AT_CHECK([ovs-ofctl add-tlv-map br0 "{class=0xffff,type=3,len=8}->tun_metadata3"])
AT_CHECK([ovs-ofctl add-flow br0 tun_metadata3=0x1234567890abcdef,actions=2])
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=3,len=8,0x1234567890abcdef}),flags(df|key)),in_port(6081),skb_mark(0),eth_type(0x0800),ipv4(frag=no)'], [0], [stdout])
Datapath actions: 2
])
-AT_CHECK([ovs-ofctl del-geneve-map br0])
+AT_CHECK([ovs-ofctl del-tlv-map br0])
OVS_VSWITCHD_STOP
AT_CLEANUP
ofport_request=2 ofport_request=2])
OVS_VSWITCHD_DISABLE_TUNNEL_PUSH_POP
-AT_CHECK([ovs-ofctl add-geneve-map br0 "{class=0xffff,type=0,len=4}->tun_metadata0,{class=0xffff,type=1,len=0}->tun_metadata1,{class=0xffff,type=2,len=4}->tun_metadata2"])
+AT_CHECK([ovs-ofctl add-tlv-map br0 "{class=0xffff,type=0,len=4}->tun_metadata0,{class=0xffff,type=1,len=0}->tun_metadata1,{class=0xffff,type=2,len=4}->tun_metadata2"])
AT_DATA([flows.txt], [dnl
priority=1,tun_metadata0,actions=2
If no \fIcommand_bucket_id\fR is present in the group specification then all
buckets of the group are removed.
.
-.SS "OpenFlow Switch Geneve Option Table Commands"
+.SS "OpenFlow Switch Tunnel TLV Table Commands"
.
-Open vSwitch maintains a mapping table between Geneve options (defined
-by <class, type, length>) and an NXM field \fBtun_metadata\fIn\fR,
+Open vSwitch maintains a mapping table between tunnel option TLVs (defined
+by <class, type, length>) and NXM fields \fBtun_metadata\fIn\fR,
where \fIn\fR ranges from 0 to 63, that can be operated on for the
-purposes of matches, actions, etc. This mapping must be explicitly
-specified by the user through the following commands.
+purposes of matches, actions, etc. This TLV table can be used for
+Geneve option TLVs or other protocols with options in same TLV format
+as Geneve options. This mapping must be explicitly specified by the user
+through the following commands.
-A Geneve option mapping is specified with the syntax
+A TLV mapping is specified with the syntax
\fB{class=\fIclass\fB,type=\fItype\fB,len=\fIlength\fB}->tun_metadata\fIn\fR.
When an option mapping exists for a given \fBtun_metadata\fIn\fR,
matching on the defined field becomes possible, e.g.:
.RS
-ovs-ofctl add-geneve-map br0 "{class=0xffff,type=0,len=4}->tun_metadata0"
+ovs-ofctl add-tlv-map br0 "{class=0xffff,type=0,len=4}->tun_metadata0"
.PP
ovs-ofctl add-flow br0 tun_metadata0=1234,actions=controller
.RE
A mapping should not be changed while it is in active
use by a flow. The result of doing so is undefined.
-Currently, the Geneve mapping table is shared between all OpenFlow
+Currently, the TLV mapping table is shared between all OpenFlow
switches in a given instance of Open vSwitch. This restriction will
be lifted in the future to allow for easier management.
These commands are Nicira extensions to OpenFlow and require Open vSwitch
2.5 or later.
-.IP "\fBadd\-geneve\-map \fIswitch option\fR[\fB,\fIoption\fR]..."
+.IP "\fBadd\-TLV\-map \fIswitch option\fR[\fB,\fIoption\fR]..."
Add each \fIoption\fR to \fIswitch\fR's tables. Duplicate fields are
rejected.
.
-.IP "\fBdel\-geneve\-map \fIswitch \fR[\fIoption\fR[\fB,\fIoption\fR]]..."
-Delete each \fIoption\fR from \fIswitch\fR's table, or all Geneve option
+.IP "\fBdel\-TLV\-map \fIswitch \fR[\fIoption\fR[\fB,\fIoption\fR]]..."
+Delete each \fIoption\fR from \fIswitch\fR's table, or all option TLV
mapping if no \fIoption\fR is specified.
Fields that aren't mapped are ignored.
.
-.IP "\fBdump\-geneve\-map \fIswitch\fR"
+.IP "\fBdump\-TLV\-map \fIswitch\fR"
Show the currently mapped fields in the switch's option table as well
as switch capabilities.
.
simply match on an option being present.
.IP
Tunnel metadata fields can be dynamically assigned onto the data
-contained in the options of Geneve packets using the commands
-described in the section \fBOpenFlow Switch Geneve Option Table
+contained in the option TLVs of packets (e.g. Geneve variable
+options stores zero or more options in TLV format and tunnel
+metadata can be assigned onto these option TLVs) using the
+commands described in the section \fBOpenFlow Switch Tunnel TLV Table
Commands\fR. Once assigned, the length of the field is variable
according to the size of the option. Before updating a mapping in
the option table, flows with references to it should be removed,
" dump-meters SWITCH print all meter configuration\n"
" meter-stats SWITCH [METER] print meter statistics\n"
" meter-features SWITCH print meter features\n"
- " add-geneve-map SWITCH MAP add Geneve option MAPpings\n"
- " del-geneve-map SWITCH [MAP] delete Geneve option MAPpings\n"
- " dump-geneve-map SWITCH print Geneve option mappings\n"
+ " add-tlv-map SWITCH MAP add TLV option MAPpings\n"
+ " del-tlv-map SWITCH [MAP] delete TLV option MAPpings\n"
+ " dump-tlv-map SWITCH print TLV option mappings\n"
"\nFor OpenFlow switches and controllers:\n"
" probe TARGET probe whether TARGET is up\n"
" ping TARGET [N] latency of N-byte echos\n"
}
static void
-ofctl_geneve_mod(struct ovs_cmdl_context *ctx, uint16_t command)
+ofctl_tlv_mod(struct ovs_cmdl_context *ctx, uint16_t command)
{
enum ofputil_protocol usable_protocols;
enum ofputil_protocol protocol;
- struct ofputil_geneve_table_mod gtm;
+ struct ofputil_tlv_table_mod ttm;
char *error;
enum ofp_version version;
struct ofpbuf *request;
struct vconn *vconn;
- error = parse_ofp_geneve_table_mod_str(>m, command, ctx->argc > 2 ?
+ error = parse_ofp_tlv_table_mod_str(&ttm, command, ctx->argc > 2 ?
ctx->argv[2] : "",
&usable_protocols);
if (error) {
protocol = open_vconn_for_flow_mod(ctx->argv[1], &vconn, usable_protocols);
version = ofputil_protocol_to_ofp_version(protocol);
- request = ofputil_encode_geneve_table_mod(version, >m);
+ request = ofputil_encode_tlv_table_mod(version, &ttm);
if (request) {
transact_noreply(vconn, request);
}
vconn_close(vconn);
- ofputil_uninit_geneve_table(>m.mappings);
+ ofputil_uninit_tlv_table(&ttm.mappings);
}
static void
-ofctl_add_geneve_map(struct ovs_cmdl_context *ctx)
+ofctl_add_tlv_map(struct ovs_cmdl_context *ctx)
{
- ofctl_geneve_mod(ctx, NXGTMC_ADD);
+ ofctl_tlv_mod(ctx, NXTTMC_ADD);
}
static void
-ofctl_del_geneve_map(struct ovs_cmdl_context *ctx)
+ofctl_del_tlv_map(struct ovs_cmdl_context *ctx)
{
- ofctl_geneve_mod(ctx, ctx->argc > 2 ? NXGTMC_DELETE : NXGTMC_CLEAR);
+ ofctl_tlv_mod(ctx, ctx->argc > 2 ? NXTTMC_DELETE : NXTTMC_CLEAR);
}
static void
-ofctl_dump_geneve_map(struct ovs_cmdl_context *ctx)
+ofctl_dump_tlv_map(struct ovs_cmdl_context *ctx)
{
- dump_trivial_transaction(ctx->argv[1], OFPRAW_NXT_GENEVE_TABLE_REQUEST);
+ dump_trivial_transaction(ctx->argv[1], OFPRAW_NXT_TLV_TABLE_REQUEST);
}
static void
1, 2, ofctl_dump_group_stats },
{ "dump-group-features", "switch",
1, 1, ofctl_dump_group_features },
- { "add-geneve-map", "switch map",
- 2, 2, ofctl_add_geneve_map },
- { "del-geneve-map", "switch [map]",
- 1, 2, ofctl_del_geneve_map },
- { "dump-geneve-map", "switch",
- 1, 1, ofctl_dump_geneve_map },
+ { "add-tlv-map", "switch map",
+ 2, 2, ofctl_add_tlv_map },
+ { "del-tlv-map", "switch [map]",
+ 1, 2, ofctl_del_tlv_map },
+ { "dump-tlv-map", "switch",
+ 1, 1, ofctl_dump_tlv_map },
{ "help", NULL, 0, INT_MAX, ofctl_help },
{ "list-commands", NULL, 0, INT_MAX, ofctl_list_commands },