This bug fix still needs a review.  Also, Kevin, if you can verify that
it fixes the behavior you see, that would also be helpful.

On Thu, Jul 06, 2017 at 04:40:30PM -0700, Ben Pfaff wrote:
> The ovs-ofctl "diff-flows" and "replace-flows" command compare the flows
> in two flow tables.  Until now, the "replace-flows" command has considered
> certain almost meaningless differences related to the version of OpenFlow
> used to add a flow as significant, which caused it to replace a flow by an
> identical-in-practice version, e.g. in the following, the "replace-flows"
> command prints a FLOW_MOD that adds the flow that was already added
> previously:
> 
>     $ cat > flows
>     actions=resubmit(,1)
>     $ ovs-vsctl add-br br0
>     $ ovs-ofctl del-flows br0
>     $ ovs-ofctl add-flows br0 flows
>     $ ovs-ofctl -vvconn replace-flows br0 flows 2>&1 | grep FLOW_MOD
> 
> Re-adding an existing flow has some effects, for example, it resets the
> flow's duration, so it's better to avoid it.
> 
> This commit fixes the problem using the same trick previously used for a
> similar problem with the "diff-flows" command, which was fixed in commit
> 98f7f427bf8b ("ovs-ofctl: Avoid printing false differences on "ovs-ofctl
> diff-flows".").
> 
> Reported-by: Kevin Lin <[email protected]>
> Signed-off-by: Ben Pfaff <[email protected]>
> ---
>  include/openvswitch/ofp-actions.h |  2 ++
>  lib/ofp-actions.c                 | 24 ++++++++++++++++++++++++
>  utilities/ovs-ofctl.c             | 18 ++++++++----------
>  3 files changed, 34 insertions(+), 10 deletions(-)
> 
> diff --git a/include/openvswitch/ofp-actions.h 
> b/include/openvswitch/ofp-actions.h
> index 7b4aa9201d9b..0dcb6452ea02 100644
> --- a/include/openvswitch/ofp-actions.h
> +++ b/include/openvswitch/ofp-actions.h
> @@ -1013,6 +1013,8 @@ bool ofpacts_output_to_group(const struct ofpact[], 
> size_t ofpacts_len,
>                               uint32_t group_id);
>  bool ofpacts_equal(const struct ofpact a[], size_t a_len,
>                     const struct ofpact b[], size_t b_len);
> +bool ofpacts_equal_stringwise(const struct ofpact a[], size_t a_len,
> +                              const struct ofpact b[], size_t b_len);
>  const struct mf_field *ofpact_get_mf_dst(const struct ofpact *ofpact);
>  uint32_t ofpacts_get_meter(const struct ofpact[], size_t ofpacts_len);
>  
> diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
> index ae27d9d88080..868b511dc908 100644
> --- a/lib/ofp-actions.c
> +++ b/lib/ofp-actions.c
> @@ -8316,6 +8316,8 @@ ofpacts_output_to_group(const struct ofpact *ofpacts, 
> size_t ofpacts_len,
>      return false;
>  }
>  
> +/* Returns true if the 'a_len' bytes of actions in 'a' and the 'b_len' bytes 
> of
> + * actions in 'b' are bytewise identical. */
>  bool
>  ofpacts_equal(const struct ofpact *a, size_t a_len,
>                const struct ofpact *b, size_t b_len)
> @@ -8323,6 +8325,28 @@ ofpacts_equal(const struct ofpact *a, size_t a_len,
>      return a_len == b_len && !memcmp(a, b, a_len);
>  }
>  
> +/* Returns true if the 'a_len' bytes of actions in 'a' and the 'b_len' bytes 
> of
> + * actions in 'b' are identical when formatted as strings.  (Converting 
> actions
> + * to string form suppresses some rarely meaningful differences, such as the
> + * 'compat' member of actions.) */
> +bool
> +ofpacts_equal_stringwise(const struct ofpact *a, size_t a_len,
> +                         const struct ofpact *b, size_t b_len)
> +{
> +    struct ds a_s = DS_EMPTY_INITIALIZER;
> +    struct ds b_s = DS_EMPTY_INITIALIZER;
> +
> +    ofpacts_format(a, a_len, NULL, &a_s);
> +    ofpacts_format(b, b_len, NULL, &b_s);
> +
> +    bool equal = !strcmp(ds_cstr(&a_s), ds_cstr(&b_s));
> +
> +    ds_destroy(&a_s);
> +    ds_destroy(&b_s);
> +
> +    return equal;
> +}
> +
>  /* Finds the OFPACT_METER action, if any, in the 'ofpacts_len' bytes of
>   * 'ofpacts'.  If found, returns its meter ID; if not, returns 0.
>   *
> diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
> index 6fb2cc08de50..5b7f1b02104f 100644
> --- a/utilities/ovs-ofctl.c
> +++ b/utilities/ovs-ofctl.c
> @@ -3146,8 +3146,8 @@ fte_version_equals(const struct fte_version *a, const 
> struct fte_version *b)
>              && a->hard_timeout == b->hard_timeout
>              && a->importance == b->importance
>              && a->table_id == b->table_id
> -            && ofpacts_equal(a->ofpacts, a->ofpacts_len,
> -                             b->ofpacts, b->ofpacts_len));
> +            && ofpacts_equal_stringwise(a->ofpacts, a->ofpacts_len,
> +                                        b->ofpacts, b->ofpacts_len));
>  }
>  
>  /* Clears 's', then if 's' has a version 'index', formats 'fte' and version
> @@ -3656,15 +3656,13 @@ ofctl_diff_flows(struct ovs_cmdl_context *ctx)
>              if (!a || !b || !fte_version_equals(a, b)) {
>                  fte_version_format(&fte_state, fte, 0, &a_s);
>                  fte_version_format(&fte_state, fte, 1, &b_s);
> -                if (strcmp(ds_cstr(&a_s), ds_cstr(&b_s))) {
> -                    if (a_s.length) {
> -                        printf("-%s", ds_cstr(&a_s));
> -                    }
> -                    if (b_s.length) {
> -                        printf("+%s", ds_cstr(&b_s));
> -                    }
> -                    differences = true;
> +                if (a_s.length) {
> +                    printf("-%s", ds_cstr(&a_s));
> +                }
> +                if (b_s.length) {
> +                    printf("+%s", ds_cstr(&b_s));
>                  }
> +                differences = true;
>              }
>          }
>      }
> -- 
> 2.10.2
> 
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to