diff options
-rw-r--r-- | src/devices/nm-device.c | 35 | ||||
-rw-r--r-- | src/dnsmasq/nm-dnsmasq-manager.c | 14 | ||||
-rw-r--r-- | src/dnsmasq/nm-dnsmasq-manager.h | 1 | ||||
-rw-r--r-- | src/nm-manager.c | 8 | ||||
-rw-r--r-- | src/nm-manager.h | 2 |
5 files changed, 57 insertions, 3 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 36ad5fa808..b435821cd5 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -10169,6 +10169,9 @@ start_sharing (NMDevice *self, NMIP4Config *config, GError **error) const NMPlatformIP4Address *ip4_addr = NULL; const char *ip_iface; GError *local = NULL; + NMConnection *conn; + NMSettingConnection *s_con; + gboolean announce_android_metered; g_return_val_if_fail (config, FALSE); @@ -10190,7 +10193,7 @@ start_sharing (NMDevice *self, NMIP4Config *config, GError **error) return FALSE; req = nm_device_get_act_request (self); - g_assert (req); + g_return_val_if_fail (req, FALSE); netmask = _nm_utils_ip4_prefix_to_netmask (ip4_addr->plen); nm_utils_inet4_ntop (netmask, str_mask); @@ -10211,7 +10214,35 @@ start_sharing (NMDevice *self, NMIP4Config *config, GError **error) nm_act_request_set_shared (req, TRUE); - if (!nm_dnsmasq_manager_start (priv->dnsmasq_manager, config, &local)) { + conn = nm_act_request_get_applied_connection (req); + s_con = nm_connection_get_setting_connection (conn); + + switch (nm_setting_connection_get_metered (s_con)) { + case NM_METERED_YES: + /* honor the metered flag. Note that reapply on the device does not affect + * the metered setting. This is different from other profiles, where the + * metered flag of an activated profile can be changed (reapplied). */ + announce_android_metered = TRUE; + break; + case NM_METERED_UNKNOWN: + /* we pick up the current value and announce it. But again, we cannot update + * the announced setting without restarting dnsmasq. That means, if the default + * route changes w.r.t. being metered, then the shared connection does not get + * updated before reactivating. */ + announce_android_metered = NM_IN_SET (nm_manager_get_metered (nm_manager_get ()), + NM_METERED_YES, + NM_METERED_GUESS_YES); + break; + default: + announce_android_metered = FALSE; + break; + } + + + if (!nm_dnsmasq_manager_start (priv->dnsmasq_manager, + config, + announce_android_metered, + &local)) { g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, "could not start dnsmasq due to %s", local->message); g_error_free (local); diff --git a/src/dnsmasq/nm-dnsmasq-manager.c b/src/dnsmasq/nm-dnsmasq-manager.c index 42917bfdd7..1afc6e0d71 100644 --- a/src/dnsmasq/nm-dnsmasq-manager.c +++ b/src/dnsmasq/nm-dnsmasq-manager.c @@ -104,6 +104,7 @@ static GPtrArray * create_dm_cmd_line (const char *iface, const NMIP4Config *ip4_config, const char *pidfile, + gboolean announce_android_metered, GError **error) { gs_unref_ptrarray GPtrArray *cmd = NULL; @@ -199,6 +200,12 @@ create_dm_cmd_line (const char *iface, nm_strv_ptrarray_take_gstring (cmd, &s); } + if (announce_android_metered) { + /* force option 43 to announce ANDROID_METERED. Do this, even if the client + * did not ask for this option. See https://www.lorier.net/docs/android-metered.html */ + nm_strv_ptrarray_add_string_dup (cmd, "--dhcp-option-force=43,ANDROID_METERED"); + } + nm_strv_ptrarray_add_string_dup (cmd, "--dhcp-lease-max=50"); nm_strv_ptrarray_add_string_printf (cmd, @@ -258,6 +265,7 @@ out: gboolean nm_dnsmasq_manager_start (NMDnsMasqManager *manager, NMIP4Config *ip4_config, + gboolean announce_android_metered, GError **error) { NMDnsMasqManagerPrivate *priv; @@ -272,7 +280,11 @@ nm_dnsmasq_manager_start (NMDnsMasqManager *manager, kill_existing_by_pidfile (priv->pidfile); - dm_cmd = create_dm_cmd_line (priv->iface, ip4_config, priv->pidfile, error); + dm_cmd = create_dm_cmd_line (priv->iface, + ip4_config, + priv->pidfile, + announce_android_metered, + error); if (!dm_cmd) return FALSE; diff --git a/src/dnsmasq/nm-dnsmasq-manager.h b/src/dnsmasq/nm-dnsmasq-manager.h index a0ad295cd4..dd4a9069c0 100644 --- a/src/dnsmasq/nm-dnsmasq-manager.h +++ b/src/dnsmasq/nm-dnsmasq-manager.h @@ -48,6 +48,7 @@ NMDnsMasqManager *nm_dnsmasq_manager_new (const char *iface); gboolean nm_dnsmasq_manager_start (NMDnsMasqManager *manager, NMIP4Config *ip4_config, + gboolean announce_android_metered, GError **error); void nm_dnsmasq_manager_stop (NMDnsMasqManager *manager); diff --git a/src/nm-manager.c b/src/nm-manager.c index a5e8c309cf..21534523c8 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1445,6 +1445,14 @@ nm_manager_update_metered (NMManager *self) } } +NMMetered +nm_manager_get_metered (NMManager *self) +{ + g_return_val_if_fail (NM_IS_MANAGER (self), NM_METERED_UNKNOWN); + + return NM_MANAGER_GET_PRIVATE (self)->metered; +} + static void nm_manager_update_state (NMManager *self) { diff --git a/src/nm-manager.h b/src/nm-manager.h index 11cba1a5ce..06ca633de8 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -174,4 +174,6 @@ void nm_manager_dbus_set_property_handle (NMDBusObject *obj, GVariant *value, gpointer user_data); +NMMetered nm_manager_get_metered (NMManager *self); + #endif /* __NETWORKMANAGER_MANAGER_H__ */ |