On 10/8/23 06:21, Mike Pattrick wrote:
> Previously the mirror_set() and mirror_get() functions took a large
> number of parameters, which was inefficient and difficult to read and
> extend. This patch moves most of the parameters into a struct.
> 
> Signed-off-by: Mike Pattrick <m...@redhat.com>
> Acked-by: Simon Horman <ho...@ovn.org>
> Acked-by: Eelco Chaudron <echau...@redhat.com>
> 

Hi, Mike.  Thanks for the patch!

See some comments inline.

Best regards, Ilya Maximets.

> ---
> 
> v6:
>   - Changed a comment to be more grammatically correct
> ---
>  ofproto/ofproto-dpif-mirror.c | 61 ++++++++++++++++++-----------------
>  ofproto/ofproto-dpif-mirror.h | 31 +++++++++++++-----
>  ofproto/ofproto-dpif-xlate.c  | 25 ++++++--------
>  ofproto/ofproto-dpif.c        |  6 ++--
>  4 files changed, 67 insertions(+), 56 deletions(-)
> 
> diff --git a/ofproto/ofproto-dpif-mirror.c b/ofproto/ofproto-dpif-mirror.c
> index 343b75f0e..17ba6f799 100644
> --- a/ofproto/ofproto-dpif-mirror.c
> +++ b/ofproto/ofproto-dpif-mirror.c
> @@ -207,19 +207,23 @@ mirror_bundle_dst(struct mbridge *mbridge, struct 
> ofbundle *ofbundle)
>  }
> 
>  int
> -mirror_set(struct mbridge *mbridge, void *aux, const char *name,
> -           struct ofbundle **srcs, size_t n_srcs,
> -           struct ofbundle **dsts, size_t n_dsts,
> -           unsigned long *src_vlans, struct ofbundle *out_bundle,
> -           uint16_t snaplen,
> -           uint16_t out_vlan)
> +mirror_set(struct mbridge *mbridge, void *aux,
> +           const struct ofproto_mirror_settings *ms, struct ofbundle **srcs,
> +           struct ofbundle **dsts, struct ofbundle *bundle)
> +
>  {
>      struct mbundle *mbundle, *out;
>      mirror_mask_t mirror_bit;
>      struct mirror *mirror;
>      struct hmapx srcs_map;          /* Contains "struct ofbundle *"s. */
>      struct hmapx dsts_map;          /* Contains "struct ofbundle *"s. */
> +    uint16_t out_vlan;
> +
> +    if (!ms || !mbridge) {
> +        return EINVAL;
> +    }
> 
> +    out_vlan = ms->out_vlan;
>      mirror = mirror_lookup(mbridge, aux);
>      if (!mirror) {
>          int idx;
> @@ -227,7 +231,7 @@ mirror_set(struct mbridge *mbridge, void *aux, const char 
> *name,
>          idx = mirror_scan(mbridge);
>          if (idx < 0) {
>              VLOG_WARN("maximum of %d port mirrors reached, cannot create %s",
> -                      MAX_MIRRORS, name);
> +                      MAX_MIRRORS, ms->name);
>              return EFBIG;
>          }
> 
> @@ -242,8 +246,8 @@ mirror_set(struct mbridge *mbridge, void *aux, const char 
> *name,
>      unsigned long *vlans = ovsrcu_get(unsigned long *, &mirror->vlans);
> 
>      /* Get the new configuration. */
> -    if (out_bundle) {
> -        out = mbundle_lookup(mbridge, out_bundle);
> +    if (bundle) {
> +        out = mbundle_lookup(mbridge, bundle);
>          if (!out) {
>              mirror_destroy(mbridge, mirror->aux);
>              return EINVAL;
> @@ -252,16 +256,16 @@ mirror_set(struct mbridge *mbridge, void *aux, const 
> char *name,
>      } else {
>          out = NULL;
>      }
> -    mbundle_lookup_multiple(mbridge, srcs, n_srcs, &srcs_map);
> -    mbundle_lookup_multiple(mbridge, dsts, n_dsts, &dsts_map);
> +    mbundle_lookup_multiple(mbridge, srcs, ms->n_srcs, &srcs_map);
> +    mbundle_lookup_multiple(mbridge, dsts, ms->n_dsts, &dsts_map);

This doesn't look right.  ms->n_srcs is the number of entries
in ms->srcs.  mirror_set__() function knows that the sizes of these
arrays are the same, but we do not know that here in this function.
Looks very prone to errors.

> 
>      /* If the configuration has not changed, do nothing. */
>      if (hmapx_equals(&srcs_map, &mirror->srcs)
>          && hmapx_equals(&dsts_map, &mirror->dsts)
> -        && vlan_bitmap_equal(vlans, src_vlans)
> +        && vlan_bitmap_equal(vlans, ms->src_vlans)
>          && mirror->out == out
>          && mirror->out_vlan == out_vlan
> -        && mirror->snaplen == snaplen)
> +        && mirror->snaplen == ms->snaplen)
>      {
>          hmapx_destroy(&srcs_map);
>          hmapx_destroy(&dsts_map);
> @@ -275,15 +279,15 @@ mirror_set(struct mbridge *mbridge, void *aux, const 
> char *name,
>      hmapx_swap(&dsts_map, &mirror->dsts);
>      hmapx_destroy(&dsts_map);
> 
> -    if (vlans || src_vlans) {
> +    if (vlans || ms->src_vlans) {
>          ovsrcu_postpone(free, vlans);
> -        vlans = vlan_bitmap_clone(src_vlans);
> +        vlans = vlan_bitmap_clone(ms->src_vlans);
>          ovsrcu_set(&mirror->vlans, vlans);
>      }
> 
>      mirror->out = out;
>      mirror->out_vlan = out_vlan;
> -    mirror->snaplen = snaplen;
> +    mirror->snaplen = ms->snaplen;
> 
>      /* Update mbundles. */
>      mirror_bit = MIRROR_MASK_C(1) << mirror->idx;
> @@ -406,23 +410,22 @@ mirror_update_stats(struct mbridge *mbridge, 
> mirror_mask_t mirrors,
>  /* Retrieves the mirror numbered 'index' in 'mbridge'.  Returns true if such 
> a
>   * mirror exists, false otherwise.
>   *
> - * If successful, '*vlans' receives the mirror's VLAN membership information,
> + * If successful 'mc->vlans' receives the mirror's VLAN membership 
> information,
>   * either a null pointer if the mirror includes all VLANs or a 4096-bit 
> bitmap
>   * in which a 1-bit indicates that the mirror includes a particular VLAN,
> - * '*dup_mirrors' receives a bitmap of mirrors whose output duplicates mirror
> - * 'index', '*out' receives the output ofbundle (if any), and '*out_vlan'
> - * receives the output VLAN (if any).
> + * 'mc->dup_mirrors' receives a bitmap of mirrors whose output duplicates
> + * mirror 'index', 'mc->out' receives the output ofbundle (if any),
> + * and 'mc->out_vlan' receives the output VLAN (if any).
>   *
>   * Everything returned here is assumed to be RCU protected.
>   */
>  bool
> -mirror_get(struct mbridge *mbridge, int index, const unsigned long **vlans,
> -           mirror_mask_t *dup_mirrors, struct ofbundle **out,
> -           int *snaplen, int *out_vlan)
> +mirror_get(struct mbridge *mbridge, int index,
> +           struct mirror_config *mc)
>  {
>      struct mirror *mirror;
> 
> -    if (!mbridge) {
> +    if (!mc || !mbridge) {
>          return false;
>      }
> 
> @@ -433,11 +436,11 @@ mirror_get(struct mbridge *mbridge, int index, const 
> unsigned long **vlans,
>      /* Assume 'mirror' is RCU protected, i.e., it will not be freed until 
> this
>       * thread quiesces. */
> 
> -    *vlans = ovsrcu_get(unsigned long *, &mirror->vlans);
> -    *dup_mirrors = mirror->dup_mirrors;
> -    *out = mirror->out ? mirror->out->ofbundle : NULL;
> -    *out_vlan = mirror->out_vlan;
> -    *snaplen = mirror->snaplen;
> +    mc->vlans = ovsrcu_get(unsigned long *, &mirror->vlans);
> +    mc->dup_mirrors = mirror->dup_mirrors;
> +    mc->bundle = mirror->out ? mirror->out->ofbundle : NULL;
> +    mc->out_vlan = mirror->out_vlan;
> +    mc->snaplen = mirror->snaplen;
>      return true;
>  }
>  
> diff --git a/ofproto/ofproto-dpif-mirror.h b/ofproto/ofproto-dpif-mirror.h
> index eed63ec4a..9d5a6d680 100644
> --- a/ofproto/ofproto-dpif-mirror.h
> +++ b/ofproto/ofproto-dpif-mirror.h
> @@ -22,9 +22,26 @@
>  #define MAX_MIRRORS 32
>  typedef uint32_t mirror_mask_t;
> 
> +struct ofproto_mirror_settings;
>  struct ofproto_dpif;
>  struct ofbundle;
> 
> +struct mirror_config {
> +    /* A bitmap of mirrors that duplicate the current mirror */

Period at the end of a comment.

> +    mirror_mask_t dup_mirrors;
> +
> +    /* VLANs of packets to select for mirroring. */
> +    unsigned long *vlans;       /* vlan_bitmap, NULL selects all VLANs. */
> +
> +    /* Output (mutually exclusive). */

'snaplen' is not mutually exclusive with bundle or out_vlan.

> +    struct ofbundle *bundle;    /* A registered ofbundle handle or NULL. */

Maybe call this 'out_bundle'?  Alternatively, we could create
an anonymous struct here named 'out' with two fields - 'vlan'
and 'bundle'.

> +    uint16_t out_vlan;          /* Output VLAN, only if out_bundle is NULL. 
> */

What excalty 'only if' means here?  The mirror structure is differentiating
unset value as -1, but here we have an unsigned field.  Will it be UNIT16_MAX
if not specified?  I'm a bit worried about type conversions.

> +    uint16_t snaplen;           /* Max size of a mirrored packet in bytes,
> +                                   if set to zero then no truncation will
> +                                   occur.  */

Each line in a block comment should start with a '*'.

> +};
> +
> +
>  /* The following functions are used by handler threads without any locking,
>   * assuming RCU protection. */
> 
> @@ -38,9 +55,8 @@ mirror_mask_t mirror_bundle_dst(struct mbridge *, struct 
> ofbundle *);
> 
>  void mirror_update_stats(struct mbridge*, mirror_mask_t, uint64_t packets,
>                           uint64_t bytes);
> -bool mirror_get(struct mbridge *, int index, const unsigned long **vlans,
> -                mirror_mask_t *dup_mirrors, struct ofbundle **out,
> -                int *snaplen, int *out_vlan);
> +bool mirror_get(struct mbridge *mbridge, int index,
> +                struct mirror_config *mc);
> 
>  /* The remaining functions are assumed to be called by the main thread only. 
> */
> 
> @@ -50,11 +66,10 @@ bool mbridge_need_revalidate(struct mbridge *);
>  void mbridge_register_bundle(struct mbridge *, struct ofbundle *);
>  void mbridge_unregister_bundle(struct mbridge *, struct ofbundle *);
> 
> -int mirror_set(struct mbridge *, void *aux, const char *name,
> -               struct ofbundle **srcs, size_t n_srcs,
> -               struct ofbundle **dsts, size_t n_dsts,
> -               unsigned long *src_vlans, struct ofbundle *out_bundle,
> -               uint16_t snaplen, uint16_t out_vlan);
> +int mirror_set(struct mbridge *mbridge, void *aux,
> +               const struct ofproto_mirror_settings *ms,
> +               struct ofbundle **srcs, struct ofbundle **dsts,
> +               struct ofbundle *bundle);
>  void mirror_destroy(struct mbridge *, void *aux);
>  int mirror_get_stats(struct mbridge *, void *aux, uint64_t *packets,
>                       uint64_t *bytes);
> diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> index be4bd6657..3746edf06 100644
> --- a/ofproto/ofproto-dpif-xlate.c
> +++ b/ofproto/ofproto-dpif-xlate.c
> @@ -2247,16 +2247,11 @@ mirror_packet(struct xlate_ctx *ctx, struct xbundle 
> *xbundle,
>       * 'used_mirrors', as long as some candidates remain.  */
>      mirror_mask_t used_mirrors = 0;
>      while (mirrors) {
> -        const unsigned long *vlans;
> -        mirror_mask_t dup_mirrors;
> -        struct ofbundle *out;
> -        int out_vlan;
> -        int snaplen;
> +        struct mirror_config mc;
> 
>          /* Get the details of the mirror represented by the rightmost 1-bit. 
> */
>          if (OVS_UNLIKELY(!mirror_get(xbridge->mbridge, raw_ctz(mirrors),
> -                                     &vlans, &dup_mirrors,
> -                                     &out, &snaplen, &out_vlan))) {
> +                                     &mc))) {

Might be better to split the line after the first argument.

>              /* The mirror got reconfigured before we got to read it's
>               * configuration. */
>              mirrors = zero_rightmost_1bit(mirrors);
> @@ -2266,10 +2261,10 @@ mirror_packet(struct xlate_ctx *ctx, struct xbundle 
> *xbundle,
> 
>          /* If this mirror selects on the basis of VLAN, and it does not 
> select
>           * 'vlan', then discard this mirror and go on to the next one. */
> -        if (vlans) {
> +        if (mc.vlans) {
>              ctx->wc->masks.vlans[0].tci |= htons(VLAN_CFI | VLAN_VID_MASK);
>          }
> -        if (vlans && !bitmap_is_set(vlans, xvlan.v[0].vid)) {
> +        if (mc.vlans && !bitmap_is_set(mc.vlans, xvlan.v[0].vid)) {
>              mirrors = zero_rightmost_1bit(mirrors);
>              continue;
>          }
> @@ -2281,21 +2276,21 @@ mirror_packet(struct xlate_ctx *ctx, struct xbundle 
> *xbundle,
>           * destination, so that we don't mirror to them again.  This must be
>           * done now to ensure that output_normal(), below, doesn't 
> recursively
>           * output to the same mirrors. */
> -        ctx->mirrors |= dup_mirrors;
> -        ctx->mirror_snaplen = snaplen;
> +        ctx->mirrors |= mc.dup_mirrors;
> +        ctx->mirror_snaplen = mc.snaplen;
> 
>          /* Send the packet to the mirror. */
> -        if (out) {
> -            struct xbundle *out_xbundle = xbundle_lookup(ctx->xcfg, out);
> +        if (mc.bundle) {
> +            struct xbundle *out_xbundle = xbundle_lookup(ctx->xcfg, 
> mc.bundle);
>              if (out_xbundle) {
>                  output_normal(ctx, out_xbundle, &xvlan);
>              }
> -        } else if (xvlan.v[0].vid != out_vlan
> +        } else if (xvlan.v[0].vid != mc.out_vlan
>                     && !eth_addr_is_reserved(ctx->xin->flow.dl_dst)) {
>              struct xbundle *xb;
>              uint16_t old_vid = xvlan.v[0].vid;
> 
> -            xvlan.v[0].vid = out_vlan;
> +            xvlan.v[0].vid = mc.out_vlan;
>              LIST_FOR_EACH (xb, list_node, &xbridge->xbundles) {
>                  if (xbundle_includes_vlan(xb, &xvlan)
>                      && !xbundle_mirror_out(xbridge, xb)) {
> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> index ba5706f6a..5a5a8ea86 100644
> --- a/ofproto/ofproto-dpif.c
> +++ b/ofproto/ofproto-dpif.c
> @@ -3663,10 +3663,8 @@ mirror_set__(struct ofproto *ofproto_, void *aux,
>          dsts[i] = bundle_lookup(ofproto, s->dsts[i]);
>      }
> 
> -    error = mirror_set(ofproto->mbridge, aux, s->name, srcs, s->n_srcs, dsts,
> -                       s->n_dsts, s->src_vlans,
> -                       bundle_lookup(ofproto, s->out_bundle),
> -                       s->snaplen, s->out_vlan);
> +    error = mirror_set(ofproto->mbridge, aux, s, srcs, dsts,
> +                       bundle_lookup(ofproto, s->out_bundle));
>      free(srcs);
>      free(dsts);
>      return error;
> --
> 2.39.3

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to