shared: merge branch 'th/metered-for-shared'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/57
This commit is contained in:
Thomas Haller 2018-12-03 12:29:29 +01:00
commit 5fb800125f
7 changed files with 265 additions and 254 deletions

View file

@ -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__ */

View file

@ -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);

View file

@ -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, 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_utils_inet4_ntop (listen_address->address, listen_address_s);
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");
}
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_dup (cmd, "--dhcp-lease-max=50");
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_printf (cmd,
"--dhcp-leasefile=%s/dnsmasq-%s.leases",
NMSTATEDIR,
iface);
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

View file

@ -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);

View file

@ -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)
{

View file

@ -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__ */

View file

@ -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_cmd_line_add_string (cmd, "nodetach");
nm_cmd_line_add_string (cmd, "lock");
nm_strv_ptrarray_add_string_dup (cmd, pppd_binary);
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