ovs: merge branch 'bg/ovs-mac-pt2'

https://bugzilla.redhat.com/show_bug.cgi?id=1852106
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/557
(cherry picked from commit 15492e6c50)

(cherry picked from commit f819a7cabf)

(cherry picked from commit 8dc357dc11)

(cherry picked from commit a9b3730bf2)

(cherry picked from commit 3d349eb5fe)
This commit is contained in:
Beniamino Galvani 2020-07-06 09:52:11 +02:00 committed by Thomas Haller
commit 5071909e7c
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
3 changed files with 105 additions and 48 deletions

View file

@ -14649,17 +14649,19 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason, CleanupType clean
nm_device_update_metered (self);
/* during device cleanup, we want to reset the MAC address of the device
* to the initial state.
*
* We certainly want to do that when reaching the UNMANAGED state... */
if (nm_device_get_state (self) <= NM_DEVICE_STATE_UNMANAGED)
nm_device_hw_addr_reset (self, "unmanage");
else {
/* for other device states (UNAVAILABLE, DISCONNECTED), allow the
* device to overwrite the reset behavior, so that Wi-Fi can set
* a randomized MAC address used during scanning. */
NM_DEVICE_GET_CLASS (self)->deactivate_reset_hw_addr (self);
if (ifindex > 0) {
/* during device cleanup, we want to reset the MAC address of the device
* to the initial state.
*
* We certainly want to do that when reaching the UNMANAGED state... */
if (nm_device_get_state (self) <= NM_DEVICE_STATE_UNMANAGED)
nm_device_hw_addr_reset (self, "unmanage");
else {
/* for other device states (UNAVAILABLE, DISCONNECTED), allow the
* device to overwrite the reset behavior, so that Wi-Fi can set
* a randomized MAC address used during scanning. */
NM_DEVICE_GET_CLASS (self)->deactivate_reset_hw_addr (self);
}
}
priv->mtu_source = NM_DEVICE_MTU_SOURCE_NONE;

View file

@ -117,6 +117,14 @@ link_changed (NMDevice *device,
priv->waiting_for_interface = FALSE;
if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) {
if (!nm_device_hw_addr_set_cloned (device,
nm_device_get_applied_connection (device),
FALSE)) {
nm_device_state_changed (device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_CONFIG_FAILED);
return;
}
nm_device_bring_up (device, TRUE, NULL);
nm_device_activate_schedule_stage3_ip_config_start (device);
}
@ -189,6 +197,13 @@ act_stage3_ip_config_start (NMDevice *device,
return NM_ACT_STAGE_RETURN_POSTPONE;
}
if (!nm_device_hw_addr_set_cloned (device,
nm_device_get_applied_connection (device),
FALSE)) {
*out_failure_reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
return NM_ACT_STAGE_RETURN_FAILURE;
}
return NM_DEVICE_CLASS (nm_device_ovs_interface_parent_class)->act_stage3_ip_config_start (device, addr_family, out_config, out_failure_reason);
}

View file

