[ovs-dev] [PATCH 3/4] flow, match, classifier: Add new functions for miniflow and minimatch.

Armando M. armamig at gmail.com
Thu Mar 29 06:53:08 UTC 2018


On 20 March 2018 at 13:46, Ben Pfaff <blp at ovn.org> wrote:

> The miniflow and minimatch APIs lack several of the features of the flow
> and match APIs.  This commit adds a few of the missing functions.
>
> These functions will be used for the first time in an upcoming commit.
>
> Signed-off-by: Ben Pfaff <blp at ovn.org>
> ---
>  include/openvswitch/match.h |  4 ++++
>  lib/classifier.c            | 19 +++++++++++++++++++
>  lib/classifier.h            |  4 ++++
>  lib/flow.h                  | 27 +++++++++++++++++++++++++++
>  lib/match.c                 | 44 ++++++++++++++++++++++++++++++
> ++++++++++++++
>  5 files changed, 98 insertions(+)
>
> diff --git a/include/openvswitch/match.h b/include/openvswitch/match.h
> index e5cf1a0d7c14..49333ae8f7a1 100644
> --- a/include/openvswitch/match.h
> +++ b/include/openvswitch/match.h
> @@ -246,6 +246,7 @@ struct minimatch {
>  };
>
>  void minimatch_init(struct minimatch *, const struct match *);
> +void minimatch_init_catchall(struct minimatch *);
>  void minimatch_clone(struct minimatch *, const struct minimatch *);
>  void minimatch_move(struct minimatch *dst, struct minimatch *src);
>  void minimatch_destroy(struct minimatch *);
> @@ -253,6 +254,7 @@ void minimatch_destroy(struct minimatch *);
>  void minimatch_expand(const struct minimatch *, struct match *);
>
>  bool minimatch_equal(const struct minimatch *a, const struct minimatch
> *b);
> +uint32_t minimatch_hash(const struct minimatch *, uint32_t basis);
>
>  bool minimatch_matches_flow(const struct minimatch *, const struct flow
> *);
>
> @@ -262,6 +264,8 @@ void minimatch_format(const struct minimatch *, const
> struct tun_table *,
>  char *minimatch_to_string(const struct minimatch *,
>                            const struct ofputil_port_map *, int priority);
>
> +bool minimatch_has_default_hidden_fields(const struct minimatch *);
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/lib/classifier.c b/lib/classifier.c
> index cea9053b6f67..edb40c89c608 100644
> --- a/lib/classifier.c
> +++ b/lib/classifier.c
> @@ -1223,6 +1223,25 @@ classifier_find_match_exactly(const struct
> classifier *cls,
>      return retval;
>  }
>
> +/* Finds and returns a rule in 'cls' with priority 'priority' and exactly
> the
> + * same matching criteria as 'target', and that is visible in 'version'.
> + * Returns a null pointer if 'cls' doesn't contain an exact match visible
> in
> + * 'version'. */
> +const struct cls_rule *
> +classifier_find_minimatch_exactly(const struct classifier *cls,
> +                              const struct minimatch *target, int
> priority,
> +                              ovs_version_t version)
> +{
> +    const struct cls_rule *retval;
> +    struct cls_rule cr;
> +
> +    cls_rule_init_from_minimatch(&cr, target, priority);
> +    retval = classifier_find_rule_exactly(cls, &cr, version);
> +    cls_rule_destroy(&cr);
> +
> +    return retval;
> +}
> +
>  /* Checks if 'target' would overlap any other rule in 'cls' in
> 'version'.  Two
>   * rules are considered to overlap if both rules have the same priority
> and a
>   * packet could match both, and if both rules are visible in the same
> version.
> diff --git a/lib/classifier.h b/lib/classifier.h
> index 1263afdfd1a9..d1bd4aa12a78 100644
> --- a/lib/classifier.h
> +++ b/lib/classifier.h
> @@ -406,6 +406,10 @@ const struct cls_rule *classifier_find_match_exactly(const
> struct classifier *,
>                                                       const struct match *,
>                                                       int priority,
>                                                       ovs_version_t);
> +const struct cls_rule *classifier_find_minimatch_exactly(
> +    const struct classifier *, const struct minimatch *,
> +    int priority, ovs_version_t);
> +
>  bool classifier_is_empty(const struct classifier *);
>  int classifier_count(const struct classifier *);
>
> diff --git a/lib/flow.h b/lib/flow.h
> index 3331e2068ed8..5e41567b2668 100644
> --- a/lib/flow.h
> +++ b/lib/flow.h
> @@ -728,6 +728,11 @@ static inline ovs_be32 miniflow_get_be32(const struct
> miniflow *,
>  static inline uint16_t miniflow_get_vid(const struct miniflow *, size_t);
>  static inline uint16_t miniflow_get_tcp_flags(const struct miniflow *);
>  static inline ovs_be64 miniflow_get_metadata(const struct miniflow *);
> +static inline uint64_t miniflow_get_tun_metadata_present_map(
> +    const struct miniflow *);
> +static inline uint32_t miniflow_get_recirc_id(const struct miniflow *);
> +static inline uint32_t miniflow_get_dp_hash(const struct miniflow *);
> +static inline ovs_be32 miniflow_get_ports(const struct miniflow *);
>
>  bool miniflow_equal(const struct miniflow *a, const struct miniflow *b);
>  bool miniflow_equal_in_minimask(const struct miniflow *a,
> @@ -857,6 +862,27 @@ miniflow_get_metadata(const struct miniflow *flow)
>      return MINIFLOW_GET_BE64(flow, metadata);
>  }
>
> +/* Returns the bitmap that indicates which tunnel metadata fields are
> present
> + * in 'flow'. */
> +static inline uint64_t
> +miniflow_get_tun_metadata_present_map(const struct miniflow *flow)
> +{
> +    return MINIFLOW_GET_U64(flow, tunnel.metadata.present.map);
> +}
> +
> +/* Returns the recirc_id in 'flow.' */
> +static inline uint32_t
> +miniflow_get_recirc_id(const struct miniflow *flow)
> +{
> +    return MINIFLOW_GET_U32(flow, recirc_id);
> +}
> +
> +/* Returns the dp_hash in 'flow.' */
> +static inline uint32_t
> +miniflow_get_dp_hash(const struct miniflow *flow)
> +{
> +    return MINIFLOW_GET_U32(flow, dp_hash);
> +}
>
>  /* Returns the 'tp_src' and 'tp_dst' fields together as one piece of
> data. */
>  static inline ovs_be32
> @@ -864,6 +890,7 @@ miniflow_get_ports(const struct miniflow *flow)
>  {
>      return MINIFLOW_GET_TYPE__(flow, ovs_be32, tp_src);
>  }
> +
>  /* Returns the mask for the OpenFlow 1.1+ "metadata" field in 'mask'.
>   *
>   * The return value is all-1-bits if 'mask' matches on the whole value of
> the
> diff --git a/lib/match.c b/lib/match.c
> index 3eab0fd5dec9..2e9a80329bb3 100644
> --- a/lib/match.c
> +++ b/lib/match.c
> @@ -1667,6 +1667,15 @@ minimatch_init(struct minimatch *dst, const struct
> match *src)
>      dst->tun_md = tun_metadata_allocation_clone(&src->tun_md);
>  }
>
> +/* Initializes 'match' as a "catch-all" match that matches every packet.
> */
> +void
> +minimatch_init_catchall(struct minimatch *match)
> +{
> +    match->flows[0] = xcalloc(2, sizeof *match->flow);
> +    match->flows[1] = match->flows[0] + 1;
> +    match->tun_md = NULL;
> +}
> +
>  /* Initializes 'dst' as a copy of 'src'.  The caller must eventually free
> 'dst'
>   * with minimatch_destroy(). */
>  void
> @@ -1718,6 +1727,16 @@ minimatch_equal(const struct minimatch *a, const
> struct minimatch *b)
>          && miniflow_equal(a->flow, b->flow);
>  }
>
> +/* Returns a hash value for the flow and wildcards in 'match', starting
> from
> + * 'basis'. */
> +uint32_t
> +minimatch_hash(const struct minimatch *match, uint32_t basis)
> +{
> +    size_t n_values = miniflow_n_values(match->flow);
> +    size_t flow_size = sizeof *match->flow +
> MINIFLOW_VALUES_SIZE(n_values);
> +    return hash_bytes(match->flow, 2 * flow_size, basis);
> +}
> +
>  /* Returns true if 'target' satisifies 'match', that is, if each bit for
> which
>   * 'match' specifies a particular value has the correct value in 'target'.
>   *
> @@ -1771,3 +1790,28 @@ minimatch_to_string(const struct minimatch *match,
>      minimatch_expand(match, &megamatch);
>      return match_to_string(&megamatch, port_map, priority);
>  }
> +
> +static bool
> +minimatch_has_default_recirc_id(const struct minimatch *m)
> +{
> +    uint32_t flow_recirc_id = miniflow_get_recirc_id(m->flow);
> +    uint32_t mask_recirc_id = miniflow_get_recirc_id(&m->mask->masks);
> +    return flow_recirc_id == 0 && (mask_recirc_id == UINT32_MAX ||
> +                                   mask_recirc_id == 0);
> +}
> +
> +static bool
> +minimatch_has_default_dp_hash(const struct minimatch *m)
> +{
> +    return (!miniflow_get_dp_hash(m->flow)
> +            && !miniflow_get_dp_hash(&m->mask->masks));
> +}
> +
> +/* Return true if the hidden fields of the match are set to the default
> values.
> + * The default values equals to those set up by
> match_init_hidden_fields(). */
> +bool
> +minimatch_has_default_hidden_fields(const struct minimatch *m)
> +{
> +    return (minimatch_has_default_recirc_id(m)
> +            && minimatch_has_default_dp_hash(m));
> +}
> --
> 2.16.1
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>

LGTM.

Reviewed-by: Armando Migliaccio <armamig at gmail.com>


More information about the dev mailing list