NMConnection * nm_act_request_get_connection (NMActRequest *req) { g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NULL); return nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (req)); }
NMVPNConnection * nm_vpn_manager_activate_connection (NMVPNManager *manager, NMConnection *connection, NMActRequest *act_request, NMDevice *device, GError **error) { NMSettingVPN *vpn_setting; NMVPNService *service; NMVPNConnection *vpn = NULL; const char *service_name; g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL); g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); g_return_val_if_fail (NM_IS_ACT_REQUEST (act_request), NULL); g_return_val_if_fail (NM_IS_DEVICE (device), NULL); g_return_val_if_fail (error != NULL, NULL); g_return_val_if_fail (*error == NULL, NULL); if (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED) { g_set_error (error, NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE, "%s", "The base device for the VPN connection was not active."); return NULL; } vpn_setting = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN); if (!vpn_setting) { g_set_error (error, NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_CONNECTION_INVALID, "%s", "The connection was not a VPN connection."); return NULL; } vpn = find_active_vpn_connection_by_connection (manager, connection); if (vpn) { nm_vpn_connection_disconnect (vpn, NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED); vpn = NULL; } service_name = nm_setting_vpn_get_service_type (vpn_setting); g_assert (service_name); service = g_hash_table_lookup (NM_VPN_MANAGER_GET_PRIVATE (manager)->services, service_name); if (!service) { g_set_error (error, NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_SERVICE_INVALID, "The VPN service '%s' was not installed.", service_name); return NULL; } vpn = nm_vpn_service_activate (service, connection, act_request, device, error); if (vpn) { g_signal_connect (vpn, "vpn-state-changed", G_CALLBACK (connection_vpn_state_changed), manager); } return vpn; }
const char * nm_act_request_get_dbus_sender (NMActRequest *req) { g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NULL); return NM_ACT_REQUEST_GET_PRIVATE (req)->dbus_sender; }
GObject * nm_act_request_get_device (NMActRequest *req) { g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NULL); return G_OBJECT (NM_ACT_REQUEST_GET_PRIVATE (req)->device); }
NMConnection * nm_act_request_get_connection (NMActRequest *req) { g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NULL); return NM_ACT_REQUEST_GET_PRIVATE (req)->connection; }
gulong nm_act_request_get_user_uid (NMActRequest *req) { g_return_val_if_fail (NM_IS_ACT_REQUEST (req), 0); return NM_ACT_REQUEST_GET_PRIVATE (req)->user_uid; }
gboolean nm_act_request_get_shared (NMActRequest *req) { g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE); return NM_ACT_REQUEST_GET_PRIVATE (req)->shared; }
void nm_act_request_cancel_secrets (NMActRequest *self, guint32 call_id) { NMActRequestPrivate *priv; GSList *iter; g_return_if_fail (self); g_return_if_fail (NM_IS_ACT_REQUEST (self)); g_return_if_fail (call_id > 0); priv = NM_ACT_REQUEST_GET_PRIVATE (self); for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) { GetSecretsInfo *info = iter->data; /* Remove the matching info */ if (info->call_id == call_id) { priv->secrets_calls = g_slist_remove_link (priv->secrets_calls, iter); g_slist_free (iter); nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection), call_id); g_free (info); break; } } }
void nm_act_request_clear_secrets (NMActRequest *self) { g_return_if_fail (NM_IS_ACT_REQUEST (self)); nm_active_connection_clear_secrets ((NMActiveConnection *) self); }
static void get_secrets_cb (NMSettingsConnection *connection, NMSettingsConnectionCallId call_id_s, const char *agent_username, const char *setting_name, GError *error, gpointer user_data) { GetSecretsInfo *info = user_data; NMActRequestPrivate *priv; g_return_if_fail (info && info->call_id == call_id_s); g_return_if_fail (NM_IS_ACT_REQUEST (info->self)); if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) return; priv = NM_ACT_REQUEST_GET_PRIVATE (info->self); g_return_if_fail (g_slist_find (priv->secrets_calls, info)); priv->secrets_calls = g_slist_remove (priv->secrets_calls, info); if (info->callback) info->callback (info->self, info, connection, error, info->callback_data); _get_secrets_info_free (info); }
void nm_act_request_set_shared (NMActRequest *req, gboolean shared) { NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req); GSList *list, *iter; g_return_if_fail (NM_IS_ACT_REQUEST (req)); NM_ACT_REQUEST_GET_PRIVATE (req)->shared = shared; /* Tear the rules down in reverse order when sharing is stopped */ list = g_slist_copy (priv->share_rules); if (!shared) list = g_slist_reverse (list); /* Send the rules to iptables */ for (iter = list; iter; iter = g_slist_next (iter)) { ShareRule *rule = (ShareRule *) iter->data; char *envp[1] = { NULL }; char **argv; char *cmd; cmd = g_strdup_printf ("%s --table %s %s %s", IPTABLES_PATH, rule->table, shared ? "--insert" : "--delete", rule->rule); if (!cmd) continue; argv = g_strsplit (cmd, " ", 0); if (argv && argv[0]) { int status; GError *error = NULL; nm_log_info (LOGD_SHARING, "Executing: %s", cmd); if (!g_spawn_sync ("/", argv, envp, G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, share_child_setup, NULL, NULL, NULL, &status, &error)) { nm_log_warn (LOGD_SHARING, "Error executing command: (%d) %s", error ? error->code : -1, (error && error->message) ? error->message : "(unknown)"); g_clear_error (&error); } else if (WEXITSTATUS (status)) { nm_log_warn (LOGD_SHARING, "** Command returned exit status %d.", WEXITSTATUS (status)); } } g_free (cmd); if (argv) g_strfreev (argv); } g_slist_free (list); /* Clear the share rule list when sharing is stopped */ if (!shared) clear_share_rules (req); }
NMActStageReturn nm_modem_stage3_ip6_config_start (NMModem *self, NMActRequest *req, NMDeviceStateReason *reason) { NMModemPrivate *priv; NMActStageReturn ret; NMConnection *connection; const char *method; g_return_val_if_fail (self != NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); connection = nm_act_request_get_applied_connection (req); g_assert (connection); method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); /* Only Ignore and Auto methods make sense for WWAN */ if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) return NM_ACT_STAGE_RETURN_STOP; if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) != 0) { nm_log_warn (LOGD_MB | LOGD_IP6, "(%s): unhandled WWAN IPv6 method '%s'; will fail", nm_modem_get_uid (self), method); *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; return NM_ACT_STAGE_RETURN_FAILURE; } priv = NM_MODEM_GET_PRIVATE (self); switch (priv->ip6_method) { case NM_MODEM_IP_METHOD_PPP: ret = ppp_stage3_ip_config_start (self, req, reason); break; case NM_MODEM_IP_METHOD_STATIC: case NM_MODEM_IP_METHOD_AUTO: /* Both static and DHCP/Auto retrieve a base IP config from the modem * which in the static case is the full config, and the DHCP/Auto case * is just the IPv6LL address to use for SLAAC. */ ret = NM_MODEM_GET_CLASS (self)->stage3_ip6_config_request (self, reason); break; default: nm_log_info (LOGD_MB, "(%s): IPv6 configuration disabled", nm_modem_get_uid (self)); ret = NM_ACT_STAGE_RETURN_STOP; break; } return ret; }
static NMActStageReturn ppp_stage3_ip4_config_start (NMModem *self, NMActRequest *req, NMDeviceStateReason *reason) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); const char *ppp_name = NULL; GError *error = NULL; NMActStageReturn ret; g_return_val_if_fail (self != NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); if (NM_MODEM_GET_CLASS (self)->get_user_pass) { NMConnection *connection = nm_act_request_get_connection (req); g_assert (connection); if (!NM_MODEM_GET_CLASS (self)->get_user_pass (self, connection, &ppp_name, NULL)) return NM_ACT_STAGE_RETURN_FAILURE; } priv->ppp_manager = nm_ppp_manager_new (priv->iface); if (nm_ppp_manager_start (priv->ppp_manager, req, ppp_name, 20, &error)) { g_signal_connect (priv->ppp_manager, "state-changed", G_CALLBACK (ppp_state_changed), self); g_signal_connect (priv->ppp_manager, "ip4-config", G_CALLBACK (ppp_ip4_config), self); g_signal_connect (priv->ppp_manager, "stats", G_CALLBACK (ppp_stats), self); ret = NM_ACT_STAGE_RETURN_POSTPONE; } else { nm_log_err (LOGD_PPP, "error starting PPP: (%d) %s", error ? error->code : -1, error && error->message ? error->message : "(unknown)"); g_error_free (error); g_object_unref (priv->ppp_manager); priv->ppp_manager = NULL; *reason = NM_DEVICE_STATE_REASON_PPP_START_FAILED; ret = NM_ACT_STAGE_RETURN_FAILURE; } return ret; }
void nm_act_request_cancel_secrets (NMActRequest *self, NMActRequestGetSecretsCallId call_id) { NMActRequestPrivate *priv; g_return_if_fail (NM_IS_ACT_REQUEST (self)); g_return_if_fail (call_id); priv = NM_ACT_REQUEST_GET_PRIVATE (self); if (!g_slist_find (priv->secrets_calls, call_id)) g_return_if_reached (); _do_cancel_secrets (self, call_id, FALSE); }
void nm_act_request_add_share_rule (NMActRequest *req, const char *table, const char *table_rule) { NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req); ShareRule *rule; g_return_if_fail (NM_IS_ACT_REQUEST (req)); g_return_if_fail (table != NULL); g_return_if_fail (table_rule != NULL); rule = g_malloc0 (sizeof (ShareRule)); rule->table = g_strdup (table); rule->rule = g_strdup (table_rule); priv->share_rules = g_slist_append (priv->share_rules, rule); }
guint32 nm_act_request_get_secrets (NMActRequest *self, const char *setting_name, NMSettingsGetSecretsFlags flags, const char *hint, NMActRequestSecretsFunc callback, gpointer callback_data) { NMActRequestPrivate *priv; GetSecretsInfo *info; guint32 call_id; NMConnection *connection; gboolean user_requested; g_return_val_if_fail (self, 0); g_return_val_if_fail (NM_IS_ACT_REQUEST (self), 0); priv = NM_ACT_REQUEST_GET_PRIVATE (self); info = g_malloc0 (sizeof (GetSecretsInfo)); info->self = self; info->callback = callback; info->callback_data = callback_data; user_requested = nm_active_connection_get_user_requested (NM_ACTIVE_CONNECTION (self)); if (user_requested) flags |= NM_SETTINGS_GET_SECRETS_FLAG_USER_REQUESTED; connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (self)); call_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (connection), user_requested, nm_active_connection_get_user_uid (NM_ACTIVE_CONNECTION (self)), setting_name, flags, hint, get_secrets_cb, info, NULL); if (call_id > 0) { info->call_id = call_id; priv->secrets_calls = g_slist_append (priv->secrets_calls, info); } else g_free (info); return call_id; }
/** * nm_act_request_get_secrets: * @self: * @setting_name: * @flags: * @hint: * @callback: * @callback_data: * * Asnychronously starts the request for secrets. This function cannot * fail. * * The return call-id can be used to cancel the request. You are * only allowed to cancel a still pending operation (once). * The callback will always be invoked once, even for canceling * or disposing of NMActRequest. * * Returns: a call-id. */ NMActRequestGetSecretsCallId nm_act_request_get_secrets (NMActRequest *self, const char *setting_name, NMSecretAgentGetSecretsFlags flags, const char *hint, NMActRequestSecretsFunc callback, gpointer callback_data) { NMActRequestPrivate *priv; GetSecretsInfo *info; NMSettingsConnectionCallId call_id_s; NMSettingsConnection *settings_connection; NMConnection *applied_connection; const char *hints[2] = { hint, NULL }; g_return_val_if_fail (NM_IS_ACT_REQUEST (self), 0); priv = NM_ACT_REQUEST_GET_PRIVATE (self); settings_connection = nm_act_request_get_settings_connection (self); applied_connection = nm_act_request_get_applied_connection (self); info = _get_secrets_info_new (self, callback, callback_data); priv->secrets_calls = g_slist_append (priv->secrets_calls, info); if (nm_active_connection_get_user_requested (NM_ACTIVE_CONNECTION (self))) flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED; call_id_s = nm_settings_connection_get_secrets (settings_connection, applied_connection, nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (self)), setting_name, flags, hints, get_secrets_cb, info); info->call_id = call_id_s; g_return_val_if_fail (call_id_s, NULL); return info; }
static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object); NMDevice *master; switch (prop_id) { case PROP_MASTER: if (priv->dep && NM_IS_ACT_REQUEST (priv->dep)) { master = NM_DEVICE (nm_act_request_get_device (NM_ACT_REQUEST (priv->dep))); g_assert (master); g_value_set_boxed (value, nm_device_get_path (master)); } else g_value_set_boxed (value, "/"); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static NMActStageReturn static_stage3_ip4_config_start (NMModem *self, NMActRequest *req, NMDeviceStateReason *reason) { NMModemPrivate *priv; g_return_val_if_fail (self != NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); priv = NM_MODEM_GET_PRIVATE (self); priv->call = dbus_g_proxy_begin_call (nm_modem_get_proxy (self, MM_DBUS_INTERFACE_MODEM), "GetIP4Config", static_stage3_done, self, NULL, G_TYPE_INVALID); return NM_ACT_STAGE_RETURN_POSTPONE; }
static NMActStageReturn ppp_stage3_ip_config_start (NMModem *self, NMActRequest *req, NMDeviceStateReason *reason) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); const char *ppp_name = NULL; GError *error = NULL; NMActStageReturn ret; guint ip_timeout = 30; g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); /* If we're already running PPP don't restart it; for example, if both * IPv4 and IPv6 are requested, IPv4 gets started first, but we use the * same pppd for both v4 and v6. */ if (priv->ppp_manager) return NM_ACT_STAGE_RETURN_POSTPONE; if (NM_MODEM_GET_CLASS (self)->get_user_pass) { NMConnection *connection = nm_act_request_get_applied_connection (req); g_assert (connection); if (!NM_MODEM_GET_CLASS (self)->get_user_pass (self, connection, &ppp_name, NULL)) return NM_ACT_STAGE_RETURN_FAILURE; } /* Check if ModemManager requested a specific IP timeout to be used. If 0 reported, * use the default one (30s) */ if (priv->mm_ip_timeout > 0) { nm_log_info (LOGD_PPP, "(%s): using modem-specified IP timeout: %u seconds", nm_modem_get_uid (self), priv->mm_ip_timeout); ip_timeout = priv->mm_ip_timeout; } priv->ppp_manager = nm_ppp_manager_new (priv->data_port); if (nm_ppp_manager_start (priv->ppp_manager, req, ppp_name, ip_timeout, &error)) { g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_STATE_CHANGED, G_CALLBACK (ppp_state_changed), self); g_signal_connect (priv->ppp_manager, "ip4-config", G_CALLBACK (ppp_ip4_config), self); g_signal_connect (priv->ppp_manager, "ip6-config", G_CALLBACK (ppp_ip6_config), self); g_signal_connect (priv->ppp_manager, "stats", G_CALLBACK (ppp_stats), self); ret = NM_ACT_STAGE_RETURN_POSTPONE; } else { nm_log_err (LOGD_PPP, "(%s): error starting PPP: %s", nm_modem_get_uid (self), error->message); g_error_free (error); nm_exported_object_clear_and_unexport (&priv->ppp_manager); *reason = NM_DEVICE_STATE_REASON_PPP_START_FAILED; ret = NM_ACT_STAGE_RETURN_FAILURE; } return ret; }
gboolean nm_ppp_manager_start (NMPPPManager *manager, NMActRequest *req, const char *ppp_name, guint32 timeout_secs, GError **err) { NMPPPManagerPrivate *priv; NMConnection *connection; NMSettingPpp *s_ppp; gboolean s_ppp_created = FALSE; NMSettingPppoe *pppoe_setting; NMSettingAdsl *adsl_setting; NMCmdLine *ppp_cmd; char *cmd_str; struct stat st; g_return_val_if_fail (NM_IS_PPP_MANAGER (manager), FALSE); g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE); priv = NM_PPP_MANAGER_GET_PRIVATE (manager); #if !WITH_PPP /* PPP support disabled */ g_set_error_literal (err, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, "PPP support is not enabled."); return FALSE; #endif priv->pid = 0; /* Make sure /dev/ppp exists (bgo #533064) */ if (stat ("/dev/ppp", &st) || !S_ISCHR (st.st_mode)) nm_utils_modprobe (NULL, FALSE, "ppp_generic", NULL); connection = nm_act_request_get_applied_connection (req); g_assert (connection); s_ppp = nm_connection_get_setting_ppp (connection); if (!s_ppp) { /* If the PPP settings are all default we may not have a PPP setting yet, * so just make a default one here. */ s_ppp = NM_SETTING_PPP (nm_setting_ppp_new ()); s_ppp_created = TRUE; } pppoe_setting = nm_connection_get_setting_pppoe (connection); if (pppoe_setting) pppoe_fill_defaults (s_ppp); adsl_setting = (NMSettingAdsl *) nm_connection_get_setting (connection, NM_TYPE_SETTING_ADSL); ppp_cmd = create_pppd_cmd_line (manager, s_ppp, pppoe_setting, adsl_setting, ppp_name, err); if (!ppp_cmd) goto out; g_ptr_array_add (ppp_cmd->array, NULL); _LOGI ("starting PPP connection"); cmd_str = nm_cmd_line_to_str (ppp_cmd); _LOGD ("command line: %s", cmd_str); g_free (cmd_str); priv->pid = 0; if (!g_spawn_async (NULL, (char **) ppp_cmd->array->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD, nm_utils_setpgid, NULL, &priv->pid, err)) { goto out; } _LOGI ("pppd started with pid %d", priv->pid); priv->ppp_watch_id = g_child_watch_add (priv->pid, (GChildWatchFunc) ppp_watch_cb, manager); priv->ppp_timeout_handler = g_timeout_add_seconds (timeout_secs, pppd_timed_out, manager); priv->act_req = g_object_ref (req); out: if (s_ppp_created) g_object_unref (s_ppp); if (ppp_cmd) nm_cmd_line_destroy (ppp_cmd); return priv->pid > 0; }
static NMActStageReturn ppp_stage3_ip4_config_start (NMModem *self, NMActRequest *req, NMDeviceStateReason *reason) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); const char *ppp_name = NULL; GError *error = NULL; NMActStageReturn ret; guint ip_timeout = 20; g_return_val_if_fail (self != NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); if (NM_MODEM_GET_CLASS (self)->get_user_pass) { NMConnection *connection = nm_act_request_get_connection (req); g_assert (connection); if (!NM_MODEM_GET_CLASS (self)->get_user_pass (self, connection, &ppp_name, NULL)) return NM_ACT_STAGE_RETURN_FAILURE; } /* Check if ModemManager requested a specific IP timeout to be used. If 0 reported, * use the default one (20s) */ if (priv->mm_ip_timeout > 0) { nm_log_info (LOGD_PPP, "using modem-specified IP timeout: %u seconds", priv->mm_ip_timeout); ip_timeout = priv->mm_ip_timeout; } priv->ppp_manager = nm_ppp_manager_new (priv->iface); if (nm_ppp_manager_start (priv->ppp_manager, req, ppp_name, ip_timeout, &error)) { g_signal_connect (priv->ppp_manager, "state-changed", G_CALLBACK (ppp_state_changed), self); g_signal_connect (priv->ppp_manager, "ip4-config", G_CALLBACK (ppp_ip4_config), self); g_signal_connect (priv->ppp_manager, "stats", G_CALLBACK (ppp_stats), self); ret = NM_ACT_STAGE_RETURN_POSTPONE; } else { nm_log_err (LOGD_PPP, "error starting PPP: (%d) %s", error ? error->code : -1, error && error->message ? error->message : "(unknown)"); g_error_free (error); g_object_unref (priv->ppp_manager); priv->ppp_manager = NULL; *reason = NM_DEVICE_STATE_REASON_PPP_START_FAILED; ret = NM_ACT_STAGE_RETURN_FAILURE; } return ret; }