@ -324,6 +324,18 @@ _set_bridge_ports (json_t *params, const char *ifname, json_t *new_ports)
);
}
static void
_set_bridge_mac (json_t *params, const char *ifname, const char *mac)
{
json_array_append_new (params,
json_pack ("{s:s, s:s, s:{s:[s, [[s, s]]]}, s:[[s, s, s]]}",
"op", "update", "table", "Bridge",
"row", "other_config", "map",
"hwaddr", mac,
"where", "name", "==", ifname)
);
}
/**
* _expect_port_interfaces:
*
@ -367,14 +379,15 @@ _set_port_interfaces (json_t *params, const char *ifname, json_t *new_interfaces
* Returns an commands that adds new interface from a given connection.
*/
static void
_insert_interface (json_t *params, NMConnection *interface, NMDevice *interface_device)
_insert_interface (json_t *params,
NMConnection *interface,
NMDevice *interface_device,
const char *cloned_mac)
{
const char *type = NULL;
NMSettingOvsInterface *s_ovs_iface;
NMSettingOvsPatch *s_ovs_patch;
json_t *options = json_array ();
gs_free char *cloned_mac = NULL;
gs_free_error GError *error = NULL;
json_t *row;
guint32 mtu = 0;
@ -390,18 +403,6 @@ _insert_interface (json_t *params, NMConnection *interface, NMDevice *interface_
mtu = nm_setting_wired_get_mtu (s_wired);
}
if (!nm_device_hw_addr_get_cloned (interface_device,
interface,
FALSE,
&cloned_mac,
NULL,
&error)) {
_LOGW ("Cannot determine cloned mac for OVS %s '%s': %s",
"interface",
nm_connection_get_interface_name (interface),
error->message);
}
json_array_append_new (options, json_string ("map"));
s_ovs_patch = nm_connection_get_setting_ovs_patch (interface);
if (s_ovs_patch) {
@ -494,7 +495,11 @@ _insert_port (json_t *params, NMConnection *port, json_t *new_interfaces)
* Returns an commands that adds new bridge from a given connection.
*/
static void
_insert_bridge (json_t *params, NMConnection *bridge, NMDevice *bridge_device, json_t *new_ports)
_insert_bridge (json_t *params,
NMConnection *bridge,
NMDevice *bridge_device,
json_t *new_ports,
const char *cloned_mac)
{
NMSettingOvsBridge *s_ovs_bridge;
const char *fail_mode = NULL;
@ -502,23 +507,9 @@ _insert_bridge (json_t *params, NMConnection *bridge, NMDevice *bridge_device, j
gboolean rstp_enable = FALSE;
gboolean stp_enable = FALSE;
json_t *row;
gs_free_error GError *error = NULL;
gs_free char *cloned_mac = NULL;
s_ovs_bridge = nm_connection_get_setting_ovs_bridge (bridge);
if (!nm_device_hw_addr_get_cloned (bridge_device,
bridge,
FALSE,
&cloned_mac,
NULL,
&error)) {
_LOGW ("Cannot determine cloned mac for OVS %s '%s': %s",
"bridge",
nm_connection_get_interface_name (bridge),
error->message);
}
row = json_object ();
if (s_ovs_bridge) {
@ -586,6 +577,9 @@ _add_interface (NMOvsdb *self, json_t *params,
const char *bridge_uuid;
const char *port_uuid;
const char *interface_uuid;
const char *bridge_name;
const char *port_name;
const char *interface_name;
OpenvswitchBridge *ovs_bridge = NULL;
OpenvswitchPort *ovs_port = NULL;
OpenvswitchInterface *ovs_interface = NULL;
@ -596,6 +590,10 @@ _add_interface (NMOvsdb *self, json_t *params,
nm_auto_decref_json json_t *interfaces = NULL;
nm_auto_decref_json json_t *new_interfaces = NULL;
gboolean has_interface = FALSE;
gboolean interface_is_internal;
gs_free char *bridge_cloned_mac = NULL;
gs_free char *interface_cloned_mac = NULL;
GError *error = NULL;
int pi;
int ii;
@ -606,11 +604,51 @@ _add_interface (NMOvsdb *self, json_t *params,
new_ports = json_array ();
new_interfaces = json_array ();
bridge_name = nm_connection_get_interface_name (bridge);
port_name = nm_connection_get_interface_name (port);
interface_name = nm_connection_get_interface_name (interface);
interface_is_internal = nm_streq0 (bridge_name, interface_name);
/* Determine cloned MAC addresses */
if (!nm_device_hw_addr_get_cloned (bridge_device,
bridge,
FALSE,
&bridge_cloned_mac,
NULL,
&error)) {
_LOGW ("Cannot determine cloned mac for OVS %s '%s': %s",
"bridge",
bridge_name,
error->message);
g_clear_error (&error);
}
if (!nm_device_hw_addr_get_cloned (interface_device,
interface,
FALSE,
&interface_cloned_mac,
NULL,
&error)) {
_LOGW ("Cannot determine cloned mac for OVS %s '%s': %s",
"interface",
interface_name,
error->message);
g_clear_error (&error);
}
if ( interface_is_internal
&& !bridge_cloned_mac
&& interface_cloned_mac) {
_LOGT ("'%s' is a local ovs-interface, the MAC will be set on ovs-bridge '%s'",
interface_name, bridge_name);
bridge_cloned_mac = g_steal_pointer (&interface_cloned_mac);
}
g_hash_table_iter_init (&iter, priv->bridges);
while (g_hash_table_iter_next (&iter, (gpointer) &bridge_uuid, (gpointer) &ovs_bridge)) {
json_array_append_new (bridges, json_pack ("[s, s]", "uuid", bridge_uuid));
if ( g_strcmp0 (ovs_bridge->name, nm_connection_get_interface_name (bridge)) != 0
if ( g_strcmp0 (ovs_bridge->name, bridge_name) != 0
|| g_strcmp0 (ovs_bridge->connection_uuid, nm_connection_get_uuid (bridge)) != 0)
continue;
@ -624,7 +662,7 @@ _add_interface (NMOvsdb *self, json_t *params,
/* This would be a violation of ovsdb's reference integrity (a bug). */
_LOGW ("Unknown port '%s' in bridge '%s'", port_uuid, bridge_uuid);
continue;
} else if ( strcmp (ovs_port->name, nm_connection_get_interface_name (port)) != 0
} else if ( strcmp (ovs_port->name, port_name) != 0
|| g_strcmp0 (ovs_port->connection_uuid, nm_connection_get_uuid (port)) != 0) {
continue;
}
@ -638,7 +676,7 @@ _add_interface (NMOvsdb *self, json_t *params,
if (!ovs_interface) {
/* This would be a violation of ovsdb's reference integrity (a bug). */
_LOGW ("Unknown interface '%s' in port '%s'", interface_uuid, port_uuid);
} else if ( strcmp (ovs_interface->name, nm_connection_get_interface_name (interface)) == 0
} else if ( strcmp (ovs_interface->name, interface_name) == 0
&& g_strcmp0 (ovs_interface->connection_uuid, nm_connection_get_uuid (interface)) == 0) {
has_interface = TRUE;
}
@ -661,12 +699,14 @@ _add_interface (NMOvsdb *self, json_t *params,
_expect_ovs_bridges (params, priv->db_uuid, bridges);
json_array_append_new (new_bridges, json_pack ("[s, s]", "named-uuid", "rowBridge"));
_set_ovs_bridges (params, priv->db_uuid, new_bridges);
_insert_bridge (params, bridge, bridge_device, new_ports);
_insert_bridge (params, bridge, bridge_device, new_ports, bridge_cloned_mac);
} else {
/* Bridge already exists. */
g_return_if_fail (ovs_bridge);
_expect_bridge_ports (params, ovs_bridge->name, ports);
_set_bridge_ports (params, nm_connection_get_interface_name (bridge), new_ports);
_set_bridge_ports (params, bridge_name, new_ports);
if (bridge_cloned_mac && interface_is_internal)
_set_bridge_mac (params, bridge_name, bridge_cloned_mac);
}
json_array_append_new (new_ports, json_pack ("[s, s]", "named-uuid", "rowPort"));
@ -675,11 +715,11 @@ _add_interface (NMOvsdb *self, json_t *params,
/* Port already exists */
g_return_if_fail (ovs_port);
_expect_port_interfaces (params, ovs_port->name, interfaces);
_set_port_interfaces (params, nm_connection_get_interface_name (port), new_interfaces);
_set_port_interfaces (params, port_name, new_interfaces);
}
if (!has_interface) {
_insert_interface (params, interface, interface_device);
_insert_interface (params, interface, interface_device, interface_cloned_mac);
json_array_append_new (new_interfaces, json_pack ("[s, s]", "named-uuid", "rowInterface"));
}
}