summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2020-07-06 09:52:11 +0200
committerThomas Haller <thaller@redhat.com>2020-08-17 18:10:56 +0200
commitaddb18312591b4f8e45ca584eb946c62b424831a (patch)
treeaa4b079a1920bb53ffd37e81f137a23e922de517
parent352f505f96875136cd894555e1d02475047de15a (diff)
parent27f224a76552ed218d60acbf84090ffe9a3a70a2 (diff)
downloadNetworkManager-th/nm-1-18.tar.gz
ovs: merge branch 'bg/ovs-mac-pt2'th/nm-1-18
https://bugzilla.redhat.com/show_bug.cgi?id=1852106 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/557 (cherry picked from commit 15492e6c503be48b90602160c2099a965a00917b) (cherry picked from commit f819a7cabfed11e0f56302ee5ac9d1b8635581dc) (cherry picked from commit 8dc357dc11f735703965193a235b4a401bd38f31) (cherry picked from commit a9b3730bf296fbd3c2d553423a31bcd436f2df4b) (cherry picked from commit 3d349eb5fe106a67ace65c03e74adee4bf591a81)
-rw-r--r--src/devices/nm-device.c24
-rw-r--r--src/devices/ovs/nm-device-ovs-interface.c15
-rw-r--r--src/devices/ovs/nm-ovsdb.c114
3 files changed, 105 insertions, 48 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 86abdc183b..7fea915858 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -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;
diff --git a/src/devices/ovs/nm-device-ovs-interface.c b/src/devices/ovs/nm-device-ovs-interface.c
index f2919b4881..5d103c16fe 100644
--- a/src/devices/ovs/nm-device-ovs-interface.c
+++ b/src/devices/ovs/nm-device-ovs-interface.c
@@ -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);
}
diff --git a/src/devices/ovs/nm-ovsdb.c b/src/devices/ovs/nm-ovsdb.c
index 7e9214e867..cedcb1d9af 100644
--- a/src/devices/ovs/nm-ovsdb.c
+++ b/src/devices/ovs/nm-ovsdb.c
@@ -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"));
}
}