On 20 January 2017 at 15:12, Yi-Hung Wei <yihung....@gmail.com> 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 <haro...@vmware.com>
> Suggested-by: Joe Stringer <j...@ovn.org>
> Suggested-by: Jarno Rajahalme <ja...@ovn.org>
> Signed-off-by: Yi-Hung Wei <yihung....@gmail.com>

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
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to