summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2018-11-29 10:58:59 +0100
committerThomas Haller <thaller@redhat.com>2018-11-30 14:54:34 +0100
commitda11a95f2c23d9c5c89339b8694aa85b002cf163 (patch)
tree83c88a73a354e72e3bc66d1bc03ed26ad9570213
parentb9fed6165459e759876fce368fb7d78dc7f86d6a (diff)
downloadNetworkManager-da11a95f2c23d9c5c89339b8694aa85b002cf163.tar.gz
device/shared: set ANDROID_METERED option 43 for shared connectionsth/metered-for-shared
The problem is that updating the metered value of a shared connection is not implemented. The user needs to fully reactivate the profile for changes to take effect. That is unfortunate, especially because reapplying the route metric works in other other cases.
-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__ */