diff options
Diffstat (limited to 'src/devices/team/nm-device-team.c')
| -rw-r--r-- | src/devices/team/nm-device-team.c | 74 |
1 files changed, 57 insertions, 17 deletions
diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c index 28d91ab3..1c4d2ef6 100644 --- a/src/devices/team/nm-device-team.c +++ b/src/devices/team/nm-device-team.c @@ -28,6 +28,7 @@ #include <sys/wait.h> #include <teamdctl.h> #include <stdlib.h> +#include <jansson.h> #include "NetworkManagerUtils.h" #include "devices/nm-device-private.h" @@ -72,7 +73,7 @@ G_DEFINE_TYPE (NMDeviceTeam, nm_device_team, NM_TYPE_DEVICE) /*****************************************************************************/ -static gboolean teamd_start (NMDevice *device, NMSettingTeam *s_team); +static gboolean teamd_start (NMDevice *device, NMConnection *connection); /*****************************************************************************/ @@ -126,7 +127,7 @@ complete_connection (NMDevice *device, { NMSettingTeam *s_team; - nm_utils_complete_generic (NM_PLATFORM_GET, + nm_utils_complete_generic (nm_device_get_platform (device), connection, NM_SETTING_TEAM_SETTING_NAME, existing_connections, @@ -415,7 +416,7 @@ teamd_dbus_appeared (GDBusConnection *connection, success = teamd_read_config (device); if (success) nm_device_activate_schedule_stage2_device_config (device); - else if (!nm_device_uses_assumed_connection (device)) + else if (!nm_device_sys_iface_state_is_external_or_assume (device)) nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); } } @@ -449,7 +450,7 @@ teamd_dbus_vanished (GDBusConnection *dbus_connection, NMConnection *connection = nm_device_get_applied_connection (device); g_assert (connection); - if (!teamd_start (device, nm_connection_get_setting_team (connection))) + if (!teamd_start (device, connection)) nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); } } @@ -513,7 +514,7 @@ teamd_kill (NMDeviceTeam *self, const char *teamd_binary, GError **error) } static gboolean -teamd_start (NMDevice *device, NMSettingTeam *s_team) +teamd_start (NMDevice *device, NMConnection *connection) { NMDeviceTeam *self = NM_DEVICE_TEAM (device); NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); @@ -523,6 +524,12 @@ teamd_start (NMDevice *device, NMSettingTeam *s_team) gs_free char *tmp_str = NULL; const char *teamd_binary; const char *config; + nm_auto_free const char *config_free = NULL; + NMSettingTeam *s_team; + gs_free char *cloned_mac = NULL; + + s_team = nm_connection_get_setting_team (connection); + g_return_val_if_fail (s_team, FALSE); teamd_binary = nm_utils_find_helper ("teamd", NULL, NULL); if (!teamd_binary) { @@ -548,7 +555,39 @@ teamd_start (NMDevice *device, NMSettingTeam *s_team) g_ptr_array_add (argv, (gpointer) "-t"); g_ptr_array_add (argv, (gpointer) iface); - config = nm_setting_team_get_config(s_team); + config = nm_setting_team_get_config (s_team); + if (!nm_device_hw_addr_get_cloned (device, connection, FALSE, &cloned_mac, NULL, &error)) { + _LOGW (LOGD_DEVICE, "set-hw-addr: %s", error->message); + return FALSE; + } + + if (cloned_mac) { + json_t *json, *hwaddr; + json_error_t jerror; + + /* Inject the hwaddr property into the JSON configuration. + * While doing so, detect potential conflicts */ + + json = json_loads (config ?: "{}", 0, &jerror); + g_return_val_if_fail (json, FALSE); + + hwaddr = json_object_get (json, "hwaddr"); + if (hwaddr) { + if ( !json_is_string (hwaddr) + || !nm_streq0 (json_string_value (hwaddr), cloned_mac)) + _LOGW (LOGD_TEAM, "set-hw-addr: can't set team cloned-mac-address as the JSON configuration already contains \"hwaddr\""); + } else { + hwaddr = json_string (cloned_mac); + json_object_set (json, "hwaddr", hwaddr); + config = config_free = json_dumps (json, JSON_INDENT(0) | + JSON_ENSURE_ASCII | + JSON_SORT_KEYS); + _LOGD (LOGD_TEAM, "set-hw-addr: injected \"hwaddr\" \"%s\" into team configuration", cloned_mac); + json_decref (hwaddr); + } + json_decref (json); + } + if (config) { g_ptr_array_add (argv, (gpointer) "-c"); g_ptr_array_add (argv, (gpointer) config); @@ -580,23 +619,24 @@ teamd_start (NMDevice *device, NMSettingTeam *s_team) } static NMActStageReturn -act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) +act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) { NMDeviceTeam *self = NM_DEVICE_TEAM (device); NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; gs_free_error GError *error = NULL; NMSettingTeam *s_team; + NMConnection *connection; const char *cfg; - g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); - - ret = NM_DEVICE_CLASS (nm_device_team_parent_class)->act_stage1_prepare (device, reason); + ret = NM_DEVICE_CLASS (nm_device_team_parent_class)->act_stage1_prepare (device, out_failure_reason); if (ret != NM_ACT_STAGE_RETURN_SUCCESS) return ret; - s_team = (NMSettingTeam *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_TEAM); - g_assert (s_team); + connection = nm_device_get_applied_connection (device); + g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE); + s_team = nm_connection_get_setting_team (connection); + g_return_val_if_fail (s_team, NM_ACT_STAGE_RETURN_FAILURE); if (priv->tdc) { /* If the existing teamd config is the same as we're about to use, @@ -614,7 +654,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) _LOGD (LOGD_TEAM, "existing teamd config mismatch; killing existing via teamdctl"); if (!teamd_kill (self, NULL, &error)) { _LOGW (LOGD_TEAM, "existing teamd config mismatch; failed to kill existing teamd: %s", error->message); - *reason = NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED; + NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); return NM_ACT_STAGE_RETURN_FAILURE; } } @@ -623,7 +663,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) teamd_cleanup (device, TRUE); } - return teamd_start (device, s_team) ? + return teamd_start (device, connection) ? NM_ACT_STAGE_RETURN_POSTPONE : NM_ACT_STAGE_RETURN_FAILURE; } @@ -681,7 +721,7 @@ enslave_slave (NMDevice *device, } } } - success = nm_platform_link_enslave (NM_PLATFORM_GET, + success = nm_platform_link_enslave (nm_device_get_platform (device), nm_device_get_ip_ifindex (device), nm_device_get_ip_ifindex (slave)); nm_device_bring_up (slave, TRUE, &no_firmware); @@ -711,7 +751,7 @@ release_slave (NMDevice *device, gboolean success, no_firmware = FALSE; if (configure) { - success = nm_platform_link_release (NM_PLATFORM_GET, + success = nm_platform_link_release (nm_device_get_platform (device), nm_device_get_ip_ifindex (device), nm_device_get_ip_ifindex (slave)); @@ -746,7 +786,7 @@ create_and_realize (NMDevice *device, const char *iface = nm_device_get_iface (device); NMPlatformError plerr; - plerr = nm_platform_link_team_add (NM_PLATFORM_GET, iface, out_plink); + plerr = nm_platform_link_team_add (nm_device_get_platform (device), iface, out_plink); if (plerr != NM_PLATFORM_ERROR_SUCCESS) { g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, "Failed to create team master interface '%s' for '%s': %s", |