On 20 January 2017 at 15:12, Yi-Hung Wei <[email protected]> wrote:
> Previously, if a flow action that involves a tunnel metadata meta-flow
> field is dumped from vswitchd, the replied field length in the OXM header
> is filled with the maximum possible field length, instead of the length
> configured in the tunnel TLV mapping table. To solve this issue, this patch
> introduces the following changes.
>
> In order to maintain the correct length of variable length mf_fields (i.e.
> tun_metadata), this patch creates a per-switch based map (struct vl_mff_map)
> that hosts the variable length mf_fields. This map is updated when a
> controller adds/deletes tlv-mapping entries to/from a switch. Although the
> per-swtch based vl_mff_map only hosts tun_metadata for now, it is able to
> support new variable length mf_fields in the future.
>
> With this commit, when a switch decodes a flow action with mf_field, the
> switch
> firstly looks up the global mf_fields map to identify the mf_field type. For
> the variable length mf_fields, the switch uses the vl_mff_map to get the
> configured mf_field entries. By lookig up vl_mff_map, the switch can check
> if the added flow action access beyond the configured size of a variable
> length mf_field, and the switch reports an ofperr if the controller adds a
> flow
> with unmapped variable length mf_field. Later on, when a controller request
> flows from the switch, with the per-switch based mf_fields, the switch will
> encode the OXM header with correct length for variable length mf_fields.
>
> To use the vl_mff_map for decoding flow actions, extract-ofp-actions is
> updated to pass the vl_mff_map to the required action decoding functions.
> Also, a new error code is introduced to identify a flow with an invalid
> variable length mf_field. Moreover, a testcase is added to prevent future
> regressions.
>
> VMWare-BZ: #1768370
> Reported-by: Harold Lim <[email protected]>
> Suggested-by: Joe Stringer <[email protected]>
> Suggested-by: Jarno Rajahalme <[email protected]>
> Signed-off-by: Yi-Hung Wei <[email protected]>
Thanks for the patch!
I wonder about renaming OFPERR_NXFMFC_INVALID_VL_MFF to something like
OFPERR_NXFMFC_INVALID_TLV_FIELD, this is slightly less cryptic than
VL_MFF to the unknowing eye. Thoughts?
<snip>
> +/* Updates the tun_metadata mf_field in 'vl_mff_map' according to 'ttm'.
> + * This function is supposed to be invoked after tun_metadata_table_mod(). */
> +enum ofperr
> +mf_vl_mff_map_mod_from_tun_metadata(struct vl_mff_map *vl_mff_map,
> + const struct ofputil_tlv_table_mod *ttm)
> + OVS_REQUIRES(vl_mff_map->mutex)
> +{
> + struct ofputil_tlv_map *tlv_map;
> + struct mf_field *mf;
> + unsigned int idx;
> +
> + switch (ttm->command) {
> + case NXTTMC_ADD:
> + LIST_FOR_EACH (tlv_map, list_node, &ttm->mappings) {
> + idx = MFF_TUN_METADATA0 + tlv_map->index;
> + if (idx >= MFF_TUN_METADATA0 + TUN_METADATA_NUM_OPTS) {
> + return OFPERR_NXTTMFC_BAD_FIELD_IDX;
> + }
> +
> + mf = xmalloc(sizeof *mf);
> + *mf = mf_fields[idx];
> + mf->n_bytes = tlv_map->option_len;
> + mf->n_bits = tlv_map->option_len * 8;
> + mf->mapped = true;
> +
> + cmap_insert(&vl_mff_map->cmap, &mf->cmap_node,
> mf_field_hash(idx));
> + }
> + break;
> +
> + case NXTTMC_DELETE:
> + LIST_FOR_EACH (tlv_map, list_node, &ttm->mappings) {
> + idx = MFF_TUN_METADATA0 + tlv_map->index;
> + if (idx >= MFF_TUN_METADATA0 + TUN_METADATA_NUM_OPTS) {
> + return OFPERR_NXTTMFC_BAD_FIELD_IDX;
> + }
> +
> + CMAP_FOR_EACH_WITH_HASH (mf, cmap_node, mf_field_hash(idx),
> + &vl_mff_map->cmap) {
> + if (mf->id == idx) {
> + cmap_remove(&vl_mff_map->cmap, &mf->cmap_node,
> + mf_field_hash(idx));
> + ovsrcu_postpone(free, mf);
> + break;
> + }
> + }
> + }
> + break;
> +
> + case NXTTMC_CLEAR:
> + mf_vl_mff_map_clear(vl_mff_map);
> + break;
> +
> + default:
> + OVS_NOT_REACHED();
> + }
I think that this could be a bit restructured to share the list
iteration/error checking between ADD and DELETE.
> +
> + return 0;
> +}
> +
> +/* If 'mff' is a variable length field, looks up 'vl_mff_map', returns a
> + * pointer to the variable length meta-flow field corresponding to 'mff'.
> + * Returns NULL if no mapping is existed for 'mff'. */
> +const struct mf_field *
> +mf_get_vl_mff(const struct mf_field *mff,
> + const struct vl_mff_map *vl_mff_map)
> +{
> + const struct mf_field *field;
> +
> + if (mff && mff->variable_len && vl_mff_map) {
> + const uint32_t id = mff->id;
> +
> + CMAP_FOR_EACH_WITH_HASH (field, cmap_node, mf_field_hash(id),
> + &vl_mff_map->cmap) {
> + if (field->id == id) {
> + return field;
> + }
> + }
> + }
> +
> + return NULL;
> +}
> +
> +/* Returns true if a variable length meta-flow field 'mff' is not mapped in
> + * the 'vl_mff_map'. */
> +bool
> +mf_vl_mff_not_mapped(const struct mf_field *mff,
> + const struct vl_mff_map *vl_mff_map)
Typically we would reverse this function so you can have calls to
"mf_vl_mff_mapped(...)", then if you want to invert the logic, you can
use "!mf_vl_mff_mapped(...)". If the name has "not" in it, then it
makes things harder to read when negation is involved.
<snip>
> diff --git a/lib/tun-metadata.c b/lib/tun-metadata.c
> index 92643b3..eb27e25 100644
> --- a/lib/tun-metadata.c
> +++ b/lib/tun-metadata.c
> @@ -32,7 +32,7 @@
>
> struct tun_meta_entry {
> struct hmap_node node; /* In struct tun_table's key_hmap. */
> - uint32_t key; /* (class << 16) | type. */
> + uint32_t key; /* (class << 8) | type. */
> struct tun_metadata_loc loc;
> bool valid; /* True if allocated to a class and type. */
> };
Was this always wrong? (Maybe it can be updated in a separate patch
since it seems to be a documentation bugfix and not directly related
to outputting variable length mapped MFFs correctly)
<snip>
I also saw a couple of spelling mistakes.
I've included an incremental diff below, if you're happy with these
changes then I'll apply them with your patch to master.
diff --git a/include/openvswitch/meta-flow.h b/include/openvswitch/meta-flow.h
index 0dc2ce6ad968..8457c86c094e 100644
--- a/include/openvswitch/meta-flow.h
+++ b/include/openvswitch/meta-flow.h
@@ -1996,5 +1996,5 @@ enum ofperr mf_vl_mff_map_mod_from_tun_metadata(
OVS_REQUIRES(vl_mff_map->mutex);
const struct mf_field * mf_get_vl_mff(const struct mf_field *,
const struct vl_mff_map *);
-bool mf_vl_mff_not_mapped(const struct mf_field *, const struct vl_mff_map *);
+bool mf_vl_mff_mapped(const struct mf_field *, const struct vl_mff_map *);
#endif /* meta-flow.h */
diff --git a/include/openvswitch/ofp-errors.h b/include/openvswitch/ofp-errors.h
index ffe6c000cb78..7ff06a122c50 100644
--- a/include/openvswitch/ofp-errors.h
+++ b/include/openvswitch/ofp-errors.h
@@ -397,7 +397,7 @@ enum ofperr {
/* NX1.0-1.1(1,536), NX1.2+(37). Attempted to add a flow with an invalid
* variable length meta-flow field. */
- OFPERR_NXFMFC_INVALID_VL_MFF,
+ OFPERR_NXFMFC_INVALID_TLV_FIELD,
/* ## ---------------------- ## */
/* ## OFPET_GROUP_MOD_FAILED ## */
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index a20fab3bced3..11753cf89e30 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -2659,6 +2659,35 @@ mf_vl_mff_map_clear(struct vl_mff_map *vl_mff_map)
}
}
+static struct mf_field *
+mf_get_vl_mff__(uint32_t id, const struct vl_mff_map *vl_mff_map)
+{
+ struct mf_field *field;
+
+ CMAP_FOR_EACH_WITH_HASH (field, cmap_node, mf_field_hash(id),
+ &vl_mff_map->cmap) {
+ if (field->id == id) {
+ return field;
+ }
+ }
+
+ return NULL;
+}
+
+/* If 'mff' is a variable length field, looks up 'vl_mff_map', returns a
+ * pointer to the variable length meta-flow field corresponding to 'mff'.
+ * Returns NULL if no mapping is existed for 'mff'. */
+const struct mf_field *
+mf_get_vl_mff(const struct mf_field *mff,
+ const struct vl_mff_map *vl_mff_map)
+{
+ if (mff && mff->variable_len && vl_mff_map) {
+ return mf_get_vl_mff__(mff->id, vl_mff_map);
+ }
+
+ return NULL;
+}
+
/* Updates the tun_metadata mf_field in 'vl_mff_map' according to 'ttm'.
* This function is supposed to be invoked after tun_metadata_table_mod(). */
enum ofperr
@@ -2667,17 +2696,22 @@ mf_vl_mff_map_mod_from_tun_metadata(struct
vl_mff_map *vl_mff_map,
OVS_REQUIRES(vl_mff_map->mutex)
{
struct ofputil_tlv_map *tlv_map;
- struct mf_field *mf;
- unsigned int idx;
-
- switch (ttm->command) {
- case NXTTMC_ADD:
- LIST_FOR_EACH (tlv_map, list_node, &ttm->mappings) {
- idx = MFF_TUN_METADATA0 + tlv_map->index;
- if (idx >= MFF_TUN_METADATA0 + TUN_METADATA_NUM_OPTS) {
- return OFPERR_NXTTMFC_BAD_FIELD_IDX;
- }
+ if (ttm->command == NXTTMC_CLEAR) {
+ mf_vl_mff_map_clear(vl_mff_map);
+ return 0;
+ }
+
+ LIST_FOR_EACH (tlv_map, list_node, &ttm->mappings) {
+ unsigned int idx = MFF_TUN_METADATA0 + tlv_map->index;
+ struct mf_field *mf;
+
+ if (idx >= MFF_TUN_METADATA0 + TUN_METADATA_NUM_OPTS) {
+ return OFPERR_NXTTMFC_BAD_FIELD_IDX;
+ }
+
+ switch (ttm->command) {
+ case NXTTMC_ADD:
mf = xmalloc(sizeof *mf);
*mf = mf_fields[idx];
mf->n_bytes = tlv_map->option_len;
@@ -2685,73 +2719,30 @@ mf_vl_mff_map_mod_from_tun_metadata(struct
vl_mff_map *vl_mff_map,
mf->mapped = true;
cmap_insert(&vl_mff_map->cmap, &mf->cmap_node, mf_field_hash(idx));
- }
- break;
+ break;
- case NXTTMC_DELETE:
- LIST_FOR_EACH (tlv_map, list_node, &ttm->mappings) {
- idx = MFF_TUN_METADATA0 + tlv_map->index;
- if (idx >= MFF_TUN_METADATA0 + TUN_METADATA_NUM_OPTS) {
- return OFPERR_NXTTMFC_BAD_FIELD_IDX;
+ case NXTTMC_DELETE:
+ mf = mf_get_vl_mff__(idx, vl_mff_map);
+ if (mf) {
+ cmap_remove(&vl_mff_map->cmap, &mf->cmap_node,
+ mf_field_hash(idx));
+ ovsrcu_postpone(free, mf);
}
+ break;
- CMAP_FOR_EACH_WITH_HASH (mf, cmap_node, mf_field_hash(idx),
- &vl_mff_map->cmap) {
- if (mf->id == idx) {
- cmap_remove(&vl_mff_map->cmap, &mf->cmap_node,
- mf_field_hash(idx));
- ovsrcu_postpone(free, mf);
- break;
- }
- }
+ case NXTTMC_CLEAR:
+ default:
+ OVS_NOT_REACHED();
}
- break;
-
- case NXTTMC_CLEAR:
- mf_vl_mff_map_clear(vl_mff_map);
- break;
-
- default:
- OVS_NOT_REACHED();
}
return 0;
}
-/* If 'mff' is a variable length field, looks up 'vl_mff_map', returns a
- * pointer to the variable length meta-flow field corresponding to 'mff'.
- * Returns NULL if no mapping is existed for 'mff'. */
-const struct mf_field *
-mf_get_vl_mff(const struct mf_field *mff,
- const struct vl_mff_map *vl_mff_map)
-{
- const struct mf_field *field;
-
- if (mff && mff->variable_len && vl_mff_map) {
- const uint32_t id = mff->id;
-
- CMAP_FOR_EACH_WITH_HASH (field, cmap_node, mf_field_hash(id),
- &vl_mff_map->cmap) {
- if (field->id == id) {
- return field;
- }
- }
- }
-
- return NULL;
-}
-
/* Returns true if a variable length meta-flow field 'mff' is not mapped in
* the 'vl_mff_map'. */
bool
-mf_vl_mff_not_mapped(const struct mf_field *mff,
- const struct vl_mff_map *vl_mff_map)
+mf_vl_mff_mapped(const struct mf_field *mff, const struct vl_mff_map *map)
{
- if (mff && vl_mff_map) {
- if (mff->variable_len && !mff->mapped) {
- return true;
- }
- }
-
- return false;
+ return !(map && mff && mff->variable_len && !mff->mapped);
}
diff --git a/lib/nx-match.c b/lib/nx-match.c
index 8824f22c4b5c..7cfd3614219a 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -232,8 +232,8 @@ mf_nxm_header(enum mf_field_id id)
}
/* Returns the 32-bit OXM or NXM header to use for field 'mff'. If 'mff' is
- * a mapped variable length mf_field, update header with the configured
- * lenght of 'mff'. Returns 0 if 'mff' cannot be expressed with a 32-bit NXM
+ * a mapped variable length mf_field, update the header with the configured
+ * length of 'mff'. Returns 0 if 'mff' cannot be expressed with a 32-bit NXM
* or OXM header.*/
uint32_t
nxm_header_from_mff(const struct mf_field *mff)
@@ -339,8 +339,8 @@ nx_pull_header__(struct ofpbuf *b, bool allow_cookie,
VLOG_DBG_RL(&rl, "OXM header "NXM_HEADER_FMT" is unknown",
NXM_HEADER_ARGS(*header));
return OFPERR_OFPBMC_BAD_FIELD;
- } else if (mf_vl_mff_not_mapped(*field, vl_mff_map)) {
- return OFPERR_NXFMFC_INVALID_VL_MFF;
+ } else if (!mf_vl_mff_mapped(*field, vl_mff_map)) {
+ return OFPERR_NXFMFC_INVALID_TLV_FIELD;
}
}
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index 180344a17d0a..276e008f9b08 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -1135,8 +1135,8 @@ decode_NXAST_RAW_OUTPUT_REG(const struct
nx_action_output_reg *naor,
output_reg->src.n_bits = nxm_decode_n_bits(naor->ofs_nbits);
output_reg->max_len = ntohs(naor->max_len);
- if (mf_vl_mff_not_mapped(output_reg->src.field, vl_mff_map)) {
- return OFPERR_NXFMFC_INVALID_VL_MFF;
+ if (!mf_vl_mff_mapped(output_reg->src.field, vl_mff_map)) {
+ return OFPERR_NXFMFC_INVALID_TLV_FIELD;
}
return mf_check_src(&output_reg->src, NULL);
@@ -1325,8 +1325,8 @@ decode_bundle(bool load, const struct
nx_action_bundle *nab,
bundle->dst.field = mf_from_nxm_header(ntohl(nab->dst), vl_mff_map);
bundle->dst.ofs = nxm_decode_ofs(nab->ofs_nbits);
bundle->dst.n_bits = nxm_decode_n_bits(nab->ofs_nbits);
- if (mf_vl_mff_not_mapped(bundle->dst.field, vl_mff_map)) {
- return OFPERR_NXFMFC_INVALID_VL_MFF;
+ if (!mf_vl_mff_mapped(bundle->dst.field, vl_mff_map)) {
+ return OFPERR_NXFMFC_INVALID_TLV_FIELD;
}
if (bundle->dst.n_bits < 16) {
@@ -2565,8 +2565,8 @@ decode_NXAST_RAW_REG_LOAD(const struct
nx_action_reg_load *narl,
dst.field = mf_from_nxm_header(ntohl(narl->dst), vl_mff_map);
dst.ofs = nxm_decode_ofs(narl->ofs_nbits);
dst.n_bits = nxm_decode_n_bits(narl->ofs_nbits);
- if (mf_vl_mff_not_mapped(dst.field, vl_mff_map)) {
- return OFPERR_NXFMFC_INVALID_VL_MFF;
+ if (!mf_vl_mff_mapped(dst.field, vl_mff_map)) {
+ return OFPERR_NXFMFC_INVALID_TLV_FIELD;
}
error = mf_check_dst(&dst, NULL);
@@ -4283,8 +4283,8 @@ get_subfield(int n_bits, const void **p, struct
mf_subfield *sf,
sf->field = mf_from_nxm_header(ntohl(get_be32(p)), vl_mff_map);
sf->ofs = ntohs(get_be16(p));
sf->n_bits = n_bits;
- if (mf_vl_mff_not_mapped(sf->field, vl_mff_map)) {
- return OFPERR_NXFMFC_INVALID_VL_MFF;
+ if (!mf_vl_mff_mapped(sf->field, vl_mff_map)) {
+ return OFPERR_NXFMFC_INVALID_TLV_FIELD;
}
return 0;
}
@@ -4664,8 +4664,8 @@ decode_NXAST_RAW_MULTIPATH(const struct
nx_action_multipath *nam,
mp->dst.ofs = nxm_decode_ofs(nam->ofs_nbits);
mp->dst.n_bits = nxm_decode_n_bits(nam->ofs_nbits);
- if (mf_vl_mff_not_mapped(mp->dst.field, vl_mff_map)) {
- return OFPERR_NXFMFC_INVALID_VL_MFF;
+ if (!mf_vl_mff_mapped(mp->dst.field, vl_mff_map)) {
+ return OFPERR_NXFMFC_INVALID_TLV_FIELD;
}
if (!flow_hash_fields_valid(mp->fields)) {
@@ -5324,8 +5324,8 @@ decode_ct_zone(const struct nx_action_conntrack *nac,
vl_mff_map);
out->zone_src.ofs = nxm_decode_ofs(nac->zone_ofs_nbits);
out->zone_src.n_bits = nxm_decode_n_bits(nac->zone_ofs_nbits);
- if (mf_vl_mff_not_mapped(out->zone_src.field, vl_mff_map)) {
- return OFPERR_NXFMFC_INVALID_VL_MFF;
+ if (!mf_vl_mff_mapped(out->zone_src.field, vl_mff_map)) {
+ return OFPERR_NXFMFC_INVALID_TLV_FIELD;
}
error = mf_check_src(&out->zone_src, NULL);
diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
index b08a3fd174c4..c08a146154b1 100644
--- a/ofproto/ofproto-provider.h
+++ b/ofproto/ofproto-provider.h
@@ -128,7 +128,7 @@ struct ofproto {
/* Tunnel TLV mapping table. */
OVSRCU_TYPE(struct tun_table *) metadata_tab;
- /* Variable length mf_field mapping map. Stores all variable length
+ /* Variable length mf_field mapping. Stores all configured variable length
* meta-flow fields (struct mf_field) in a switch. */
struct vl_mff_map vl_mff_map;
};
diff --git a/tests/ofproto.at b/tests/ofproto.at
index 48f30cff4958..c899ec80c6cf 100644
--- a/tests/ofproto.at
+++ b/tests/ofproto.at
@@ -5707,7 +5707,7 @@ NXST_FLOW reply (xid=0x4):
dnl Check actions that may use tun_metadata
AT_CHECK([ovs-ofctl add-flow br0 "in_port=2
actions=move:tun_metadata1[[0..31]]->NXM_NX_REG0[[]]"], [1], [],
[stderr])
AT_CHECK([strip_xids < stderr | sed '/FLOW_MOD/,$d'], [0], [dnl
-OFPT_ERROR: NXFMFC_INVALID_VL_MFF
+OFPT_ERROR: NXFMFC_INVALID_TLV_FIELD
])
AT_CHECK([ovs-ofctl add-flow br0 "in_port=2
actions=move:tun_metadata0[[32..63]]->NXM_NX_REG0[[]]"], [1], [],
[stderr])
@@ -5717,7 +5717,7 @@ OFPT_ERROR: OFPBAC_BAD_SET_LEN
AT_CHECK([ovs-ofctl add-flow br0 "in_port=2
actions=push:tun_metadata1[[0..31]]"], [1], [], [stderr])
AT_CHECK([strip_xids < stderr | sed '/FLOW_MOD/,$d'], [0], [dnl
-OFPT_ERROR: NXFMFC_INVALID_VL_MFF
+OFPT_ERROR: NXFMFC_INVALID_TLV_FIELD
])
AT_CHECK([ovs-ofctl add-flow br0 "in_port=2
actions=pop:tun_metadata0[[32..63]]"], [1], [], [stderr])
@@ -5727,12 +5727,12 @@ OFPT_ERROR: OFPBAC_BAD_SET_LEN
AT_CHECK([ovs-ofctl add-flow br0 "in_port=3,
actions=load:0x11223344->tun_metadata1"], [1], [], [stderr])
AT_CHECK([strip_xids < stderr | sed '/FLOW_MOD/,$d'], [0], [dnl
-OFPT_ERROR: NXFMFC_INVALID_VL_MFF
+OFPT_ERROR: NXFMFC_INVALID_TLV_FIELD
])
AT_CHECK([ovs-ofctl add-flow br0 "in_port=2
actions=output:tun_metadata1[[0..31]]"], [1], [], [stderr])
AT_CHECK([strip_xids < stderr | sed '/FLOW_MOD/,$d'], [0], [dnl
-OFPT_ERROR: NXFMFC_INVALID_VL_MFF
+OFPT_ERROR: NXFMFC_INVALID_TLV_FIELD
])
AT_CHECK([ovs-ofctl add-flow br0 "in_port=2
actions=output:tun_metadata0[[32..63]]"], [1], [], [stderr])
@@ -5742,7 +5742,7 @@ OFPT_ERROR: OFPBAC_BAD_SET_LEN
AT_CHECK([ovs-ofctl add-flow br0 "in_port=2
actions=multipath(eth_src,50,modulo_n,1,0,tun_metadata1[[0..31]])"],
[1], [], [stderr])
AT_CHECK([strip_xids < stderr | sed '/FLOW_MOD/,$d'], [0], [dnl
-OFPT_ERROR: NXFMFC_INVALID_VL_MFF
+OFPT_ERROR: NXFMFC_INVALID_TLV_FIELD
])
AT_CHECK([ovs-ofctl add-flow br0 "in_port=2
actions=multipath(eth_src,50,modulo_n,1,0,tun_metadata0[[32..63]])"],
[1], [], [stderr])
@@ -5752,7 +5752,7 @@ OFPT_ERROR: OFPBAC_BAD_SET_LEN
AT_CHECK([ovs-ofctl add-flow br0 "in_port=2
actions=bundle_load(eth_src,50,hrw,ofport,tun_metadata1[[0..31]],
slaves:4,8)"], [1], [], [stderr])
AT_CHECK([strip_xids < stderr | sed '/FLOW_MOD/,$d'], [0], [dnl
-OFPT_ERROR: NXFMFC_INVALID_VL_MFF
+OFPT_ERROR: NXFMFC_INVALID_TLV_FIELD
])
AT_CHECK([ovs-ofctl add-flow br0 "in_port=2
actions=bundle_load(eth_src,50,hrw,ofport,tun_metadata0[[32..63]],
slaves:4,8)"], [1], [], [stderr])
@@ -5762,7 +5762,7 @@ OFPT_ERROR: OFPBAC_BAD_SET_LEN
AT_CHECK([ovs-ofctl add-flow br0 "in_port=2
actions=learn(tun_metadata1[[0..31]]=reg0[[0..31]])"], [1], [],
[stderr])
AT_CHECK([strip_xids < stderr | sed '/FLOW_MOD/,$d'], [0], [dnl
-OFPT_ERROR: NXFMFC_INVALID_VL_MFF
+OFPT_ERROR: NXFMFC_INVALID_TLV_FIELD
])
AT_CHECK([ovs-ofctl add-flow br0 "in_port=2
actions=learn(tun_metadata0[[32..63]]=reg0[[0..31]])"], [1], [],
[stderr])
@@ -5772,7 +5772,7 @@ OFPT_ERROR: OFPBAC_BAD_SET_LEN
AT_CHECK([ovs-ofctl add-flow br0 "in_port=2
actions=clone(move:tun_metadata1[[0..31]]->reg0[[0..31]])"], [1], [],
[stderr])
AT_CHECK([strip_xids < stderr | sed '/FLOW_MOD/,$d'], [0], [dnl
-OFPT_ERROR: NXFMFC_INVALID_VL_MFF
+OFPT_ERROR: NXFMFC_INVALID_TLV_FIELD
])
AT_CHECK([ovs-ofctl add-flow br0 "in_port=2
actions=clone(move:tun_metadata0[[32..63]]->reg0[[0..31]])"], [1], [],
[stderr])
@@ -5782,7 +5782,7 @@ OFPT_ERROR: OFPBAC_BAD_SET_LEN
AT_CHECK([ovs-ofctl add-flow br0 "ip
actions=ct(commit,zone=tun_metadata1[[0..15]],exec(set_field:0x01->ct_mark))"],
[1], [], [stderr])
AT_CHECK([strip_xids < stderr | sed '/FLOW_MOD/,$d'], [0], [dnl
-OFPT_ERROR: NXFMFC_INVALID_VL_MFF
+OFPT_ERROR: NXFMFC_INVALID_TLV_FIELD
])
AT_CHECK([ovs-ofctl add-flow br0 "ip
actions=ct(commit,zone=tun_metadata0[[32..47]],exec(set_field:0x01->ct_mark))"],
[1], [], [stderr])
@@ -5792,7 +5792,7 @@ OFPT_ERROR: OFPBAC_BAD_SET_LEN
AT_CHECK([ovs-ofctl add-flow br0 "ip
actions=ct(commit,zone=1,exec(move:tun_metadata1[[0..31]]->ct_mark))"],
[1], [], [stderr])
AT_CHECK([strip_xids < stderr | sed '/FLOW_MOD/,$d'], [0], [dnl
-OFPT_ERROR: NXFMFC_INVALID_VL_MFF
+OFPT_ERROR: NXFMFC_INVALID_TLV_FIELD
])
AT_CHECK([ovs-ofctl add-flow br0 "ip
actions=ct(commit,zone=1,exec(move:tun_metadata0[[32..63]]->ct_mark))"],
[1], [], [stderr])
@@ -5806,7 +5806,7 @@ NXST_FLOW reply (xid=0x4):
cookie=0x0, duration=?s, table=0, n_packets=0, n_bytes=0,
idle_age=?, in_port=1
actions=move:NXM_NX_TUN_METADATA0[[0..31]]->NXM_NX_REG0[[]]
])
-OVS_VSWITCHD_STOP(["/NXFMFC_INVALID_VL_MFF/d
+OVS_VSWITCHD_STOP(["/NXFMFC_INVALID_TLV_FIELD/d
/tun_metadata0/d
/OFPBAC_BAD_SET_LEN/d"])
AT_CLEANUP
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev