This commit introduces pipeline length validation between ovn-northd and ovn-controller, enabling dynamic adjustment of OpenFlow table numbering when pipeline dimensions change.
Runtime validation features: - Northd publishes pipeline lengths in SB_Global options - Controller detects length mismatches and dynamically renumbers tables - Full recompute triggered only when necessary for consistency The solution enables flexible upgrade scenarios where: - New northd versions can extend pipeline lengths without breaking older controllers. Signed-off-by: Alexandra Rukomoinikova <[email protected]> --- controller/ovn-controller.c | 53 ++++++++++++++++++++++++++++++++++++- lib/oftable.c | 47 ++++++++++++++++++++++++++++++++ lib/oftable.h | 3 +++ northd/en-global-config.c | 7 +++++ 4 files changed, 109 insertions(+), 1 deletion(-) diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c index f5935098f..b4d46435f 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -61,6 +61,7 @@ #include "lib/ovn-dirs.h" #include "lib/ovn-sb-idl.h" #include "lib/ovn-util.h" +#include "lib/oftable.h" #include "ovsport.h" #include "patch.h" #include "vif-plug.h" @@ -6465,6 +6466,52 @@ check_northd_version(struct ovsdb_idl *ovs_idl, struct ovsdb_idl *ovnsb_idl, return true; } +static bool +verify_pipeline_length_compatibility(struct ovsdb_idl *ovnsb_idl) +{ + bool pipeline_length_mismatch; + + const struct sbrec_sb_global *sb = sbrec_sb_global_first(ovnsb_idl); + if (!sb) { + pipeline_length_mismatch = true; + return false; + } + + /* No results found - indicates legacy northd version; + * preserve backward compatibility by skipping processing. */ + int northd_ingress_pipeline_len = smap_get_int(&sb->options, + "log-pipeline-ingress-len", + LOG_PIPELINE_INGRESS_LEN); + int northd_egress_pipeline_len = smap_get_int(&sb->options, + "log-pipeline-egress-len", + LOG_PIPELINE_EGRESS_LEN); + + /* Check if northd pipeline lengths differ from + * controller's configuration. */ + pipeline_length_mismatch = (northd_ingress_pipeline_len != + LOG_PIPELINE_INGRESS_LEN) || + (northd_egress_pipeline_len != + LOG_PIPELINE_EGRESS_LEN); + + /* If the pipeline lengths don't match, + * shift the table numbers and force a full recompute.*/ + if (pipeline_length_mismatch) { + VLOG_INFO("Pipeline length mismatch detected: " + "northd(ingress=%d, egress=%d) " + "vs controller(ingress=%d, egress=%d)", + northd_ingress_pipeline_len, + northd_egress_pipeline_len, + LOG_PIPELINE_INGRESS_LEN, + LOG_PIPELINE_EGRESS_LEN); + recalculate_oftable_offsets(northd_ingress_pipeline_len, + northd_egress_pipeline_len); + engine_set_force_recompute(); + } + + pipeline_length_mismatch = false; + return true; +} + static void br_int_remote_update(struct br_int_remote *remote, const struct ovsrec_bridge *br_int, @@ -7282,6 +7329,9 @@ main(int argc, char *argv[]) check_northd_version(ovs_idl_loop.idl, ovnsb_idl_loop.idl, ovn_version); + bool pipeline_length_match = + verify_pipeline_length_compatibility(ovnsb_idl_loop.idl); + init_validate_actions(ovs_idl_loop.idl); if (validate_actions.controller_validate_actions) { @@ -7326,7 +7376,8 @@ main(int argc, char *argv[]) if (ovsdb_idl_has_ever_connected(ovnsb_idl_loop.idl) && northd_version_match && cfg && - validate_actions.validated) { + validate_actions.validated && + pipeline_length_match) { /* Unconditionally remove all deleted lflows from the lflow * cache. */ diff --git a/lib/oftable.c b/lib/oftable.c index 721b3ad49..49f8c0cc5 100644 --- a/lib/oftable.c +++ b/lib/oftable.c @@ -15,6 +15,7 @@ #include <config.h> #include "lib/oftable.h" +#include "lib/ovn-util.h" int OFTABLE_PHY_TO_LOG = 0; @@ -53,3 +54,49 @@ int OFTABLE_FLOOD_REMOTE_CHASSIS = 84; int OFTABLE_CT_STATE_SAVE = 85; int OFTABLE_CT_ORIG_PROTO_LOAD = 86; int OFTABLE_GET_REMOTE_FDB = 87; + +void +recalculate_oftable_offsets(int new_ingress_len, + int new_egress_len) +{ + const int ingress_delta = + new_ingress_len - LOG_PIPELINE_INGRESS_LEN; + + OFTABLE_OUTPUT_LARGE_PKT_DETECT += ingress_delta; + OFTABLE_OUTPUT_INIT += ingress_delta; + OFTABLE_OUTPUT_LARGE_PKT_PROCESS += ingress_delta; + OFTABLE_REMOTE_OUTPUT += ingress_delta; + OFTABLE_REMOTE_VTEP_OUTPUT += ingress_delta; + OFTABLE_LOCAL_OUTPUT += ingress_delta; + OFTABLE_CHECK_LOOPBACK += ingress_delta; + + /* Start of LOG_PIPELINE_LEN tables. */ + OFTABLE_LOG_EGRESS_PIPELINE += ingress_delta; + OFTABLE_SAVE_INPORT += ingress_delta; + OFTABLE_LOG_TO_PHY += ingress_delta; + OFTABLE_MAC_BINDING += ingress_delta; + OFTABLE_MAC_LOOKUP += ingress_delta; + OFTABLE_CHK_LB_HAIRPIN += ingress_delta; + OFTABLE_CHK_LB_HAIRPIN_REPLY += ingress_delta; + OFTABLE_CT_SNAT_HAIRPIN += ingress_delta; + OFTABLE_GET_FDB += ingress_delta; + OFTABLE_LOOKUP_FDB += ingress_delta; + OFTABLE_CHK_IN_PORT_SEC += ingress_delta; + OFTABLE_CHK_IN_PORT_SEC_ND += ingress_delta; + OFTABLE_CHK_OUT_PORT_SEC += ingress_delta; + OFTABLE_ECMP_NH_MAC += ingress_delta; + OFTABLE_ECMP_NH += ingress_delta; + OFTABLE_CHK_LB_AFFINITY += ingress_delta; + OFTABLE_MAC_CACHE_USE += ingress_delta; + OFTABLE_CT_ZONE_LOOKUP += ingress_delta; + OFTABLE_CT_ORIG_NW_DST_LOAD += ingress_delta; + OFTABLE_CT_ORIG_IP6_DST_LOAD += ingress_delta; + OFTABLE_CT_ORIG_TP_DST_LOAD += ingress_delta; + OFTABLE_FLOOD_REMOTE_CHASSIS += ingress_delta; + OFTABLE_CT_STATE_SAVE += ingress_delta; + OFTABLE_CT_ORIG_PROTO_LOAD += ingress_delta; + OFTABLE_GET_REMOTE_FDB += ingress_delta; + + LOG_PIPELINE_INGRESS_LEN = new_ingress_len; + LOG_PIPELINE_EGRESS_LEN = new_egress_len; +} diff --git a/lib/oftable.h b/lib/oftable.h index 54425964d..ddabb65c5 100644 --- a/lib/oftable.h +++ b/lib/oftable.h @@ -56,3 +56,6 @@ extern int OFTABLE_FLOOD_REMOTE_CHASSIS; extern int OFTABLE_CT_STATE_SAVE; extern int OFTABLE_CT_ORIG_PROTO_LOAD; extern int OFTABLE_GET_REMOTE_FDB; + +void recalculate_oftable_offsets(int new_ingress_len, + int new_egress_len); diff --git a/northd/en-global-config.c b/northd/en-global-config.c index 51a991ce5..96a8dc690 100644 --- a/northd/en-global-config.c +++ b/northd/en-global-config.c @@ -682,6 +682,13 @@ update_sb_config_options_to_sbrec(struct ed_type_global_config *config_data, * register usage. */ smap_add(options, "register_consolidation", "true"); + + smap_add_format(options, "log-pipeline-ingress-len", + "%d", LOG_PIPELINE_INGRESS_LEN); + + smap_add_format(options, "log-pipeline-egress-len", + "%d", LOG_PIPELINE_EGRESS_LEN); + if (!smap_equal(&sb->options, options)) { sbrec_sb_global_set_options(sb, options); } -- 2.48.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
