1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /* NetworkManager -- Network link manager
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Copyright (C) 2004 - 2013 Red Hat, Inc.
19 * Copyright (C) 2007 - 2008 Novell, Inc.
20 */
21
22 #include <config.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <errno.h>
26 #include <netdb.h>
27
28 #include <gio/gio.h>
29
30 #include "nm-policy.h"
31 #include "NetworkManagerUtils.h"
32 #include "nm-wifi-ap.h"
33 #include "nm-activation-request.h"
34 #include "nm-logging.h"
35 #include "nm-device.h"
36 #include "nm-dbus-manager.h"
37 #include "nm-setting-ip4-config.h"
38 #include "nm-setting-connection.h"
39 #include "nm-platform.h"
40 #include "nm-dns-manager.h"
41 #include "nm-vpn-manager.h"
42 #include "nm-manager-auth.h"
43 #include "nm-firewall-manager.h"
44 #include "nm-dispatcher.h"
45 #include "nm-utils.h"
46 #include "nm-glib-compat.h"
47
48 typedef struct {
49 NMManager *manager;
50 guint update_state_id;
51 GSList *pending_activation_checks;
52 GSList *manager_ids;
53 GSList *settings_ids;
54 GSList *dev_ids;
55
56 GSList *pending_secondaries;
57
58 NMFirewallManager *fw_manager;
59 gulong fw_started_id;
60
61 NMSettings *settings;
62
63 NMDevice *default_device4, *activating_device4;
64 NMDevice *default_device6, *activating_device6;
65
66 GResolver *resolver;
67 GInetAddress *lookup_addr;
68 GCancellable *lookup_cancellable;
69 NMDnsManager *dns_manager;
70 gulong config_changed_id;
71
72 gint reset_retries_id; /* idle handler for resetting the retries count */
73
74 char *orig_hostname; /* hostname at NM start time */
75 char *cur_hostname; /* hostname we want to assign */
76 gboolean hostname_changed; /* TRUE if NM ever set the hostname */
77 } NMPolicyPrivate;
78
79 #define NM_POLICY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_POLICY, NMPolicyPrivate))
80
81 G_DEFINE_TYPE (NMPolicy, nm_policy, G_TYPE_OBJECT)
82
83 enum {
84 PROP_0,
85
86 PROP_DEFAULT_IP4_DEVICE,
87 PROP_DEFAULT_IP6_DEVICE,
88 PROP_ACTIVATING_IP4_DEVICE,
89 PROP_ACTIVATING_IP6_DEVICE
90 };
91
92 #define RETRIES_TAG "autoconnect-retries"
93 #define RETRIES_DEFAULT 4
94 #define RESET_RETRIES_TIMESTAMP_TAG "reset-retries-timestamp-tag"
95 #define RESET_RETRIES_TIMER 300
96 #define FAILURE_REASON_TAG "failure-reason"
97
98 static void schedule_activate_all (NMPolicy *policy);
99
100
101 static NMDevice *
102 get_best_ip4_device (NMManager *manager, gboolean fully_activated)
103 {
104 GSList *devices, *iter;
105 NMDevice *best = NULL;
106 int best_prio = G_MAXINT;
107
108 g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
109
110 devices = nm_manager_get_devices (manager);
111 for (iter = devices; iter; iter = g_slist_next (iter)) {
112 NMDevice *dev = NM_DEVICE (iter->data);
113 NMDeviceType devtype = nm_device_get_device_type (dev);
114 NMDeviceState state = nm_device_get_state (dev);
115 NMActRequest *req;
116 NMConnection *connection;
117 NMIP4Config *ip4_config;
118 NMSettingIP4Config *s_ip4;
119 int prio;
120 const char *method = NULL;
121
122 if ( state <= NM_DEVICE_STATE_DISCONNECTED
123 || state >= NM_DEVICE_STATE_DEACTIVATING)
124 continue;
125
126 if (fully_activated && state < NM_DEVICE_STATE_SECONDARIES)
127 continue;
128
129 ip4_config = nm_device_get_ip4_config (dev);
130 if (ip4_config) {
131 /* Make sure the device has a gateway */
132 if (!nm_ip4_config_get_gateway (ip4_config) && (devtype != NM_DEVICE_TYPE_MODEM))
133 continue;
134
135 /* 'never-default' devices can't ever be the default */
136 if (nm_ip4_config_get_never_default (ip4_config))
137 continue;
138 } else if (fully_activated)
139 continue;
140
141 req = nm_device_get_act_request (dev);
142 g_assert (req);
143 connection = nm_act_request_get_connection (req);
144 g_assert (connection);
145
146 method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
147 /* If IPv4 is disabled or link-local-only, it can't be the default */
148 if ( !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)
149 || !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL))
150 continue;
151
152 /* 'never-default' devices can't ever be the default */
153 s_ip4 = nm_connection_get_setting_ip4_config (connection);
154 g_assert (s_ip4);
155 if (nm_setting_ip4_config_get_never_default (s_ip4))
156 continue;
157
158 prio = nm_device_get_priority (dev);
159 if (prio > 0 && prio < best_prio) {
160 best = dev;
161 best_prio = prio;
162 }
163 }
164
165 if (!best)
166 return NULL;
167
168 if (!fully_activated) {
169 NMDeviceState state = nm_device_get_state (best);
170
171 /* There's only a best activating device if the best device
172 * among all activating and already-activated devices is a
173 * still-activating one.
174 */
175 if (state >= NM_DEVICE_STATE_SECONDARIES)
176 return NULL;
177 }
178
179 return best;
180 }
181
182 static NMDevice *
183 get_best_ip6_device (NMManager *manager, gboolean fully_activated)
184 {
185 GSList *devices, *iter;
186 NMDevice *best = NULL;
187 int best_prio = G_MAXINT;
188
189 g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
190
191 devices = nm_manager_get_devices (manager);
192 for (iter = devices; iter; iter = g_slist_next (iter)) {
193 NMDevice *dev = NM_DEVICE (iter->data);
194 NMDeviceType devtype = nm_device_get_device_type (dev);
195 NMDeviceState state = nm_device_get_state (dev);
196 NMActRequest *req;
197 NMConnection *connection;
198 NMIP6Config *ip6_config;
199 NMSettingIP6Config *s_ip6;
200 int prio;
201 const char *method = NULL;
202
203 if ( state <= NM_DEVICE_STATE_DISCONNECTED
204 || state >= NM_DEVICE_STATE_DEACTIVATING)
205 continue;
206
207 if (fully_activated && state < NM_DEVICE_STATE_SECONDARIES)
208 continue;
209
210 ip6_config = nm_device_get_ip6_config (dev);
211 if (ip6_config) {
212 if (!nm_ip6_config_get_gateway (ip6_config) && (devtype != NM_DEVICE_TYPE_MODEM))
213 continue;
214
215 if (nm_ip6_config_get_never_default (ip6_config))
216 continue;
217 } else if (fully_activated)
218 continue;
219
220 req = nm_device_get_act_request (dev);
221 g_assert (req);
222 connection = nm_act_request_get_connection (req);
223 g_assert (connection);
224
225 method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
226 if ( !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)
227 || !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL))
228 continue;
229
230 s_ip6 = nm_connection_get_setting_ip6_config (connection);
231 g_assert (s_ip6);
232 if (nm_setting_ip6_config_get_never_default (s_ip6))
233 continue;
234
235 prio = nm_device_get_priority (dev);
236 if (prio > 0 && prio < best_prio) {
237 best = dev;
238 best_prio = prio;
239 }
240 }
241
242 if (!best)
243 return NULL;
244
245 if (!fully_activated) {
246 NMDeviceState state = nm_device_get_state (best);
247
248 /* There's only a best activating device if the best device
249 * among all activating and already-activated devices is an
250 * activating one.
251 */
252 if (state >= NM_DEVICE_STATE_SECONDARIES)
253 return NULL;
254 }
255
256 return best;
257 }
258
259 #define FALLBACK_HOSTNAME4 "localhost.localdomain"
260
261 static gboolean
262 set_system_hostname (const char *new_hostname, const char *msg)
263 {
264 char old_hostname[HOST_NAME_MAX + 1];
265 const char *name;
266 int ret;
267
268 if (new_hostname)
269 g_warn_if_fail (strlen (new_hostname));
270
271 old_hostname[HOST_NAME_MAX] = '\0';
272 errno = 0;
273 ret = gethostname (old_hostname, HOST_NAME_MAX);
274 if (ret != 0) {
275 nm_log_warn (LOGD_DNS, "couldn't get the system hostname: (%d) %s",
276 errno, strerror (errno));
277 } else {
278 /* Don't set the hostname if it isn't actually changing */
279 if ( (new_hostname && !strcmp (old_hostname, new_hostname))
280 || (!new_hostname && !strcmp (old_hostname, FALLBACK_HOSTNAME4)))
281 return FALSE;
282 }
283
284 name = (new_hostname && strlen (new_hostname)) ? new_hostname : FALLBACK_HOSTNAME4;
285
286 nm_log_info (LOGD_DNS, "Setting system hostname to '%s' (%s)", name, msg);
287 ret = sethostname (name, strlen (name));
288 if (ret != 0) {
289 nm_log_warn (LOGD_DNS, "couldn't set the system hostname to '%s': (%d) %s",
290 name, errno, strerror (errno));
291 }
292
293 return (ret == 0);
294 }
295
296 static void
297 _set_hostname (NMPolicy *policy,
298 const char *new_hostname,
299 const char *msg)
300 {
301 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
302
303 /* The incoming hostname *can* be NULL, which will get translated to
304 * 'localhost.localdomain' or such in the hostname policy code, but we
305 * keep cur_hostname = NULL in the case because we need to know that
306 * there was no valid hostname to start with.
307 */
308
309 /* Clear lookup adresses if we have a hostname, so that we don't
310 * restart the reverse lookup thread later.
311 */
312 if (new_hostname)
313 g_clear_object (&priv->lookup_addr);
314
315 /* Don't change the hostname or update DNS this is the first time we're
316 * trying to change the hostname, and it's not actually changing.
317 */
318 if ( priv->orig_hostname
319 && (priv->hostname_changed == FALSE)
320 && g_strcmp0 (priv->orig_hostname, new_hostname) == 0)
321 return;
322
323 /* Don't change the hostname or update DNS if the hostname isn't actually
324 * going to change.
325 */
326 if (g_strcmp0 (priv->cur_hostname, new_hostname) == 0)
327 return;
328
329 g_free (priv->cur_hostname);
330 priv->cur_hostname = g_strdup (new_hostname);
331 priv->hostname_changed = TRUE;
332
333 nm_dns_manager_set_hostname (priv->dns_manager, priv->cur_hostname);
334
335 if (set_system_hostname (priv->cur_hostname, msg))
336 nm_dispatcher_call (DISPATCHER_ACTION_HOSTNAME, NULL, NULL, NULL, NULL);
337 }
338
339 static void
340 lookup_callback (GObject *source,
341 GAsyncResult *result,
342 gpointer user_data)
343 {
344 NMPolicy *policy = (NMPolicy *) user_data;
345 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
346 const char *hostname;
347 GError *error = NULL;
348
349 hostname = g_resolver_lookup_by_address_finish (G_RESOLVER (source), result, &error);
350 if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
351 /* Don't touch policy; it may have been freed already */
352 g_error_free (error);
353 return;
354 }
355
356 if (hostname)
357 _set_hostname (policy, hostname, "from address lookup");
358 else {
359 _set_hostname (policy, NULL, error->message);
360 g_error_free (error);
361 }
362
363 g_clear_object (&priv->lookup_cancellable);
364 }
365
366 static void
367 update_system_hostname (NMPolicy *policy, NMDevice *best4, NMDevice *best6)
368 {
369 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
370 char *configured_hostname = NULL;
371 const char *dhcp_hostname, *p;
372
373 g_return_if_fail (policy != NULL);
374
375 if (priv->lookup_cancellable) {
376 g_cancellable_cancel (priv->lookup_cancellable);
377 g_clear_object (&priv->lookup_cancellable);
378 }
379
380 /* Hostname precedence order:
381 *
382 * 1) a configured hostname (from settings)
383 * 2) automatic hostname from the default device's config (DHCP, VPN, etc)
384 * 3) the original hostname when NM started
385 * 4) reverse-DNS of the best device's IPv4 address
386 *
387 */
388
389 /* Try a persistent hostname first */
390 g_object_get (G_OBJECT (priv->manager), NM_MANAGER_HOSTNAME, &configured_hostname, NULL);
391 if (configured_hostname) {
392 _set_hostname (policy, configured_hostname, "from system configuration");
393 g_free (configured_hostname);
394 return;
395 }
396
397 /* Try automatically determined hostname from the best device's IP config */
398 if (!best4)
399 best4 = get_best_ip4_device (priv->manager, TRUE);
400 if (!best6)
401 best6 = get_best_ip6_device (priv->manager, TRUE);
402
403 if (!best4 && !best6) {
404 /* No best device; fall back to original hostname or if there wasn't
405 * one, 'localhost.localdomain'
406 */
407 _set_hostname (policy, priv->orig_hostname, "no default device");
408 return;
409 }
410
411 if (best4) {
412 NMDHCP4Config *dhcp4_config;
413
414 /* Grab a hostname out of the device's DHCP4 config */
415 dhcp4_config = nm_device_get_dhcp4_config (best4);
416 if (dhcp4_config) {
417 p = dhcp_hostname = nm_dhcp4_config_get_option (dhcp4_config, "host_name");
418 if (dhcp_hostname && strlen (dhcp_hostname)) {
419 /* Sanity check; strip leading spaces */
420 while (*p) {
421 if (!g_ascii_isspace (*p++)) {
422 _set_hostname (policy, p-1, "from DHCPv4");
423 return;
424 }
425 }
426 nm_log_warn (LOGD_DNS, "DHCPv4-provided hostname '%s' looks invalid; ignoring it",
427 dhcp_hostname);
428 }
429 }
430 } else if (best6) {
431 NMDHCP6Config *dhcp6_config;
432
433 /* Grab a hostname out of the device's DHCP6 config */
434 dhcp6_config = nm_device_get_dhcp6_config (best6);
435 if (dhcp6_config) {
436 p = dhcp_hostname = nm_dhcp6_config_get_option (dhcp6_config, "host_name");
437 if (dhcp_hostname && strlen (dhcp_hostname)) {
438 /* Sanity check; strip leading spaces */
439 while (*p) {
440 if (!g_ascii_isspace (*p++)) {
441 _set_hostname (policy, p-1, "from DHCPv6");
442 return;
443 }
444 }
445 nm_log_warn (LOGD_DNS, "DHCPv6-provided hostname '%s' looks invalid; ignoring it",
446 dhcp_hostname);
447 }
448 }
449 }
450
451 /* If no automatically-configured hostname, try using the hostname from
452 * when NM started up.
453 */
454 if (priv->orig_hostname) {
455 _set_hostname (policy, priv->orig_hostname, "from system startup");
456 return;
457 }
458
459 /* No configured hostname, no automatically determined hostname, and no
460 * bootup hostname. Start reverse DNS of the current IPv4 or IPv6 address.
461 */
462 if (best4) {
463 NMIP4Config *ip4_config;
464 const NMPlatformIP4Address *addr4;
465
466 ip4_config = nm_device_get_ip4_config (best4);
467 if ( !ip4_config
468 || (nm_ip4_config_get_num_nameservers (ip4_config) == 0)
469 || (nm_ip4_config_get_num_addresses (ip4_config) == 0)) {
470 /* No valid IP4 config (!!); fall back to localhost.localdomain */
471 _set_hostname (policy, NULL, "no IPv4 config");
472 return;
473 }
474
475 addr4 = nm_ip4_config_get_address (ip4_config, 0);
476 g_assert (addr4); /* checked for > 1 address above */
477
478 priv->lookup_addr = g_inet_address_new_from_bytes ((guint8 *) &addr4->address,
479 G_SOCKET_FAMILY_IPV4);
480 } else {
481 NMIP6Config *ip6_config;
482 const NMPlatformIP6Address *addr6;
483
484 ip6_config = nm_device_get_ip6_config (best6);
485 if ( !ip6_config
486 || (nm_ip6_config_get_num_nameservers (ip6_config) == 0)
487 || (nm_ip6_config_get_num_addresses (ip6_config) == 0)) {
488 /* No valid IP6 config (!!); fall back to localhost.localdomain */
489 _set_hostname (policy, NULL, "no IPv6 config");
490 return;
491 }
492
493 addr6 = nm_ip6_config_get_address (ip6_config, 0);
494 g_assert (addr6); /* checked for > 1 address above */
495
496 priv->lookup_addr = g_inet_address_new_from_bytes ((guint8 *) &addr6->address,
497 G_SOCKET_FAMILY_IPV6);
498 }
499
500 priv->lookup_cancellable = g_cancellable_new ();
501 g_resolver_lookup_by_address_async (priv->resolver,
502 priv->lookup_addr,
503 priv->lookup_cancellable,
504 lookup_callback, policy);
505 }
506
507 static void
508 update_default_ac (NMPolicy *policy,
509 NMActiveConnection *best,
510 void (*set_active_func)(NMActiveConnection*, gboolean))
511 {
512 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
513 const GSList *connections, *iter;
514
515 /* Clear the 'default[6]' flag on all active connections that aren't the new
516 * default active connection. We'll set the new default after; this ensures
517 * we don't ever have two marked 'default[6]' simultaneously.
518 */
519 connections = nm_manager_get_active_connections (priv->manager);
520 for (iter = connections; iter; iter = g_slist_next (iter)) {
521 if (NM_ACTIVE_CONNECTION (iter->data) != best)
522 set_active_func (NM_ACTIVE_CONNECTION (iter->data), FALSE);
523 }
524
525 /* Mark new default active connection */
526 if (best)
527 set_active_func (best, TRUE);
528 }
529
530 static NMIP4Config *
531 get_best_ip4_config (NMPolicy *policy,
532 gboolean ignore_never_default,
533 const char **out_ip_iface,
534 int *out_ip_ifindex,
535 NMActiveConnection **out_ac,
536 NMDevice **out_device,
537 NMVPNConnection **out_vpn)
538 {
539 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
540 const GSList *connections, *iter;
541 NMDevice *device;
542 NMActRequest *req = NULL;
543 NMIP4Config *ip4_config = NULL;
544
545 /* If a VPN connection is active, it is preferred */
546 connections = nm_manager_get_active_connections (priv->manager);
547 for (iter = connections; iter; iter = g_slist_next (iter)) {
548 NMActiveConnection *active = NM_ACTIVE_CONNECTION (iter->data);
549 NMVPNConnection *candidate;
550 NMIP4Config *vpn_ip4;
551 NMConnection *tmp;
552 NMSettingIP4Config *s_ip4;
553 NMVPNConnectionState vpn_state;
554
555 if (!NM_IS_VPN_CONNECTION (active))
556 continue;
557
558 candidate = NM_VPN_CONNECTION (active);
559
560 tmp = nm_active_connection_get_connection (active);
561 g_assert (tmp);
562
563 vpn_state = nm_vpn_connection_get_vpn_state (candidate);
564 if (vpn_state != NM_VPN_CONNECTION_STATE_ACTIVATED)
565 continue;
566
567 vpn_ip4 = nm_vpn_connection_get_ip4_config (candidate);
568 if (!vpn_ip4)
569 continue;
570
571 if (ignore_never_default == FALSE) {
572 /* Check for a VPN-provided config never-default */
573 if (nm_ip4_config_get_never_default (vpn_ip4))
574 continue;
575
576 /* Check the user's preference from the NMConnection */
577 s_ip4 = nm_connection_get_setting_ip4_config (tmp);
578 if (nm_setting_ip4_config_get_never_default (s_ip4))
579 continue;
580 }
581
582 ip4_config = vpn_ip4;
583 if (out_vpn)
584 *out_vpn = candidate;
585 if (out_ac)
586 *out_ac = active;
587 if (out_ip_iface)
588 *out_ip_iface = nm_vpn_connection_get_ip_iface (candidate);
589 if (out_ip_ifindex)
590 *out_ip_ifindex = nm_vpn_connection_get_ip_ifindex (candidate);
591 break;
592 }
593
594 /* If no VPN connections, we use the best device instead */
595 if (!ip4_config) {
596 device = get_best_ip4_device (priv->manager, TRUE);
597 if (device) {
598 ip4_config = nm_device_get_ip4_config (device);
599 g_assert (ip4_config);
600 req = nm_device_get_act_request (device);
601 g_assert (req);
602
603 if (out_device)
604 *out_device = device;
605 if (out_ac)
606 *out_ac = NM_ACTIVE_CONNECTION (req);
607 if (out_ip_iface)
608 *out_ip_iface = nm_device_get_ip_iface (device);
609 if (out_ip_ifindex)
610 *out_ip_ifindex = nm_device_get_ip_ifindex (device);
611 }
612 }
613
614 return ip4_config;
615 }
616
617 static void
618 update_ip4_dns (NMPolicy *policy, NMDnsManager *dns_mgr)
619 {
620 NMIP4Config *ip4_config;
621 const char *ip_iface = NULL;
622 NMVPNConnection *vpn = NULL;
623 NMDnsIPConfigType dns_type = NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE;
624
625 ip4_config = get_best_ip4_config (policy, TRUE, &ip_iface, NULL, NULL, NULL, &vpn);
626 if (ip4_config) {
627 if (vpn)
628 dns_type = NM_DNS_IP_CONFIG_TYPE_VPN;
629
630 /* Tell the DNS manager this config is preferred by re-adding it with
631 * a different IP config type.
632 */
633 nm_dns_manager_add_ip4_config (dns_mgr, ip_iface, ip4_config, dns_type);
634 }
635 }
636
637 static void
638 update_ip4_routing (NMPolicy *policy, gboolean force_update)
639 {
640 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
641 NMDevice *best = NULL, *default_device;
642 NMConnection *connection = NULL;
643 NMVPNConnection *vpn = NULL;
644 NMActiveConnection *best_ac = NULL;
645 NMIP4Config *ip4_config = NULL;
646 const char *ip_iface = NULL;
647 int ip_ifindex = -1;
648 guint32 gw_addr = 0;
649
650 /* Note that we might have an IPv4 VPN tunneled over an IPv6-only device,
651 * so we can get (vpn != NULL && best == NULL).
652 */
653 ip4_config = get_best_ip4_config (policy, FALSE, &ip_iface, &ip_ifindex, &best_ac, &best, &vpn);
654 if (!ip4_config) {
655 gboolean changed;
656
657 changed = (priv->default_device4 != NULL);
658 priv->default_device4 = NULL;
659 if (changed)
660 g_object_notify (G_OBJECT (policy), NM_POLICY_DEFAULT_IP4_DEVICE);
661
662 return;
663 }
664 g_assert ((best || vpn) && best_ac);
665
666 if (!force_update && best && (best == priv->default_device4))
667 return;
668
669 gw_addr = nm_ip4_config_get_gateway (ip4_config);
670
671 if (vpn) {
672 NMDevice *parent = nm_vpn_connection_get_parent_device (vpn);
673 int parent_ifindex = nm_device_get_ip_ifindex (parent);
674 NMIP4Config *parent_ip4 = nm_device_get_ip4_config (parent);
675 guint32 parent_mss = parent_ip4 ? nm_ip4_config_get_mss (parent_ip4) : 0;
676 in_addr_t int_gw = nm_vpn_connection_get_ip4_internal_gateway (vpn);
677 int mss = nm_ip4_config_get_mss (ip4_config);
678
679 if (!nm_platform_ip4_route_add (ip_ifindex, 0, 0, int_gw, 0, mss)) {
680 nm_platform_ip4_route_add (parent_ifindex, gw_addr, 32, 0, 0, parent_mss);
681 if (!nm_platform_ip4_route_add (ip_ifindex, 0, 0, int_gw, 0, mss)) {
682 nm_log_err (LOGD_IP4 | LOGD_VPN, "Failed to set default route.");
683 }
684 }
685
686 default_device = nm_vpn_connection_get_parent_device (vpn);
687 } else {
688 int mss = nm_ip4_config_get_mss (ip4_config);
689
690 if (!nm_platform_ip4_route_add (ip_ifindex, 0, 0, gw_addr, 0, mss)) {
691 nm_platform_ip4_route_add (ip_ifindex, gw_addr, 32, 0, 0, mss);
692 if (!nm_platform_ip4_route_add (ip_ifindex, 0, 0, gw_addr, 0, mss)) {
693 nm_log_err (LOGD_IP4, "Failed to set default route.");
694 }
695 }
696
697 default_device = best;
698 }
699
700 update_default_ac (policy, best_ac, nm_active_connection_set_default);
701
702 if (default_device == priv->default_device4)
703 return;
704
705 priv->default_device4 = default_device;
706 connection = nm_active_connection_get_connection (best_ac);
707 nm_log_info (LOGD_CORE, "Policy set '%s' (%s) as default for IPv4 routing and DNS.",
708 nm_connection_get_id (connection), ip_iface);
709 g_object_notify (G_OBJECT (policy), NM_POLICY_DEFAULT_IP4_DEVICE);
710 }
711
712 static NMIP6Config *
713 get_best_ip6_config (NMPolicy *policy,
714 gboolean ignore_never_default,
715 const char **out_ip_iface,
716 int *out_ip_ifindex,
717 NMActiveConnection **out_ac,
718 NMDevice **out_device,
719 NMVPNConnection **out_vpn)
720 {
721 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
722 const GSList *connections, *iter;
723 NMDevice *device;
724 NMActRequest *req = NULL;
725 NMIP6Config *ip6_config = NULL;
726
727 /* If a VPN connection is active, it is preferred */
728 connections = nm_manager_get_active_connections (priv->manager);
729 for (iter = connections; iter; iter = g_slist_next (iter)) {
730 NMActiveConnection *active = NM_ACTIVE_CONNECTION (iter->data);
731 NMVPNConnection *candidate;
732 NMIP6Config *vpn_ip6;
733 NMConnection *tmp;
734 NMSettingIP6Config *s_ip6;
735 NMVPNConnectionState vpn_state;
736
737 if (!NM_IS_VPN_CONNECTION (active))
738 continue;
739
740 candidate = NM_VPN_CONNECTION (active);
741
742 tmp = nm_active_connection_get_connection (active);
743 g_assert (tmp);
744
745 vpn_state = nm_vpn_connection_get_vpn_state (candidate);
746 if (vpn_state != NM_VPN_CONNECTION_STATE_ACTIVATED)
747 continue;
748
749 vpn_ip6 = nm_vpn_connection_get_ip6_config (candidate);
750 if (!vpn_ip6)
751 continue;
752
753 if (ignore_never_default == FALSE) {
754 /* Check for a VPN-provided config never-default */
755 if (nm_ip6_config_get_never_default (vpn_ip6))
756 continue;
757
758 /* Check the user's preference from the NMConnection */
759 s_ip6 = nm_connection_get_setting_ip6_config (tmp);
760 if (nm_setting_ip6_config_get_never_default (s_ip6))
761 continue;
762 }
763
764 ip6_config = vpn_ip6;
765 if (out_vpn)
766 *out_vpn = candidate;
767 if (out_ac)
768 *out_ac = NM_ACTIVE_CONNECTION (candidate);
769 if (out_ip_iface)
770 *out_ip_iface = nm_vpn_connection_get_ip_iface (candidate);
771 if (out_ip_ifindex)
772 *out_ip_ifindex = nm_vpn_connection_get_ip_ifindex (candidate);
773 break;
774 }
775
776 /* If no VPN connections, we use the best device instead */
777 if (!ip6_config) {
778 device = get_best_ip6_device (priv->manager, TRUE);
779 if (device) {
780 req = nm_device_get_act_request (device);
781 g_assert (req);
782 ip6_config = nm_device_get_ip6_config (device);
783 g_assert (ip6_config);
784
785 if (out_device)
786 *out_device = device;
787 if (out_ac)
788 *out_ac = NM_ACTIVE_CONNECTION (req);
789 if (out_ip_iface)
790 *out_ip_iface = nm_device_get_ip_iface (device);
791 if (out_ip_ifindex)
792 *out_ip_ifindex = nm_device_get_ip_ifindex (device);
793 }
794 }
795
796 return ip6_config;
797 }
798
799 static void
800 update_ip6_dns (NMPolicy *policy, NMDnsManager *dns_mgr)
801 {
802 NMIP6Config *ip6_config;
803 const char *ip_iface = NULL;
804 NMVPNConnection *vpn = NULL;
805 NMDnsIPConfigType dns_type = NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE;
806
807 ip6_config = get_best_ip6_config (policy, TRUE, &ip_iface, NULL, NULL, NULL, &vpn);
808 if (ip6_config) {
809 if (vpn)
810 dns_type = NM_DNS_IP_CONFIG_TYPE_VPN;
811
812 /* Tell the DNS manager this config is preferred by re-adding it with
813 * a different IP config type.
814 */
815 nm_dns_manager_add_ip6_config (dns_mgr, ip_iface, ip6_config, dns_type);
816 }
817 }
818
819 static void
820 update_ip6_routing (NMPolicy *policy, gboolean force_update)
821 {
822 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
823 NMDevice *best = NULL, *default_device6;
824 NMConnection *connection = NULL;
825 NMVPNConnection *vpn = NULL;
826 NMActiveConnection *best_ac = NULL;
827 NMIP6Config *ip6_config = NULL;
828 const char *ip_iface = NULL;
829 int ip_ifindex = -1;
830 const struct in6_addr *gw_addr;
831
832 /* Note that we might have an IPv6 VPN tunneled over an IPv4-only device,
833 * so we can get (vpn != NULL && best == NULL).
834 */
835 ip6_config = get_best_ip6_config (policy, FALSE, &ip_iface, &ip_ifindex, &best_ac, &best, &vpn);
(1) Event cond_false: |
Condition "!ip6_config", taking false branch |
836 if (!ip6_config) {
837 gboolean changed;
838
839 changed = (priv->default_device6 != NULL);
840 priv->default_device6 = NULL;
841 if (changed)
842 g_object_notify (G_OBJECT (policy), NM_POLICY_DEFAULT_IP6_DEVICE);
843
844 return;
(2) Event if_end: |
End of if statement |
845 }
(3) Event cond_false: |
Condition "best", taking false branch |
(4) Event cond_true: |
Condition "vpn", taking true branch |
(5) Event cond_true: |
Condition "best_ac", taking true branch |
(6) Event if_fallthrough: |
Falling through to end of if statement |
(7) Event if_end: |
End of if statement |
(8) Event cond_true: |
Condition "({...})", taking true branch |
(9) Event if_fallthrough: |
Falling through to end of if statement |
(10) Event if_end: |
End of if statement |
846 g_assert ((best || vpn) && best_ac);
847
(11) Event cond_true: |
Condition "!force_update", taking true branch |
(12) Event cond_false: |
Condition "best", taking false branch |
848 if (!force_update && best && (best == priv->default_device6))
(13) Event if_end: |
End of if statement |
849 return;
850
851 /* If no better gateway is found, use ::; not all configurations will
852 * have a gateway, especially WWAN/Point-to-Point connections.
853 */
854 gw_addr = nm_ip6_config_get_gateway (ip6_config);
(14) Event cond_true: |
Condition "!gw_addr", taking true branch |
855 if (!gw_addr)
856 gw_addr = &in6addr_any;
857
858 /* If we don't find a paired gateway, try the generic IPv6 gateway */
(15) Event cond_true: |
Condition "__a->__in6_u.__u6_addr32[0] == 0", taking true branch |
(16) Event cond_true: |
Condition "__a->__in6_u.__u6_addr32[1] == 0", taking true branch |
(17) Event cond_true: |
Condition "__a->__in6_u.__u6_addr32[2] == 0", taking true branch |
(18) Event cond_true: |
Condition "__a->__in6_u.__u6_addr32[3] == 0", taking true branch |
(19) Event cond_true: |
Condition "({...})", taking true branch |
(20) Event cond_true: |
Condition "nm_ip6_config_get_gateway(ip6_config)", taking true branch |
859 if ( IN6_IS_ADDR_UNSPECIFIED (gw_addr)
860 && nm_ip6_config_get_gateway (ip6_config))
861 gw_addr = nm_ip6_config_get_gateway (ip6_config);
862
(21) Event cond_true: |
Condition "vpn", taking true branch |
863 if (vpn) {
864 NMDevice *parent = nm_vpn_connection_get_parent_device (vpn);
865 int parent_ifindex = nm_device_get_ip_ifindex (parent);
866 NMIP6Config *parent_ip6 = nm_device_get_ip6_config (parent);
867 guint32 parent_mss = parent_ip6 ? nm_ip6_config_get_mss (parent_ip6) : 0;
868 struct in6_addr int_gw = *nm_vpn_connection_get_ip6_internal_gateway (vpn);
869 int mss = nm_ip6_config_get_mss (ip6_config);
870
(22) Event cond_true: |
Condition "!nm_platform_ip6_route_add(ip_ifindex, in6addr_any, 0, int_gw, 0, mss)", taking true branch |
(24) Event example_checked: |
Example1: "nm_platform_ip6_route_add(ip_ifindex, in6addr_any, 0, int_gw, 0, mss)" has its value checked in "nm_platform_ip6_route_add(ip_ifindex, in6addr_any, 0, int_gw, 0, mss)". |
Also see events: |
[check_return][example_checked][example_checked][example_checked][example_checked][unchecked_value] |
871 if (!nm_platform_ip6_route_add (ip_ifindex, in6addr_any, 0, int_gw, 0, mss)) {
(23) Event check_return: |
Calling function "nm_platform_ip6_route_add(int, struct in6_addr, int, struct in6_addr, int, int)" without checking return value (as is done elsewhere 13 out of 16 times). |
(29) Event unchecked_value: |
No check of the return value of "nm_platform_ip6_route_add(parent_ifindex, *gw_addr, 128, in6addr_any, 0, parent_mss)". |
Also see events: |
[example_checked][example_checked][example_checked][example_checked][example_checked] |
872 nm_platform_ip6_route_add (parent_ifindex, *gw_addr, 128, in6addr_any, 0, parent_mss);
(25) Event example_checked: |
Example2: "nm_platform_ip6_route_add(ip_ifindex, in6addr_any, 0, int_gw, 0, mss)" has its value checked in "nm_platform_ip6_route_add(ip_ifindex, in6addr_any, 0, int_gw, 0, mss)". |
Also see events: |
[check_return][example_checked][example_checked][example_checked][example_checked][unchecked_value] |
873 if (!nm_platform_ip6_route_add (ip_ifindex, in6addr_any, 0, int_gw, 0, mss)) {
874 nm_log_err (LOGD_IP6 | LOGD_VPN, "Failed to set default route.");
875 }
876 }
877
878 default_device6 = nm_vpn_connection_get_parent_device (vpn);
879 } else {
880 int mss = nm_ip6_config_get_mss (ip6_config);
881
(26) Event example_checked: |
Example3: "nm_platform_ip6_route_add(ip_ifindex, in6addr_any, 0, *gw_addr, 0, mss)" has its value checked in "nm_platform_ip6_route_add(ip_ifindex, in6addr_any, 0, *gw_addr, 0, mss)". |
Also see events: |
[check_return][example_checked][example_checked][example_checked][example_checked][unchecked_value] |
882 if (!nm_platform_ip6_route_add (ip_ifindex, in6addr_any, 0, *gw_addr, 0, mss)) {
883 nm_platform_ip6_route_add (ip_ifindex, *gw_addr, 128, in6addr_any, 0, mss);
(27) Event example_checked: |
Example4: "nm_platform_ip6_route_add(ip_ifindex, in6addr_any, 0, *gw_addr, 0, mss)" has its value checked in "nm_platform_ip6_route_add(ip_ifindex, in6addr_any, 0, *gw_addr, 0, mss)". |
Also see events: |
[check_return][example_checked][example_checked][example_checked][example_checked][unchecked_value] |
884 if (!nm_platform_ip6_route_add (ip_ifindex, in6addr_any, 0, *gw_addr, 0, mss)) {
885 nm_log_err (LOGD_IP6, "Failed to set default route.");
886 }
887 }
888
889 default_device6 = best;
890 }
891
892 update_default_ac (policy, best_ac, nm_active_connection_set_default6);
893
894 if (default_device6 == priv->default_device6)
895 return;
896
897 priv->default_device6 = default_device6;
898 connection = nm_active_connection_get_connection (best_ac);
899 nm_log_info (LOGD_CORE, "Policy set '%s' (%s) as default for IPv6 routing and DNS.",
900 nm_connection_get_id (connection), ip_iface);
901 g_object_notify (G_OBJECT (policy), NM_POLICY_DEFAULT_IP6_DEVICE);
902 }
903
904 static void
905 update_routing_and_dns (NMPolicy *policy, gboolean force_update)
906 {
907 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
908 NMDnsManager *mgr;
909
910 mgr = nm_dns_manager_get ();
911 nm_dns_manager_begin_updates (mgr, __func__);
912
913 update_ip4_dns (policy, mgr);
914 update_ip6_dns (policy, mgr);
915
916 update_ip4_routing (policy, force_update);
917 update_ip6_routing (policy, force_update);
918
919 /* Update the system hostname */
920 update_system_hostname (policy, priv->default_device4, priv->default_device6);
921
922 nm_dns_manager_end_updates (mgr, __func__);
923 g_object_unref (mgr);
924 }
925
926 static void
927 check_activating_devices (NMPolicy *policy)
928 {
929 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
930 GObject *object = G_OBJECT (policy);
931 NMDevice *best4, *best6 = NULL;
932
933 best4 = get_best_ip4_device (priv->manager, FALSE);
934 best6 = get_best_ip6_device (priv->manager, FALSE);
935
936 g_object_freeze_notify (object);
937
938 if (best4 != priv->activating_device4) {
939 priv->activating_device4 = best4;
940 g_object_notify (object, NM_POLICY_ACTIVATING_IP4_DEVICE);
941 }
942 if (best6 != priv->activating_device6) {
943 priv->activating_device6 = best6;
944 g_object_notify (object, NM_POLICY_ACTIVATING_IP6_DEVICE);
945 }
946
947 g_object_thaw_notify (object);
948 }
949
950 static void
951 set_connection_auto_retries (NMConnection *connection, guint retries)
952 {
953 /* add +1 so that the tag still exists if the # retries is 0 */
954 g_object_set_data (G_OBJECT (connection), RETRIES_TAG, GUINT_TO_POINTER (retries + 1));
955 }
956
957 static guint32
958 get_connection_auto_retries (NMConnection *connection)
959 {
960 /* subtract 1 to handle the +1 from set_connection_auto_retries() */
961 return GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), RETRIES_TAG)) - 1;
962 }
963
964 typedef struct {
965 NMPolicy *policy;
966 NMDevice *device;
967 guint id;
968 } ActivateData;
969
970 static void
971 activate_data_free (ActivateData *data)
972 {
973 nm_device_remove_pending_action (data->device, "autoactivate");
974
975 if (data->id)
976 g_source_remove (data->id);
977 g_object_unref (data->device);
978 memset (data, 0, sizeof (*data));
979 g_free (data);
980 }
981
982 static gboolean
983 auto_activate_device (gpointer user_data)
984 {
985 ActivateData *data = (ActivateData *) user_data;
986 NMPolicy *policy;
987 NMPolicyPrivate *priv;
988 NMConnection *best_connection;
989 char *specific_object = NULL;
990 GSList *connections, *iter;
991
992 g_assert (data);
993 policy = data->policy;
994 priv = NM_POLICY_GET_PRIVATE (policy);
995
996 data->id = 0;
997 priv->pending_activation_checks = g_slist_remove (priv->pending_activation_checks, data);
998
999 // FIXME: if a device is already activating (or activated) with a connection
1000 // but another connection now overrides the current one for that device,
1001 // deactivate the device and activate the new connection instead of just
1002 // bailing if the device is already active
1003 if (nm_device_get_act_request (data->device))
1004 goto out;
1005
1006 iter = connections = nm_settings_get_connections (priv->settings);
1007
1008 /* Remove connections that shouldn't be auto-activated */
1009 while (iter) {
1010 NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (iter->data);
1011 gboolean remove_it = FALSE;
1012 const char *permission;
1013
1014 /* Grab next item before we possibly delete the current item */
1015 iter = g_slist_next (iter);
1016
1017 /* Ignore connections that were tried too many times or are not visible
1018 * to any logged-in users. Also ignore shared wifi connections for
1019 * which no user has the shared wifi permission.
1020 */
1021 if ( get_connection_auto_retries (NM_CONNECTION (candidate)) == 0
1022 || nm_settings_connection_is_visible (candidate) == FALSE)
1023 remove_it = TRUE;
1024 else {
1025 permission = nm_utils_get_shared_wifi_permission (NM_CONNECTION (candidate));
1026 if (permission) {
1027 if (nm_settings_connection_check_permission (candidate, permission) == FALSE)
1028 remove_it = TRUE;
1029 }
1030 }
1031
1032 if (remove_it)
1033 connections = g_slist_remove (connections, candidate);
1034 }
1035
1036 best_connection = nm_device_get_best_auto_connection (data->device, connections, &specific_object);
1037 if (best_connection) {
1038 GError *error = NULL;
1039
1040 nm_log_info (LOGD_DEVICE, "Auto-activating connection '%s'.",
1041 nm_connection_get_id (best_connection));
1042 if (!nm_manager_activate_connection (priv->manager,
1043 best_connection,
1044 specific_object,
1045 nm_device_get_path (data->device),
1046 NULL,
1047 &error)) {
1048 nm_log_info (LOGD_DEVICE, "Connection '%s' auto-activation failed: (%d) %s",
1049 nm_connection_get_id (best_connection),
1050 error ? error->code : -1,
1051 error ? error->message : "(none)");
1052 g_error_free (error);
1053 }
1054 }
1055
1056 g_slist_free (connections);
1057
1058 out:
1059 activate_data_free (data);
1060 return FALSE;
1061 }
1062
1063 static ActivateData *
1064 activate_data_new (NMPolicy *policy, NMDevice *device, guint delay_seconds)
1065 {
1066 ActivateData *data;
1067
1068 data = g_malloc0 (sizeof (ActivateData));
1069 data->policy = policy;
1070 data->device = g_object_ref (device);
1071 if (delay_seconds > 0)
1072 data->id = g_timeout_add_seconds (delay_seconds, auto_activate_device, data);
1073 else
1074 data->id = g_idle_add (auto_activate_device, data);
1075
1076 nm_device_add_pending_action (device, "autoactivate");
1077
1078 return data;
1079 }
1080
1081 static ActivateData *
1082 find_pending_activation (GSList *list, NMDevice *device)
1083 {
1084 GSList *iter;
1085
1086 for (iter = list; iter; iter = g_slist_next (iter)) {
1087 if (((ActivateData *) iter->data)->device == device)
1088 return iter->data;
1089 }
1090 return NULL;
1091 }
1092
1093 /*****************************************************************************/
1094
1095 typedef struct {
1096 NMDevice *device;
1097 GSList *secondaries;
1098 } PendingSecondaryData;
1099
1100 static PendingSecondaryData *
1101 pending_secondary_data_new (NMDevice *device, GSList *secondaries)
1102 {
1103 PendingSecondaryData *data;
1104
1105 data = g_malloc0 (sizeof (PendingSecondaryData));
1106 data->device = g_object_ref (device);
1107 data->secondaries = secondaries;
1108 return data;
1109 }
1110
1111 static void
1112 pending_secondary_data_free (PendingSecondaryData *data)
1113 {
1114 g_object_unref (data->device);
1115 g_slist_free_full (data->secondaries, g_free);
1116 memset (data, 0, sizeof (*data));
1117 g_free (data);
1118 }
1119
1120 static void
1121 process_secondaries (NMPolicy *policy,
1122 NMActiveConnection *active,
1123 gboolean connected)
1124 {
1125 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1126 NMDevice *device = NULL;
1127 const char *ac_path;
1128 GSList *iter, *iter2;
1129
1130 nm_log_dbg (LOGD_DEVICE, "Secondary connection '%s' %s; active path '%s'",
1131 nm_active_connection_get_name (active),
1132 connected ? "SUCCEEDED" : "FAILED",
1133 nm_active_connection_get_path (active));
1134
1135 ac_path = nm_active_connection_get_path (active);
1136
1137 if (NM_IS_VPN_CONNECTION (active))
1138 device = nm_vpn_connection_get_parent_device (NM_VPN_CONNECTION (active));
1139
1140 for (iter = priv->pending_secondaries; iter; iter = g_slist_next (iter)) {
1141 PendingSecondaryData *secondary_data = (PendingSecondaryData *) iter->data;
1142 NMDevice *item_device = secondary_data->device;
1143
1144 if (!device || item_device == device) {
1145 for (iter2 = secondary_data->secondaries; iter2; iter2 = g_slist_next (iter2)) {
1146 char *list_ac_path = (char *) iter2->data;
1147
1148 if (g_strcmp0 (ac_path, list_ac_path) == 0) {
1149 if (connected) {
1150 /* Secondary connection activated */
1151 secondary_data->secondaries = g_slist_remove (secondary_data->secondaries, list_ac_path);
1152 g_free (list_ac_path);
1153 if (!secondary_data->secondaries) {
1154 /* None secondary UUID remained -> remove the secondary data item */
1155 priv->pending_secondaries = g_slist_remove (priv->pending_secondaries, secondary_data);
1156 pending_secondary_data_free (secondary_data);
1157 nm_device_state_changed (item_device, NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_REASON_NONE);
1158 return;
1159 }
1160 } else {
1161 /* Secondary connection failed -> do not watch other connections */
1162 priv->pending_secondaries = g_slist_remove (priv->pending_secondaries, secondary_data);
1163 pending_secondary_data_free (secondary_data);
1164 nm_device_state_changed (item_device, NM_DEVICE_STATE_FAILED,
1165 NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED);
1166 return;
1167 }
1168 }
1169 }
1170 return;
1171 }
1172 }
1173 }
1174
1175 static void
1176 global_state_changed (NMManager *manager, NMState state, gpointer user_data)
1177 {
1178 }
1179
1180 static void
1181 hostname_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data)
1182 {
1183 update_system_hostname ((NMPolicy *) user_data, NULL, NULL);
1184 }
1185
1186 static void
1187 reset_retries_all (NMSettings *settings, NMDevice *device)
1188 {
1189 GSList *connections, *iter;
1190 GError *error = NULL;
1191
1192 connections = nm_settings_get_connections (settings);
1193 for (iter = connections; iter; iter = g_slist_next (iter)) {
1194 if (!device || nm_device_check_connection_compatible (device, iter->data, &error))
1195 set_connection_auto_retries (NM_CONNECTION (iter->data), RETRIES_DEFAULT);
1196 g_clear_error (&error);
1197 }
1198 g_slist_free (connections);
1199 }
1200
1201 static void
1202 reset_retries_for_failed_secrets (NMSettings *settings)
1203 {
1204 GSList *connections, *iter;
1205
1206 connections = nm_settings_get_connections (settings);
1207 for (iter = connections; iter; iter = g_slist_next (iter)) {
1208 NMDeviceStateReason reason = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (iter->data), FAILURE_REASON_TAG));
1209
1210 if (reason == NM_DEVICE_STATE_REASON_NO_SECRETS) {
1211 set_connection_auto_retries (NM_CONNECTION (iter->data), RETRIES_DEFAULT);
1212 g_object_set_data (G_OBJECT (iter->data), FAILURE_REASON_TAG, GUINT_TO_POINTER (0));
1213 }
1214 }
1215 g_slist_free (connections);
1216 }
1217
1218 static void
1219 sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data)
1220 {
1221 NMPolicy *policy = user_data;
1222 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1223 gboolean sleeping = FALSE, enabled = FALSE;
1224
1225 g_object_get (G_OBJECT (manager), NM_MANAGER_SLEEPING, &sleeping, NULL);
1226 g_object_get (G_OBJECT (manager), NM_MANAGER_NETWORKING_ENABLED, &enabled, NULL);
1227
1228 /* Reset retries on all connections so they'll checked on wakeup */
1229 if (sleeping || !enabled)
1230 reset_retries_all (priv->settings, NULL);
1231 }
1232
1233 static void
1234 schedule_activate_check (NMPolicy *policy, NMDevice *device, guint delay_seconds)
1235 {
1236 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1237 ActivateData *data;
1238
1239 if (nm_manager_get_state (priv->manager) == NM_STATE_ASLEEP)
1240 return;
1241
1242 if (!nm_device_can_activate (device, NULL))
1243 return;
1244
1245 if (!nm_device_get_enabled (device))
1246 return;
1247
1248 if (!nm_device_autoconnect_allowed (device))
1249 return;
1250
1251 /* Schedule an auto-activation if there isn't one already for this device */
1252 if (find_pending_activation (priv->pending_activation_checks, device) == NULL) {
1253 data = activate_data_new (policy, device, delay_seconds);
1254 priv->pending_activation_checks = g_slist_append (priv->pending_activation_checks, data);
1255 }
1256 }
1257
1258 static gboolean
1259 reset_connections_retries (gpointer user_data)
1260 {
1261 NMPolicy *policy = (NMPolicy *) user_data;
1262 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1263 GSList *connections, *iter;
1264 time_t con_stamp, min_stamp, now;
1265 gboolean changed = FALSE;
1266
1267 priv->reset_retries_id = 0;
1268
1269 min_stamp = now = time (NULL);
1270 connections = nm_settings_get_connections (priv->settings);
1271 for (iter = connections; iter; iter = g_slist_next (iter)) {
1272 con_stamp = GPOINTER_TO_SIZE (g_object_get_data (G_OBJECT (iter->data), RESET_RETRIES_TIMESTAMP_TAG));
1273 if (con_stamp == 0)
1274 continue;
1275 if (con_stamp + RESET_RETRIES_TIMER <= now) {
1276 set_connection_auto_retries (NM_CONNECTION (iter->data), RETRIES_DEFAULT);
1277 g_object_set_data (G_OBJECT (iter->data), RESET_RETRIES_TIMESTAMP_TAG, GSIZE_TO_POINTER (0));
1278 changed = TRUE;
1279 continue;
1280 }
1281 if (con_stamp < min_stamp)
1282 min_stamp = con_stamp;
1283 }
1284 g_slist_free (connections);
1285
1286 /* Schedule the handler again if there are some stamps left */
1287 if (min_stamp != now)
1288 priv->reset_retries_id = g_timeout_add_seconds (RESET_RETRIES_TIMER - (now - min_stamp), reset_connections_retries, policy);
1289
1290 /* If anything changed, try to activate the newly re-enabled connections */
1291 if (changed)
1292 schedule_activate_all (policy);
1293
1294 return FALSE;
1295 }
1296
1297 static void schedule_activate_all (NMPolicy *policy);
1298
1299 static void
1300 activate_slave_connections (NMPolicy *policy, NMConnection *connection,
1301 NMDevice *device)
1302 {
1303 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1304 const char *master_device;
1305 GSList *connections, *iter;
1306
1307 master_device = nm_device_get_iface (device);
1308 g_assert (master_device);
1309
1310 connections = nm_settings_get_connections (priv->settings);
1311 for (iter = connections; iter; iter = g_slist_next (iter)) {
1312 NMConnection *slave;
1313 NMSettingConnection *s_slave_con;
1314
1315 slave = NM_CONNECTION (iter->data);
1316 g_assert (slave);
1317
1318 s_slave_con = nm_connection_get_setting_connection (slave);
1319 g_assert (s_slave_con);
1320
1321 if (!g_strcmp0 (nm_setting_connection_get_master (s_slave_con), master_device))
1322 set_connection_auto_retries (slave, RETRIES_DEFAULT);
1323 }
1324
1325 g_slist_free (connections);
1326
1327 schedule_activate_all (policy);
1328 }
1329
1330 static gboolean
1331 activate_secondary_connections (NMPolicy *policy,
1332 NMConnection *connection,
1333 NMDevice *device)
1334 {
1335 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1336 NMSettingConnection *s_con;
1337 NMSettingsConnection *settings_con;
1338 NMActiveConnection *ac;
1339 PendingSecondaryData *secondary_data;
1340 GSList *secondary_ac_list = NULL;
1341 GError *error = NULL;
1342 guint32 i;
1343 gboolean success = TRUE;
1344
1345 s_con = nm_connection_get_setting_connection (connection);
1346 g_assert (s_con);
1347
1348 for (i = 0; i < nm_setting_connection_get_num_secondaries (s_con); i++) {
1349 const char *sec_uuid = nm_setting_connection_get_secondary (s_con, i);
1350
1351 settings_con = nm_settings_get_connection_by_uuid (priv->settings, sec_uuid);
1352 if (settings_con) {
1353 NMActRequest *req = nm_device_get_act_request (device);
1354 g_assert (req);
1355
1356 nm_log_dbg (LOGD_DEVICE, "Activating secondary connection '%s (%s)' for base connection '%s (%s)'",
1357 nm_connection_get_id (NM_CONNECTION (settings_con)), sec_uuid,
1358 nm_connection_get_id (connection), nm_connection_get_uuid (connection));
1359 ac = nm_manager_activate_connection (priv->manager,
1360 NM_CONNECTION (settings_con),
1361 nm_active_connection_get_path (NM_ACTIVE_CONNECTION (req)),
1362 nm_device_get_path (device),
1363 nm_act_request_get_dbus_sender (req),
1364 &error);
1365 if (ac) {
1366 secondary_ac_list = g_slist_append (secondary_ac_list,
1367 g_strdup (nm_active_connection_get_path (ac)));
1368 } else {
1369 nm_log_warn (LOGD_DEVICE, "Secondary connection '%s' auto-activation failed: (%d) %s",
1370 sec_uuid,
1371 error ? error->code : 0,
1372 (error && error->message) ? error->message : "unknown");
1373 g_clear_error (&error);
1374 success = FALSE;
1375 break;
1376 }
1377 } else {
1378 nm_log_warn (LOGD_DEVICE, "Secondary connection '%s' auto-activation failed: The connection doesn't exist.",
1379 sec_uuid);
1380 success = FALSE;
1381 break;
1382 }
1383 }
1384
1385 if (success && secondary_ac_list != NULL) {
1386 secondary_data = pending_secondary_data_new (device, secondary_ac_list);
1387 priv->pending_secondaries = g_slist_append (priv->pending_secondaries, secondary_data);
1388 } else
1389 g_slist_free_full (secondary_ac_list, g_free);
1390
1391 return success;
1392 }
1393
1394 static void
1395 device_state_changed (NMDevice *device,
1396 NMDeviceState new_state,
1397 NMDeviceState old_state,
1398 NMDeviceStateReason reason,
1399 gpointer user_data)
1400 {
1401 NMPolicy *policy = (NMPolicy *) user_data;
1402 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1403 NMConnection *connection = nm_device_get_connection (device);
1404 const char *ip_iface = nm_device_get_ip_iface (device);
1405 NMIP4Config *ip4_config;
1406 NMIP6Config *ip6_config;
1407 NMSettingConnection *s_con;
1408
1409 if (connection)
1410 g_object_set_data (G_OBJECT (connection), FAILURE_REASON_TAG, GUINT_TO_POINTER (0));
1411
1412 switch (new_state) {
1413 case NM_DEVICE_STATE_FAILED:
1414 /* Mark the connection invalid if it failed during activation so that
1415 * it doesn't get automatically chosen over and over and over again.
1416 */
1417 if ( connection
1418 && old_state >= NM_DEVICE_STATE_PREPARE
1419 && old_state <= NM_DEVICE_STATE_ACTIVATED) {
1420 guint32 tries = get_connection_auto_retries (connection);
1421
1422 if (reason == NM_DEVICE_STATE_REASON_NO_SECRETS) {
1423 /* If the connection couldn't get the secrets it needed (ex because
1424 * the user canceled, or no secrets exist), there's no point in
1425 * automatically retrying because it's just going to fail anyway.
1426 */
1427 set_connection_auto_retries (connection, 0);
1428
1429 /* Mark the connection as failed due to missing secrets so that we can reset
1430 * RETRIES_TAG and automatically re-try when an secret agent registers.
1431 */
1432 g_object_set_data (G_OBJECT (connection), FAILURE_REASON_TAG, GUINT_TO_POINTER (NM_DEVICE_STATE_REASON_NO_SECRETS));
1433 } else if (tries > 0) {
1434 /* Otherwise if it's a random failure, just decrease the number
1435 * of automatic retries so that the connection gets tried again
1436 * if it still has a retry count.
1437 */
1438 set_connection_auto_retries (connection, tries - 1);
1439 }
1440
1441 if (get_connection_auto_retries (connection) == 0) {
1442 nm_log_info (LOGD_DEVICE, "Marking connection '%s' invalid.", nm_connection_get_id (connection));
1443 /* Schedule a handler to reset retries count */
1444 g_object_set_data (G_OBJECT (connection), RESET_RETRIES_TIMESTAMP_TAG, GSIZE_TO_POINTER ((gsize) time (NULL)));
1445 if (!priv->reset_retries_id)
1446 priv->reset_retries_id = g_timeout_add_seconds (RESET_RETRIES_TIMER, reset_connections_retries, policy);
1447 }
1448 nm_connection_clear_secrets (connection);
1449 }
1450 schedule_activate_check (policy, device, 3);
1451 break;
1452 case NM_DEVICE_STATE_ACTIVATED:
1453 if (connection) {
1454 /* Reset auto retries back to default since connection was successful */
1455 set_connection_auto_retries (connection, RETRIES_DEFAULT);
1456
1457 /* And clear secrets so they will always be requested from the
1458 * settings service when the next connection is made.
1459 */
1460 nm_connection_clear_secrets (connection);
1461 }
1462
1463 /* Add device's new IPv4 and IPv6 configs to DNS */
1464
1465 nm_dns_manager_begin_updates (priv->dns_manager, __func__);
1466
1467 ip4_config = nm_device_get_ip4_config (device);
1468 if (ip4_config)
1469 nm_dns_manager_add_ip4_config (priv->dns_manager, ip_iface, ip4_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT);
1470 ip6_config = nm_device_get_ip6_config (device);
1471 if (ip6_config)
1472 nm_dns_manager_add_ip6_config (priv->dns_manager, ip_iface, ip6_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT);
1473
1474 update_routing_and_dns (policy, FALSE);
1475
1476 nm_dns_manager_end_updates (priv->dns_manager, __func__);
1477 break;
1478 case NM_DEVICE_STATE_UNMANAGED:
1479 case NM_DEVICE_STATE_UNAVAILABLE:
1480 if (old_state > NM_DEVICE_STATE_DISCONNECTED)
1481 update_routing_and_dns (policy, FALSE);
1482 break;
1483 case NM_DEVICE_STATE_DISCONNECTED:
1484 /* Reset RETRIES_TAG when carrier on. If cable was unplugged
1485 * and plugged again, we should try to reconnect */
1486 if (reason == NM_DEVICE_STATE_REASON_CARRIER && old_state == NM_DEVICE_STATE_UNAVAILABLE)
1487 reset_retries_all (priv->settings, device);
1488
1489 if (old_state > NM_DEVICE_STATE_DISCONNECTED)
1490 update_routing_and_dns (policy, FALSE);
1491
1492 /* Device is now available for auto-activation */
1493 schedule_activate_check (policy, device, 0);
1494 break;
1495
1496 case NM_DEVICE_STATE_PREPARE:
1497 /* Reset auto-connect retries of all slaves and schedule them for
1498 * activation. */
1499 activate_slave_connections (policy, connection, device);
1500 break;
1501 case NM_DEVICE_STATE_SECONDARIES:
1502 s_con = nm_connection_get_setting_connection (connection);
1503 if (s_con && nm_setting_connection_get_num_secondaries (s_con) > 0) {
1504 /* Make routes and DNS up-to-date before activating dependent connections */
1505 update_routing_and_dns (policy, FALSE);
1506
1507 /* Activate secondary (VPN) connections */
1508 if (!activate_secondary_connections (policy, connection, device))
1509 nm_device_queue_state (device, NM_DEVICE_STATE_FAILED,
1510 NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED);
1511 } else
1512 nm_device_queue_state (device, NM_DEVICE_STATE_ACTIVATED,
1513 NM_DEVICE_STATE_REASON_NONE);
1514 break;
1515
1516 default:
1517 break;
1518 }
1519
1520 check_activating_devices (policy);
1521 }
1522
1523 static void
1524 device_ip4_config_changed (NMDevice *device,
1525 NMIP4Config *new_config,
1526 NMIP4Config *old_config,
1527 gpointer user_data)
1528 {
1529 NMPolicy *policy = user_data;
1530 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1531 const char *ip_iface = nm_device_get_ip_iface (device);
1532
1533 nm_dns_manager_begin_updates (priv->dns_manager, __func__);
1534
1535 /* Ignore IP config changes while the device is activating, because we'll
1536 * catch all the changes when the device moves to ACTIVATED state.
1537 * Prevents unecessary changes to DNS information.
1538 */
1539 if (!nm_device_is_activating (device)) {
1540 if (old_config != new_config) {
1541 if (old_config)
1542 nm_dns_manager_remove_ip4_config (priv->dns_manager, old_config);
1543 if (new_config)
1544 nm_dns_manager_add_ip4_config (priv->dns_manager, ip_iface, new_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT);
1545 }
1546 update_ip4_dns (policy, priv->dns_manager);
1547 update_ip4_routing (policy, TRUE);
1548 } else {
1549 /* Old configs get removed immediately */
1550 if (old_config)
1551 nm_dns_manager_remove_ip4_config (priv->dns_manager, old_config);
1552 }
1553
1554 nm_dns_manager_end_updates (priv->dns_manager, __func__);
1555 }
1556
1557 static void
1558 device_ip6_config_changed (NMDevice *device,
1559 NMIP6Config *new_config,
1560 NMIP6Config *old_config,
1561 gpointer user_data)
1562 {
1563 NMPolicy *policy = user_data;
1564 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1565 const char *ip_iface = nm_device_get_ip_iface (device);
1566
1567 nm_dns_manager_begin_updates (priv->dns_manager, __func__);
1568
1569 /* Ignore IP config changes while the device is activating, because we'll
1570 * catch all the changes when the device moves to ACTIVATED state.
1571 * Prevents unecessary changes to DNS information.
1572 */
1573 if (!nm_device_is_activating (device)) {
1574 if (old_config != new_config) {
1575 if (old_config)
1576 nm_dns_manager_remove_ip6_config (priv->dns_manager, old_config);
1577 if (new_config)
1578 nm_dns_manager_add_ip6_config (priv->dns_manager, ip_iface, new_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT);
1579 }
1580 update_ip6_dns (policy, priv->dns_manager);
1581 update_ip6_routing (policy, TRUE);
1582 } else {
1583 /* Old configs get removed immediately */
1584 if (old_config)
1585 nm_dns_manager_remove_ip6_config (priv->dns_manager, old_config);
1586 }
1587
1588 nm_dns_manager_end_updates (priv->dns_manager, __func__);
1589 }
1590
1591 static void
1592 device_autoconnect_changed (NMDevice *device,
1593 GParamSpec *pspec,
1594 gpointer user_data)
1595 {
1596 if (nm_device_get_autoconnect (device))
1597 schedule_activate_check ((NMPolicy *) user_data, device, 0);
1598 }
1599
1600 static void
1601 wireless_networks_changed (NMDevice *device, GObject *ap, gpointer user_data)
1602 {
1603 schedule_activate_check ((NMPolicy *) user_data, device, 0);
1604 }
1605
1606 static void
1607 nsps_changed (NMDevice *device, GObject *nsp, gpointer user_data)
1608 {
1609 schedule_activate_check ((NMPolicy *) user_data, device, 0);
1610 }
1611
1612 static void
1613 modem_enabled_changed (NMDevice *device, gpointer user_data)
1614 {
1615 schedule_activate_check ((NMPolicy *) (user_data), device, 0);
1616 }
1617
1618 typedef struct {
1619 gulong id;
1620 NMDevice *device;
1621 } DeviceSignalId;
1622
1623 static void
1624 _connect_device_signal (NMPolicy *policy, NMDevice *device, const char *name, gpointer callback)
1625 {
1626 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1627 DeviceSignalId *data;
1628
1629 data = g_slice_new0 (DeviceSignalId);
1630 g_assert (data);
1631 data->id = g_signal_connect (device, name, callback, policy);
1632 data->device = device;
1633 priv->dev_ids = g_slist_prepend (priv->dev_ids, data);
1634 }
1635
1636 static void
1637 device_added (NMManager *manager, NMDevice *device, gpointer user_data)
1638 {
1639 NMPolicy *policy = (NMPolicy *) user_data;
1640
1641 _connect_device_signal (policy, device, "state-changed", device_state_changed);
1642 _connect_device_signal (policy, device, NM_DEVICE_IP4_CONFIG_CHANGED, device_ip4_config_changed);
1643 _connect_device_signal (policy, device, NM_DEVICE_IP6_CONFIG_CHANGED, device_ip6_config_changed);
1644 _connect_device_signal (policy, device, "notify::" NM_DEVICE_AUTOCONNECT, device_autoconnect_changed);
1645
1646 switch (nm_device_get_device_type (device)) {
1647 case NM_DEVICE_TYPE_WIFI:
1648 _connect_device_signal (policy, device, "access-point-added", wireless_networks_changed);
1649 _connect_device_signal (policy, device, "access-point-removed", wireless_networks_changed);
1650 break;
1651 case NM_DEVICE_TYPE_WIMAX:
1652 _connect_device_signal (policy, device, "nsp-added", nsps_changed);
1653 _connect_device_signal (policy, device, "nsp-removed", nsps_changed);
1654 break;
1655 case NM_DEVICE_TYPE_MODEM:
1656 _connect_device_signal (policy, device, "enable-changed", modem_enabled_changed);
1657 break;
1658 default:
1659 break;
1660 }
1661 }
1662
1663 static void
1664 device_removed (NMManager *manager, NMDevice *device, gpointer user_data)
1665 {
1666 NMPolicy *policy = (NMPolicy *) user_data;
1667 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1668 ActivateData *tmp;
1669 GSList *iter;
1670
1671 /* Clear any idle callbacks for this device */
1672 tmp = find_pending_activation (priv->pending_activation_checks, device);
1673 if (tmp) {
1674 priv->pending_activation_checks = g_slist_remove (priv->pending_activation_checks, tmp);
1675 activate_data_free (tmp);
1676 }
1677
1678 /* Clear any signal handlers for this device */
1679 iter = priv->dev_ids;
1680 while (iter) {
1681 DeviceSignalId *data = iter->data;
1682 GSList *next = g_slist_next (iter);
1683
1684 if (data->device == device) {
1685 g_signal_handler_disconnect (data->device, data->id);
1686 g_slice_free (DeviceSignalId, data);
1687 priv->dev_ids = g_slist_delete_link (priv->dev_ids, iter);
1688 }
1689 iter = next;
1690 }
1691
1692 /* Don't update routing and DNS here as we've already handled that
1693 * for devices that need it when the device's state changed to UNMANAGED.
1694 */
1695 }
1696
1697 /**************************************************************************/
1698
1699 static void
1700 vpn_connection_activated (NMPolicy *policy, NMVPNConnection *vpn)
1701 {
1702 NMDnsManager *mgr;
1703 NMIP4Config *ip4_config;
1704 NMIP6Config *ip6_config;
1705 const char *ip_iface;
1706
1707 mgr = nm_dns_manager_get ();
1708 nm_dns_manager_begin_updates (mgr, __func__);
1709
1710 ip_iface = nm_vpn_connection_get_ip_iface (vpn);
1711
1712 /* Add the VPN connection's IP configs from DNS */
1713
1714 ip4_config = nm_vpn_connection_get_ip4_config (vpn);
1715 if (ip4_config)
1716 nm_dns_manager_add_ip4_config (mgr, ip_iface, ip4_config, NM_DNS_IP_CONFIG_TYPE_VPN);
1717
1718 ip6_config = nm_vpn_connection_get_ip6_config (vpn);
1719 if (ip6_config)
1720 nm_dns_manager_add_ip6_config (mgr, ip_iface, ip6_config, NM_DNS_IP_CONFIG_TYPE_VPN);
1721
1722 update_routing_and_dns (policy, TRUE);
1723
1724 nm_dns_manager_end_updates (mgr, __func__);
1725
1726 process_secondaries (policy, NM_ACTIVE_CONNECTION (vpn), TRUE);
1727 }
1728
1729 static void
1730 vpn_connection_deactivated (NMPolicy *policy, NMVPNConnection *vpn)
1731 {
1732 NMDnsManager *mgr;
1733 NMIP4Config *ip4_config;
1734 NMIP6Config *ip6_config;
1735 const char *ip_iface;
1736 NMDevice *parent;
1737
1738 mgr = nm_dns_manager_get ();
1739 nm_dns_manager_begin_updates (mgr, __func__);
1740
1741 ip_iface = nm_vpn_connection_get_ip_iface (vpn);
1742 parent = nm_vpn_connection_get_parent_device (vpn);
1743
1744 ip4_config = nm_vpn_connection_get_ip4_config (vpn);
1745 if (ip4_config) {
1746 /* Remove the VPN connection's IP4 config from DNS */
1747 nm_dns_manager_remove_ip4_config (mgr, ip4_config);
1748 }
1749
1750 ip6_config = nm_vpn_connection_get_ip6_config (vpn);
1751 if (ip6_config) {
1752 /* Remove the VPN connection's IP6 config from DNS */
1753 nm_dns_manager_remove_ip6_config (mgr, ip6_config);
1754 }
1755
1756 update_routing_and_dns (policy, TRUE);
1757
1758 nm_dns_manager_end_updates (mgr, __func__);
1759
1760 process_secondaries (policy, NM_ACTIVE_CONNECTION (vpn), FALSE);
1761 }
1762
1763 static void
1764 active_connection_state_changed (NMActiveConnection *active,
1765 GParamSpec *pspec,
1766 NMPolicy *policy)
1767 {
1768 switch (nm_active_connection_get_state (active)) {
1769 case NM_ACTIVE_CONNECTION_STATE_ACTIVATED:
1770 if (NM_IS_VPN_CONNECTION (active))
1771 vpn_connection_activated (policy, NM_VPN_CONNECTION (active));
1772 break;
1773 case NM_ACTIVE_CONNECTION_STATE_DEACTIVATED:
1774 if (NM_IS_VPN_CONNECTION (active))
1775 vpn_connection_deactivated (policy, NM_VPN_CONNECTION (active));
1776 break;
1777 default:
1778 break;
1779 }
1780 }
1781
1782 static void
1783 active_connection_added (NMManager *manager,
1784 NMActiveConnection *active,
1785 gpointer user_data)
1786 {
1787 NMPolicy *policy = (NMPolicy *) user_data;
1788
1789 g_signal_connect (active, "notify::" NM_ACTIVE_CONNECTION_STATE,
1790 G_CALLBACK (active_connection_state_changed),
1791 policy);
1792 }
1793
1794 static void
1795 active_connection_removed (NMManager *manager,
1796 NMActiveConnection *active,
1797 gpointer user_data)
1798 {
1799 g_signal_handlers_disconnect_by_func (active,
1800 active_connection_state_changed,
1801 (NMPolicy *) user_data);
1802 }
1803
1804 /**************************************************************************/
1805
1806 static void
1807 schedule_activate_all (NMPolicy *policy)
1808 {
1809 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1810 GSList *iter, *devices;
1811
1812 devices = nm_manager_get_devices (priv->manager);
1813 for (iter = devices; iter; iter = g_slist_next (iter))
1814 schedule_activate_check (policy, NM_DEVICE (iter->data), 0);
1815 }
1816
1817 static void
1818 connection_added (NMSettings *settings,
1819 NMConnection *connection,
1820 gpointer user_data)
1821 {
1822 set_connection_auto_retries (connection, RETRIES_DEFAULT);
1823 schedule_activate_all ((NMPolicy *) user_data);
1824 }
1825
1826 static void
1827 connections_loaded (NMSettings *settings, gpointer user_data)
1828 {
1829 // FIXME: "connections-loaded" signal is emmitted *before* we connect to it
1830 // in nm_policy_new(). So this function is never called. Currently we work around
1831 // that by calling reset_retries_all() in nm_policy_new()
1832
1833 /* Initialize connections' auto-retries */
1834 reset_retries_all (settings, NULL);
1835
1836 schedule_activate_all ((NMPolicy *) user_data);
1837 }
1838
1839 static void
1840 add_or_change_zone_cb (GError *error, gpointer user_data)
1841 {
1842 NMDevice *device = NM_DEVICE (user_data);
1843
1844 if (error) {
1845 /* FIXME: what do we do here? */
1846 }
1847
1848 g_object_unref (device);
1849 }
1850
1851 static void
1852 firewall_update_zone (NMPolicy *policy, NMConnection *connection)
1853 {
1854 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1855 NMSettingConnection *s_con = nm_connection_get_setting_connection (connection);
1856 GSList *iter, *devices;
1857
1858 devices = nm_manager_get_devices (priv->manager);
1859 /* find dev with passed connection and change zone its interface belongs to */
1860 for (iter = devices; iter; iter = g_slist_next (iter)) {
1861 NMDevice *dev = NM_DEVICE (iter->data);
1862
1863 if ( (nm_device_get_connection (dev) == connection)
1864 && (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED)) {
1865 nm_firewall_manager_add_or_change_zone (priv->fw_manager,
1866 nm_device_get_ip_iface (dev),
1867 nm_setting_connection_get_zone (s_con),
1868 FALSE, /* change zone */
1869 add_or_change_zone_cb,
1870 g_object_ref (dev));
1871 }
1872 }
1873 }
1874
1875 static void
1876 firewall_started (NMFirewallManager *manager,
1877 gpointer user_data)
1878 {
1879 NMPolicy *policy = (NMPolicy *) user_data;
1880 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1881 NMConnection *connection;
1882 NMSettingConnection *s_con;
1883 GSList *iter, *devices;
1884
1885 devices = nm_manager_get_devices (priv->manager);
1886 /* add interface of each device to correct zone */
1887 for (iter = devices; iter; iter = g_slist_next (iter)) {
1888 NMDevice *dev = NM_DEVICE (iter->data);
1889
1890 connection = nm_device_get_connection (dev);
1891 s_con = nm_connection_get_setting_connection (connection);
1892 if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED) {
1893 nm_firewall_manager_add_or_change_zone (priv->fw_manager,
1894 nm_device_get_ip_iface (dev),
1895 nm_setting_connection_get_zone (s_con),
1896 TRUE, /* add zone */
1897 add_or_change_zone_cb,
1898 g_object_ref (dev));
1899 }
1900 }
1901 }
1902
1903 static void
1904 dns_config_changed (NMDnsManager *dns_manager, gpointer user_data)
1905 {
1906 NMPolicy *policy = (NMPolicy *) user_data;
1907 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1908
1909 /* Restart a thread for reverse-DNS lookup after we are signalled that
1910 * DNS changed. Because the result from a previous run may not be right
1911 * (race in updating DNS and doing the reverse lookup).
1912 */
1913
1914 /* Stop a lookup thread if any. */
1915 if (priv->lookup_cancellable) {
1916 g_cancellable_cancel (priv->lookup_cancellable);
1917 g_clear_object (&priv->lookup_cancellable);
1918 }
1919
1920 /* Re-start the hostname lookup thread if we don't have hostname yet. */
1921 if (priv->lookup_addr) {
1922 nm_log_dbg (LOGD_DNS, "restarting reverse-lookup thread for address %s'",
1923 g_inet_address_to_string (priv->lookup_addr));
1924
1925 priv->lookup_cancellable = g_cancellable_new ();
1926 g_resolver_lookup_by_address_async (priv->resolver,
1927 priv->lookup_addr,
1928 priv->lookup_cancellable,
1929 lookup_callback, policy);
1930 }
1931 }
1932
1933 static void
1934 connection_updated (NMSettings *settings,
1935 NMConnection *connection,
1936 gpointer user_data)
1937 {
1938 NMPolicy *policy = (NMPolicy *) user_data;
1939
1940 firewall_update_zone (policy, connection);
1941
1942 /* Reset auto retries back to default since connection was updated */
1943 set_connection_auto_retries (connection, RETRIES_DEFAULT);
1944
1945 schedule_activate_all (policy);
1946 }
1947
1948 static void
1949 _deactivate_if_active (NMManager *manager, NMConnection *connection)
1950 {
1951 const GSList *active, *iter;
1952
1953 active = nm_manager_get_active_connections (manager);
1954 for (iter = active; iter; iter = g_slist_next (iter)) {
1955 NMActiveConnection *ac = iter->data;
1956 NMActiveConnectionState state = nm_active_connection_get_state (ac);
1957 GError *error = NULL;
1958
1959 if (nm_active_connection_get_connection (ac) == connection &&
1960 (state <= NM_ACTIVE_CONNECTION_STATE_ACTIVATED)) {
1961 if (!nm_manager_deactivate_connection (manager,
1962 nm_active_connection_get_path (ac),
1963 NM_DEVICE_STATE_REASON_CONNECTION_REMOVED,
1964 &error)) {
1965 nm_log_warn (LOGD_DEVICE, "Connection '%s' disappeared, but error deactivating it: (%d) %s",
1966 nm_connection_get_id (connection),
1967 error ? error->code : -1,
1968 error ? error->message : "(unknown)");
1969 g_clear_error (&error);
1970 }
1971 }
1972 }
1973 }
1974
1975 static void
1976 connection_removed (NMSettings *settings,
1977 NMConnection *connection,
1978 gpointer user_data)
1979 {
1980 NMPolicy *policy = user_data;
1981 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1982
1983 _deactivate_if_active (priv->manager, connection);
1984 }
1985
1986 static void
1987 connection_visibility_changed (NMSettings *settings,
1988 NMSettingsConnection *connection,
1989 gpointer user_data)
1990 {
1991 NMPolicy *policy = user_data;
1992 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
1993
1994 if (nm_settings_connection_is_visible (connection))
1995 schedule_activate_all (policy);
1996 else
1997 _deactivate_if_active (priv->manager, NM_CONNECTION (connection));
1998 }
1999
2000 static void
2001 secret_agent_registered (NMSettings *settings,
2002 NMSecretAgent *agent,
2003 gpointer user_data)
2004 {
2005 /* The registered secret agent may provide some missing secrets. Thus we
2006 * reset retries count here and schedule activation, so that the
2007 * connections failed due to missing secrets may re-try auto-connection.
2008 */
2009 reset_retries_for_failed_secrets (settings);
2010 schedule_activate_all ((NMPolicy *) user_data);
2011 }
2012
2013 static void
2014 _connect_manager_signal (NMPolicy *policy, const char *name, gpointer callback)
2015 {
2016 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
2017 guint id;
2018
2019 id = g_signal_connect (priv->manager, name, callback, policy);
2020 priv->manager_ids = g_slist_prepend (priv->manager_ids, GUINT_TO_POINTER (id));
2021 }
2022
2023 static void
2024 _connect_settings_signal (NMPolicy *policy, const char *name, gpointer callback)
2025 {
2026 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
2027 guint id;
2028
2029 id = g_signal_connect (priv->settings, name, callback, policy);
2030 priv->settings_ids = g_slist_prepend (priv->settings_ids, GUINT_TO_POINTER (id));
2031 }
2032
2033 NMPolicy *
2034 nm_policy_new (NMManager *manager, NMSettings *settings)
2035 {
2036 NMPolicy *policy;
2037 NMPolicyPrivate *priv;
2038 static gboolean initialized = FALSE;
2039 gulong id;
2040 char hostname[HOST_NAME_MAX + 2];
2041
2042 g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
2043 g_return_val_if_fail (initialized == FALSE, NULL);
2044
2045 policy = g_object_new (NM_TYPE_POLICY, NULL);
2046 priv = NM_POLICY_GET_PRIVATE (policy);
2047 priv->manager = manager;
2048 priv->settings = g_object_ref (settings);
2049 priv->update_state_id = 0;
2050
2051 /* Grab hostname on startup and use that if nothing provides one */
2052 memset (hostname, 0, sizeof (hostname));
2053 if (gethostname (&hostname[0], HOST_NAME_MAX) == 0) {
2054 /* only cache it if it's a valid hostname */
2055 if ( strlen (hostname)
2056 && strcmp (hostname, "localhost")
2057 && strcmp (hostname, "localhost.localdomain")
2058 && strcmp (hostname, "(none)"))
2059 priv->orig_hostname = g_strdup (hostname);
2060 }
2061
2062 priv->fw_manager = nm_firewall_manager_get();
2063 id = g_signal_connect (priv->fw_manager, "started",
2064 G_CALLBACK (firewall_started), policy);
2065 priv->fw_started_id = id;
2066
2067 priv->dns_manager = nm_dns_manager_get ();
2068 priv->config_changed_id = g_signal_connect (priv->dns_manager, "config-changed",
2069 G_CALLBACK (dns_config_changed), policy);
2070
2071 priv->resolver = g_resolver_get_default ();
2072
2073 _connect_manager_signal (policy, "state-changed", global_state_changed);
2074 _connect_manager_signal (policy, "notify::" NM_MANAGER_HOSTNAME, hostname_changed);
2075 _connect_manager_signal (policy, "notify::" NM_MANAGER_SLEEPING, sleeping_changed);
2076 _connect_manager_signal (policy, "notify::" NM_MANAGER_NETWORKING_ENABLED, sleeping_changed);
2077 _connect_manager_signal (policy, "device-added", device_added);
2078 _connect_manager_signal (policy, "device-removed", device_removed);
2079 _connect_manager_signal (policy, NM_MANAGER_ACTIVE_CONNECTION_ADDED, active_connection_added);
2080 _connect_manager_signal (policy, NM_MANAGER_ACTIVE_CONNECTION_REMOVED, active_connection_removed);
2081
2082 _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTIONS_LOADED, connections_loaded);
2083 _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_ADDED, connection_added);
2084 _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, connection_updated);
2085 _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, connection_removed);
2086 _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED,
2087 connection_visibility_changed);
2088 _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_AGENT_REGISTERED, secret_agent_registered);
2089
2090 /* Initialize connections' auto-retries */
2091 reset_retries_all (priv->settings, NULL);
2092
2093 initialized = TRUE;
2094 return policy;
2095 }
2096
2097 NMDevice *
2098 nm_policy_get_default_ip4_device (NMPolicy *policy)
2099 {
2100 return NM_POLICY_GET_PRIVATE (policy)->default_device4;
2101 }
2102
2103 NMDevice *
2104 nm_policy_get_default_ip6_device (NMPolicy *policy)
2105 {
2106 return NM_POLICY_GET_PRIVATE (policy)->default_device6;
2107 }
2108
2109 NMDevice *
2110 nm_policy_get_activating_ip4_device (NMPolicy *policy)
2111 {
2112 return NM_POLICY_GET_PRIVATE (policy)->activating_device4;
2113 }
2114
2115 NMDevice *
2116 nm_policy_get_activating_ip6_device (NMPolicy *policy)
2117 {
2118 return NM_POLICY_GET_PRIVATE (policy)->activating_device6;
2119 }
2120
2121 static void
2122 nm_policy_init (NMPolicy *policy)
2123 {
2124 }
2125
2126 static void
2127 get_property (GObject *object, guint prop_id,
2128 GValue *value, GParamSpec *pspec)
2129 {
2130 NMPolicy *policy = NM_POLICY (object);
2131 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
2132
2133 switch (prop_id) {
2134 case PROP_DEFAULT_IP4_DEVICE:
2135 g_value_set_object (value, priv->default_device4);
2136 break;
2137 case PROP_DEFAULT_IP6_DEVICE:
2138 g_value_set_object (value, priv->default_device6);
2139 break;
2140 case PROP_ACTIVATING_IP4_DEVICE:
2141 g_value_set_object (value, priv->activating_device4);
2142 break;
2143 case PROP_ACTIVATING_IP6_DEVICE:
2144 g_value_set_object (value, priv->activating_device6);
2145 break;
2146 default:
2147 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2148 break;
2149 }
2150 }
2151
2152 static void
2153 dispose (GObject *object)
2154 {
2155 NMPolicy *policy = NM_POLICY (object);
2156 NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
2157 const GSList *connections, *iter;
2158
2159 /* Tell any existing hostname lookup thread to die. */
2160 if (priv->lookup_cancellable) {
2161 g_cancellable_cancel (priv->lookup_cancellable);
2162 g_clear_object (&priv->lookup_cancellable);
2163 }
2164 g_clear_object (&priv->lookup_addr);
2165 g_clear_object (&priv->resolver);
2166
2167 g_slist_free_full (priv->pending_activation_checks, (GDestroyNotify) activate_data_free);
2168 priv->pending_activation_checks = NULL;
2169
2170 g_slist_free_full (priv->pending_secondaries, (GDestroyNotify) pending_secondary_data_free);
2171 priv->pending_secondaries = NULL;
2172
2173 if (priv->fw_manager) {
2174 g_signal_handler_disconnect (priv->fw_manager, priv->fw_started_id);
2175 g_object_unref (priv->fw_manager);
2176 priv->fw_manager = NULL;
2177 }
2178
2179 if (priv->dns_manager) {
2180 g_signal_handler_disconnect (priv->dns_manager, priv->config_changed_id);
2181 g_object_unref (priv->dns_manager);
2182 priv->dns_manager = NULL;
2183 }
2184
2185 for (iter = priv->manager_ids; iter; iter = g_slist_next (iter))
2186 g_signal_handler_disconnect (priv->manager, GPOINTER_TO_UINT (iter->data));
2187 g_clear_pointer (&priv->manager_ids, g_slist_free);
2188
2189 for (iter = priv->settings_ids; iter; iter = g_slist_next (iter))
2190 g_signal_handler_disconnect (priv->settings, GPOINTER_TO_UINT (iter->data));
2191 g_clear_pointer (&priv->settings_ids, g_slist_free);
2192
2193 for (iter = priv->dev_ids; iter; iter = g_slist_next (iter)) {
2194 DeviceSignalId *data = iter->data;
2195
2196 g_signal_handler_disconnect (data->device, data->id);
2197 g_slice_free (DeviceSignalId, data);
2198 }
2199 g_clear_pointer (&priv->dev_ids, g_slist_free);
2200
2201 /* The manager should have disposed of ActiveConnections already, which
2202 * will have called active_connection_removed() and thus we don't need
2203 * to clean anything up. Assert that this is TRUE.
2204 */
2205 connections = nm_manager_get_active_connections (priv->manager);
2206 g_assert (connections == NULL);
2207
2208 if (priv->reset_retries_id) {
2209 g_source_remove (priv->reset_retries_id);
2210 priv->reset_retries_id = 0;
2211 }
2212
2213 g_clear_pointer (&priv->orig_hostname, g_free);
2214 g_clear_pointer (&priv->cur_hostname, g_free);
2215
2216 g_clear_object (&priv->settings);
2217
2218 G_OBJECT_CLASS (nm_policy_parent_class)->dispose (object);
2219 }
2220
2221 static void
2222 nm_policy_class_init (NMPolicyClass *policy_class)
2223 {
2224 GObjectClass *object_class = G_OBJECT_CLASS (policy_class);
2225
2226 g_type_class_add_private (policy_class, sizeof (NMPolicyPrivate));
2227
2228 object_class->get_property = get_property;
2229 object_class->dispose = dispose;
2230
2231 g_object_class_install_property
2232 (object_class, PROP_DEFAULT_IP4_DEVICE,
2233 g_param_spec_object (NM_POLICY_DEFAULT_IP4_DEVICE,
2234 "Default IP4 device",
2235 "Default IP4 device",
2236 NM_TYPE_DEVICE,
2237 G_PARAM_READABLE));
2238 g_object_class_install_property
2239 (object_class, PROP_DEFAULT_IP6_DEVICE,
2240 g_param_spec_object (NM_POLICY_DEFAULT_IP6_DEVICE,
2241 "Default IP6 device",
2242 "Default IP6 device",
2243 NM_TYPE_DEVICE,
2244 G_PARAM_READABLE));
2245 g_object_class_install_property
2246 (object_class, PROP_ACTIVATING_IP4_DEVICE,
2247 g_param_spec_object (NM_POLICY_ACTIVATING_IP4_DEVICE,
2248 "Activating default IP4 device",
2249 "Activating default IP4 device",
2250 NM_TYPE_DEVICE,
2251 G_PARAM_READABLE));
2252 g_object_class_install_property
2253 (object_class, PROP_ACTIVATING_IP6_DEVICE,
2254 g_param_spec_object (NM_POLICY_ACTIVATING_IP6_DEVICE,
2255 "Activating default IP6 device",
2256 "Activating default IP6 device",
2257 NM_TYPE_DEVICE,
2258 G_PARAM_READABLE));
2259 }
2260