core: support slave devices in nm_platform_generate_connection()

Ask each device class to update the slave configuration for their
type of slave.
This commit is contained in:
Pavel Šimerda 2013-08-22 20:41:01 +02:00 committed by Dan Williams
parent 60b88d526c
commit 10f9b6c58b
5 changed files with 149 additions and 0 deletions

View file

@ -310,6 +310,54 @@ update_connection (NMDevice *device, NMConnection *connection)
}
}
/**
* nm_bridge_update_slave_connection:
* @slave: the slave #NMDevice, is *not* necessarily a bridge interface
* @connection: the #NMConnection to update with the bridge port settings
*
* Reads bridge port configuration and updates @connection with those
* properties.
*
* Returns: %TRUE if the port configuration was read and @connection updated,
* %FALSE if not.
*/
gboolean
nm_bridge_update_slave_connection (NMDevice *slave, NMConnection *connection)
{
NMSettingBridgePort *s_port;
int ifindex = nm_device_get_ifindex (slave);
const Option *option;
g_return_val_if_fail (NM_IS_DEVICE (slave), FALSE);
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
s_port = nm_connection_get_setting_bridge_port (connection);
if (!s_port) {
s_port = (NMSettingBridgePort *) nm_setting_bridge_port_new ();
nm_connection_add_setting (connection, NM_SETTING (s_port));
}
for (option = slave_options; option->name; option++) {
gs_free char *str = nm_platform_slave_get_option (ifindex, option->sysname);
int value;
if (str) {
value = strtol (str, NULL, 10);
/* See comments in set_sysfs_uint() about centiseconds. */
if (option->user_hz_compensate)
value /= 100;
g_object_set (s_port, option->name, value, NULL);
} else {
nm_log_warn (LOGD_BRIDGE, "(%s): failed to read bridge port setting '%s'",
nm_device_get_iface (slave), option->sysname);
}
}
return TRUE;
}
static NMActStageReturn
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
{

View file

@ -57,6 +57,8 @@ GType nm_device_bridge_get_type (void);
NMDevice *nm_device_bridge_new (NMPlatformLink *platform_device);
NMDevice *nm_device_bridge_new_for_connection (NMConnection *connection);
gboolean nm_bridge_update_slave_connection (NMDevice *slave, NMConnection *connection);
G_END_DECLS
#endif /* NM_DEVICE_BRIDGE_H */

View file

@ -31,6 +31,7 @@
#if WITH_TEAMDCTL
#include <teamdctl.h>
#endif
#include <stdlib.h>
#include "nm-device-team.h"
#include "nm-logging.h"
@ -246,6 +247,61 @@ update_connection (NMDevice *device, NMConnection *connection)
/******************************************************************/
gboolean
nm_team_update_slave_connection (NMDevice *slave, NMConnection *connection)
{
NMSettingTeamPort *s_port;
const char *iface = nm_device_get_iface (slave);
char *port_config = NULL;
gboolean success = FALSE;
#if WITH_TEAMDCTL
const char *master_iface;
int master_ifindex;
struct teamdctl *tdc;
int err;
#endif
g_return_val_if_fail (NM_IS_DEVICE (slave), FALSE);
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
#if WITH_TEAMDCTL
master_ifindex = nm_platform_link_get_master (nm_device_get_ifindex (slave));
g_assert (master_ifindex > 0);
master_iface = nm_platform_link_get_name (master_ifindex);
g_assert (master_iface);
tdc = teamdctl_alloc ();
g_assert (tdc);
err = teamdctl_connect (tdc, master_iface, NULL, NULL);
if (err) {
nm_log_err (LOGD_TEAM, "(%s): failed to connect to teamd for master %s",
iface, master_iface);
teamdctl_free (tdc);
return FALSE;
}
/* FIXME: wait for libteamd to implement getting port config */
/* port_config = teamdctl_port_config_get_raw (tdc, iface); */
teamdctl_free (tdc);
#endif
s_port = nm_connection_get_setting_team_port (connection);
if (!s_port) {
s_port = (NMSettingTeamPort *) nm_setting_team_port_new ();
nm_connection_add_setting (connection, NM_SETTING (s_port));
}
if (port_config) {
g_object_set (G_OBJECT (s_port), NM_SETTING_TEAM_PORT_CONFIG, port_config, NULL);
free (port_config);
success = TRUE;
} else
nm_log_err (LOGD_TEAM, "(%s): failed to read teamd port configuration", iface);
return success;
}
/******************************************************************/
static gboolean
ensure_killed (gpointer data)
{

View file

@ -57,6 +57,8 @@ GType nm_device_team_get_type (void);
NMDevice *nm_device_team_new (NMPlatformLink *platform_device);
NMDevice *nm_device_team_new_for_connection (NMConnection *connection);
gboolean nm_team_update_slave_connection (NMDevice *slave, NMConnection *connection);
G_END_DECLS
#endif /* NM_DEVICE_TEAM_H */

View file

@ -69,6 +69,10 @@
#include "nm-config.h"
#include "nm-platform.h"
#include "nm-device-bridge.h"
#include "nm-device-bond.h"
#include "nm-device-team.h"
static void impl_device_disconnect (NMDevice *device, DBusGMethodInvocation *context);
#include "nm-device-glue.h"
@ -1634,12 +1638,14 @@ nm_device_generate_connection (NMDevice *device)
NMDeviceClass *klass = NM_DEVICE_GET_CLASS (device);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
const char *ifname = nm_device_get_iface (device);
int ifindex = nm_device_get_ifindex (device);
NMConnection *connection;
NMSetting *s_con;
NMSetting *s_ip4;
NMSetting *s_ip6;
gs_free char *uuid = NULL;
gs_free char *name = NULL;
int master_ifindex = 0;
/* If update_connection() is not implemented, just fail. */
if (!klass->update_connection)
@ -1666,6 +1672,41 @@ nm_device_generate_connection (NMDevice *device)
g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, klass->connection_type, NULL);
nm_connection_add_setting (connection, s_con);
/* If the device is a slave, update various slave settings */
if (ifindex)
master_ifindex = nm_platform_link_get_master (ifindex);
if (master_ifindex) {
const char *master_iface = nm_platform_link_get_name (master_ifindex);
const char *slave_type = NULL;
gboolean success = FALSE;
switch (nm_platform_link_get_type (master_ifindex)) {
case NM_LINK_TYPE_BRIDGE:
slave_type = NM_SETTING_BRIDGE_SETTING_NAME;
success = nm_bridge_update_slave_connection (device, connection);
break;
case NM_LINK_TYPE_BOND:
slave_type = NM_SETTING_BOND_SETTING_NAME;
success = TRUE;
break;
case NM_LINK_TYPE_TEAM:
slave_type = NM_SETTING_TEAM_SETTING_NAME;
success = nm_team_update_slave_connection (device, connection);
break;
default:
g_warn_if_reached ();
break;
}
if (!success)
nm_log_err (LOGD_DEVICE, "(%s): failed to read slave configuration", ifname);
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, master_iface,
NM_SETTING_CONNECTION_SLAVE_TYPE, slave_type,
NULL);
}
s_ip4 = nm_setting_ip4_config_new ();
nm_connection_add_setting (connection, s_ip4);
if (priv->ip4_config)