summaryrefslogtreecommitdiff
path: root/src/devices/nm-device.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/nm-device.c')
-rw-r--r--src/devices/nm-device.c79
1 files changed, 72 insertions, 7 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index ee6c3862ea..a38506f949 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -237,6 +237,7 @@ typedef struct {
IpState ip4_state;
NMIP4Config * dev_ip4_config; /* Config from DHCP, PPP, LLv4, etc */
NMIP4Config * ext_ip4_config; /* Stuff added outside NM */
+ NMIP4Config * wwan_ip4_config; /* WWAN configuration */
/* DHCPv4 tracking */
NMDHCPClient * dhcp4_client;
@@ -263,6 +264,7 @@ typedef struct {
NMIP6Config * ip6_config;
IpState ip6_state;
NMIP6Config * vpn6_config; /* routes added by a VPN which uses this device */
+ NMIP6Config * wwan_ip6_config;
NMIP6Config * ext_ip6_config; /* Stuff added outside NM */
NMRDisc * rdisc;
@@ -445,7 +447,7 @@ reason_to_string (NMDeviceStateReason reason)
/***********************************************************/
-static inline gboolean
+gboolean
nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value)
{
return nm_platform_sysctl_set (nm_utils_ip6_property_path (nm_device_get_ip_iface (self), property), value);
@@ -2662,6 +2664,12 @@ ip4_config_merge_and_apply (NMDevice *self,
if (priv->ext_ip4_config)
nm_ip4_config_merge (composite, priv->ext_ip4_config);
+ /* Merge WWAN config *last* to ensure modem-given settings overwrite
+ * any external stuff set by pppd or other scripts.
+ */
+ if (priv->wwan_ip4_config)
+ nm_ip4_config_merge (composite, priv->wwan_ip4_config);
+
/* Merge user overrides into the composite config */
connection = nm_device_get_connection (self);
if (connection) {
@@ -3089,6 +3097,12 @@ ip6_config_merge_and_apply (NMDevice *self,
if (priv->ext_ip6_config)
nm_ip6_config_merge (composite, priv->ext_ip6_config);
+ /* Merge WWAN config *last* to ensure modem-given settings overwrite
+ * any external stuff set by pppd or other scripts.
+ */
+ if (priv->wwan_ip6_config)
+ nm_ip6_config_merge (composite, priv->wwan_ip6_config);
+
/* Merge user overrides into the composite config */
connection = nm_device_get_connection (self);
if (connection) {
@@ -3141,10 +3155,17 @@ dhcp6_fail (NMDevice *device, gboolean timeout)
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
dhcp6_cleanup (device, TRUE, FALSE);
- if (timeout || (priv->ip6_state == IP_CONF))
- nm_device_activate_schedule_ip6_config_timeout (device);
- else if (priv->ip6_state == IP_FAIL)
- nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
+
+ if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED) {
+ if (timeout || (priv->ip6_state == IP_CONF))
+ nm_device_activate_schedule_ip6_config_timeout (device);
+ else if (priv->ip6_state == IP_FAIL)
+ nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
+ } else {
+ /* not a hard failure; just live with the RA info */
+ if (priv->ip6_state == IP_CONF)
+ nm_device_activate_schedule_ip6_config_result (device);
+ }
}
static void
@@ -4623,11 +4644,11 @@ nm_device_activate_schedule_ip4_config_result (NMDevice *self, NMIP4Config *conf
NMDevicePrivate *priv;
g_return_if_fail (NM_IS_DEVICE (self));
- g_return_if_fail (NM_IS_IP4_CONFIG (config));
priv = NM_DEVICE_GET_PRIVATE (self);
g_clear_object (&priv->dev_ip4_config);
- priv->dev_ip4_config = g_object_ref (config);
+ if (config)
+ priv->dev_ip4_config = g_object_ref (config);
activation_source_schedule (self, nm_device_activate_ip4_config_commit, AF_INET);
@@ -5204,6 +5225,25 @@ nm_device_set_vpn4_config (NMDevice *device, NMIP4Config *config)
}
}
+void
+nm_device_set_wwan_ip4_config (NMDevice *device, NMIP4Config *config)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
+
+ if (priv->wwan_ip4_config == config)
+ return;
+
+ g_clear_object (&priv->wwan_ip4_config);
+ if (config)
+ priv->wwan_ip4_config = g_object_ref (config);
+
+ /* NULL to use existing configs */
+ if (!ip4_config_merge_and_apply (device, NULL, TRUE, NULL)) {
+ nm_log_warn (LOGD_IP4, "(%s): failed to set WWAN IPv4 configuration",
+ nm_device_get_ip_iface (device));
+ }
+}
+
static gboolean
nm_device_set_ip6_config (NMDevice *self,
NMIP6Config *new_config,
@@ -5308,6 +5348,25 @@ nm_device_set_vpn6_config (NMDevice *device, NMIP6Config *config)
}
}
+void
+nm_device_set_wwan_ip6_config (NMDevice *device, NMIP6Config *config)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
+
+ if (priv->wwan_ip6_config == config)
+ return;
+
+ g_clear_object (&priv->wwan_ip6_config);
+ if (config)
+ priv->wwan_ip6_config = g_object_ref (config);
+
+ /* NULL to use existing configs */
+ if (!ip6_config_merge_and_apply (device, TRUE, NULL)) {
+ nm_log_warn (LOGD_IP6, "(%s): failed to set WWAN IPv6 configuration",
+ nm_device_get_ip_iface (device));
+ }
+}
+
NMDHCP6Config *
nm_device_get_dhcp6_config (NMDevice *self)
{
@@ -5864,6 +5923,8 @@ update_ip_config (NMDevice *self, gboolean initial)
nm_ip4_config_subtract (priv->ext_ip4_config, priv->dev_ip4_config);
if (priv->vpn4_config)
nm_ip4_config_subtract (priv->ext_ip4_config, priv->vpn4_config);
+ if (priv->wwan_ip4_config)
+ nm_ip4_config_subtract (priv->ext_ip4_config, priv->wwan_ip4_config);
ip4_config_merge_and_apply (self, NULL, FALSE, NULL);
}
@@ -5881,6 +5942,8 @@ update_ip_config (NMDevice *self, gboolean initial)
nm_ip6_config_subtract (priv->ext_ip6_config, priv->ac_ip6_config);
if (priv->dhcp6_ip6_config)
nm_ip6_config_subtract (priv->ext_ip6_config, priv->dhcp6_ip6_config);
+ if (priv->wwan_ip6_config)
+ nm_ip6_config_subtract (priv->ext_ip6_config, priv->wwan_ip6_config);
if (priv->vpn6_config)
nm_ip6_config_subtract (priv->ext_ip6_config, priv->vpn6_config);
@@ -6511,11 +6574,13 @@ _cleanup_generic_post (NMDevice *self, gboolean deconfigure)
nm_device_set_ip6_config (self, NULL, TRUE, &ignored);
g_clear_object (&priv->dev_ip4_config);
g_clear_object (&priv->ext_ip4_config);
+ g_clear_object (&priv->wwan_ip4_config);
g_clear_object (&priv->vpn4_config);
g_clear_object (&priv->ip4_config);
g_clear_object (&priv->ac_ip6_config);
g_clear_object (&priv->ext_ip6_config);
g_clear_object (&priv->vpn6_config);
+ g_clear_object (&priv->wwan_ip6_config);
g_clear_object (&priv->ip6_config);
clear_act_request (self);