diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c index 99aa0aff2c..eb7f5ad6fd 100644 --- a/src/devices/nm-device-bridge.c +++ b/src/devices/nm-device-bridge.c @@ -444,7 +444,7 @@ nm_device_bridge_new_for_connection (NMConnection *connection) iface = nm_connection_get_virtual_iface_name (connection); g_return_val_if_fail (iface != NULL, NULL); - if ( !nm_platform_bridge_add (iface) + if ( !nm_platform_bridge_add (iface, NULL, 0) && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { nm_log_warn (LOGD_DEVICE | LOGD_BRIDGE, "(%s): failed to create bridge master interface for '%s': %s", iface, nm_connection_get_id (connection), diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index 2da3181fe0..dce98d8a9b 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -185,7 +185,7 @@ link_added_emit (gpointer user_data) } static gboolean -link_add (NMPlatform *platform, const char *name, NMLinkType type) +link_add (NMPlatform *platform, const char *name, NMLinkType type, const void *address, size_t address_len) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); NMFakePlatformLink device; @@ -600,7 +600,7 @@ vlan_add (NMPlatform *platform, const char *name, int parent, int vlan_id, guint { NMFakePlatformLink *device; - if (!link_add (platform, name, NM_LINK_TYPE_VLAN)) + if (!link_add (platform, name, NM_LINK_TYPE_VLAN, NULL, 0)) return FALSE; device = link_get (platform, link_get_ifindex (platform, name)); @@ -651,7 +651,7 @@ infiniband_partition_add (NMPlatform *platform, int parent, int p_key) g_return_val_if_fail (parent_device != NULL, FALSE); name = g_strdup_printf ("%s.%04x", parent_device->link.name, p_key); - success = link_add (platform, name, NM_LINK_TYPE_INFINIBAND); + success = link_add (platform, name, NM_LINK_TYPE_INFINIBAND, NULL, 0); g_free (name); return success; @@ -1232,15 +1232,15 @@ static gboolean setup (NMPlatform *platform) { /* skip zero element */ - link_add (platform, NULL, NM_LINK_TYPE_NONE); + link_add (platform, NULL, NM_LINK_TYPE_NONE, NULL, 0); /* add loopback interface */ - link_add (platform, "lo", NM_LINK_TYPE_LOOPBACK); + link_add (platform, "lo", NM_LINK_TYPE_LOOPBACK, NULL, 0); /* add some ethernets */ - link_add (platform, "eth0", NM_LINK_TYPE_ETHERNET); - link_add (platform, "eth1", NM_LINK_TYPE_ETHERNET); - link_add (platform, "eth2", NM_LINK_TYPE_ETHERNET); + link_add (platform, "eth0", NM_LINK_TYPE_ETHERNET, NULL, 0); + link_add (platform, "eth1", NM_LINK_TYPE_ETHERNET, NULL, 0); + link_add (platform, "eth2", NM_LINK_TYPE_ETHERNET, NULL, 0); return TRUE; } diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 9b98bda051..3d7c307fb0 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -1871,9 +1871,10 @@ build_rtnl_link (int ifindex, const char *name, NMLinkType type) } static gboolean -link_add (NMPlatform *platform, const char *name, NMLinkType type) +link_add (NMPlatform *platform, const char *name, NMLinkType type, const void *address, size_t address_len) { int r; + struct nl_object *link; if (type == NM_LINK_TYPE_BOND) { /* When the kernel loads the bond module, either via explicit modprobe @@ -1891,7 +1892,15 @@ link_add (NMPlatform *platform, const char *name, NMLinkType type) debug ("link: add link '%s' of type '%s' (%d)", name, type_to_string (type), (int) type); - return add_object (platform, build_rtnl_link (0, name, type)); + link = build_rtnl_link (0, name, type); + + g_assert ( (address != NULL) ^ (address_len == 0) ); + if (address) { + auto_nl_addr struct nl_addr *nladdr = _nm_nl_addr_build (AF_LLC, address, address_len); + + rtnl_link_set_addr ((struct rtnl_link *) link, nladdr); + } + return add_object (platform, link); } static struct rtnl_link * diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 64802212ec..daa023ffdd 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -443,18 +443,21 @@ nm_platform_link_get_all (void) * nm_platform_link_add: * @name: Interface name * @type: Interface type + * @address: (allow-none): set the mac address of the link + * @address_len: the length of the @address * * Add a software interface. Sets platform->error to NM_PLATFORM_ERROR_EXISTS * if interface is already already exists. Any link-added signal will be * emitted from an idle handler and not within this function. */ static gboolean -nm_platform_link_add (const char *name, NMLinkType type) +nm_platform_link_add (const char *name, NMLinkType type, const void *address, size_t address_len) { reset_error (); g_return_val_if_fail (name, FALSE); g_return_val_if_fail (klass->link_add, FALSE); + g_return_val_if_fail ( (address != NULL) ^ (address_len == 0) , FALSE); if (nm_platform_link_exists (name)) { debug ("link: already exists"); @@ -462,7 +465,7 @@ nm_platform_link_add (const char *name, NMLinkType type) return FALSE; } - return klass->link_add (platform, name, type); + return klass->link_add (platform, name, type, address, address_len); } /** @@ -477,7 +480,7 @@ nm_platform_dummy_add (const char *name) g_return_val_if_fail (name, FALSE); debug ("link: adding dummy '%s'", name); - return nm_platform_link_add (name, NM_LINK_TYPE_DUMMY); + return nm_platform_link_add (name, NM_LINK_TYPE_DUMMY, NULL, 0); } /** @@ -985,14 +988,16 @@ nm_platform_link_get_master (int slave) /** * nm_platform_bridge_add: * @name: New interface name + * @address: (allow-none): set the mac address of the new bridge + * @address_len: the length of the @address * * Create a software bridge. */ gboolean -nm_platform_bridge_add (const char *name) +nm_platform_bridge_add (const char *name, const void *address, size_t address_len) { debug ("link: adding bridge '%s'", name); - return nm_platform_link_add (name, NM_LINK_TYPE_BRIDGE); + return nm_platform_link_add (name, NM_LINK_TYPE_BRIDGE, address, address_len); } /** @@ -1005,7 +1010,7 @@ gboolean nm_platform_bond_add (const char *name) { debug ("link: adding bond '%s'", name); - return nm_platform_link_add (name, NM_LINK_TYPE_BOND); + return nm_platform_link_add (name, NM_LINK_TYPE_BOND, NULL, 0); } /** @@ -1018,7 +1023,7 @@ gboolean nm_platform_team_add (const char *name) { debug ("link: adding team '%s'", name); - return nm_platform_link_add (name, NM_LINK_TYPE_TEAM); + return nm_platform_link_add (name, NM_LINK_TYPE_TEAM, NULL, 0); } /** diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 28800f895e..2353e6aab5 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -347,7 +347,7 @@ typedef struct { char * (*sysctl_get) (NMPlatform *, const char *path); GArray *(*link_get_all) (NMPlatform *); - gboolean (*link_add) (NMPlatform *, const char *name, NMLinkType type); + gboolean (*link_add) (NMPlatform *, const char *name, NMLinkType type, const void *address, size_t address_len); gboolean (*link_delete) (NMPlatform *, int ifindex); int (*link_get_ifindex) (NMPlatform *, const char *name); const char *(*link_get_name) (NMPlatform *, int ifindex); @@ -479,7 +479,7 @@ gint64 nm_platform_sysctl_get_int_checked (const char *path, guint base, gint64 GArray *nm_platform_link_get_all (void); gboolean nm_platform_dummy_add (const char *name); -gboolean nm_platform_bridge_add (const char *name); +gboolean nm_platform_bridge_add (const char *name, const void *address, size_t address_len); gboolean nm_platform_bond_add (const char *name); gboolean nm_platform_team_add (const char *name); gboolean nm_platform_link_exists (const char *name); diff --git a/src/platform/tests/platform.c b/src/platform/tests/platform.c index cd42c566f0..1802ac2c08 100644 --- a/src/platform/tests/platform.c +++ b/src/platform/tests/platform.c @@ -96,7 +96,7 @@ do_dummy_add (char **argv) static gboolean do_bridge_add (char **argv) { - return nm_platform_bridge_add (argv[0]); + return nm_platform_bridge_add (argv[0], NULL, 0); } static gboolean diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index 2be4b5f19f..1767d3c874 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -89,7 +89,7 @@ software_add (NMLinkType link_type, const char *name) case NM_LINK_TYPE_DUMMY: return nm_platform_dummy_add (name); case NM_LINK_TYPE_BRIDGE: - return nm_platform_bridge_add (name); + return nm_platform_bridge_add (name, NULL, 0); case NM_LINK_TYPE_BOND: { gboolean bond0_exists = nm_platform_link_exists ("bond0"); @@ -111,7 +111,7 @@ software_add (NMLinkType link_type, const char *name) /* Don't call link_callback for the bridge interface */ parent_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, PARENT_NAME); - if (nm_platform_bridge_add (PARENT_NAME)) + if (nm_platform_bridge_add (PARENT_NAME, NULL, 0)) wait_signal (parent_added); free_signal (parent_added);