summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/devices/nm-device.c35
-rw-r--r--src/dnsmasq/nm-dnsmasq-manager.c14
-rw-r--r--src/dnsmasq/nm-dnsmasq-manager.h1
-rw-r--r--src/nm-manager.c8
-rw-r--r--src/nm-manager.h2
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__ */