summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2017-11-23 18:40:27 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2017-11-23 18:40:27 +0100
commitf71a2bf8fe4dbbb338b3779f8193e28e8dc3df55 (patch)
tree35a8b9fc2312df479dbbd154cfc4039a95be8268
parent2b88418efcf415d7ce13eb3b283601370e93be95 (diff)
downloadNetworkManager-bg/ppp.tar.gz
ppp: fix IPv6 supportbg/ppp
-rw-r--r--src/devices/nm-device-ppp.c172
1 files changed, 141 insertions, 31 deletions
diff --git a/src/devices/nm-device-ppp.c b/src/devices/nm-device-ppp.c
index 8b3968d513..72a8cc695e 100644
--- a/src/devices/nm-device-ppp.c
+++ b/src/devices/nm-device-ppp.c
@@ -21,6 +21,8 @@
#include "nm-device-private.h"
#include "nm-manager.h"
#include "nm-setting-pppoe.h"
+#include "nm-setting-ip4-config.h"
+#include "nm-setting-ip6-config.h"
#include "platform/nm-platform.h"
#include "ppp/nm-ppp-manager.h"
#include "ppp/nm-ppp-manager-call.h"
@@ -35,8 +37,9 @@ _LOG_DECLARE_SELF(NMDevicePpp);
typedef struct _NMDevicePppPrivate {
NMPPPManager *ppp_manager;
- NMIP4Config *pending_ip4_config;
- char *pending_ifname;
+ NMIP4Config *ip4_config;
+ NMIP6Config *ip6_config;
+ char *iface;
} NMDevicePppPrivate;
struct _NMDevicePpp {
@@ -88,9 +91,6 @@ ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_
case NM_PPP_STATUS_DEAD:
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_FAILED);
break;
- case NM_PPP_STATUS_RUNNING:
- nm_device_activate_schedule_stage3_ip_config_start (device);
- break;
default:
break;
}
@@ -111,23 +111,86 @@ ppp_ip4_config (NMPPPManager *ppp_manager,
if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) {
if (nm_device_activate_ip4_state_in_conf (device)) {
- if (!nm_device_take_over_link (device, iface, &renamed)) {
- nm_device_state_changed (device, NM_DEVICE_STATE_FAILED,
- NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
- return;
- }
- if (renamed)
- nm_manager_remove_device (nm_manager_get (), iface, NM_DEVICE_TYPE_PPP);
-
nm_device_activate_schedule_ip4_config_result (device, config);
+ }
+ return;
+ }
+
+ /* We are not yet in the IP configuration stage: cache the
+ * configuration for later.
+ */
+ if (priv->ip4_config)
+ g_object_unref (priv->ip4_config);
+ priv->ip4_config = g_object_ref (config);
+
+ if (priv->iface)
+ g_assert_cmpstr (priv->iface, ==, iface);
+ else {
+ /* Complete device initialization when we receive the first
+ * IP{4,6} configuration and we know the name of the interface
+ * created by pppd.
+ */
+ priv->iface = g_strdup (iface);
+ if (!nm_device_take_over_link (device, iface, &renamed)) {
+ nm_device_state_changed (device, NM_DEVICE_STATE_FAILED,
+ NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
+ return;
+ }
+ if (renamed)
+ nm_manager_remove_device (nm_manager_get (), iface, NM_DEVICE_TYPE_PPP);
+
+ /* Once the device gets an ifindex, start with IP configuration */
+ nm_device_activate_schedule_stage3_ip_config_start (device);
+ }
+}
+
+static void
+ppp_ip6_config (NMPPPManager *ppp_manager,
+ const char *iface,
+ const NMUtilsIPv6IfaceId *iid,
+ NMIP6Config *config,
+ gpointer user_data)
+{
+ NMDevice *device = NM_DEVICE (user_data);
+ NMDevicePpp *self = NM_DEVICE_PPP (device);
+ NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE (self);
+ gboolean renamed;
+
+ _LOGT (LOGD_DEVICE | LOGD_PPP, "received IPv6 config from pppd");
+
+ if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) {
+ if (nm_device_activate_ip6_state_in_conf (device)) {
+ nm_device_set_ac_ip6_config (device, config);
+ nm_device_activate_schedule_ip6_config_result (device);
+ }
+ return;
+ }
+
+ /* We are not yet in the IP configuration stage: cache the
+ * configuration for later.
+ */
+ if (priv->ip6_config)
+ g_object_unref (priv->ip6_config);
+ priv->ip6_config = g_object_ref (config);
+
+ if (priv->iface)
+ g_assert_cmpstr (priv->iface, ==, iface);
+ else {
+ /* Complete device initialization when we receive the first
+ * IP{4,6} configuration and we know the name of the interface
+ * created by pppd.
+ */
+ priv->iface = g_strdup (iface);
+ if (!nm_device_take_over_link (device, iface, &renamed)) {
+ nm_device_state_changed (device, NM_DEVICE_STATE_FAILED,
+ NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
return;
}
- } else {
- if (priv->pending_ip4_config)
- g_object_unref (priv->pending_ip4_config);
- priv->pending_ip4_config = g_object_ref (config);
- g_free (priv->pending_ifname);
- priv->pending_ifname = g_strdup (iface);
+ if (renamed)
+ nm_manager_remove_device (nm_manager_get (), iface, NM_DEVICE_TYPE_PPP);
+
+ /* Once the device gets an ifindex, start with IP configuration */
+ nm_device_activate_schedule_stage3_ip_config_start (device);
}
}
@@ -146,8 +209,9 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
s_pppoe = (NMSettingPppoe *) nm_device_get_applied_setting ((NMDevice *) self, NM_TYPE_SETTING_PPPOE);
g_return_val_if_fail (s_pppoe, NM_ACT_STAGE_RETURN_FAILURE);
- g_clear_object (&priv->pending_ip4_config);
- nm_clear_g_free (&priv->pending_ifname);
+ g_clear_object (&priv->ip4_config);
+ g_clear_object (&priv->ip6_config);
+ nm_clear_g_free (&priv->iface);
priv->ppp_manager = nm_ppp_manager_create (nm_setting_pppoe_get_parent (s_pppoe), &error);
@@ -178,6 +242,9 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_SIGNAL_IP4_CONFIG,
G_CALLBACK (ppp_ip4_config),
self);
+ g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_SIGNAL_IP6_CONFIG,
+ G_CALLBACK (ppp_ip6_config),
+ self);
return NM_ACT_STAGE_RETURN_POSTPONE;
}
@@ -189,17 +256,25 @@ act_stage3_ip4_config_start (NMDevice *device,
{
NMDevicePpp *self = NM_DEVICE_PPP (device);
NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE (self);
- gboolean renamed;
+ NMSettingIPConfig *s_ip4;
+ NMDeviceClass *dev_class;
+
+ _LOGT (LOGD_DEVICE | LOGD_PPP, "ip4 config start");
+
+ s_ip4 = (NMSettingIPConfig *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_IP4_CONFIG);
+ if (!nm_streq0 (nm_setting_ip_config_get_method (s_ip4),
+ NM_SETTING_IP4_CONFIG_METHOD_AUTO)) {
+ dev_class = NM_DEVICE_CLASS (nm_device_ppp_parent_class);
+ return dev_class->act_stage3_ip4_config_start (device,
+ out_config,
+ out_failure_reason);
+ }
- if (priv->pending_ip4_config) {
- if (!nm_device_take_over_link (device, priv->pending_ifname, &renamed))
- return NM_ACT_STAGE_RETURN_FAILURE;
- if (renamed)
- nm_manager_remove_device (nm_manager_get (), priv->pending_ifname, NM_DEVICE_TYPE_PPP);
+ if (priv->ip4_config) {
if (out_config)
- *out_config = g_steal_pointer (&priv->pending_ip4_config);
+ *out_config = g_steal_pointer (&priv->ip4_config);
else
- g_clear_object (&priv->pending_ip4_config);
+ g_clear_object (&priv->ip4_config);
return NM_ACT_STAGE_RETURN_SUCCESS;
}
@@ -207,6 +282,39 @@ act_stage3_ip4_config_start (NMDevice *device,
return NM_ACT_STAGE_RETURN_POSTPONE;
}
+static NMActStageReturn
+act_stage3_ip6_config_start (NMDevice *device,
+ NMIP6Config **out_config,
+ NMDeviceStateReason *out_failure_reason)
+{
+ NMDevicePpp *self = NM_DEVICE_PPP (device);
+ NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE (self);
+ NMSettingIPConfig *s_ip6;
+ NMDeviceClass *dev_class;
+
+ _LOGT (LOGD_DEVICE | LOGD_PPP, "ip6 config start");
+
+ s_ip6 = (NMSettingIPConfig *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_IP6_CONFIG);
+ if (!nm_streq0 (nm_setting_ip_config_get_method (s_ip6),
+ NM_SETTING_IP6_CONFIG_METHOD_AUTO)) {
+ dev_class = NM_DEVICE_CLASS (nm_device_ppp_parent_class);
+ return dev_class->act_stage3_ip6_config_start (device,
+ out_config,
+ out_failure_reason);
+ }
+
+ if (priv->ip6_config) {
+ if (out_config)
+ *out_config = g_steal_pointer (&priv->ip6_config);
+ else
+ g_clear_object (&priv->ip6_config);
+ return NM_ACT_STAGE_RETURN_SUCCESS;
+ }
+
+ /* Wait IPV6CP termination */
+ return NM_ACT_STAGE_RETURN_POSTPONE;
+}
+
static gboolean
create_and_realize (NMDevice *device,
NMConnection *connection,
@@ -255,8 +363,9 @@ dispose (GObject *object)
NMDevicePpp *self = NM_DEVICE_PPP (object);
NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE (self);
- g_clear_object (&priv->pending_ip4_config);
- nm_clear_g_free (&priv->pending_ifname);
+ g_clear_object (&priv->ip4_config);
+ g_clear_object (&priv->ip6_config);
+ nm_clear_g_free (&priv->iface);
G_OBJECT_CLASS (nm_device_ppp_parent_class)->dispose (object);
}
@@ -273,6 +382,7 @@ nm_device_ppp_class_init (NMDevicePppClass *klass)
parent_class->act_stage2_config = act_stage2_config;
parent_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start;
+ parent_class->act_stage3_ip6_config_start = act_stage3_ip6_config_start;
parent_class->check_connection_compatible = check_connection_compatible;
parent_class->create_and_realize = create_and_realize;
parent_class->deactivate = deactivate;