merge: branch 'bg/ovs-bridge-ext-port'

ovs: only keep bridges and ports with NM interfaces attached

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2193

(cherry picked from commit e8e0d43f04)
This commit is contained in:
Beniamino Galvani 2025-04-29 07:18:27 +00:00 committed by Íñigo Huguet
commit 4e240c493d

View file

@ -1374,88 +1374,113 @@ _delete_interface(NMOvsdb *self, json_t *params, const char *ifname)
nm_auto_decref_json json_t *bridges = NULL;
nm_auto_decref_json json_t *new_bridges = NULL;
gboolean bridges_changed;
gboolean ports_changed;
gboolean interfaces_changed;
int pi;
int ii;
bridges = json_array();
new_bridges = json_array();
bridges_changed = FALSE;
/* Loop over all bridges */
g_hash_table_iter_init(&iter, priv->bridges);
while (g_hash_table_iter_next(&iter, (gpointer) &ovs_bridge, NULL)) {
nm_auto_decref_json json_t *ports = NULL;
nm_auto_decref_json json_t *new_ports = NULL;
nm_auto_decref_json json_t *ports = NULL;
nm_auto_decref_json json_t *new_ports = NULL;
guint num_nm_ports = 0;
gboolean ports_changed = FALSE;
int pi;
ports = json_array();
new_ports = json_array();
ports_changed = FALSE;
ports = json_array();
new_ports = json_array();
/* Add the bridge UUID to the list of known bridges for the "expect" condition */
json_array_append_new(bridges, json_pack("[s,s]", "uuid", ovs_bridge->bridge_uuid));
if (!ovs_bridge->connection_uuid) {
/* Externally created, don't touch it */
json_array_append_new(new_bridges, json_pack("[s,s]", "uuid", ovs_bridge->bridge_uuid));
continue;
}
/* Loop over all bridge's ports */
for (pi = 0; pi < ovs_bridge->ports->len; pi++) {
nm_auto_decref_json json_t *interfaces = NULL;
nm_auto_decref_json json_t *new_interfaces = NULL;
nm_auto_decref_json json_t *interfaces = NULL;
nm_auto_decref_json json_t *new_interfaces = NULL;
guint num_nm_interfaces = 0;
gboolean interfaces_changed = FALSE;
int ii;
interfaces = json_array();
new_interfaces = json_array();
port_uuid = g_ptr_array_index(ovs_bridge->ports, pi);
ovs_port = g_hash_table_lookup(priv->ports, &port_uuid);
/* Add the port UUID to the list of known bridge port for the "expect" condition */
json_array_append_new(ports, json_pack("[s,s]", "uuid", port_uuid));
interfaces_changed = FALSE;
if (!ovs_port) {
/* This would be a violation of ovsdb's reference integrity (a bug). */
_LOGW("Unknown port '%s' in bridge '%s'", port_uuid, ovs_bridge->bridge_uuid);
continue;
}
/* Loop over all port's interfaces */
for (ii = 0; ii < ovs_port->interfaces->len; ii++) {
interface_uuid = g_ptr_array_index(ovs_port->interfaces, ii);
ovs_interface = g_hash_table_lookup(priv->interfaces, &interface_uuid);
/* Add the interface UUID to the list of known port interfaces for the "expect" condition */
json_array_append_new(interfaces, json_pack("[s,s]", "uuid", interface_uuid));
if (ovs_interface) {
if (nm_streq(ovs_interface->name, ifname)) {
/* skip the interface */
/* We are deleting this interface, don't count it */
interfaces_changed = TRUE;
continue;
}
if (ovs_interface->connection_uuid)
num_nm_interfaces++;
} else {
/* This would be a violation of ovsdb's reference integrity (a bug). */
_LOGW("Unknown interface '%s' in port '%s'", interface_uuid, port_uuid);
}
/* Add the interface to the list of new interfaces to set on the port */
json_array_append_new(new_interfaces, json_pack("[s,s]", "uuid", interface_uuid));
}
if (json_array_size(new_interfaces) == 0) {
if (num_nm_interfaces == 0) {
/* The port no longer has any NM interface. Don't add it to "new_ports" and set
* ports_changed=TRUE, so that it will be deleted. */
ports_changed = TRUE;
} else {
if (interfaces_changed) {
/* An interface needs to be deleted from this port */
_expect_port_interfaces(params, ovs_port->name, interfaces);
_set_port_interfaces(params, ovs_port->name, new_interfaces);
}
/* The port is still alive */
json_array_append_new(new_ports, json_pack("[s,s]", "uuid", port_uuid));
if (ovs_port->connection_uuid)
num_nm_ports++;
}
}
if (json_array_size(new_ports) == 0) {
if (num_nm_ports == 0) {
/* The bridge no longer has any NM port. Don't add it to "new_bridges" and set
* bridges_changed=TRUE, so that it will be deleted. */
bridges_changed = TRUE;
} else {
if (ports_changed) {
/* A port needs to be deleted from this bridge */
_expect_bridge_ports(params, ovs_bridge->name, ports);
_set_bridge_ports(params, ovs_bridge->name, new_ports);
}
/* The bridge is still alive */
json_array_append_new(new_bridges, json_pack("[s,s]", "uuid", ovs_bridge->bridge_uuid));
}
}
if (bridges_changed) {
/* A port needs to be deleted from this bridge */
_expect_ovs_bridges(params, priv->db_uuid, bridges);
_set_ovs_bridges(params, priv->db_uuid, new_bridges);
}