On Mon, Dec 16, 2024 at 8:03 PM Mark Michelson <[email protected]> wrote:

> This capability is not in all OVS versions, so we need to check for it
> in order to use it.
>
> A future commit will make use of this feature, so this lays the
> groundwork for being able to confirm if chassis all support being able
> to flush CT entries using label or mark bits.
>
> Signed-off-by: Mark Michelson <[email protected]>
> ---
> v2 -> v3:
>  * No changes
>
> v1 -> v2:
>  * Added this patch to the series
> ---
>  controller/chassis.c      | 15 +++++++++++
>  include/ovn/features.h    |  3 +++
>  lib/features.c            | 57 ++++++++++++++++++++++++++++++++++++++-
>  northd/en-global-config.c | 10 +++++++
>  northd/en-global-config.h |  1 +
>  5 files changed, 85 insertions(+), 1 deletion(-)
>
> diff --git a/controller/chassis.c b/controller/chassis.c
> index 8b1964c54..e14f438f4 100644
> --- a/controller/chassis.c
> +++ b/controller/chassis.c
> @@ -71,6 +71,8 @@ struct ovs_chassis_cfg {
>      bool is_interconn;
>      /* Does OVS support sampling with ids taken from registers? */
>      bool sample_with_regs;
> +    /* Does OVS support flushing CT zones using label/mark? */
> +    bool ct_label_flush;
>  };
>
>  static void
> @@ -354,6 +356,8 @@ chassis_parse_ovs_config(const struct
> ovsrec_open_vswitch_table *ovs_table,
>      ovs_cfg->is_interconn = get_is_interconn(&cfg->external_ids,
> chassis_id);
>      ovs_cfg->sample_with_regs =
>          ovs_feature_is_supported(OVS_SAMPLE_REG_SUPPORT);
> +    ovs_cfg->ct_label_flush =
> +        ovs_feature_is_supported(OVS_CT_LABEL_FLUSH_SUPPORT);
>
>      return true;
>  }
> @@ -391,6 +395,8 @@ chassis_build_other_config(const struct
> ovs_chassis_cfg *ovs_cfg,
>      smap_replace(config, OVN_FEATURE_SAMPLE_WITH_REGISTERS,
>                   ovs_cfg->sample_with_regs ? "true" : "false");
>      smap_replace(config, OVN_FEATURE_CT_NEXT_ZONE, "true");
> +    smap_replace(config, OVN_FEATURE_CT_LABEL_FLUSH,
> +                 ovs_cfg->ct_label_flush ? "true" :"false");
>  }
>
>  /*
> @@ -556,6 +562,14 @@ chassis_other_config_changed(const struct
> ovs_chassis_cfg *ovs_cfg,
>          return true;
>      }
>
> +    bool chassis_ct_label_flush =
> +        smap_get_bool(&chassis_rec->other_config,
> +                      OVN_FEATURE_CT_LABEL_FLUSH,
> +                      false);
> +    if (chassis_ct_label_flush != ovs_cfg->ct_label_flush) {
> +        return true;
> +    }
> +
>      return false;
>  }
>
> @@ -714,6 +728,7 @@ update_supported_sset(struct sset *supported)
>      sset_add(supported, OVN_FEATURE_CT_COMMIT_TO_ZONE);
>      sset_add(supported, OVN_FEATURE_SAMPLE_WITH_REGISTERS);
>      sset_add(supported, OVN_FEATURE_CT_NEXT_ZONE);
> +    sset_add(supported, OVN_FEATURE_CT_LABEL_FLUSH);
>  }
>
>  static void
> diff --git a/include/ovn/features.h b/include/ovn/features.h
> index 3566ab60f..94595ba77 100644
> --- a/include/ovn/features.h
> +++ b/include/ovn/features.h
> @@ -31,6 +31,7 @@
>  #define OVN_FEATURE_CT_COMMIT_TO_ZONE "ct-commit-to-zone"
>  #define OVN_FEATURE_SAMPLE_WITH_REGISTERS "ovn-sample-with-registers"
>  #define OVN_FEATURE_CT_NEXT_ZONE "ct-next-zone"
> +#define OVN_FEATURE_CT_LABEL_FLUSH "ct-label-flush"
>
>  /* OVS datapath supported features.  Based on availability OVN might
> generate
>   * different types of openflows.
> @@ -42,6 +43,7 @@ enum ovs_feature_support_bits {
>      OVS_DP_HASH_L4_SYM_BIT,
>      OVS_OF_GROUP_SUPPORT_BIT,
>      OVS_SAMPLE_REG_SUPPORT_BIT,
> +    OVS_CT_LABEL_FLUSH_BIT,
>  };
>
>  enum ovs_feature_value {
> @@ -51,6 +53,7 @@ enum ovs_feature_value {
>      OVS_DP_HASH_L4_SYM_SUPPORT = (1 << OVS_DP_HASH_L4_SYM_BIT),
>      OVS_OF_GROUP_SUPPORT = (1 << OVS_OF_GROUP_SUPPORT_BIT),
>      OVS_SAMPLE_REG_SUPPORT = (1 << OVS_SAMPLE_REG_SUPPORT_BIT),
> +    OVS_CT_LABEL_FLUSH_SUPPORT = (1 << OVS_CT_LABEL_FLUSH_BIT),
>  };
>
>  void ovs_feature_support_destroy(void);
> diff --git a/lib/features.c b/lib/features.c
> index 98d56602c..11448bba8 100644
> --- a/lib/features.c
> +++ b/lib/features.c
> @@ -32,6 +32,7 @@
>  #include "openvswitch/ofp-group.h"
>  #include "openvswitch/ofp-print.h"
>  #include "openvswitch/ofp-util.h"
> +#include "openvswitch/ofp-ct.h"
>  #include "openvswitch/rconn.h"
>  #include "ovn/features.h"
>  #include "controller/ofctrl.h"
> @@ -268,6 +269,52 @@ sample_with_reg_handle_barrier(struct
> ovs_openflow_feature *feature OVS_UNUSED)
>      return true;
>  }
>
> +static void
> +ct_label_flush_send_request(struct ovs_openflow_feature *feature)
> +{
> +    /* At the time of this code being written, the highest bits
> +     * of the CT label are not used for anything. Setting these
> +     * is most likely to minimize flushing a valid CT entry by
> +     * mistake.
> +     */
> +    ovs_u128 ct_mask = {
> +        .u64.hi = 0x10000000,
> +    };
> +    ovs_u128 ct_value = {
> +        .u64.hi = 0x10000000,
> +    };
> +    struct ofp_ct_match match = {
> +        .labels = ct_value,
> +        .labels_mask = ct_mask,
> +        /* ICMP type 1 is unassigned. This should reduce the
> +         * risk of flushing legitimate CT entries by mistake
> +         */
> +        .tuple_orig.icmp_type = 1,
> +    };
> +
> +    struct ofpbuf *msg = ofp_ct_match_encode(&match, NULL,
> +                                             rconn_get_version(swconn));
> +    const struct ofp_header *oh = msg->data;
> +    feature->xid = oh->xid;
> +    rconn_send(swconn, msg, NULL);
> +}
> +
> +static bool
> +ct_label_flush_handle_response(struct ovs_openflow_feature *feature,
> +                               enum ofptype type, const struct ofp_header
> *oh)
> +{
> +    if (type != OFPTYPE_ERROR) {
> +        log_unexpected_reply(feature, oh);
> +    }
> +    return false;
> +}
> +
> +static bool
> +ct_label_flush_handle_barrier(struct ovs_openflow_feature *feature
> OVS_UNUSED)
> +{
> +    return true;
> +}
> +
>  static struct ovs_openflow_feature all_openflow_features[] = {
>          {
>              .value = OVS_DP_METER_SUPPORT,
> @@ -289,7 +336,14 @@ static struct ovs_openflow_feature
> all_openflow_features[] = {
>              .send_request = sample_with_reg_send_request,
>              .handle_response = sample_with_reg_handle_response,
>              .handle_barrier = sample_with_reg_handle_barrier,
> -        }
> +        },
> +        {
> +            .value = OVS_CT_LABEL_FLUSH_SUPPORT,
> +            .name = "ct_label_flush",
> +            .send_request = ct_label_flush_send_request,
> +            .handle_response = ct_label_flush_handle_response,
> +            .handle_barrier = ct_label_flush_handle_barrier,
> +        },
>  };
>
>  static bool
> @@ -362,6 +416,7 @@ ovs_feature_is_valid(enum ovs_feature_value feature)
>      case OVS_DP_HASH_L4_SYM_SUPPORT:
>      case OVS_OF_GROUP_SUPPORT:
>      case OVS_SAMPLE_REG_SUPPORT:
> +    case OVS_CT_LABEL_FLUSH_SUPPORT:
>          return true;
>      default:
>          return false;
> diff --git a/northd/en-global-config.c b/northd/en-global-config.c
> index fff2aaa16..ffe462b7c 100644
> --- a/northd/en-global-config.c
> +++ b/northd/en-global-config.c
> @@ -383,6 +383,7 @@ northd_enable_all_features(struct
> ed_type_global_config *data)
>          .ct_commit_to_zone = true,
>          .sample_with_reg = true,
>          .ct_next_zone = true,
> +        .ct_label_flush = true,
>      };
>  }
>
> @@ -462,6 +463,15 @@ build_chassis_features(const struct
> sbrec_chassis_table *sbrec_chassis_table,
>              chassis_features->ct_next_zone) {
>              chassis_features->ct_next_zone = false;
>          }
> +
> +        bool ct_label_flush =
> +                smap_get_bool(&chassis->other_config,
> +                              OVN_FEATURE_CT_LABEL_FLUSH,
> +                              false);
> +        if (!ct_label_flush &&
> +            chassis_features->ct_label_flush) {
> +            chassis_features->ct_label_flush = false;
> +        }
>      }
>  }
>
> diff --git a/northd/en-global-config.h b/northd/en-global-config.h
> index 767810542..a95ba2a6c 100644
> --- a/northd/en-global-config.h
> +++ b/northd/en-global-config.h
> @@ -21,6 +21,7 @@ struct chassis_features {
>      bool ct_commit_to_zone;
>      bool sample_with_reg;
>      bool ct_next_zone;
> +    bool ct_label_flush;
>  };
>
>  struct global_config_tracked_data {
> --
> 2.45.2
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
>
Looks good to me, thanks.

Acked-by: Ales Musil <[email protected]>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to