If anyone disagrees with this approach and thinks I should do it the
other way of changing the schema to allow 0 encaps then let me know.

On 10/28/26 8:46 PM, Rosemarie O'Riorden wrote:
> This change makes it so that if a chassis has no encaps configured, the
> entire Chassis record is deleted.
> 
> If a chassis hv1 has encap A, and then encap A is removed from hv1,
> chassis hv2 should be able to use encap A. But this is not possible if
> the Encap record is still present in the sb db.
> 
> The reasoning for deleting the entire Chassis record rather than just
> its Encap is that a chassis is already considered misconfigured if it
> has no encaps set. We could allow encap-less chassis, but we already
> have the behavior established of deleting chassis with no valid encaps
> (if there are duplicates) in chassis_update(), and allowing 0 encaps
> would also require a schema change and checking for n_encaps>0 in many
> places.
> 
> So the easiest solution is just to remove the chassis record altogether.
> When encaps are readded, the chassis record will be recreated.
> 
> Reported-at: https://redhat.atlassian.net/browse/FDP-1945
> Signed-off-by: Rosemarie O'Riorden <[email protected]>
> ---
>  controller/chassis.c    | 46 +++++++++++++++++++++++++++++++------
>  tests/ovn-controller.at | 51 +++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 90 insertions(+), 7 deletions(-)
> 
> diff --git a/controller/chassis.c b/controller/chassis.c
> index b82683064..ed3d0e878 100644
> --- a/controller/chassis.c
> +++ b/controller/chassis.c
> @@ -82,6 +82,12 @@ enum chassis_update_status {
>      CHASSIS_NEED_DELETE
>  };
>  
> +enum chassis_parse_status {
> +    CHASSIS_PARSED,
> +    CHASSIS_NO_CFG,
> +    CHASSIS_DELETE_NO_ENCAPS,
> +};
> +
>  static void
>  ovs_chassis_cfg_init(struct ovs_chassis_cfg *cfg)
>  {
> @@ -303,9 +309,12 @@ chassis_parse_ovs_iface_types(char **iface_types, size_t 
> n_iface_types,
>  }
>  
>  /*
> - * Parse the 'ovs_table' entry and populate 'ovs_cfg'.
> + * Parse the 'ovs_table' entry and populate 'ovs_cfg'.  If successful,
> + * returns CHASSIS_PARSED.
> + * Otherwise, returns CHASSIS_NO_CFG if 'ovs_table' is NULL, or
> + * CHASSIS_DELETE_NO_ENCAPS if encap type or ip is NULL.
>   */
> -static bool
> +static enum chassis_parse_status
>  chassis_parse_ovs_config(const struct ovsrec_open_vswitch_table *ovs_table,
>                           const struct ovsrec_bridge *br_int,
>                           struct ovs_chassis_cfg *ovs_cfg)
> @@ -316,7 +325,7 @@ chassis_parse_ovs_config(const struct 
> ovsrec_open_vswitch_table *ovs_table,
>  
>      if (!cfg) {
>          VLOG_INFO("No Open_vSwitch row defined.");
> -        return false;
> +        return CHASSIS_NO_CFG;
>      }
>  
>      const char *chassis_id = get_ovs_chassis_id(ovs_table);
> @@ -328,8 +337,9 @@ chassis_parse_ovs_config(const struct 
> ovsrec_open_vswitch_table *ovs_table,
>          get_chassis_external_id_value(&cfg->external_ids, chassis_id,
>                                        "ovn-encap-ip", NULL);
>      if (!encap_type || !encap_ips) {
> -        VLOG_INFO_RL(&rl, "Need to specify an encap type and ip");
> -        return false;
> +        VLOG_WARN_RL(&rl, "No encap type and/or ip on chassis '%s'. Deleting 
> "
> +                     "chassis.", chassis_id);
> +        return CHASSIS_DELETE_NO_ENCAPS;
>      }
>  
>      ovs_cfg->hostname = get_hostname(&cfg->external_ids, chassis_id);
> @@ -386,7 +396,7 @@ chassis_parse_ovs_config(const struct 
> ovsrec_open_vswitch_table *ovs_table,
>      ovs_cfg->ct_label_flush =
>          ovs_feature_is_supported(OVS_CT_LABEL_FLUSH_SUPPORT);
>  
> -    return true;
> +    return CHASSIS_PARSED;
>  }
>  
>  static void
> @@ -958,7 +968,29 @@ chassis_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
>  
>      /* Get the chassis config from the ovs table. */
>      ovs_chassis_cfg_init(&ovs_cfg);
> -    if (!chassis_parse_ovs_config(ovs_table, br_int, &ovs_cfg)) {
> +    enum chassis_parse_status parse_status =
> +        chassis_parse_ovs_config(ovs_table, br_int, &ovs_cfg);
> +
> +    if (parse_status == CHASSIS_NO_CFG) {
> +        ovs_chassis_cfg_destroy(&ovs_cfg);
> +        return NULL;
> +    }
> +
> +    /* If no encaps are configured, delete the Chassis record. */
> +    if (parse_status == CHASSIS_DELETE_NO_ENCAPS) {
> +        const struct sbrec_chassis *chassis_rec =
> +            chassis_lookup_by_name(sbrec_chassis_by_name, chassis_id);
> +        if (chassis_rec && ovnsb_idl_txn) {
> +            sbrec_chassis_delete(chassis_rec);
> +        }
> +        *chassis_private =
> +            chassis_private_lookup_by_name(sbrec_chassis_private_by_name,
> +                                           chassis_id);
> +        if (*chassis_private && ovnsb_idl_txn) {
> +            sbrec_chassis_private_delete(*chassis_private);
> +        }
> +
> +        ovs_chassis_cfg_destroy(&ovs_cfg);
>          return NULL;
>      }
>  
> diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at
> index d600ba2cd..4d1860136 100644
> --- a/tests/ovn-controller.at
> +++ b/tests/ovn-controller.at
> @@ -4520,3 +4520,54 @@ done
>  OVN_CLEANUP([gw1],[gw3],[hv2])
>  AT_CLEANUP
>  ])
> +
> +OVN_FOR_EACH_NORTHD([
> +AT_SETUP([ovn-controller - remove encap from chassis add to other chassis])
> +AT_KEYWORDS([ovn])
> +ovn_start
> +net_add n1
> +
> +sim_add hv1
> +as hv1 check ovs-vsctl add-br br-phys
> +ovn_attach n1 br-phys 192.168.0.11
> +
> +sim_add hv2
> +as hv2 check ovs-vsctl add-br br-phys
> +ovn_attach n1 br-phys 192.168.0.12
> +
> +as hv2
> +OVS_WAIT_FOR_OUTPUT([ovs-vsctl find Interface type=geneve | grep -c _uuid], 
> [0], [1
> +])
> +
> +as hv1
> +OVS_WAIT_FOR_OUTPUT([ovs-vsctl find Interface type=geneve | grep -c _uuid], 
> [0], [1
> +])
> +wait_row_count Encap 4
> +wait_row_count Chassis 2
> +
> +# Remove hv1's encap.
> +as hv1 check ovs-vsctl remove Open_vSwitch . external-ids 
> ovn-encap-ip="192.168.0.11"
> +check ovn-nbctl --wait=sb sync
> +
> +# Make sure that hv1's chassis rec was deleted from sb.  And of course with
> +# that its encaps too.
> +OVS_WAIT_UNTIL([test $(ovn-sbctl --bare find Encap chassis_name=hv1 
> ip="192.168.0.11" | wc -l) -eq 0])
> +wait_row_count Encap 0 chassis_name="hv1" ip="192.168.0.11"
> +wait_row_count Chassis 0 name="hv1"
> +OVS_WAIT_UNTIL([grep -q "No encap type and/or ip on chassis 'hv1'. Deleting 
> chassis."  hv1/ovn-controller.log
> +])
> +
> +# Assign hv1's old encap ip to hv2.  Verify it worked.
> +as hv2 check ovs-vsctl set Open_vSwitch . 
> external-ids:ovn-encap-ip="192.168.0.11"
> +wait_row_count Encap 0 chassis_name="hv2" ip="192.168.0.12"
> +wait_row_count Encap 2 chassis_name="hv2" ip="192.168.0.11"
> +
> +# Now give hv1 a new different encap ip.  Verify the chassis is back.
> +as hv1 check ovs-vsctl set Open_vSwitch . 
> external-ids:ovn-encap-ip="192.168.0.13"
> +check ovn-nbctl --wait=hv sync
> +wait_row_count Encap 2 chassis_name="hv1" ip="192.168.0.13"
> +wait_row_count Chassis 1 name="hv1"
> +
> +OVN_CLEANUP([hv1],[hv2])
> +AT_CLEANUP
> +])

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to