platform: allow setting address when adding software link (bridge)

Add an additional address parameter to link_add/bridge_add, to set the
MAC address of software devices.

https://bugzilla.gnome.org/show_bug.cgi?id=729844

Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
Thomas Haller 2014-05-13 18:13:52 +02:00
parent a03a76ea60
commit 968b468b2f
7 changed files with 37 additions and 23 deletions

View file

@ -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),

View file

@ -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;
}

View file

@ -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 *

View file

@ -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);
}
/**

View file

@ -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);

View file

@ -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

View file

@ -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);