summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2018-12-03 12:29:29 +0100
committerThomas Haller <thaller@redhat.com>2018-12-03 12:29:29 +0100
commit5fb800125fd753c7d7ba66f1ad1eaa899b73741e (patch)
treea74939d6597dd890f7f724316a7c84e1715cd165
parent8b87cd9ddf47c81dc1210247b44668f30748bc98 (diff)
parent1a2e767f1fd2d8b550ab61cdfabc721280cf923e (diff)
shared: merge branch 'th/metered-for-shared'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/57
-rw-r--r--shared/nm-utils/nm-shared-utils.h71
-rw-r--r--src/devices/nm-device.c35
-rw-r--r--src/dnsmasq/nm-dnsmasq-manager.c171
-rw-r--r--src/dnsmasq/nm-dnsmasq-manager.h1
-rw-r--r--src/nm-manager.c8
-rw-r--r--src/nm-manager.h2
-rw-r--r--src/ppp/nm-ppp-manager.c231
7 files changed, 265 insertions, 254 deletions
diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h
index 940a193f7..e82b53f7c 100644
--- a/shared/nm-utils/nm-shared-utils.h
+++ b/shared/nm-utils/nm-shared-utils.h
@@ -296,6 +296,37 @@ nm_memdup (gconstpointer data, gsize size)
/*****************************************************************************/
+/* generic macro to convert an int to a (heap allocated) string.
+ *
+ * Usually, an inline function nm_strdup_int64() would be enough. However,
+ * that cannot be used for guint64. So, we would also need nm_strdup_uint64().
+ * This causes suble error potential, because the caller needs to ensure to
+ * use the right one (and compiler isn't going to help as it silently casts).
+ *
+ * Instead, this generic macro is supposed to handle all integers correctly. */
+#if _NM_CC_SUPPORT_GENERIC
+#define nm_strdup_int(val) \
+ _Generic ((val), \
+ gint8: g_strdup_printf ("%d", (int) (val)), \
+ gint16: g_strdup_printf ("%d", (int) (val)), \
+ gint32: g_strdup_printf ("%d", (int) (val)), \
+ gint64: g_strdup_printf ("%"G_GINT64_FORMAT, (gint64) (val)), \
+ \
+ guint8: g_strdup_printf ("%u", (guint) (val)), \
+ guint16: g_strdup_printf ("%u", (guint) (val)), \
+ guint32: g_strdup_printf ("%u", (guint) (val)), \
+ guint64: g_strdup_printf ("%"G_GUINT64_FORMAT, (guint64) (val)) \
+ )
+#else
+#define nm_strdup_int(val) \
+ ( ( sizeof (val) == sizeof (guint64) \
+ && ((typeof (val)) -1) > 0) \
+ ? g_strdup_printf ("%"G_GUINT64_FORMAT, (guint64) (val)) \
+ : g_strdup_printf ("%"G_GINT64_FORMAT, (gint64) (val)))
+#endif
+
+/*****************************************************************************/
+
extern const void *const _NM_PTRARRAY_EMPTY[1];
#define NM_PTRARRAY_EMPTY(type) ((type const*) _NM_PTRARRAY_EMPTY)
@@ -959,4 +990,44 @@ void nm_utils_invoke_on_idle (NMUtilsInvokeOnIdleCallback callback,
gpointer callback_user_data,
GCancellable *cancellable);
+/*****************************************************************************/
+
+static inline void
+nm_strv_ptrarray_add_string_take (GPtrArray *cmd,
+ char *str)
+{
+ nm_assert (cmd);
+ nm_assert (str);
+
+ g_ptr_array_add (cmd, str);
+}
+
+static inline void
+nm_strv_ptrarray_add_string_dup (GPtrArray *cmd,
+ const char *str)
+{
+ nm_strv_ptrarray_add_string_take (cmd,
+ g_strdup (str));
+}
+
+#define nm_strv_ptrarray_add_string_concat(cmd, ...) \
+ nm_strv_ptrarray_add_string_take ((cmd), g_strconcat (__VA_ARGS__, NULL))
+
+#define nm_strv_ptrarray_add_string_printf(cmd, ...) \
+ nm_strv_ptrarray_add_string_take ((cmd), g_strdup_printf (__VA_ARGS__))
+
+#define nm_strv_ptrarray_add_int(cmd, val) \
+ nm_strv_ptrarray_add_string_take ((cmd), nm_strdup_int (val))
+
+static inline void
+nm_strv_ptrarray_take_gstring (GPtrArray *cmd,
+ GString **gstr)
+{
+ nm_assert (gstr && *gstr);
+
+ nm_strv_ptrarray_add_string_take (cmd,
+ g_string_free (g_steal_pointer (gstr),
+ FALSE));
+}
+
#endif /* __NM_SHARED_UTILS_H__ */
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 57021e4b7..c2223a985 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -10175,6 +10175,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);
@@ -10196,7 +10199,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);
@@ -10217,7 +10220,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 3fe2f4892..1afc6e0d7 100644
--- a/src/dnsmasq/nm-dnsmasq-manager.c
+++ b/src/dnsmasq/nm-dnsmasq-manager.c
@@ -73,51 +73,6 @@ G_DEFINE_TYPE (NMDnsMasqManager, nm_dnsmasq_manager, G_TYPE_OBJECT)
/*****************************************************************************/
-typedef struct {
- GPtrArray *array;
- GStringChunk *chunk;
-} NMCmdLine;
-
-static NMCmdLine *
-nm_cmd_line_new (void)
-{
- NMCmdLine *cmd;
-
- cmd = g_slice_new (NMCmdLine);
- cmd->array = g_ptr_array_new ();
- cmd->chunk = g_string_chunk_new (1024);
-
- return cmd;
-}
-
-static void
-nm_cmd_line_destroy (NMCmdLine *cmd)
-{
- g_ptr_array_free (cmd->array, TRUE);
- g_string_chunk_free (cmd->chunk);
- g_slice_free (NMCmdLine, cmd);
-}
-
-static char *
-nm_cmd_line_to_str (NMCmdLine *cmd)
-{
- char *str;
-
- g_ptr_array_add (cmd->array, NULL);
- str = g_strjoinv (" ", (char **) cmd->array->pdata);
- g_ptr_array_remove_index (cmd->array, cmd->array->len - 1);
-
- return str;
-}
-
-static void
-nm_cmd_line_add_string (NMCmdLine *cmd, const char *str)
-{
- g_ptr_array_add (cmd->array, g_string_chunk_insert (cmd->chunk, str));
-}
-
-/*****************************************************************************/
-
static void
dm_watch_cb (GPid pid, int status, gpointer user_data)
{
@@ -145,40 +100,40 @@ dm_watch_cb (GPid pid, int status, gpointer user_data)
g_signal_emit (manager, signals[STATE_CHANGED], 0, NM_DNSMASQ_STATUS_DEAD);
}
-static NMCmdLine *
+static GPtrArray *
create_dm_cmd_line (const char *iface,
const NMIP4Config *ip4_config,
const char *pidfile,
+ gboolean announce_android_metered,
GError **error)
{
- NMCmdLine *cmd;
+ gs_unref_ptrarray GPtrArray *cmd = NULL;
nm_auto_free_gstring GString *s = NULL;
char first[INET_ADDRSTRLEN];
char last[INET_ADDRSTRLEN];
- char localaddr[INET_ADDRSTRLEN];
+ char listen_address_s[INET_ADDRSTRLEN];
char tmpaddr[INET_ADDRSTRLEN];
- char *error_desc = NULL;
+ gs_free char *error_desc = NULL;
const char *dm_binary;
const NMPlatformIP4Address *listen_address;
guint i, n;
listen_address = nm_ip4_config_get_first_address (ip4_config);
+
g_return_val_if_fail (listen_address, NULL);
dm_binary = nm_utils_find_helper ("dnsmasq", DNSMASQ_PATH, error);
if (!dm_binary)
return NULL;
- s = g_string_sized_new (100);
+ cmd = g_ptr_array_new_with_free_func (g_free);
- /* Create dnsmasq command line */
- cmd = nm_cmd_line_new ();
- nm_cmd_line_add_string (cmd, dm_binary);
+ nm_strv_ptrarray_add_string_dup (cmd, dm_binary);
if ( nm_logging_enabled (LOGL_TRACE, LOGD_SHARING)
|| getenv ("NM_DNSMASQ_DEBUG")) {
- nm_cmd_line_add_string (cmd, "--log-dhcp");
- nm_cmd_line_add_string (cmd, "--log-queries");
+ nm_strv_ptrarray_add_string_dup (cmd, "--log-dhcp");
+ nm_strv_ptrarray_add_string_dup (cmd, "--log-queries");
}
/* dnsmasq may read from its default config file location, which if that
@@ -187,25 +142,23 @@ create_dm_cmd_line (const char *iface,
* as the gateway or whatever. So tell dnsmasq not to use any config file
* at all.
*/
- nm_cmd_line_add_string (cmd, "--conf-file=/dev/null");
+ nm_strv_ptrarray_add_string_dup (cmd, "--conf-file=/dev/null");
- nm_cmd_line_add_string (cmd, "--no-hosts");
- nm_cmd_line_add_string (cmd, "--keep-in-foreground");
- nm_cmd_line_add_string (cmd, "--bind-interfaces");
- nm_cmd_line_add_string (cmd, "--except-interface=lo");
- nm_cmd_line_add_string (cmd, "--clear-on-reload");
+ nm_strv_ptrarray_add_string_dup (cmd, "--no-hosts");
+ nm_strv_ptrarray_add_string_dup (cmd, "--keep-in-foreground");
+ nm_strv_ptrarray_add_string_dup (cmd, "--bind-interfaces");
+ nm_strv_ptrarray_add_string_dup (cmd, "--except-interface=lo");
+ nm_strv_ptrarray_add_string_dup (cmd, "--clear-on-reload");
/* Use strict order since in the case of VPN connections, the VPN's
* nameservers will be first in resolv.conf, and those need to be tried
* first by dnsmasq to successfully resolve names from the VPN.
*/
- nm_cmd_line_add_string (cmd, "--strict-order");
+ nm_strv_ptrarray_add_string_dup (cmd, "--strict-order");
+
+ nm_utils_inet4_ntop (listen_address->address, listen_address_s);
- nm_utils_inet4_ntop (listen_address->address, localaddr);
- g_string_append (s, "--listen-address=");
- g_string_append (s, localaddr);
- nm_cmd_line_add_string (cmd, s->str);
- g_string_truncate (s, 0);
+ nm_strv_ptrarray_add_string_concat (cmd, "--listen-address=", listen_address_s);
if (!nm_dnsmasq_utils_get_range (listen_address, first, last, &error_desc)) {
g_set_error_literal (error,
@@ -213,59 +166,61 @@ create_dm_cmd_line (const char *iface,
NM_MANAGER_ERROR_FAILED,
error_desc);
_LOGW ("failed to find DHCP address ranges: %s", error_desc);
- g_free (error_desc);
- nm_cmd_line_destroy (cmd);
return NULL;
}
- g_string_append_printf (s, "--dhcp-range=%s,%s,60m", first, last);
- nm_cmd_line_add_string (cmd, s->str);
- g_string_truncate (s, 0);
+ nm_strv_ptrarray_add_string_printf (cmd,
+ "--dhcp-range=%s,%s,60m",
+ first,
+ last);
if (nm_ip4_config_best_default_route_get (ip4_config)) {
- g_string_append (s, "--dhcp-option=option:router,");
- g_string_append (s, localaddr);
- nm_cmd_line_add_string (cmd, s->str);
- g_string_truncate (s, 0);
+ nm_strv_ptrarray_add_string_concat (cmd,
+ "--dhcp-option=option:router,",
+ listen_address_s);
}
if ((n = nm_ip4_config_get_num_nameservers (ip4_config))) {
+ nm_gstring_prepare (&s);
g_string_append (s, "--dhcp-option=option:dns-server");
for (i = 0; i < n; i++) {
g_string_append_c (s, ',');
g_string_append (s, nm_utils_inet4_ntop (nm_ip4_config_get_nameserver (ip4_config, i), tmpaddr));
}
- nm_cmd_line_add_string (cmd, s->str);
- g_string_truncate (s, 0);
+ nm_strv_ptrarray_take_gstring (cmd, &s);
}
if ((n = nm_ip4_config_get_num_searches (ip4_config))) {
+ nm_gstring_prepare (&s);
g_string_append (s, "--dhcp-option=option:domain-search");
for (i = 0; i < n; i++) {
g_string_append_c (s, ',');
g_string_append (s, nm_ip4_config_get_search (ip4_config, i));
}
- nm_cmd_line_add_string (cmd, s->str);
- g_string_truncate (s, 0);
+ nm_strv_ptrarray_take_gstring (cmd, &s);
}
- nm_cmd_line_add_string (cmd, "--dhcp-lease-max=50");
+ 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");
- g_string_append (s, "--dhcp-leasefile=" NMSTATEDIR);
- g_string_append_printf (s, "/dnsmasq-%s.leases", iface);
- nm_cmd_line_add_string (cmd, s->str);
- g_string_truncate (s, 0);
+ nm_strv_ptrarray_add_string_printf (cmd,
+ "--dhcp-leasefile=%s/dnsmasq-%s.leases",
+ NMSTATEDIR,
+ iface);
- g_string_append (s, "--pid-file=");
- g_string_append (s, pidfile);
- nm_cmd_line_add_string (cmd, s->str);
- g_string_truncate (s, 0);
+ nm_strv_ptrarray_add_string_concat (cmd, "--pid-file=", pidfile);
/* dnsmasq exits if the conf dir is not present */
if (g_file_test (CONFDIR, G_FILE_TEST_IS_DIR))
- nm_cmd_line_add_string (cmd, "--conf-dir=" CONFDIR);
+ nm_strv_ptrarray_add_string_dup (cmd, "--conf-dir=" CONFDIR);
- return cmd;
+ g_ptr_array_add (cmd, NULL);
+ return g_steal_pointer (&cmd);
}
static void
@@ -310,10 +265,11 @@ out:
gboolean
nm_dnsmasq_manager_start (NMDnsMasqManager *manager,
NMIP4Config *ip4_config,
+ gboolean announce_android_metered,
GError **error)
{
NMDnsMasqManagerPrivate *priv;
- NMCmdLine *dm_cmd;
+ gs_unref_ptrarray GPtrArray *dm_cmd = NULL;
gs_free char *cmd_str = NULL;
g_return_val_if_fail (NM_IS_DNSMASQ_MANAGER (manager), FALSE);
@@ -324,32 +280,35 @@ 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;
- g_ptr_array_add (dm_cmd->array, NULL);
-
_LOGI ("starting dnsmasq...");
- _LOGD ("command line: %s", (cmd_str = nm_cmd_line_to_str (dm_cmd)));
+ _LOGD ("command line: %s", (cmd_str = g_strjoinv (" ", (char **) dm_cmd->pdata)));
priv->pid = 0;
- if (!g_spawn_async (NULL, (char **) dm_cmd->array->pdata, NULL,
+ if (!g_spawn_async (NULL,
+ (char **) dm_cmd->pdata,
+ NULL,
G_SPAWN_DO_NOT_REAP_CHILD,
- nm_utils_setpgid, NULL,
- &priv->pid, error)) {
- goto out;
- }
+ nm_utils_setpgid,
+ NULL,
+ &priv->pid,
+ error))
+ return FALSE;
+
+ nm_assert (priv->pid > 0);
_LOGD ("dnsmasq started with pid %d", priv->pid);
priv->dm_watch_id = g_child_watch_add (priv->pid, (GChildWatchFunc) dm_watch_cb, manager);
- out:
- if (dm_cmd)
- nm_cmd_line_destroy (dm_cmd);
-
- return priv->pid > 0;
+ return TRUE;
}
void
diff --git a/src/dnsmasq/nm-dnsmasq-manager.h b/src/dnsmasq/nm-dnsmasq-manager.h
index a0ad295cd..dd4a9069c 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 0710483d1..7914d16d1 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 11cba1a5c..06ca633de 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__ */
diff --git a/src/ppp/nm-ppp-manager.c b/src/ppp/nm-ppp-manager.c
index 1595961f4..d012fcb71 100644
--- a/src/ppp/nm-ppp-manager.c
+++ b/src/ppp/nm-ppp-manager.c
@@ -675,61 +675,6 @@ out:
/*****************************************************************************/
-typedef struct {
- GPtrArray *array;
- GStringChunk *chunk;
-} NMCmdLine;
-
-static NMCmdLine *
-nm_cmd_line_new (void)
-{
- NMCmdLine *cmd;
-
- cmd = g_slice_new (NMCmdLine);
- cmd->array = g_ptr_array_new ();
- cmd->chunk = g_string_chunk_new (1024);
-
- return cmd;
-}
-
-static void
-nm_cmd_line_destroy (NMCmdLine *cmd)
-{
- g_ptr_array_free (cmd->array, TRUE);
- g_string_chunk_free (cmd->chunk);
- g_slice_free (NMCmdLine, cmd);
-}
-
-static char *
-nm_cmd_line_to_str (NMCmdLine *cmd)
-{
- char *str;
-
- g_ptr_array_add (cmd->array, NULL);
- str = g_strjoinv (" ", (char **) cmd->array->pdata);
- g_ptr_array_remove_index (cmd->array, cmd->array->len - 1);
-
- return str;
-}
-
-static void
-nm_cmd_line_add_string (NMCmdLine *cmd, const char *str)
-{
- g_ptr_array_add (cmd->array, g_string_chunk_insert (cmd->chunk, str));
-}
-
-static void
-nm_cmd_line_add_int (NMCmdLine *cmd, int i)
-{
- char *str;
-
- str = g_strdup_printf ("%d", i);
- nm_cmd_line_add_string (cmd, str);
- g_free (str);
-}
-
-/*****************************************************************************/
-
NM_UTILS_LOOKUP_STR_DEFINE_STATIC (pppd_exit_code_to_str, int,
NM_UTILS_LOOKUP_DEFAULT ("Unknown error"),
NM_UTILS_LOOKUP_STR_ITEM ( 1, "Fatal pppd error");
@@ -801,7 +746,7 @@ pppd_timed_out (gpointer data)
return FALSE;
}
-static NMCmdLine *
+static GPtrArray *
create_pppd_cmd_line (NMPPPManager *self,
NMSettingPpp *setting,
NMSettingPppoe *pppoe,
@@ -814,9 +759,8 @@ create_pppd_cmd_line (NMPPPManager *self,
{
NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self);
const char *pppd_binary = NULL;
- NMCmdLine *cmd;
+ gs_unref_ptrarray GPtrArray *cmd = NULL;
gboolean ppp_debug;
- static int unit;
g_return_val_if_fail (setting != NULL, NULL);
@@ -836,53 +780,50 @@ create_pppd_cmd_line (NMPPPManager *self,
return NULL;
}
- /* Create pppd command line */
- cmd = nm_cmd_line_new ();
- nm_cmd_line_add_string (cmd, pppd_binary);
+ cmd = g_ptr_array_new_with_free_func (g_free);
+
+ nm_strv_ptrarray_add_string_dup (cmd, pppd_binary);
- nm_cmd_line_add_string (cmd, "nodetach");
- nm_cmd_line_add_string (cmd, "lock");
+ nm_strv_ptrarray_add_string_dup (cmd, "nodetach");
+ nm_strv_ptrarray_add_string_dup (cmd, "lock");
/* NM handles setting the default route */
- nm_cmd_line_add_string (cmd, "nodefaultroute");
+ nm_strv_ptrarray_add_string_dup (cmd, "nodefaultroute");
if (!ip4_enabled)
- nm_cmd_line_add_string (cmd, "noip");
+ nm_strv_ptrarray_add_string_dup (cmd, "noip");
if (ip6_enabled) {
/* Allow IPv6 to be configured by IPV6CP */
- nm_cmd_line_add_string (cmd, "ipv6");
- nm_cmd_line_add_string (cmd, ",");
+ nm_strv_ptrarray_add_string_dup (cmd, "ipv6");
+ nm_strv_ptrarray_add_string_dup (cmd, ",");
} else
- nm_cmd_line_add_string (cmd, "noipv6");
+ nm_strv_ptrarray_add_string_dup (cmd, "noipv6");
ppp_debug = !!getenv ("NM_PPP_DEBUG");
if (nm_logging_enabled (LOGL_DEBUG, LOGD_PPP))
ppp_debug = TRUE;
if (ppp_debug)
- nm_cmd_line_add_string (cmd, "debug");
+ nm_strv_ptrarray_add_string_dup (cmd, "debug");
if (ppp_name) {
- nm_cmd_line_add_string (cmd, "user");
- nm_cmd_line_add_string (cmd, ppp_name);
+ nm_strv_ptrarray_add_string_dup (cmd, "user");
+ nm_strv_ptrarray_add_string_dup (cmd, ppp_name);
}
if (pppoe) {
- char *dev_str;
const char *pppoe_service;
- nm_cmd_line_add_string (cmd, "plugin");
- nm_cmd_line_add_string (cmd, "rp-pppoe.so");
+ nm_strv_ptrarray_add_string_dup (cmd, "plugin");
+ nm_strv_ptrarray_add_string_dup (cmd, "rp-pppoe.so");
- dev_str = g_strdup_printf ("nic-%s", priv->parent_iface);
- nm_cmd_line_add_string (cmd, dev_str);
- g_free (dev_str);
+ nm_strv_ptrarray_add_string_concat (cmd, "nic-", priv->parent_iface);
pppoe_service = nm_setting_pppoe_get_service (pppoe);
if (pppoe_service) {
- nm_cmd_line_add_string (cmd, "rp_pppoe_service");
- nm_cmd_line_add_string (cmd, pppoe_service);
+ nm_strv_ptrarray_add_string_dup (cmd, "rp_pppoe_service");
+ nm_strv_ptrarray_add_string_dup (cmd, pppoe_service);
}
} else if (adsl) {
const char *protocol = nm_setting_adsl_get_protocol (adsl);
@@ -891,110 +832,110 @@ create_pppd_cmd_line (NMPPPManager *self,
guint32 vpi = nm_setting_adsl_get_vpi (adsl);
guint32 vci = nm_setting_adsl_get_vci (adsl);
const char *encaps = nm_setting_adsl_get_encapsulation (adsl);
- char *vpivci;
- nm_cmd_line_add_string (cmd, "plugin");
- nm_cmd_line_add_string (cmd, "pppoatm.so");
+ nm_strv_ptrarray_add_string_dup (cmd, "plugin");
+ nm_strv_ptrarray_add_string_dup (cmd, "pppoatm.so");
- vpivci = g_strdup_printf("%d.%d", vpi, vci);
- nm_cmd_line_add_string (cmd, vpivci);
- g_free (vpivci);
+ nm_strv_ptrarray_add_string_printf (cmd, "%d.%d", vpi, vci);
if (g_strcmp0 (encaps, NM_SETTING_ADSL_ENCAPSULATION_LLC) == 0)
- nm_cmd_line_add_string (cmd, "llc-encaps");
+ nm_strv_ptrarray_add_string_dup (cmd, "llc-encaps");
else /*if (g_strcmp0 (encaps, NM_SETTING_ADSL_ENCAPSULATION_VCMUX) == 0)*/
- nm_cmd_line_add_string (cmd, "vc-encaps");
+ nm_strv_ptrarray_add_string_dup (cmd, "vc-encaps");
} else if (!strcmp (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOE)) {
- nm_cmd_line_add_string (cmd, "plugin");
- nm_cmd_line_add_string (cmd, "rp-pppoe.so");
- nm_cmd_line_add_string (cmd, priv->parent_iface);
+ nm_strv_ptrarray_add_string_dup (cmd, "plugin");
+ nm_strv_ptrarray_add_string_dup (cmd, "rp-pppoe.so");
+ nm_strv_ptrarray_add_string_dup (cmd, priv->parent_iface);
}
- nm_cmd_line_add_string (cmd, "noipdefault");
+ nm_strv_ptrarray_add_string_dup (cmd, "noipdefault");
} else {
- nm_cmd_line_add_string (cmd, priv->parent_iface);
+ nm_strv_ptrarray_add_string_dup (cmd, priv->parent_iface);
/* Don't send some random address as the local address */
- nm_cmd_line_add_string (cmd, "noipdefault");
+ nm_strv_ptrarray_add_string_dup (cmd, "noipdefault");
}
if (nm_setting_ppp_get_baud (setting))
- nm_cmd_line_add_int (cmd, nm_setting_ppp_get_baud (setting));
+ nm_strv_ptrarray_add_int (cmd, nm_setting_ppp_get_baud (setting));
else if (baud_override)
- nm_cmd_line_add_int (cmd, (int) baud_override);
+ nm_strv_ptrarray_add_int (cmd, baud_override);
/* noauth by default, because we certainly don't have any information
* with which to verify anything the peer gives us if we ask it to
* authenticate itself, which is what 'auth' really means.
*/
- nm_cmd_line_add_string (cmd, "noauth");
+ nm_strv_ptrarray_add_string_dup (cmd, "noauth");
if (nm_setting_ppp_get_refuse_eap (setting))
- nm_cmd_line_add_string (cmd, "refuse-eap");
+ nm_strv_ptrarray_add_string_dup (cmd, "refuse-eap");
if (nm_setting_ppp_get_refuse_pap (setting))
- nm_cmd_line_add_string (cmd, "refuse-pap");
+ nm_strv_ptrarray_add_string_dup (cmd, "refuse-pap");
if (nm_setting_ppp_get_refuse_chap (setting))
- nm_cmd_line_add_string (cmd, "refuse-chap");
+ nm_strv_ptrarray_add_string_dup (cmd, "refuse-chap");
if (nm_setting_ppp_get_refuse_mschap (setting))
- nm_cmd_line_add_string (cmd, "refuse-mschap");
+ nm_strv_ptrarray_add_string_dup (cmd, "refuse-mschap");
if (nm_setting_ppp_get_refuse_mschapv2 (setting))
- nm_cmd_line_add_string (cmd, "refuse-mschap-v2");
+ nm_strv_ptrarray_add_string_dup (cmd, "refuse-mschap-v2");
if (nm_setting_ppp_get_nobsdcomp (setting))
- nm_cmd_line_add_string (cmd, "nobsdcomp");
+ nm_strv_ptrarray_add_string_dup (cmd, "nobsdcomp");
if (nm_setting_ppp_get_no_vj_comp (setting))
- nm_cmd_line_add_string (cmd, "novj");
+ nm_strv_ptrarray_add_string_dup (cmd, "novj");
if (nm_setting_ppp_get_nodeflate (setting))
- nm_cmd_line_add_string (cmd, "nodeflate");
+ nm_strv_ptrarray_add_string_dup (cmd, "nodeflate");
if (nm_setting_ppp_get_require_mppe (setting))
- nm_cmd_line_add_string (cmd, "require-mppe");
+ nm_strv_ptrarray_add_string_dup (cmd, "require-mppe");
if (nm_setting_ppp_get_require_mppe_128 (setting))
- nm_cmd_line_add_string (cmd, "require-mppe-128");
+ nm_strv_ptrarray_add_string_dup (cmd, "require-mppe-128");
if (nm_setting_ppp_get_mppe_stateful (setting))
- nm_cmd_line_add_string (cmd, "mppe-stateful");
+ nm_strv_ptrarray_add_string_dup (cmd, "mppe-stateful");
if (nm_setting_ppp_get_crtscts (setting))
- nm_cmd_line_add_string (cmd, "crtscts");
+ nm_strv_ptrarray_add_string_dup (cmd, "crtscts");
/* Always ask for DNS, we don't have to use them if the connection
* overrides the returned servers.
*/
- nm_cmd_line_add_string (cmd, "usepeerdns");
+ nm_strv_ptrarray_add_string_dup (cmd, "usepeerdns");
if (nm_setting_ppp_get_mru (setting)) {
- nm_cmd_line_add_string (cmd, "mru");
- nm_cmd_line_add_int (cmd, nm_setting_ppp_get_mru (setting));
+ nm_strv_ptrarray_add_string_dup (cmd, "mru");
+ nm_strv_ptrarray_add_int (cmd, nm_setting_ppp_get_mru (setting));
}
if (nm_setting_ppp_get_mtu (setting)) {
- nm_cmd_line_add_string (cmd, "mtu");
- nm_cmd_line_add_int (cmd, nm_setting_ppp_get_mtu (setting));
+ nm_strv_ptrarray_add_string_dup (cmd, "mtu");
+ nm_strv_ptrarray_add_int (cmd, nm_setting_ppp_get_mtu (setting));
}
- nm_cmd_line_add_string (cmd, "lcp-echo-failure");
- nm_cmd_line_add_int (cmd, nm_setting_ppp_get_lcp_echo_failure (setting));
+ nm_strv_ptrarray_add_string_dup (cmd, "lcp-echo-failure");
+ nm_strv_ptrarray_add_int (cmd, nm_setting_ppp_get_lcp_echo_failure (setting));
- nm_cmd_line_add_string (cmd, "lcp-echo-interval");
- nm_cmd_line_add_int (cmd, nm_setting_ppp_get_lcp_echo_interval (setting));
+ nm_strv_ptrarray_add_string_dup (cmd, "lcp-echo-interval");
+ nm_strv_ptrarray_add_int (cmd, nm_setting_ppp_get_lcp_echo_interval (setting));
/* Avoid pppd to exit if no traffic going through */
- nm_cmd_line_add_string (cmd, "idle");
- nm_cmd_line_add_int (cmd, 0);
+ nm_strv_ptrarray_add_string_dup (cmd, "idle");
+ nm_strv_ptrarray_add_string_dup (cmd, "0");
- nm_cmd_line_add_string (cmd, "ipparam");
- nm_cmd_line_add_string (cmd, nm_dbus_object_get_path (NM_DBUS_OBJECT (self)));
+ nm_strv_ptrarray_add_string_dup (cmd, "ipparam");
+ nm_strv_ptrarray_add_string_dup (cmd, nm_dbus_object_get_path (NM_DBUS_OBJECT (self)));
- nm_cmd_line_add_string (cmd, "plugin");
- nm_cmd_line_add_string (cmd, NM_PPPD_PLUGIN);
+ nm_strv_ptrarray_add_string_dup (cmd, "plugin");
+ nm_strv_ptrarray_add_string_dup (cmd, NM_PPPD_PLUGIN);
if (pppoe && nm_setting_pppoe_get_parent (pppoe)) {
+ static int unit;
+
/* The PPP interface is going to be renamed, so pass a
* different unit each time so that activations don't
* race with each others. */
- nm_cmd_line_add_string (cmd, "unit");
- nm_cmd_line_add_int (cmd, unit);
+ nm_strv_ptrarray_add_string_dup (cmd, "unit");
+ nm_strv_ptrarray_add_int (cmd, unit);
unit = unit < G_MAXINT ? unit + 1 : 0;
}
- return cmd;
+ g_ptr_array_add (cmd, NULL);
+ return g_steal_pointer (&cmd);
}
static void
@@ -1038,8 +979,8 @@ _ppp_manager_start (NMPPPManager *self,
gs_unref_object NMSettingPpp *s_ppp_free = NULL;
NMSettingPppoe *pppoe_setting;
NMSettingAdsl *adsl_setting;
- NMCmdLine *ppp_cmd;
- char *cmd_str;
+ gs_unref_ptrarray GPtrArray *ppp_cmd = NULL;
+ gs_free char *cmd_str = NULL;
struct stat st;
const char *ip6_method, *ip4_method;
gboolean ip6_enabled = FALSE;
@@ -1104,23 +1045,25 @@ _ppp_manager_start (NMPPPManager *self,
ip6_enabled,
err);
if (!ppp_cmd)
- goto out;
-
- g_ptr_array_add (ppp_cmd->array, NULL);
+ goto fail;
_LOGI ("starting PPP connection");
- cmd_str = nm_cmd_line_to_str (ppp_cmd);
_LOGD ("command line: %s", cmd_str);
- g_free (cmd_str);
+ (cmd_str = g_strjoinv (" ", (char **) ppp_cmd->pdata));
priv->pid = 0;
- if (!g_spawn_async (NULL, (char **) ppp_cmd->array->pdata, NULL,
+ if (!g_spawn_async (NULL,
+ (char **) ppp_cmd->pdata,
+ NULL,
G_SPAWN_DO_NOT_REAP_CHILD,
- nm_utils_setpgid, NULL,
- &priv->pid, err)) {
- goto out;
- }
+ nm_utils_setpgid,
+ NULL,
+ &priv->pid,
+ err))
+ goto fail;
+
+ nm_assert (priv->pid > 0);
_LOGI ("pppd started with pid %lld", (long long) priv->pid);
@@ -1128,14 +1071,10 @@ _ppp_manager_start (NMPPPManager *self,
priv->ppp_timeout_handler = g_timeout_add_seconds (timeout_secs, pppd_timed_out, self);
priv->act_req = g_object_ref (req);
-out:
- if (ppp_cmd)
- nm_cmd_line_destroy (ppp_cmd);
-
- if (priv->pid <= 0)
- nm_dbus_object_unexport (NM_DBUS_OBJECT (self));
-
- return priv->pid > 0;
+ return TRUE;
+fail:
+ nm_dbus_object_unexport (NM_DBUS_OBJECT (self));
+ return FALSE;
}
static void