diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/NetworkManager.c | 2 | ||||
-rw-r--r-- | src/NetworkManagerPolicy.c | 2 | ||||
-rw-r--r-- | src/NetworkManagerSystem.c | 21 | ||||
-rw-r--r-- | src/NetworkManagerUtils.c | 27 | ||||
-rw-r--r-- | src/dhcp-manager/nm-dhcp-manager.c | 12 | ||||
-rw-r--r-- | src/dnsmasq-manager/nm-dnsmasq-manager.c | 1 | ||||
-rw-r--r-- | src/modem-manager/nm-modem-device.c | 7 | ||||
-rw-r--r-- | src/modem-manager/nm-modem-manager.c | 21 | ||||
-rw-r--r-- | src/modem-manager/nm-modem-types.h | 5 | ||||
-rw-r--r-- | src/nm-activation-request.c | 106 | ||||
-rw-r--r-- | src/nm-device-ethernet.c | 7 | ||||
-rw-r--r-- | src/nm-device-wifi.c | 38 | ||||
-rw-r--r-- | src/nm-device.c | 8 | ||||
-rw-r--r-- | src/nm-ip4-config.c | 80 | ||||
-rw-r--r-- | src/nm-ip4-config.h | 13 | ||||
-rw-r--r-- | src/nm-manager.c | 31 | ||||
-rw-r--r-- | src/nm-manager.h | 2 | ||||
-rw-r--r-- | src/ppp-manager/nm-ppp-manager.c | 267 | ||||
-rw-r--r-- | src/ppp-manager/nm-ppp-manager.h | 9 | ||||
-rw-r--r-- | src/ppp-manager/nm-pppd-plugin.c | 38 | ||||
-rw-r--r-- | src/ppp-manager/nm-pppd-plugin.h | 1 | ||||
-rw-r--r-- | src/vpn-manager/nm-vpn-connection.c | 144 |
22 files changed, 470 insertions, 372 deletions
diff --git a/src/NetworkManager.c b/src/NetworkManager.c index f6651de16c..9468c94ba0 100644 --- a/src/NetworkManager.c +++ b/src/NetworkManager.c @@ -303,7 +303,7 @@ main (int argc, char *argv[]) goto done; } - manager = nm_manager_new (); + manager = nm_manager_get (); if (manager == NULL) { nm_error ("Failed to initialize the network manager."); goto done; diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c index 1a6608e3a1..17b5041400 100644 --- a/src/NetworkManagerPolicy.c +++ b/src/NetworkManagerPolicy.c @@ -147,7 +147,7 @@ update_routing_and_dns (NMPolicy *policy, gboolean force_update) /* Never set the default route through an IPv4LL-addressed device */ s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); - if (s_ip4 && !strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_AUTOIP)) + if (s_ip4 && !strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) continue; /* Make sure at least one of this device's IP addresses has a gateway */ diff --git a/src/NetworkManagerSystem.c b/src/NetworkManagerSystem.c index 8aa885c0f2..bf6b11d792 100644 --- a/src/NetworkManagerSystem.c +++ b/src/NetworkManagerSystem.c @@ -107,6 +107,7 @@ nm_system_device_set_ip4_route (const char *iface, guint32 ip4_dest, guint32 ip4_prefix, guint32 ip4_gateway, + guint32 metric, int mss) { struct nl_handle *nlh; @@ -148,6 +149,10 @@ nm_system_device_set_ip4_route (const char *iface, } } + /* Metric */ + if (metric) + rtnl_route_set_prio (route, metric); + /* Add the route */ err = rtnl_route_add (nlh, route, 0); if (err == -ESRCH && ip4_gateway) { @@ -284,14 +289,15 @@ nm_system_device_set_from_ip4_config (const char *iface, sleep (1); - len = nm_ip4_config_get_num_static_routes (config); + len = nm_ip4_config_get_num_routes (config); for (i = 0; i < len; i++) { - const NMSettingIP4Address *route = nm_ip4_config_get_static_route (config, i); + const NMSettingIP4Route *route = nm_ip4_config_get_route (config, i); nm_system_device_set_ip4_route (iface, config, route->address, route->prefix, - route->gateway, + route->next_hop, + route->metric, nm_ip4_config_get_mss (config)); } @@ -344,7 +350,7 @@ nm_system_vpn_device_set_from_ip4_config (NMDevice *active_device, } nm_system_device_set_ip4_route (nm_device_get_ip_iface (active_device), - ad_config, vpn_gw, 32, ad_gw, + ad_config, vpn_gw, 32, ad_gw, 0, nm_ip4_config_get_mss (config)); } } @@ -362,14 +368,15 @@ nm_system_vpn_device_set_from_ip4_config (NMDevice *active_device, nm_system_device_set_mtu (iface, nm_ip4_config_get_mtu (config)); /* Set routes */ - num = nm_ip4_config_get_num_static_routes (config); + num = nm_ip4_config_get_num_routes (config); for (i = 0; i < num; i++) { - const NMSettingIP4Address *route = nm_ip4_config_get_static_route (config, i); + const NMSettingIP4Route *route = nm_ip4_config_get_route (config, i); nm_system_device_set_ip4_route (iface, config, route->address, route->prefix, - route->gateway, + route->next_hop, + route->metric, nm_ip4_config_get_mss (config)); } diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index a4a56448eb..66fe990795 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -278,11 +278,14 @@ nm_utils_merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting) if (!setting) return; /* Defaults are just fine */ - if (setting->ignore_dhcp_dns) { + if (setting->ignore_auto_dns) { nm_ip4_config_reset_nameservers (ip4_config); nm_ip4_config_reset_searches (ip4_config); } + if (setting->ignore_auto_routes) + nm_ip4_config_reset_routes (ip4_config); + if (setting->dns) { int i, j; @@ -344,25 +347,27 @@ nm_utils_merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting) nm_ip4_config_add_address (ip4_config, setting_addr); } - /* IPv4 static routes */ + /* IPv4 routes */ for (iter = setting->routes; iter; iter = g_slist_next (iter)) { - NMSettingIP4Address *setting_route = (NMSettingIP4Address *) iter->data; + NMSettingIP4Route *setting_route = (NMSettingIP4Route *) iter->data; guint32 i, num; - num = nm_ip4_config_get_num_static_routes (ip4_config); + num = nm_ip4_config_get_num_routes (ip4_config); for (i = 0; i < num; i++) { - const NMSettingIP4Address *cfg_route; - - cfg_route = nm_ip4_config_get_static_route (ip4_config, i); - /* Dupe, override with user-specified address */ - if (cfg_route->address == setting_route->address) { - nm_ip4_config_replace_static_route (ip4_config, i, setting_route); + const NMSettingIP4Route *cfg_route; + + cfg_route = nm_ip4_config_get_route (ip4_config, i); + /* Dupe, override with user-specified route */ + if ( (cfg_route->address == setting_route->address) + && (cfg_route->prefix == setting_route->prefix) + && (cfg_route->next_hop == setting_route->next_hop)) { + nm_ip4_config_replace_route (ip4_config, i, setting_route); break; } } if (i == num) - nm_ip4_config_add_static_route (ip4_config, setting_route); + nm_ip4_config_add_route (ip4_config, setting_route); } } diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index 4846bf1044..94c4a65c61 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -829,6 +829,7 @@ nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager, char **s; for (s = searches; *s; s += 2) { + NMSettingIP4Route *route; struct in_addr rt_addr; struct in_addr rt_route; @@ -843,13 +844,12 @@ nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager, // FIXME: ensure the IP addresse and route are sane - addr = g_malloc0 (sizeof (NMSettingIP4Address)); - addr->address = (guint32) rt_addr.s_addr; - addr->prefix = 32; /* 255.255.255.255 */ - addr->gateway = (guint32) rt_route.s_addr; + route = g_malloc0 (sizeof (NMSettingIP4Route)); + route->address = (guint32) rt_addr.s_addr; + route->prefix = 32; /* 255.255.255.255 */ + route->next_hop = (guint32) rt_route.s_addr; - nm_ip4_config_take_static_route (ip4_config, addr); - addr = NULL; + nm_ip4_config_take_route (ip4_config, route); nm_info (" static route %s gw %s", *s, *(s + 1)); } } else { diff --git a/src/dnsmasq-manager/nm-dnsmasq-manager.c b/src/dnsmasq-manager/nm-dnsmasq-manager.c index e064a7e6c7..7ae4ef2224 100644 --- a/src/dnsmasq-manager/nm-dnsmasq-manager.c +++ b/src/dnsmasq-manager/nm-dnsmasq-manager.c @@ -255,6 +255,7 @@ create_dm_cmd_line (const char *iface, nm_cmd_line_add_string (cmd, "--keep-in-foreground"); nm_cmd_line_add_string (cmd, "--bind-interfaces"); nm_cmd_line_add_string (cmd, "--no-poll"); + nm_cmd_line_add_string (cmd, "--except-interface=lo"); s = g_string_new ("--listen-address="); addr.s_addr = tmp->address; diff --git a/src/modem-manager/nm-modem-device.c b/src/modem-manager/nm-modem-device.c index 21056ec2d6..7cfe142d78 100644 --- a/src/modem-manager/nm-modem-device.c +++ b/src/modem-manager/nm-modem-device.c @@ -338,12 +338,9 @@ real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) req = nm_device_get_act_request (device); g_assert (req); - priv->ppp_manager = nm_ppp_manager_new (); + priv->ppp_manager = nm_ppp_manager_new (nm_device_get_iface (device)); - if (nm_ppp_manager_start (priv->ppp_manager, - nm_device_get_iface (device), - req, - &err)) { + if (nm_ppp_manager_start (priv->ppp_manager, req, &err)) { g_signal_connect (priv->ppp_manager, "state-changed", G_CALLBACK (ppp_state_changed), device); diff --git a/src/modem-manager/nm-modem-manager.c b/src/modem-manager/nm-modem-manager.c index 2c9a912dbc..03aac5bf4d 100644 --- a/src/modem-manager/nm-modem-manager.c +++ b/src/modem-manager/nm-modem-manager.c @@ -114,9 +114,9 @@ create_modem (NMModemManager *manager, const char *path) { NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (manager); NMModemDevice *modem; - char *data_device; - char *driver; - uint modem_type; + char *data_device = NULL; + char *driver = NULL; + uint modem_type = MM_MODEM_TYPE_UNKNOWN; if (g_hash_table_lookup (priv->modems, path)) { nm_warning ("Modem with path %s already exists, ignoring", path); @@ -127,6 +127,21 @@ create_modem (NMModemManager *manager, const char *path) &data_device, &driver, &modem_type)) return; + if (modem_type == MM_MODEM_TYPE_UNKNOWN) { + nm_warning ("Modem with path %s has unknown type, ignoring", path); + return; + } + + if (!driver || !strlen (driver)) { + nm_warning ("Modem with path %s has unknown driver, ignoring", path); + return; + } + + if (!data_device || !strlen (data_device)) { + nm_warning ("Modem with path %s has unknown data device, ignoring", path); + return; + } + modem = nm_modem_device_new (path, data_device, driver, diff --git a/src/modem-manager/nm-modem-types.h b/src/modem-manager/nm-modem-types.h index 14467caa73..b41ff4b2f3 100644 --- a/src/modem-manager/nm-modem-types.h +++ b/src/modem-manager/nm-modem-types.h @@ -8,8 +8,9 @@ #define MM_DBUS_INTERFACE "org.freedesktop.ModemManager" #define MM_DBUS_INTERFACE_MODEM "org.freedesktop.ModemManager.Modem" -#define MM_MODEM_TYPE_GSM 1 -#define MM_MODEM_TYPE_CDMA 2 +#define MM_MODEM_TYPE_UNKNOWN 0 +#define MM_MODEM_TYPE_GSM 1 +#define MM_MODEM_TYPE_CDMA 2 #define MM_MODEM_ERROR_GENERAL MM_DBUS_INTERFACE_MODEM ".GeneralError" #define MM_MODEM_ERROR_PIN_NEEDED MM_DBUS_INTERFACE_MODEM ".PINNeeded" diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index 36c4fc07f4..4df9f887e9 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -35,8 +35,6 @@ #include "nm-manager.h" /* FIXME! */ -#define CONNECTION_GET_SECRETS_CALL_TAG "get-secrets-call" - G_DEFINE_TYPE (NMActRequest, nm_act_request, G_TYPE_OBJECT) #define NM_ACT_REQUEST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_ACT_REQUEST, NMActRequestPrivate)) @@ -53,7 +51,11 @@ static guint signals[LAST_SIGNAL] = { 0 }; typedef struct { + gboolean disposed; + NMConnection *connection; + DBusGProxyCall *secrets_call; + char *specific_object; NMDevice *device; gboolean user_requested; @@ -168,32 +170,44 @@ nm_act_request_init (NMActRequest *req) } static void +cleanup_secrets_dbus_call (NMActRequest *self) +{ + NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self); + DBusGProxy *proxy; + + g_return_if_fail (priv->connection != NULL); + g_return_if_fail (NM_IS_CONNECTION (priv->connection)); + + proxy = g_object_get_data (G_OBJECT (priv->connection), NM_MANAGER_CONNECTION_SECRETS_PROXY_TAG); + g_assert (proxy); + + if (priv->secrets_call) { + dbus_g_proxy_cancel_call (proxy, priv->secrets_call); + priv->secrets_call = NULL; + } +} + +static void dispose (GObject *object) { NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object); - DBusGProxy *proxy; - DBusGProxyCall *call; - if (!priv->connection) - goto out; + if (priv->disposed) { + G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object); + return; + } + priv->disposed = TRUE; + + g_assert (priv->connection); g_signal_handlers_disconnect_by_func (G_OBJECT (priv->device), G_CALLBACK (device_state_changed), NM_ACT_REQUEST (object)); - proxy = g_object_get_data (G_OBJECT (priv->connection), - NM_MANAGER_CONNECTION_SECRETS_PROXY_TAG); - call = g_object_get_data (G_OBJECT (priv->connection), - CONNECTION_GET_SECRETS_CALL_TAG); - - if (proxy && call) - dbus_g_proxy_cancel_call (proxy, call); + cleanup_secrets_dbus_call (NM_ACT_REQUEST (object)); - g_object_set_data (G_OBJECT (priv->connection), - CONNECTION_GET_SECRETS_CALL_TAG, NULL); g_object_unref (priv->connection); -out: G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object); } @@ -443,7 +457,9 @@ get_secrets_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) g_return_if_fail (info->setting_name); priv = NM_ACT_REQUEST_GET_PRIVATE (info->req); - g_object_set_data (G_OBJECT (priv->connection), CONNECTION_GET_SECRETS_CALL_TAG, NULL); + + g_return_if_fail (call == priv->secrets_call); + priv->secrets_call = NULL; if (!dbus_g_proxy_end_call (proxy, call, &err, DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &settings, @@ -498,40 +514,31 @@ out: } gboolean -nm_act_request_request_connection_secrets (NMActRequest *req, +nm_act_request_request_connection_secrets (NMActRequest *self, const char *setting_name, gboolean request_new, RequestSecretsCaller caller, const char *hint1, const char *hint2) { - DBusGProxy *proxy; - DBusGProxyCall *call; + DBusGProxy *secrets_proxy; GetSecretsInfo *info = NULL; NMActRequestPrivate *priv = NULL; GPtrArray *hints = NULL; - g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE); + g_return_val_if_fail (NM_IS_ACT_REQUEST (self), FALSE); g_return_val_if_fail (setting_name != NULL, FALSE); - priv = NM_ACT_REQUEST_GET_PRIVATE (req); - proxy = g_object_get_data (G_OBJECT (priv->connection), NM_MANAGER_CONNECTION_SECRETS_PROXY_TAG); - if (!DBUS_IS_G_PROXY (proxy)) { - nm_warning ("Couldn't get dbus proxy for connection."); - goto error; - } + priv = NM_ACT_REQUEST_GET_PRIVATE (self); + + cleanup_secrets_dbus_call (self); info = g_malloc0 (sizeof (GetSecretsInfo)); - if (!info) { - nm_warning ("Not enough memory to get secrets"); - goto error; - } + g_return_val_if_fail (info != NULL, FALSE); + info->req = self; + info->caller = caller; info->setting_name = g_strdup (setting_name); - if (!info->setting_name) { - nm_warning ("Not enough memory to get secrets"); - goto error; - } /* Empty for now */ hints = g_ptr_array_sized_new (2); @@ -541,29 +548,30 @@ nm_act_request_request_connection_secrets (NMActRequest *req, if (hint2) g_ptr_array_add (hints, g_strdup (hint2)); - info->req = req; - info->caller = caller; - call = dbus_g_proxy_begin_call_with_timeout (proxy, "GetSecrets", - get_secrets_cb, - info, - free_get_secrets_info, - G_MAXINT32, - G_TYPE_STRING, setting_name, - DBUS_TYPE_G_ARRAY_OF_STRING, hints, - G_TYPE_BOOLEAN, request_new, - G_TYPE_INVALID); + secrets_proxy = g_object_get_data (G_OBJECT (priv->connection), NM_MANAGER_CONNECTION_SECRETS_PROXY_TAG); + g_assert (secrets_proxy); + + priv->secrets_call = dbus_g_proxy_begin_call_with_timeout (secrets_proxy, "GetSecrets", + get_secrets_cb, + info, + free_get_secrets_info, + G_MAXINT32, + G_TYPE_STRING, setting_name, + DBUS_TYPE_G_ARRAY_OF_STRING, hints, + G_TYPE_BOOLEAN, request_new, + G_TYPE_INVALID); g_ptr_array_free (hints, TRUE); - if (!call) { - nm_warning ("Could not call GetSecrets"); + if (!priv->secrets_call) { + nm_warning ("Could not call get secrets"); goto error; } - g_object_set_data (G_OBJECT (priv->connection), CONNECTION_GET_SECRETS_CALL_TAG, call); return TRUE; error: if (info) free_get_secrets_info (info); + cleanup_secrets_dbus_call (self); return FALSE; } diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index d1df23ea03..a07f9573c2 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -1178,11 +1178,8 @@ pppoe_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason) req = nm_device_get_act_request (NM_DEVICE (self)); g_assert (req); - priv->ppp_manager = nm_ppp_manager_new (); - if (nm_ppp_manager_start (priv->ppp_manager, - nm_device_get_iface (NM_DEVICE (self)), - req, - &err)) { + priv->ppp_manager = nm_ppp_manager_new (nm_device_get_iface (NM_DEVICE (self))); + if (nm_ppp_manager_start (priv->ppp_manager, req, &err)) { g_signal_connect (priv->ppp_manager, "state-changed", G_CALLBACK (ppp_state_changed), self); diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index 413fe33b88..744c3b0d7d 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -2770,6 +2770,7 @@ real_act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) NMConnection * connection; NMSettingConnection * s_connection; const char * setting_name; + NMSettingWireless * s_wireless; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); @@ -2787,33 +2788,31 @@ real_act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) s_connection = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); g_assert (s_connection); + s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + g_assert (s_wireless); + /* If we need secrets, get them */ setting_name = nm_connection_need_secrets (connection, NULL); if (setting_name) { - NMActStageReturn auth_ret; - nm_info ("Activation (%s/wireless): access point '%s' has security," " but secrets are required.", iface, s_connection->id); - auth_ret = handle_auth_or_fail (self, req, FALSE); - if (auth_ret == NM_ACT_STAGE_RETURN_FAILURE) { + ret = handle_auth_or_fail (self, req, FALSE); + if (ret == NM_ACT_STAGE_RETURN_FAILURE) *reason = NM_DEVICE_STATE_REASON_NO_SECRETS; - goto out; - } - } else { - NMSettingWireless *s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, - NM_TYPE_SETTING_WIRELESS); + goto out; + } - if (s_wireless->security) { - nm_info ("Activation (%s/wireless): connection '%s' has security" - ", and secrets exist. No new secrets needed.", - iface, s_connection->id); - } else { - nm_info ("Activation (%s/wireless): connection '%s' requires no " - "security. No secrets needed.", - iface, s_connection->id); - } + /* have secrets, or no secrets required */ + if (s_wireless->security) { + nm_info ("Activation (%s/wireless): connection '%s' has security" + ", and secrets exist. No new secrets needed.", + iface, s_connection->id); + } else { + nm_info ("Activation (%s/wireless): connection '%s' requires no " + "security. No secrets needed.", + iface, s_connection->id); } config = build_supplicant_config (self, connection, ap); @@ -3417,7 +3416,8 @@ nm_device_wifi_set_enabled (NMDeviceWifi *self, gboolean enabled) return; if (enabled) { - g_warn_if_fail (state == NM_DEVICE_STATE_UNAVAILABLE); + if (state != NM_DEVICE_STATE_UNAVAILABLE); + nm_warning ("not in expected unavailable state!"); if (!nm_device_hw_bring_up (NM_DEVICE (self), TRUE)) { /* The device sucks, or HAL was lying to us about the killswitch state */ diff --git a/src/nm-device.c b/src/nm-device.c index ea0910c539..a97986cd08 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -649,7 +649,7 @@ nm_device_handle_autoip4_event (NMDevice *self, /* Ignore if the connection isn't an AutoIP connection */ s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); - if (!s_ip4 || !s_ip4->method || strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_AUTOIP)) + if (!s_ip4 || !s_ip4->method || strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) return; iface = nm_device_get_iface (self); @@ -828,7 +828,7 @@ real_act_stage3_ip_config_start (NMDevice *self, NMDeviceStateReason *reason) NM_TYPE_SETTING_IP4_CONFIG); /* If we did not receive IP4 configuration information, default to DHCP */ - if (!s_ip4 || !strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_DHCP)) { + if (!s_ip4 || !strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); gboolean success; @@ -850,7 +850,7 @@ real_act_stage3_ip_config_start (NMDevice *self, NMDeviceStateReason *reason) *reason = NM_DEVICE_STATE_REASON_DHCP_START_FAILED; ret = NM_ACT_STAGE_RETURN_FAILURE; } - } else if (s_ip4 && !strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_AUTOIP)) { + } else if (s_ip4 && !strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { GError *error = NULL; /* Start avahi-autoipd */ @@ -1026,7 +1026,7 @@ real_act_stage4_get_ip4_config (NMDevice *self, g_assert (s_ip4); g_assert (s_ip4->method); - if (!strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_AUTOIP)) { + if (!strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { *config = aipd_get_ip4_config (self, reason); } else if (!strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { *config = nm_ip4_config_new (); diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 40acfc364a..0bf780b894 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -58,7 +58,7 @@ typedef struct { gchar *hostname; gchar *nis_domain; GArray *nis_servers; - GSList *static_routes; + GSList *routes; } NMIP4ConfigPrivate; @@ -70,7 +70,7 @@ enum { PROP_DOMAINS, PROP_NIS_DOMAIN, PROP_NIS_SERVERS, - PROP_STATIC_ROUTES, + PROP_ROUTES, LAST_PROP }; @@ -133,13 +133,13 @@ NMIP4Config *nm_ip4_config_copy (NMIP4Config *src_config) for (i = 0; i < len; i++) nm_ip4_config_add_nis_server (dst_config, nm_ip4_config_get_nis_server (src_config, i)); - for (iter = src_priv->static_routes; iter; iter = g_slist_next (iter)) { - NMSettingIP4Address *src_addr = (NMSettingIP4Address *) iter->data; - NMSettingIP4Address *dst_addr; + for (iter = src_priv->routes; iter; iter = g_slist_next (iter)) { + NMSettingIP4Route *src_route = (NMSettingIP4Route *) iter->data; + NMSettingIP4Route *dst_route; - dst_addr = g_malloc0 (sizeof (NMSettingIP4Address)); - memcpy (dst_addr, src_addr, sizeof (NMSettingIP4Address)); - nm_ip4_config_take_static_route (dst_config, dst_addr); + dst_route = g_malloc0 (sizeof (NMSettingIP4Route)); + memcpy (dst_route, src_route, sizeof (NMSettingIP4Route)); + nm_ip4_config_take_route (dst_config, dst_route); } return dst_config; @@ -310,38 +310,38 @@ const char *nm_ip4_config_get_nis_domain (NMIP4Config *config) } void -nm_ip4_config_take_static_route (NMIP4Config *config, - NMSettingIP4Address *address) +nm_ip4_config_take_route (NMIP4Config *config, + NMSettingIP4Route *route) { NMIP4ConfigPrivate *priv; g_return_if_fail (NM_IS_IP4_CONFIG (config)); - g_return_if_fail (address != NULL); + g_return_if_fail (route != NULL); priv = NM_IP4_CONFIG_GET_PRIVATE (config); - priv->static_routes = g_slist_append (priv->static_routes, address); + priv->routes = g_slist_append (priv->routes, route); } void -nm_ip4_config_add_static_route (NMIP4Config *config, - NMSettingIP4Address *address) +nm_ip4_config_add_route (NMIP4Config *config, + NMSettingIP4Route *route) { NMIP4ConfigPrivate *priv; - NMSettingIP4Address *copy; + NMSettingIP4Route *copy; g_return_if_fail (NM_IS_IP4_CONFIG (config)); - g_return_if_fail (address != NULL); + g_return_if_fail (route != NULL); priv = NM_IP4_CONFIG_GET_PRIVATE (config); - copy = g_malloc0 (sizeof (NMSettingIP4Address)); - memcpy (copy, address, sizeof (NMSettingIP4Address)); - priv->static_routes = g_slist_append (priv->static_routes, copy); + copy = g_malloc0 (sizeof (NMSettingIP4Route)); + memcpy (copy, route, sizeof (NMSettingIP4Route)); + priv->routes = g_slist_append (priv->routes, copy); } void -nm_ip4_config_replace_static_route (NMIP4Config *config, +nm_ip4_config_replace_route (NMIP4Config *config, guint i, - NMSettingIP4Address *new_address) + NMSettingIP4Route *new_route) { NMIP4ConfigPrivate *priv; GSList *old; @@ -349,28 +349,38 @@ nm_ip4_config_replace_static_route (NMIP4Config *config, g_return_if_fail (NM_IS_IP4_CONFIG (config)); priv = NM_IP4_CONFIG_GET_PRIVATE (config); - old = g_slist_nth (priv->static_routes, i); + old = g_slist_nth (priv->routes, i); g_return_if_fail (old != NULL); g_free (old->data); - old->data = new_address; + old->data = new_route; } -const NMSettingIP4Address * -nm_ip4_config_get_static_route (NMIP4Config *config, guint i) +const NMSettingIP4Route * +nm_ip4_config_get_route (NMIP4Config *config, guint i) { g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL); - return (const NMSettingIP4Address *) g_slist_nth_data (NM_IP4_CONFIG_GET_PRIVATE (config)->static_routes, i); + return (const NMSettingIP4Route *) g_slist_nth_data (NM_IP4_CONFIG_GET_PRIVATE (config)->routes, i); } -guint32 nm_ip4_config_get_num_static_routes (NMIP4Config *config) +guint32 nm_ip4_config_get_num_routes (NMIP4Config *config) { g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0); - return g_slist_length (NM_IP4_CONFIG_GET_PRIVATE (config)->static_routes); + return g_slist_length (NM_IP4_CONFIG_GET_PRIVATE (config)->routes); } +void nm_ip4_config_reset_routes (NMIP4Config *config) +{ + NMIP4ConfigPrivate *priv; + + g_return_if_fail (NM_IS_IP4_CONFIG (config)); + + priv = NM_IP4_CONFIG_GET_PRIVATE (config); + g_slist_foreach (priv->routes, (GFunc) g_free, NULL); + priv->routes = NULL; +} void nm_ip4_config_add_domain (NMIP4Config *config, const char *domain) { @@ -572,7 +582,7 @@ finalize (GObject *object) g_ptr_array_free (priv->domains, TRUE); g_ptr_array_free (priv->searches, TRUE); g_array_free (priv->nis_servers, TRUE); - nm_utils_slist_free (priv->static_routes, g_free); + nm_utils_slist_free (priv->routes, g_free); } static void @@ -629,8 +639,8 @@ get_property (GObject *object, guint prop_id, case PROP_NIS_SERVERS: g_value_set_boxed (value, priv->nis_servers); break; - case PROP_STATIC_ROUTES: - ip4_addresses_to_gvalue (priv->static_routes, value); + case PROP_ROUTES: + ip4_addresses_to_gvalue (priv->routes, value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -694,10 +704,10 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) G_PARAM_READABLE)); g_object_class_install_property - (object_class, PROP_STATIC_ROUTES, - g_param_spec_boxed (NM_IP4_CONFIG_STATIC_ROUTES, - "Static routes", - "Static routes", + (object_class, PROP_ROUTES, + g_param_spec_boxed (NM_IP4_CONFIG_ROUTES, + "Routes", + "Routes", DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, G_PARAM_READABLE)); diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index e071dd8e96..00f0f1620d 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -50,7 +50,7 @@ typedef struct { #define NM_IP4_CONFIG_DOMAINS "domains" #define NM_IP4_CONFIG_NIS_DOMAIN "nis-domain" #define NM_IP4_CONFIG_NIS_SERVERS "nis-servers" -#define NM_IP4_CONFIG_STATIC_ROUTES "static-routes" +#define NM_IP4_CONFIG_ROUTES "routes" GType nm_ip4_config_get_type (void); @@ -76,11 +76,12 @@ void nm_ip4_config_add_nis_server (NMIP4Config *config, guint32 nis_server); guint32 nm_ip4_config_get_nis_server (NMIP4Config *config, guint i); guint32 nm_ip4_config_get_num_nis_servers (NMIP4Config *config); -void nm_ip4_config_take_static_route (NMIP4Config *config, NMSettingIP4Address *address); -void nm_ip4_config_add_static_route (NMIP4Config *config, NMSettingIP4Address *address); -void nm_ip4_config_replace_static_route (NMIP4Config *config, guint32 i, NMSettingIP4Address *new_address); -const NMSettingIP4Address * nm_ip4_config_get_static_route (NMIP4Config *config, guint32 i); -guint32 nm_ip4_config_get_num_static_routes (NMIP4Config *config); +void nm_ip4_config_take_route (NMIP4Config *config, NMSettingIP4Route *route); +void nm_ip4_config_add_route (NMIP4Config *config, NMSettingIP4Route *route); +void nm_ip4_config_replace_route (NMIP4Config *config, guint32 i, NMSettingIP4Route *new_route); +const NMSettingIP4Route * nm_ip4_config_get_route (NMIP4Config *config, guint32 i); +guint32 nm_ip4_config_get_num_routes (NMIP4Config *config); +void nm_ip4_config_reset_routes (NMIP4Config *config); void nm_ip4_config_set_hostname (NMIP4Config *config, const char *hostname); const char * nm_ip4_config_get_hostname (NMIP4Config *config); diff --git a/src/nm-manager.c b/src/nm-manager.c index 5f51adbd8a..f804f3139f 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1405,49 +1405,54 @@ deferred_sync_devices (gpointer user_data) } NMManager * -nm_manager_new (void) +nm_manager_get (void) { - GObject *object; + static NMManager *singleton = NULL; NMManagerPrivate *priv; - object = g_object_new (NM_TYPE_MANAGER, NULL); - priv = NM_MANAGER_GET_PRIVATE (object); + if (singleton) + return g_object_ref (singleton); + + singleton = (NMManager *) g_object_new (NM_TYPE_MANAGER, NULL); + g_assert (singleton); + + priv = NM_MANAGER_GET_PRIVATE (singleton); dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (priv->dbus_mgr), NM_DBUS_PATH, - object); + G_OBJECT (singleton)); g_signal_connect (priv->dbus_mgr, "name-owner-changed", G_CALLBACK (nm_manager_name_owner_changed), - NM_MANAGER (object)); + singleton); - g_idle_add ((GSourceFunc) initial_get_connections, NM_MANAGER (object)); + g_idle_add ((GSourceFunc) initial_get_connections, singleton); priv->hal_mgr = nm_hal_manager_new (); - priv->sync_devices_id = g_idle_add (deferred_sync_devices, object); + priv->sync_devices_id = g_idle_add (deferred_sync_devices, singleton); g_signal_connect (priv->hal_mgr, "udi-added", G_CALLBACK (hal_manager_udi_added_cb), - NM_MANAGER (object)); + singleton); g_signal_connect (priv->hal_mgr, "udi-removed", G_CALLBACK (hal_manager_udi_removed_cb), - NM_MANAGER (object)); + singleton); g_signal_connect (priv->hal_mgr, "rfkill-changed", G_CALLBACK (hal_manager_rfkill_changed_cb), - NM_MANAGER (object)); + singleton); g_signal_connect (priv->hal_mgr, "hal-reappeared", G_CALLBACK (hal_manager_hal_reappeared_cb), - NM_MANAGER (object)); + singleton); - return NM_MANAGER (object); + return singleton; } static void diff --git a/src/nm-manager.h b/src/nm-manager.h index fb53bdd597..fd744325fc 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -52,7 +52,7 @@ typedef struct { GType nm_manager_get_type (void); -NMManager *nm_manager_new (void); +NMManager *nm_manager_get (void); /* Device handling */ diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index 7a9881235a..4209748d70 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -19,6 +19,7 @@ #endif #include <linux/if_ppp.h> +#include "NetworkManager.h" #include "nm-ppp-manager.h" #include "nm-setting-connection.h" #include "nm-setting-ppp.h" @@ -43,12 +44,15 @@ static gboolean impl_ppp_manager_set_ip4_config (NMPPPManager *manager, #include "nm-ppp-manager-glue.h" #define NM_PPPD_PLUGIN PLUGINDIR "/nm-pppd-plugin.so" -#define NM_PPP_WAIT_PPPD 10000 /* 10 seconds */ +#define NM_PPP_WAIT_PPPD 15000 /* 10 seconds */ #define PPP_MANAGER_SECRET_TRIES "ppp-manager-secret-tries" typedef struct { GPid pid; NMDBusManager *dbus_manager; + char *dbus_path; + + char *parent_iface; NMActRequest *act_req; DBusGMethodInvocation *pending_secrets_context; @@ -57,7 +61,7 @@ typedef struct { guint32 ppp_timeout_handler; /* Monitoring */ - char *iface; + char *ip_iface; int monitor_fd; guint monitor_id; } NMPPPManagerPrivate; @@ -76,6 +80,12 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; +enum { + PROP_0, + PROP_PARENT_IFACE, + LAST_PROP +}; + typedef enum { NM_PPP_MANAGER_ERROR_UNKOWN } NMPPPManagerError; @@ -104,9 +114,8 @@ constructor (GType type, GObject *object; NMPPPManagerPrivate *priv; DBusGConnection *connection; - DBusGProxy *proxy; - guint request_name_result; - GError *err = NULL; + static gboolean name_requested = FALSE; + static guint32 counter = 0; object = G_OBJECT_CLASS (nm_ppp_manager_parent_class)->constructor (type, n_construct_params, @@ -116,28 +125,48 @@ constructor (GType type, priv = NM_PPP_MANAGER_GET_PRIVATE (object); priv->dbus_manager = nm_dbus_manager_get (); + if (!priv->dbus_manager) { + g_object_unref (object); + return NULL; + } connection = nm_dbus_manager_get_connection (priv->dbus_manager); - proxy = dbus_g_proxy_new_for_name (connection, - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus"); + /* Only need to request bus name the first time */ + if (!name_requested) { + DBusGProxy *proxy; + gboolean success; + guint request_name_result; + GError *err = NULL; + + proxy = dbus_g_proxy_new_for_name (connection, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus"); + success = dbus_g_proxy_call (proxy, "RequestName", &err, + G_TYPE_STRING, NM_DBUS_SERVICE_PPP, + G_TYPE_UINT, 0, + G_TYPE_INVALID, + G_TYPE_UINT, &request_name_result, + G_TYPE_INVALID); + g_object_unref (proxy); + + if (!success) { + nm_warning ("Failed to acquire PPP manager service: %s", err->message); + g_object_unref (object); + return NULL; + } - if (dbus_g_proxy_call (proxy, "RequestName", &err, - G_TYPE_STRING, NM_DBUS_SERVICE_PPP, - G_TYPE_UINT, 0, - G_TYPE_INVALID, - G_TYPE_UINT, &request_name_result, - G_TYPE_INVALID)) - dbus_g_connection_register_g_object (connection, NM_DBUS_PATH_PPP, object); + name_requested = TRUE; + } - g_object_unref (proxy); + priv->dbus_path = g_strdup_printf (NM_DBUS_PATH "/PPP/%d", counter++); + dbus_g_connection_register_g_object (connection, priv->dbus_path, object); return object; } static void -finalize (GObject *object) +dispose (GObject *object) { NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (object); @@ -146,21 +175,75 @@ finalize (GObject *object) g_object_unref (priv->act_req); g_object_unref (priv->dbus_manager); + G_OBJECT_CLASS (nm_ppp_manager_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (object); + + g_free (priv->ip_iface); + g_free (priv->parent_iface); + G_OBJECT_CLASS (nm_ppp_manager_parent_class)->finalize (object); } static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_PARENT_IFACE: + if (priv->parent_iface) + g_free (priv->parent_iface); + priv->parent_iface = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_PARENT_IFACE: + g_value_set_string (value, priv->parent_iface); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void nm_ppp_manager_class_init (NMPPPManagerClass *manager_class) { GObjectClass *object_class = G_OBJECT_CLASS (manager_class); g_type_class_add_private (manager_class, sizeof (NMPPPManagerPrivate)); - dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (manager_class), - &dbus_glib_nm_ppp_manager_object_info); - object_class->constructor = constructor; + object_class->dispose = dispose; object_class->finalize = finalize; + object_class->get_property = get_property; + object_class->set_property = set_property; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_PARENT_IFACE, + g_param_spec_string (NM_PPP_MANAGER_PARENT_IFACE, + "ParentIface", + "Parent interface", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); /* signals */ signals[STATE_CHANGED] = @@ -193,12 +276,19 @@ nm_ppp_manager_class_init (NMPPPManagerClass *manager_class) nm_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); + + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (manager_class), + &dbus_glib_nm_ppp_manager_object_info); } NMPPPManager * -nm_ppp_manager_new (void) +nm_ppp_manager_new (const char *iface) { - return (NMPPPManager *) g_object_new (NM_TYPE_PPP_MANAGER, NULL); + g_return_val_if_fail (iface != NULL, NULL); + + return (NMPPPManager *) g_object_new (NM_TYPE_PPP_MANAGER, + NM_PPP_MANAGER_PARENT_IFACE, iface, + NULL); } /*******************************************/ @@ -213,7 +303,7 @@ monitor_cb (gpointer user_data) memset (&req, 0, sizeof (req)); req.stats_ptr = (caddr_t) &req.stats; - strncpy (req.ifr__name, priv->iface, sizeof (req.ifr__name)); + strncpy (req.ifr__name, priv->ip_iface, sizeof (req.ifr__name)); if (!ioctl (priv->monitor_fd, SIOCGPPPSTATS, &req) < 0) nm_warning ("Could not read ppp stats: %s", strerror (errno)); else @@ -225,15 +315,14 @@ monitor_cb (gpointer user_data) } static void -monitor_stats (NMPPPManager *manager, const char *iface) +monitor_stats (NMPPPManager *manager) { NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); priv->monitor_fd = socket (AF_INET, SOCK_DGRAM, 0); - if (priv->monitor_fd > 0) { - priv->iface = g_strdup (iface); + if (priv->monitor_fd > 0) priv->monitor_id = g_timeout_add (5000, monitor_cb, manager); - } else + else nm_warning ("Could not open pppd monitor: %s", strerror (errno)); } @@ -257,12 +346,10 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); NMConnection *connection; NMSettingConnection *s_con; - NMSetting *setting; const char *setting_name; guint32 tries; - char *hint1 = NULL; - - remove_timeout_handler (manager); + GPtrArray *hints = NULL; + const char *hint1 = NULL, *hint2 = NULL; connection = nm_act_request_get_connection (priv->act_req); @@ -271,54 +358,73 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, g_assert (s_con->type); nm_connection_clear_secrets (connection); - setting_name = nm_connection_need_secrets (connection, NULL); - if (setting_name) { - setting = nm_connection_get_setting_by_name (connection, setting_name); - } else { - /* Always ask for secrets unless the connection's type setting doesn't - * even exist (which shouldn't happen). Empty username and password are - * valid, but we need to tell the pppd plugin that this is valid by - * sending back blank secrets. - */ + setting_name = nm_connection_need_secrets (connection, &hints); + if (!setting_name) { + NMSetting *setting; + setting = nm_connection_get_setting_by_name (connection, s_con->type); - if (!setting) { + if (setting) { + const char *username = NULL; + const char *password = NULL; + + /* FIXME: push this down to the settings and keep PPP manager generic */ + if (NM_IS_SETTING_PPPOE (setting)) { + username = NM_SETTING_PPPOE (setting)->username; + password = NM_SETTING_PPPOE (setting)->password; + } else if (NM_IS_SETTING_GSM (setting)) { + username = NM_SETTING_GSM (setting)->username; + password = NM_SETTING_GSM (setting)->password; + } else if (NM_IS_SETTING_CDMA (setting)) { + username = NM_SETTING_CDMA (setting)->username; + password = NM_SETTING_CDMA (setting)->password; + } + + /* If secrets are not required, send the existing username and password + * back to the PPP plugin immediately. + */ + priv->pending_secrets_context = context; + nm_ppp_manager_update_secrets (manager, + NULL, /* FIXME: pass device name */ + username ? username : "", + password ? password : "", + NULL); + } else { GError *err = NULL; g_set_error (&err, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR_UNKOWN, "Missing type-specific setting; no secrets could be found."); nm_warning ("%s", err->message); dbus_g_method_return_error (context, err); - return; } - setting_name = nm_setting_get_name (setting); + return; } - /* FIXME: figure out some way of pushing this down to the settings - * themselves and keeping the PPP Manager generic. - */ - if (NM_IS_SETTING_PPPOE (setting)) - hint1 = NM_SETTING_PPPOE_PASSWORD; - else if (NM_IS_SETTING_GSM (setting)) - hint1 = NM_SETTING_GSM_PASSWORD; - else if (NM_IS_SETTING_CDMA (setting)) - hint1 = NM_SETTING_CDMA_PASSWORD; + /* Extract hints */ + if (hints) { + if (hints->len > 0) + hint1 = g_ptr_array_index (hints, 0); + if (hints->len > 1) + hint2 = g_ptr_array_index (hints, 1); + } tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES)); nm_act_request_request_connection_secrets (priv->act_req, setting_name, - tries == 0 ? TRUE : FALSE, + tries ? TRUE : FALSE, SECRETS_CALLER_PPP, hint1, - NULL); + hint2); g_object_set_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES, GUINT_TO_POINTER (++tries)); priv->pending_secrets_context = context; + + if (hints) + g_ptr_array_free (hints, TRUE); } static gboolean impl_ppp_manager_set_state (NMPPPManager *manager, guint32 state, GError **err) { - remove_timeout_handler (manager); g_signal_emit (manager, signals[STATE_CHANGED], 0, state); return TRUE; @@ -329,10 +435,11 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager, GHashTable *config_hash, GError **err) { + NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); + NMConnection *connection; NMIP4Config *config; NMSettingIP4Address *addr; GValue *val; - const char *iface; int i; nm_info ("PPP manager(IP Config Get) reply received."); @@ -374,16 +481,21 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager, } val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_INTERFACE); - if (val) - iface = g_value_get_string (val); - else { + if (!val || !G_VALUE_HOLDS_STRING (val)) { nm_warning ("No interface"); goto out; } + priv->ip_iface = g_value_dup_string (val); - g_signal_emit (manager, signals[IP4_CONFIG], 0, iface, config); + /* Got successful IP4 config; obviously the secrets worked */ + connection = nm_act_request_get_connection (priv->act_req); + g_assert (connection); + g_object_set_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES, NULL); - monitor_stats (manager, iface); + /* Push the IP4 config up to the device */ + g_signal_emit (manager, signals[IP4_CONFIG], 0, priv->ip_iface, config); + + monitor_stats (manager); out: g_object_unref (config); @@ -582,11 +694,12 @@ pppd_timed_out (gpointer data) } static NMCmdLine * -create_pppd_cmd_line (NMSettingPPP *setting, - NMSettingPPPOE *pppoe, - const char *device, - GError **err) +create_pppd_cmd_line (NMPPPManager *self, + NMSettingPPP *setting, + NMSettingPPPOE *pppoe, + GError **err) { + NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self); const char *ppp_binary; NMCmdLine *cmd; @@ -610,7 +723,7 @@ create_pppd_cmd_line (NMSettingPPP *setting, nm_cmd_line_add_string (cmd, "plugin"); nm_cmd_line_add_string (cmd, "rp-pppoe.so"); - dev_str = g_strdup_printf ("nic-%s", device); + dev_str = g_strdup_printf ("nic-%s", priv->parent_iface); nm_cmd_line_add_string (cmd, dev_str); g_free (dev_str); @@ -622,7 +735,7 @@ create_pppd_cmd_line (NMSettingPPP *setting, nm_cmd_line_add_string (cmd, "user"); nm_cmd_line_add_string (cmd, pppoe->username); } else { - nm_cmd_line_add_string (cmd, device); + nm_cmd_line_add_string (cmd, priv->parent_iface); /* Don't send some random address as the local address */ nm_cmd_line_add_string (cmd, "noipdefault"); } @@ -680,6 +793,9 @@ create_pppd_cmd_line (NMSettingPPP *setting, nm_cmd_line_add_int (cmd, setting->lcp_echo_interval); } + nm_cmd_line_add_string (cmd, "ipparam"); + nm_cmd_line_add_string (cmd, priv->dbus_path); + nm_cmd_line_add_string (cmd, "plugin"); nm_cmd_line_add_string (cmd, NM_PPPD_PLUGIN); @@ -726,10 +842,7 @@ pppoe_fill_defaults (NMSettingPPP *setting) } gboolean -nm_ppp_manager_start (NMPPPManager *manager, - const char *device, - NMActRequest *req, - GError **err) +nm_ppp_manager_start (NMPPPManager *manager, NMActRequest *req, GError **err) { NMPPPManagerPrivate *priv; NMConnection *connection; @@ -739,7 +852,6 @@ nm_ppp_manager_start (NMPPPManager *manager, char *cmd_str; g_return_val_if_fail (NM_IS_PPP_MANAGER (manager), FALSE); - g_return_val_if_fail (device != NULL, FALSE); g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE); connection = nm_act_request_get_connection (req); @@ -750,7 +862,7 @@ nm_ppp_manager_start (NMPPPManager *manager, if (pppoe_setting) pppoe_fill_defaults (ppp_setting); - ppp_cmd = create_pppd_cmd_line (ppp_setting, pppoe_setting, device, err); + ppp_cmd = create_pppd_cmd_line (manager, ppp_setting, pppoe_setting, err); if (!ppp_cmd) return FALSE; @@ -820,10 +932,7 @@ nm_ppp_manager_update_secrets (NMPPPManager *manager, the plugin would need to link against libnm-util just to parse this. So instead, let's just send what it needs */ - /* FIXME: Do we have to strdup the values here? */ - dbus_g_method_return (priv->pending_secrets_context, - g_strdup (username), - g_strdup (password)); + dbus_g_method_return (priv->pending_secrets_context, username, password); } priv->pending_secrets_context = NULL; } @@ -863,8 +972,6 @@ nm_ppp_manager_stop (NMPPPManager *manager) priv->monitor_fd = 0; } - g_free (priv->iface); - if (priv->ppp_timeout_handler) { g_source_remove (priv->ppp_timeout_handler); priv->ppp_timeout_handler = 0; diff --git a/src/ppp-manager/nm-ppp-manager.h b/src/ppp-manager/nm-ppp-manager.h index ac6543d88c..4e0e576e40 100644 --- a/src/ppp-manager/nm-ppp-manager.h +++ b/src/ppp-manager/nm-ppp-manager.h @@ -19,6 +19,8 @@ #define NM_IS_PPP_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_PPP_MANAGER)) #define NM_PPP_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_PPP_MANAGER, NMPPPManagerClass)) +#define NM_PPP_MANAGER_PARENT_IFACE "parent-iface" + typedef struct { GObject parent; } NMPPPManager; @@ -34,12 +36,9 @@ typedef struct { GType nm_ppp_manager_get_type (void); -NMPPPManager *nm_ppp_manager_new (void); +NMPPPManager *nm_ppp_manager_new (const char *iface); -gboolean nm_ppp_manager_start (NMPPPManager *manager, - const char *device, - NMActRequest *req, - GError **err); +gboolean nm_ppp_manager_start (NMPPPManager *manager, NMActRequest *req, GError **err); void nm_ppp_manager_update_secrets (NMPPPManager *manager, const char *device, diff --git a/src/ppp-manager/nm-pppd-plugin.c b/src/ppp-manager/nm-pppd-plugin.c index 8b9878d9ab..1f0595f46a 100644 --- a/src/ppp-manager/nm-pppd-plugin.c +++ b/src/ppp-manager/nm-pppd-plugin.c @@ -91,9 +91,8 @@ nm_phasechange (void *data, int arg) if (ppp_status != NM_PPP_STATUS_UNKNOWN) { dbus_g_proxy_call_no_reply (proxy, "SetState", - G_TYPE_UINT, ppp_status, - G_TYPE_INVALID, - G_TYPE_INVALID); + G_TYPE_UINT, ppp_status, G_TYPE_INVALID, + G_TYPE_INVALID); } } @@ -133,16 +132,18 @@ value_destroy (gpointer data) static void nm_ip_up (void *data, int arg) { - ipcp_options opts = ipcp_gotoptions[ifunit]; - ipcp_options peer_opts = ipcp_hisoptions[ifunit]; + ipcp_options opts = ipcp_gotoptions[0]; + ipcp_options peer_opts = ipcp_hisoptions[0]; GHashTable *hash; GArray *array; GValue *val; + guint32 pppd_made_up_address = htonl (0x0a404040 + ifunit); g_return_if_fail (DBUS_IS_G_PROXY (proxy)); if (!opts.ouraddr) { - g_warning ("Didn't receive an internal IP from pppd"); + g_warning ("Didn't receive an internal IP from pppd!"); + nm_phasechange (NULL, PHASE_DEAD); return; } @@ -155,12 +156,20 @@ nm_ip_up (void *data, int arg) g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_ADDRESS, uint_to_gvalue (opts.ouraddr)); - if (opts.hisaddr) { + /* Prefer the peer options remote address first, _unless_ pppd made the + * address up, at which point prefer the local options remote address, + * and if that's not right, use the made-up address as a last resort. + */ + if (peer_opts.hisaddr && (peer_opts.hisaddr != pppd_made_up_address)) { g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_GATEWAY, - uint_to_gvalue (opts.hisaddr)); - } else if (peer_opts.hisaddr) { + uint_to_gvalue (peer_opts.hisaddr)); + } else if (opts.hisaddr) { g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_GATEWAY, - uint_to_gvalue (peer_opts.hisaddr)); + uint_to_gvalue (opts.hisaddr)); + } else if (peer_opts.hisaddr == pppd_made_up_address) { + /* As a last resort, use the made-up address */ + g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_GATEWAY, + uint_to_gvalue (peer_opts.hisaddr)); } g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_PREFIX, uint_to_gvalue (32)); @@ -289,10 +298,13 @@ plugin_init (void) return -1; } + /* NM passes in the object path of the corresponding PPPManager + * object as the 'ipparam' argument to pppd. + */ proxy = dbus_g_proxy_new_for_name (bus, - NM_DBUS_SERVICE_PPP, - NM_DBUS_PATH_PPP, - NM_DBUS_INTERFACE_PPP); + NM_DBUS_SERVICE_PPP, + ipparam, + NM_DBUS_INTERFACE_PPP); dbus_g_connection_unref (bus); diff --git a/src/ppp-manager/nm-pppd-plugin.h b/src/ppp-manager/nm-pppd-plugin.h index 9899641406..d4e7f2ce67 100644 --- a/src/ppp-manager/nm-pppd-plugin.h +++ b/src/ppp-manager/nm-pppd-plugin.h @@ -1,5 +1,4 @@ #define NM_DBUS_SERVICE_PPP "org.freedesktop.NetworkManager.PPP" -#define NM_DBUS_PATH_PPP "/org/freedesktop/NetworkManager/PPP" #define NM_DBUS_INTERFACE_PPP "org.freedesktop.NetworkManager.PPP" #define NM_PPP_IP4_CONFIG_INTERFACE "interface" diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 9bd11ea3d8..be32ead556 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -48,8 +48,6 @@ #include "nm-dbus-glib-types.h" #include "NetworkManagerUtils.h" -#define CONNECTION_GET_SECRETS_CALL_TAG "get-secrets-call" - #include "nm-vpn-connection-glue.h" G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, G_TYPE_OBJECT) @@ -58,6 +56,8 @@ typedef struct { gboolean disposed; NMConnection *connection; + DBusGProxyCall *secrets_call; + NMActRequest *act_request; NMDevice *parent_dev; char *ac_path; @@ -299,13 +299,15 @@ print_vpn_config (NMIP4Config *config, ip_address_to_string (nm_ip4_config_get_ptp_address (config))); nm_info ("Maximum Segment Size (MSS): %d", nm_ip4_config_get_mss (config)); - num = nm_ip4_config_get_num_static_routes (config); + num = nm_ip4_config_get_num_routes (config); for (i = 0; i < num; i++) { - addr = nm_ip4_config_get_static_route (config, i); - nm_info ("Static Route: %s/%d Gateway: %s", - ip_address_to_string (addr->address), - addr->prefix, - ip_address_to_string (addr->gateway)); + const NMSettingIP4Route *route; + + route = nm_ip4_config_get_route (config, i); + nm_info ("Static Route: %s/%d Next Hop: %s", + ip_address_to_string (route->address), + route->prefix, + ip_address_to_string (route->next_hop)); } num = nm_ip4_config_get_num_nameservers (config); @@ -322,57 +324,6 @@ print_vpn_config (NMIP4Config *config, } static void -merge_vpn_routes (NMVPNConnection *connection, NMIP4Config *config) -{ - NMSettingVPN *setting; - GSList *iter; - - setting = NM_SETTING_VPN (nm_connection_get_setting (NM_VPN_CONNECTION_GET_PRIVATE (connection)->connection, - NM_TYPE_SETTING_VPN)); - - /* FIXME: Shouldn't the routes from user (NMSettingVPN) be inserted in the beginning - instead of appending to the end? - */ - - for (iter = setting->routes; iter; iter = iter->next) { - struct in_addr tmp; - char *p, *route; - long int prefix = 32; - - route = g_strdup ((char *) iter->data); - p = strchr (route, '/'); - if (!p || !(*(p + 1))) { - nm_warning ("Ignoring invalid route '%s'", route); - goto next; - } - - errno = 0; - prefix = strtol (p + 1, NULL, 10); - if (errno || prefix <= 0 || prefix > 32) { - nm_warning ("Ignoring invalid route '%s'", route); - goto next; - } - - /* don't pass the prefix to inet_pton() */ - *p = '\0'; - if (inet_pton (AF_INET, route, &tmp) > 0) { - NMSettingIP4Address *addr; - - addr = g_new0 (NMSettingIP4Address, 1); - addr->address = tmp.s_addr; - addr->prefix = (guint32) prefix; - addr->gateway = 0; - - nm_ip4_config_take_static_route (config, addr); - } else - nm_warning ("Ignoring invalid route '%s'", route); - -next: - g_free (route); - } -} - -static void nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, GHashTable *config_hash, gpointer user_data) @@ -463,9 +414,9 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, GSList *routes; GSList *iter; - routes = nm_utils_ip4_addresses_from_gvalue (val); + routes = nm_utils_ip4_routes_from_gvalue (val); for (iter = routes; iter; iter = iter->next) - nm_ip4_config_take_static_route (config, (NMSettingIP4Address *) iter->data); + nm_ip4_config_take_route (config, (NMSettingIP4Route *) iter->data); g_slist_free (routes); } @@ -478,7 +429,6 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, /* Merge in user overrides from the NMConnection's IPv4 setting */ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (priv->connection, NM_TYPE_SETTING_IP4_CONFIG)); nm_utils_merge_ip4_config (config, s_ip4); - merge_vpn_routes (connection, config); if (nm_system_vpn_device_set_from_ip4_config (priv->parent_dev, priv->tundev, priv->ip4_config)) { nm_info ("VPN connection '%s' (IP Config Get) complete.", @@ -672,27 +622,21 @@ nm_vpn_connection_disconnect (NMVPNConnection *connection, /******************************************************************************/ static void -clear_need_auth (NMVPNConnection *vpn_connection) +cleanup_secrets_dbus_call (NMVPNConnection *self) { - NMVPNConnectionPrivate *priv; + NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); DBusGProxy *proxy; - DBusGProxyCall *call; - g_return_if_fail (vpn_connection != NULL); - - priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn_connection); - g_assert (priv->connection); + g_return_if_fail (priv->connection != NULL); + g_return_if_fail (NM_IS_CONNECTION (priv->connection)); proxy = g_object_get_data (G_OBJECT (priv->connection), NM_MANAGER_CONNECTION_SECRETS_PROXY_TAG); - if (!proxy || !DBUS_IS_G_PROXY (proxy)) - return; + g_assert (proxy); - call = g_object_get_data (G_OBJECT (vpn_connection), CONNECTION_GET_SECRETS_CALL_TAG); - if (!call) - return; - - dbus_g_proxy_cancel_call (proxy, call); - g_object_set_data (G_OBJECT (vpn_connection), CONNECTION_GET_SECRETS_CALL_TAG, NULL); + if (priv->secrets_call) { + dbus_g_proxy_cancel_call (proxy, priv->secrets_call); + priv->secrets_call = NULL; + } } typedef struct GetSecretsInfo { @@ -737,7 +681,7 @@ get_secrets_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) priv = NM_VPN_CONNECTION_GET_PRIVATE (info->vpn_connection); - g_object_set_data (G_OBJECT (info->vpn_connection), CONNECTION_GET_SECRETS_CALL_TAG, NULL); + priv->secrets_call = NULL; if (!dbus_g_proxy_end_call (proxy, call, &err, DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &settings, @@ -770,7 +714,6 @@ get_connection_secrets (NMVPNConnection *vpn_connection, NMVPNConnectionPrivate *priv; DBusGProxy *secrets_proxy; GetSecretsInfo *info = NULL; - DBusGProxyCall *call; GPtrArray *hints; g_return_val_if_fail (vpn_connection != NULL, FALSE); @@ -780,48 +723,39 @@ get_connection_secrets (NMVPNConnection *vpn_connection, priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn_connection); g_assert (priv->connection); - secrets_proxy = g_object_get_data (G_OBJECT (priv->connection), - NM_MANAGER_CONNECTION_SECRETS_PROXY_TAG); - g_return_val_if_fail (secrets_proxy && DBUS_IS_G_PROXY (secrets_proxy), FALSE); + secrets_proxy = g_object_get_data (G_OBJECT (priv->connection), NM_MANAGER_CONNECTION_SECRETS_PROXY_TAG); + g_assert (secrets_proxy); info = g_slice_new0 (GetSecretsInfo); g_return_val_if_fail (info != NULL, FALSE); info->setting_name = g_strdup (setting_name); - if (!info->setting_name) { - nm_warning ("Not enough memory to get secrets"); - goto error; - } - info->vpn_connection = g_object_ref (vpn_connection); /* Empty for now... */ hints = g_ptr_array_new (); /* use ..._with_timeout to give the user time to enter secrets */ - call = dbus_g_proxy_begin_call_with_timeout (secrets_proxy, "GetSecrets", - get_secrets_cb, - info, - free_get_secrets_info, - G_MAXINT32, - G_TYPE_STRING, setting_name, - DBUS_TYPE_G_ARRAY_OF_STRING, hints, - G_TYPE_BOOLEAN, request_new, - G_TYPE_INVALID); + priv->secrets_call = dbus_g_proxy_begin_call_with_timeout (secrets_proxy, "GetSecrets", + get_secrets_cb, + info, + free_get_secrets_info, + G_MAXINT32, + G_TYPE_STRING, setting_name, + DBUS_TYPE_G_ARRAY_OF_STRING, hints, + G_TYPE_BOOLEAN, request_new, + G_TYPE_INVALID); g_ptr_array_free (hints, TRUE); - if (!call) { + if (!priv->secrets_call) { nm_warning ("Could not call GetSecrets"); goto error; } - - g_object_set_data (G_OBJECT (vpn_connection), - CONNECTION_GET_SECRETS_CALL_TAG, - call); return TRUE; error: if (info) free_get_secrets_info (info); + cleanup_secrets_dbus_call (vpn_connection); return FALSE; } @@ -833,9 +767,7 @@ connection_need_secrets_cb (DBusGProxy *proxy, { NMVPNConnection *vpn_connection = NM_VPN_CONNECTION (user_data); - g_object_set_data (G_OBJECT (vpn_connection), - CONNECTION_GET_SECRETS_CALL_TAG, - NULL); + cleanup_secrets_dbus_call (vpn_connection); if (error) { g_warning ("%s.%d: NeedSecrets failed: %s %s", @@ -876,7 +808,7 @@ connection_vpn_state_changed (NMVPNConnection *connection, { NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); - clear_need_auth (connection); + cleanup_secrets_dbus_call (connection); switch (state) { case NM_VPN_CONNECTION_STATE_NEED_AUTH: @@ -962,6 +894,8 @@ dispose (GObject *object) } priv->disposed = TRUE; + cleanup_secrets_dbus_call (NM_VPN_CONNECTION (object)); + if (priv->parent_dev) { if (priv->device_monitor) g_signal_handler_disconnect (priv->parent_dev, priv->device_monitor); |