summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2019-10-24 15:59:43 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2020-01-15 13:27:32 +0100
commitc2d831d679ead8c8d5a2878e8d2e87f7cf7621f0 (patch)
tree7456768db67310ff8c8f9128ccef0e3c27435c74
parentf9431bbe500cec3f9febb05df9c5580fcbc0bdf5 (diff)
downloadNetworkManager-nm-1-12.tar.gz
ovs: allow changing mac address of bridges and interfacesnm-1-12
Allow changing the cloned MAC address for OVS bridges and interfaces. The MAC address set on the bridge is propagated by ovs to the local interface (the one with the same name as the bridge), while all other internal interfaces use the address defined in the interface connection. https://bugzilla.redhat.com/show_bug.cgi?id=1763734 https://bugzilla.redhat.com/show_bug.cgi?id=1740557 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/321 (cherry picked from commit 101e65d2bb1920853da4621e220b4825860ec46d) (cherry picked from commit b366234a3a1deb4a6924744f6b7cafa9f2650e3e) (cherry picked from commit 5a4a5f637bb65e9833836e724b3beea19158e9f8) (cherry picked from commit 46bb51d3d60ed9990debd7e311dd5916c32c4dc3) (cherry picked from commit d1dfeb4a5fb0e2bfb6043bb1eda6c76c2648476b)
-rw-r--r--clients/common/nm-meta-setting-desc.c1
-rw-r--r--src/devices/ovs/nm-device-ovs-port.c5
-rw-r--r--src/devices/ovs/nm-ovsdb.c88
-rw-r--r--src/devices/ovs/nm-ovsdb.h1
4 files changed, 79 insertions, 16 deletions
diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c
index 6c458afc6d..b13b522416 100644
--- a/clients/common/nm-meta-setting-desc.c
+++ b/clients/common/nm-meta-setting-desc.c
@@ -7781,6 +7781,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
.valid_parts = NM_META_SETTING_VALID_PARTS (
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
NM_META_SETTING_VALID_PART_ITEM (OVS_BRIDGE, TRUE),
+ NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
),
),
SETTING_INFO (OVS_INTERFACE,
diff --git a/src/devices/ovs/nm-device-ovs-port.c b/src/devices/ovs/nm-device-ovs-port.c
index e1243fd6b0..edeab2c664 100644
--- a/src/devices/ovs/nm-device-ovs-port.c
+++ b/src/devices/ovs/nm-device-ovs-port.c
@@ -128,6 +128,7 @@ enslave_slave (NMDevice *device, NMDevice *slave, NMConnection *connection, gboo
{
NMActiveConnection *ac_port = NULL;
NMActiveConnection *ac_bridge = NULL;
+ NMDevice *bridge_device;
if (!configure)
return TRUE;
@@ -137,10 +138,14 @@ enslave_slave (NMDevice *device, NMDevice *slave, NMConnection *connection, gboo
if (!ac_bridge)
ac_bridge = ac_port;
+ bridge_device = nm_active_connection_get_device (ac_bridge);
+
nm_ovsdb_add_interface (nm_ovsdb_get (),
nm_active_connection_get_applied_connection (ac_bridge),
nm_device_get_applied_connection (device),
nm_device_get_applied_connection (slave),
+ bridge_device,
+ slave,
add_iface_cb, g_object_ref (slave));
return TRUE;
diff --git a/src/devices/ovs/nm-ovsdb.c b/src/devices/ovs/nm-ovsdb.c
index ba592e7363..b60af94232 100644
--- a/src/devices/ovs/nm-ovsdb.c
+++ b/src/devices/ovs/nm-ovsdb.c
@@ -29,6 +29,7 @@
#include "devices/nm-device.h"
#include "platform/nm-platform.h"
#include "nm-core-internal.h"
+#include "devices/nm-device.h"
/*****************************************************************************/
@@ -132,6 +133,8 @@ typedef struct {
NMConnection *bridge;
NMConnection *port;
NMConnection *interface;
+ NMDevice *bridge_device;
+ NMDevice *interface_device;
};
};
} OvsdbMethodCall;
@@ -184,6 +187,7 @@ static void
ovsdb_call_method (NMOvsdb *self, OvsdbCommand command,
const char *ifname,
NMConnection *bridge, NMConnection *port, NMConnection *interface,
+ NMDevice *bridge_device, NMDevice *interface_device,
OvsdbMethodCallback callback, gpointer user_data)
{
NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE (self);
@@ -206,6 +210,8 @@ ovsdb_call_method (NMOvsdb *self, OvsdbCommand command,
call->bridge = nm_simple_connection_new_clone (bridge);
call->port = nm_simple_connection_new_clone (port);
call->interface = nm_simple_connection_new_clone (interface);
+ call->bridge_device = g_object_ref (bridge_device);
+ call->interface_device = g_object_ref (interface_device);
break;
case OVSDB_DEL_INTERFACE:
call->ifname = g_strdup (ifname);
@@ -338,17 +344,32 @@ _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)
+_insert_interface (json_t *params, NMConnection *interface, NMDevice *interface_device)
{
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;
s_ovs_iface = nm_connection_get_setting_ovs_interface (interface);
if (s_ovs_iface)
type = nm_setting_ovs_interface_get_interface_type (s_ovs_iface);
+ 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) {
@@ -359,14 +380,22 @@ _insert_interface (json_t *params, NMConnection *interface)
json_array_append_new (options, json_array ());
}
+ row = json_pack ("{s:s, s:s, s:o, s:[s, [[s, s]]]}",
+ "name", nm_connection_get_interface_name (interface),
+ "type", type ?: "",
+ "options", options,
+ "external_ids", "map",
+ "NM.connection.uuid", nm_connection_get_uuid (interface));
+
+ if (cloned_mac)
+ json_object_set_new (row, "mac", json_string (cloned_mac));
+
json_array_append_new (params,
- json_pack ("{s:s, s:s, s:{s:s, s:s, s:o, s:[s, [[s, s]]]}, s:s}",
- "op", "insert", "table", "Interface", "row",
- "name", nm_connection_get_interface_name (interface),
- "type", type ?: "",
- "options", options,
- "external_ids", "map", "NM.connection.uuid", nm_connection_get_uuid (interface),
- "uuid-name", "rowInterface"));
+ json_pack ("{s:s, s:s, s:o, s:s}",
+ "op", "insert",
+ "table", "Interface",
+ "row", row,
+ "uuid-name", "rowInterface"));
}
/**
@@ -430,7 +459,7 @@ _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, json_t *new_ports)
+_insert_bridge (json_t *params, NMConnection *bridge, NMDevice *bridge_device, json_t *new_ports)
{
NMSettingOvsBridge *s_ovs_bridge;
const char *fail_mode = NULL;
@@ -438,9 +467,23 @@ _insert_bridge (json_t *params, NMConnection *bridge, json_t *new_ports)
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) {
@@ -465,6 +508,12 @@ _insert_bridge (json_t *params, NMConnection *bridge, json_t *new_ports)
json_pack ("[s, [[s, s]]]", "map",
"NM.connection.uuid", nm_connection_get_uuid (bridge)));
+ if (cloned_mac) {
+ json_object_set_new (row, "other_config",
+ json_pack ("[s, [[s, s]]]", "map",
+ "hwaddr", cloned_mac));
+ }
+
/* Create a new one. */
json_array_append_new (params,
json_pack ("{s:s, s:s, s:o, s:s}", "op", "insert", "table", "Bridge",
@@ -494,7 +543,8 @@ _inc_next_cfg (const char *db_uuid)
*/
static void
_add_interface (NMOvsdb *self, json_t *params,
- NMConnection *bridge, NMConnection *port, NMConnection *interface)
+ NMConnection *bridge, NMConnection *port, NMConnection *interface,
+ NMDevice *bridge_device, NMDevice *interface_device)
{
NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE (self);
GHashTableIter iter;
@@ -564,7 +614,7 @@ _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, new_ports);
+ _insert_bridge (params, bridge, bridge_device, new_ports);
} else {
/* Bridge already exists. */
g_return_if_fail (ovs_bridge);
@@ -582,7 +632,7 @@ _add_interface (NMOvsdb *self, json_t *params,
}
if (!has_interface) {
- _insert_interface (params, interface);
+ _insert_interface (params, interface, interface_device);
json_array_append_new (new_interfaces, json_pack ("[s, s]", "named-uuid", "rowInterface"));
}
@@ -743,7 +793,8 @@ ovsdb_next_command (NMOvsdb *self)
json_array_append_new (params, json_string ("Open_vSwitch"));
json_array_append_new (params, _inc_next_cfg (priv->db_uuid));
- _add_interface (self, params, call->bridge, call->port, call->interface);
+ _add_interface (self, params, call->bridge, call->port, call->interface,
+ call->bridge_device, call->interface_device);
msg = json_pack ("{s:i, s:s, s:o}",
"id", call->id,
@@ -1397,7 +1448,7 @@ ovsdb_try_connect (NMOvsdb *self)
/* Queue a monitor call before any other command, ensuring that we have an up
* to date view of existing bridged that we need for add and remove ops. */
ovsdb_call_method (self, OVSDB_MONITOR, NULL,
- NULL, NULL, NULL, _monitor_bridges_cb, NULL);
+ NULL, NULL, NULL, NULL, NULL, _monitor_bridges_cb, NULL);
}
/*****************************************************************************/
@@ -1438,6 +1489,7 @@ out:
void
nm_ovsdb_add_interface (NMOvsdb *self,
NMConnection *bridge, NMConnection *port, NMConnection *interface,
+ NMDevice *bridge_device, NMDevice *interface_device,
NMOvsdbCallback callback, gpointer user_data)
{
OvsdbCall *call;
@@ -1447,7 +1499,9 @@ nm_ovsdb_add_interface (NMOvsdb *self,
call->user_data = user_data;
ovsdb_call_method (self, OVSDB_ADD_INTERFACE, NULL,
- bridge, port, interface, _transact_cb, call);
+ bridge, port, interface,
+ bridge_device, interface_device,
+ _transact_cb, call);
}
void
@@ -1461,7 +1515,7 @@ nm_ovsdb_del_interface (NMOvsdb *self, const char *ifname,
call->user_data = user_data;
ovsdb_call_method (self, OVSDB_DEL_INTERFACE, ifname,
- NULL, NULL, NULL, _transact_cb, call);
+ NULL, NULL, NULL, NULL, NULL, _transact_cb, call);
}
/*****************************************************************************/
@@ -1478,6 +1532,8 @@ _clear_call (gpointer data)
g_clear_object (&call->bridge);
g_clear_object (&call->port);
g_clear_object (&call->interface);
+ g_clear_object (&call->bridge_device);
+ g_clear_object (&call->interface_device);
break;
case OVSDB_DEL_INTERFACE:
g_clear_pointer (&call->ifname, g_free);
diff --git a/src/devices/ovs/nm-ovsdb.h b/src/devices/ovs/nm-ovsdb.h
index cf9fe2a21b..f9dbabbb7a 100644
--- a/src/devices/ovs/nm-ovsdb.h
+++ b/src/devices/ovs/nm-ovsdb.h
@@ -42,6 +42,7 @@ GType nm_ovsdb_get_type (void);
void nm_ovsdb_add_interface (NMOvsdb *self,
NMConnection *bridge, NMConnection *port, NMConnection *interface,
+ NMDevice *bridge_device, NMDevice *interface_device,
NMOvsdbCallback callback, gpointer user_data);
void nm_ovsdb_del_interface (NMOvsdb *self, const char *ifname,