diff options
| author | Michael Biebl <biebl@debian.org> | 2020-10-05 22:27:18 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2020-10-05 22:27:18 +0200 |
| commit | aafc1dbe4712c86189bbc1d4d54ad8cb4c69be7e (patch) | |
| tree | a2a9bb4d007339a0b1304540388230ccedac32bd /src/nm-policy.c | |
| parent | e7b44ef4c80907346ec7492a09c45277459924fc (diff) | |
New upstream version 1.27.90 upstream/1.27.90
Diffstat (limited to 'src/nm-policy.c')
| -rw-r--r-- | src/nm-policy.c | 4654 |
1 files changed, 2371 insertions, 2283 deletions
diff --git a/src/nm-policy.c b/src/nm-policy.c index 04cbace6..60f5fb02 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2004 - 2013 Red Hat, Inc. * Copyright (C) 2007 - 2008 Novell, Inc. @@ -36,174 +36,177 @@ /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE (NMPolicy, - PROP_MANAGER, - PROP_SETTINGS, - PROP_DEFAULT_IP4_AC, - PROP_DEFAULT_IP6_AC, - PROP_ACTIVATING_IP4_AC, - PROP_ACTIVATING_IP6_AC, -); +NM_GOBJECT_PROPERTIES_DEFINE(NMPolicy, + PROP_MANAGER, + PROP_SETTINGS, + PROP_DEFAULT_IP4_AC, + PROP_DEFAULT_IP6_AC, + PROP_ACTIVATING_IP4_AC, + PROP_ACTIVATING_IP6_AC, ); typedef struct { - NMManager *manager; - NMNetns *netns; - NMFirewallManager *firewall_manager; - CList pending_activation_checks; + NMManager * manager; + NMNetns * netns; + NMFirewallManager *firewall_manager; + CList pending_activation_checks; - NMAgentManager *agent_mgr; + NMAgentManager *agent_mgr; - GHashTable *devices; - GHashTable *pending_active_connections; + GHashTable *devices; + GHashTable *pending_active_connections; - GSList *pending_secondaries; + GSList *pending_secondaries; - NMSettings *settings; + NMSettings *settings; - NMHostnameManager *hostname_manager; + NMHostnameManager *hostname_manager; - NMActiveConnection *default_ac4, *activating_ac4; - NMActiveConnection *default_ac6, *activating_ac6; + NMActiveConnection *default_ac4, *activating_ac4; + NMActiveConnection *default_ac6, *activating_ac6; - struct { - GInetAddress *addr; - GResolver *resolver; - GCancellable *cancellable; - } lookup; + struct { + GInetAddress *addr; + GResolver * resolver; + GCancellable *cancellable; + } lookup; - NMDnsManager *dns_manager; - gulong config_changed_id; + NMDnsManager *dns_manager; + gulong config_changed_id; - guint reset_retries_id; /* idle handler for resetting the retries count */ + guint reset_retries_id; /* idle handler for resetting the retries count */ - guint schedule_activate_all_id; /* idle handler for schedule_activate_all(). */ + guint schedule_activate_all_id; /* idle handler for schedule_activate_all(). */ - NMPolicyHostnameMode hostname_mode; - char *orig_hostname; /* hostname at NM start time */ - char *cur_hostname; /* hostname we want to assign */ - char *last_hostname; /* last hostname NM set (to detect if someone else changed it in the meanwhile) */ - gboolean changing_hostname; /* hostname set operation still in progress */ - gboolean dhcp_hostname; /* current hostname was set from dhcp */ + NMPolicyHostnameMode hostname_mode; + char * orig_hostname; /* hostname at NM start time */ + char * cur_hostname; /* hostname we want to assign */ + char * + last_hostname; /* last hostname NM set (to detect if someone else changed it in the meanwhile) */ + gboolean changing_hostname; /* hostname set operation still in progress */ + gboolean dhcp_hostname; /* current hostname was set from dhcp */ - GArray *ip6_prefix_delegations; /* pool of ip6 prefixes delegated to all devices */ + GArray *ip6_prefix_delegations; /* pool of ip6 prefixes delegated to all devices */ } NMPolicyPrivate; struct _NMPolicy { - GObject parent; - NMPolicyPrivate _priv; + GObject parent; + NMPolicyPrivate _priv; }; struct _NMPolicyClass { - GObjectClass parent; + GObjectClass parent; }; -G_DEFINE_TYPE (NMPolicy, nm_policy, G_TYPE_OBJECT) +G_DEFINE_TYPE(NMPolicy, nm_policy, G_TYPE_OBJECT) -#define NM_POLICY_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMPolicy, NM_IS_POLICY) +#define NM_POLICY_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMPolicy, NM_IS_POLICY) static NMPolicy * -_PRIV_TO_SELF (NMPolicyPrivate *priv) +_PRIV_TO_SELF(NMPolicyPrivate *priv) { - NMPolicy *self; + NMPolicy *self; - nm_assert (priv); + nm_assert(priv); - self = (NMPolicy *) (((char *) priv) - G_STRUCT_OFFSET (NMPolicy, _priv)); + self = (NMPolicy *) (((char *) priv) - G_STRUCT_OFFSET(NMPolicy, _priv)); - nm_assert (NM_IS_POLICY (self)); - return self; + nm_assert(NM_IS_POLICY(self)); + return self; } /*****************************************************************************/ -#define _NMLOG_PREFIX_NAME "policy" -#define _NMLOG(level, domain, ...) \ - G_STMT_START { \ - nm_log ((level), (domain), NULL, NULL, \ - "%s" _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - _NMLOG_PREFIX_NAME": " \ - _NM_UTILS_MACRO_REST (__VA_ARGS__)); \ - } G_STMT_END +#define _NMLOG_PREFIX_NAME "policy" +#define _NMLOG(level, domain, ...) \ + G_STMT_START \ + { \ + nm_log((level), \ + (domain), \ + NULL, \ + NULL, \ + "%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME ": " _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + G_STMT_END /*****************************************************************************/ -static void schedule_activate_all (NMPolicy *self); -static void schedule_activate_check (NMPolicy *self, NMDevice *device); -static NMDevice *get_default_device (NMPolicy *self, int addr_family); +static void schedule_activate_all(NMPolicy *self); +static void schedule_activate_check(NMPolicy *self, NMDevice *device); +static NMDevice *get_default_device(NMPolicy *self, int addr_family); /*****************************************************************************/ static void -_dns_manager_set_ip_config (NMDnsManager *dns_manager, - NMIPConfig *ip_config, - NMDnsIPConfigType ip_config_type, - NMDevice *device) +_dns_manager_set_ip_config(NMDnsManager * dns_manager, + NMIPConfig * ip_config, + NMDnsIPConfigType ip_config_type, + NMDevice * device) { - if ( NM_IN_SET (ip_config_type, NM_DNS_IP_CONFIG_TYPE_DEFAULT, - NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE) - && device - && nm_device_get_route_metric_default (nm_device_get_device_type (device)) == NM_VPN_ROUTE_METRIC_DEFAULT) { - /* some device types are inherently VPN. */ - ip_config_type = NM_DNS_IP_CONFIG_TYPE_VPN; - } + if (NM_IN_SET(ip_config_type, NM_DNS_IP_CONFIG_TYPE_DEFAULT, NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE) + && device + && nm_device_get_route_metric_default(nm_device_get_device_type(device)) + == NM_VPN_ROUTE_METRIC_DEFAULT) { + /* some device types are inherently VPN. */ + ip_config_type = NM_DNS_IP_CONFIG_TYPE_VPN; + } - nm_dns_manager_set_ip_config (dns_manager, ip_config, ip_config_type); + nm_dns_manager_set_ip_config(dns_manager, ip_config, ip_config_type); } /*****************************************************************************/ typedef struct { - NMPlatformIP6Address prefix; - NMDevice *device; /* The requesting ("uplink") device */ - guint64 next_subnet; /* Cache of the next subnet number to be - * assigned from this prefix */ - GHashTable *subnets; /* ifindex -> NMPlatformIP6Address */ + NMPlatformIP6Address prefix; + NMDevice * device; /* The requesting ("uplink") device */ + guint64 next_subnet; /* Cache of the next subnet number to be + * assigned from this prefix */ + GHashTable * subnets; /* ifindex -> NMPlatformIP6Address */ } IP6PrefixDelegation; static void -_clear_ip6_subnet (gpointer key, gpointer value, gpointer user_data) +_clear_ip6_subnet(gpointer key, gpointer value, gpointer user_data) { - NMPlatformIP6Address *subnet = value; - NMDevice *device = nm_manager_get_device_by_ifindex (NM_MANAGER_GET, - GPOINTER_TO_INT (key)); + NMPlatformIP6Address *subnet = value; + NMDevice *device = nm_manager_get_device_by_ifindex(NM_MANAGER_GET, GPOINTER_TO_INT(key)); - if (device) { - /* We can not remove a subnet we already started announcing. - * Just un-prefer it. */ - subnet->preferred = 0; - nm_device_use_ip6_subnet (device, subnet); - } - g_slice_free (NMPlatformIP6Address, subnet); + if (device) { + /* We can not remove a subnet we already started announcing. + * Just un-prefer it. */ + subnet->preferred = 0; + nm_device_use_ip6_subnet(device, subnet); + } + g_slice_free(NMPlatformIP6Address, subnet); } static void -clear_ip6_prefix_delegation (gpointer data) +clear_ip6_prefix_delegation(gpointer data) { - IP6PrefixDelegation *delegation = data; - char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + IP6PrefixDelegation *delegation = data; + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; - _LOGD (LOGD_IP6, "ipv6-pd: undelegating prefix %s/%d", - _nm_utils_inet6_ntop (&delegation->prefix.address, sbuf), - delegation->prefix.plen); + _LOGD(LOGD_IP6, + "ipv6-pd: undelegating prefix %s/%d", + _nm_utils_inet6_ntop(&delegation->prefix.address, sbuf), + delegation->prefix.plen); - g_hash_table_foreach (delegation->subnets, _clear_ip6_subnet, NULL); - g_hash_table_destroy (delegation->subnets); + g_hash_table_foreach(delegation->subnets, _clear_ip6_subnet, NULL); + g_hash_table_destroy(delegation->subnets); } static void -expire_ip6_delegations (NMPolicy *self) +expire_ip6_delegations(NMPolicy *self) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - guint32 now = nm_utils_get_monotonic_timestamp_sec (); - IP6PrefixDelegation *delegation = NULL; - guint i; + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + guint32 now = nm_utils_get_monotonic_timestamp_sec(); + IP6PrefixDelegation *delegation = NULL; + guint i; - for (i = 0; i < priv->ip6_prefix_delegations->len; i++) { - delegation = &g_array_index (priv->ip6_prefix_delegations, - IP6PrefixDelegation, i); - if (delegation->prefix.timestamp + delegation->prefix.lifetime < now) - g_array_remove_index_fast (priv->ip6_prefix_delegations, i); - } + for (i = 0; i < priv->ip6_prefix_delegations->len; i++) { + delegation = &g_array_index(priv->ip6_prefix_delegations, IP6PrefixDelegation, i); + if (delegation->prefix.timestamp + delegation->prefix.lifetime < now) + g_array_remove_index_fast(priv->ip6_prefix_delegations, i); + } } /* @@ -213,52 +216,54 @@ expire_ip6_delegations (NMPolicy *self) * this prefix (and other prefix should be used -- and requested if necessary). */ static gboolean -ip6_subnet_from_delegation (IP6PrefixDelegation *delegation, NMDevice *device) -{ - NMPlatformIP6Address *subnet; - int ifindex = nm_device_get_ifindex (device); - char sbuf[NM_UTILS_INET_ADDRSTRLEN]; - - subnet = g_hash_table_lookup (delegation->subnets, GINT_TO_POINTER (ifindex)); - if (!subnet) { - /* Check for out-of-prefixes condition. */ - if (delegation->next_subnet >= (1 << (64 - delegation->prefix.plen))) { - _LOGD (LOGD_IP6, "ipv6-pd: no more prefixes in %s/%d", - _nm_utils_inet6_ntop (&delegation->prefix.address, sbuf), - delegation->prefix.plen); - return FALSE; - } - - /* Allocate a new subnet. */ - subnet = g_slice_new0 (NMPlatformIP6Address); - g_hash_table_insert (delegation->subnets, GINT_TO_POINTER (ifindex), subnet); - - subnet->plen = 64; - subnet->address.s6_addr32[0] = delegation->prefix.address.s6_addr32[0] - | htonl (delegation->next_subnet >> 32); - subnet->address.s6_addr32[1] = delegation->prefix.address.s6_addr32[1] - | htonl (delegation->next_subnet); - - /* Out subnet pool management is pretty unsophisticated. We only add - * the subnets and index them by ifindex. That keeps the implementation - * simple and the dead entries make it easy to reuse the same subnet on - * subsequent activations. On the other hand they may waste the subnet - * space. */ - delegation->next_subnet++; - } - - subnet->timestamp = delegation->prefix.timestamp; - subnet->lifetime = delegation->prefix.lifetime; - subnet->preferred = delegation->prefix.preferred; - - _LOGD (LOGD_IP6, "ipv6-pd: %s allocated from a /%d prefix on %s", - _nm_utils_inet6_ntop (&subnet->address, sbuf), - delegation->prefix.plen, - nm_device_get_iface (device)); - - nm_device_use_ip6_subnet (device, subnet); - - return TRUE; +ip6_subnet_from_delegation(IP6PrefixDelegation *delegation, NMDevice *device) +{ + NMPlatformIP6Address *subnet; + int ifindex = nm_device_get_ifindex(device); + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + + subnet = g_hash_table_lookup(delegation->subnets, GINT_TO_POINTER(ifindex)); + if (!subnet) { + /* Check for out-of-prefixes condition. */ + if (delegation->next_subnet >= (1 << (64 - delegation->prefix.plen))) { + _LOGD(LOGD_IP6, + "ipv6-pd: no more prefixes in %s/%d", + _nm_utils_inet6_ntop(&delegation->prefix.address, sbuf), + delegation->prefix.plen); + return FALSE; + } + + /* Allocate a new subnet. */ + subnet = g_slice_new0(NMPlatformIP6Address); + g_hash_table_insert(delegation->subnets, GINT_TO_POINTER(ifindex), subnet); + + subnet->plen = 64; + subnet->address.s6_addr32[0] = + delegation->prefix.address.s6_addr32[0] | htonl(delegation->next_subnet >> 32); + subnet->address.s6_addr32[1] = + delegation->prefix.address.s6_addr32[1] | htonl(delegation->next_subnet); + + /* Out subnet pool management is pretty unsophisticated. We only add + * the subnets and index them by ifindex. That keeps the implementation + * simple and the dead entries make it easy to reuse the same subnet on + * subsequent activations. On the other hand they may waste the subnet + * space. */ + delegation->next_subnet++; + } + + subnet->timestamp = delegation->prefix.timestamp; + subnet->lifetime = delegation->prefix.lifetime; + subnet->preferred = delegation->prefix.preferred; + + _LOGD(LOGD_IP6, + "ipv6-pd: %s allocated from a /%d prefix on %s", + _nm_utils_inet6_ntop(&subnet->address, sbuf), + delegation->prefix.plen, + nm_device_get_iface(device)); + + nm_device_use_ip6_subnet(device, subnet); + + return TRUE; } /* @@ -267,2547 +272,2630 @@ ip6_subnet_from_delegation (IP6PrefixDelegation *delegation, NMDevice *device) * Requests a new prefix if no subnet could be found. */ static void -ip6_subnet_from_device (NMPolicy *self, NMDevice *from_device, NMDevice *device) +ip6_subnet_from_device(NMPolicy *self, NMDevice *from_device, NMDevice *device) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - IP6PrefixDelegation *delegation = NULL; - gboolean got_subnet = FALSE; - guint have_prefixes = 0; - guint i; + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + IP6PrefixDelegation *delegation = NULL; + gboolean got_subnet = FALSE; + guint have_prefixes = 0; + guint i; - expire_ip6_delegations (self); + expire_ip6_delegations(self); - for (i = 0; i < priv->ip6_prefix_delegations->len; i++) { - delegation = &g_array_index (priv->ip6_prefix_delegations, - IP6PrefixDelegation, i); + for (i = 0; i < priv->ip6_prefix_delegations->len; i++) { + delegation = &g_array_index(priv->ip6_prefix_delegations, IP6PrefixDelegation, i); - if (delegation->device != from_device) - continue; + if (delegation->device != from_device) + continue; - if (ip6_subnet_from_delegation (delegation, device)) - got_subnet = TRUE; - have_prefixes++; - } + if (ip6_subnet_from_delegation(delegation, device)) + got_subnet = TRUE; + have_prefixes++; + } - if (!got_subnet) { - _LOGI (LOGD_IP6, "ipv6-pd: none of %u prefixes of %s can be shared on %s", - have_prefixes, nm_device_get_iface (from_device), - nm_device_get_iface (device)); - nm_device_request_ip6_prefixes (from_device, have_prefixes + 1); - } + if (!got_subnet) { + _LOGI(LOGD_IP6, + "ipv6-pd: none of %u prefixes of %s can be shared on %s", + have_prefixes, + nm_device_get_iface(from_device), + nm_device_get_iface(device)); + nm_device_request_ip6_prefixes(from_device, have_prefixes + 1); + } } static void -ip6_remove_device_prefix_delegations (NMPolicy *self, NMDevice *device) +ip6_remove_device_prefix_delegations(NMPolicy *self, NMDevice *device) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - IP6PrefixDelegation *delegation = NULL; - guint i; + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + IP6PrefixDelegation *delegation = NULL; + guint i; - for (i = 0; i < priv->ip6_prefix_delegations->len; i++) { - delegation = &g_array_index (priv->ip6_prefix_delegations, - IP6PrefixDelegation, i); - if (delegation->device == device) - g_array_remove_index_fast (priv->ip6_prefix_delegations, i); - } + for (i = 0; i < priv->ip6_prefix_delegations->len; i++) { + delegation = &g_array_index(priv->ip6_prefix_delegations, IP6PrefixDelegation, i); + if (delegation->device == device) + g_array_remove_index_fast(priv->ip6_prefix_delegations, i); + } } static void -device_ip6_prefix_delegated (NMDevice *device, - NMPlatformIP6Address *prefix, - gpointer user_data) -{ - NMPolicyPrivate *priv = user_data; - NMPolicy *self = _PRIV_TO_SELF (priv); - IP6PrefixDelegation *delegation = NULL; - guint i; - const CList *tmp_list; - NMActiveConnection *ac; - char sbuf[NM_UTILS_INET_ADDRSTRLEN]; - - _LOGI (LOGD_IP6, "ipv6-pd: received a prefix %s/%d from %s", - _nm_utils_inet6_ntop (&prefix->address, sbuf), - prefix->plen, - nm_device_get_iface (device)); - - expire_ip6_delegations (self); - - for (i = 0; i < priv->ip6_prefix_delegations->len; i++) { - /* Look for an already known prefix to update. */ - delegation = &g_array_index (priv->ip6_prefix_delegations, IP6PrefixDelegation, i); - if (IN6_ARE_ADDR_EQUAL (&delegation->prefix.address, &prefix->address)) - break; - } - - if (i == priv->ip6_prefix_delegations->len) { - /* Allocate a delegation delegation for new prefix. */ - g_array_set_size (priv->ip6_prefix_delegations, i + 1); - delegation = &g_array_index (priv->ip6_prefix_delegations, IP6PrefixDelegation, i); - delegation->subnets = g_hash_table_new (nm_direct_hash, NULL); - delegation->next_subnet = 0; - } - - delegation->device = device; - delegation->prefix = *prefix; - - /* The newly activated connections are added to the list beginning, - * so traversing it from the beginning makes it likely for newly - * activated connections that have no subnet assigned to be served - * first. That is a simple yet fair policy, which is good. */ - nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { - NMDevice *to_device; - - to_device = nm_active_connection_get_device (ac); - if (nm_device_needs_ip6_subnet (to_device)) - ip6_subnet_from_delegation (delegation, to_device); - } +device_ip6_prefix_delegated(NMDevice *device, NMPlatformIP6Address *prefix, gpointer user_data) +{ + NMPolicyPrivate * priv = user_data; + NMPolicy * self = _PRIV_TO_SELF(priv); + IP6PrefixDelegation *delegation = NULL; + guint i; + const CList * tmp_list; + NMActiveConnection * ac; + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + + _LOGI(LOGD_IP6, + "ipv6-pd: received a prefix %s/%d from %s", + _nm_utils_inet6_ntop(&prefix->address, sbuf), + prefix->plen, + nm_device_get_iface(device)); + + expire_ip6_delegations(self); + + for (i = 0; i < priv->ip6_prefix_delegations->len; i++) { + /* Look for an already known prefix to update. */ + delegation = &g_array_index(priv->ip6_prefix_delegations, IP6PrefixDelegation, i); + if (IN6_ARE_ADDR_EQUAL(&delegation->prefix.address, &prefix->address)) + break; + } + + if (i == priv->ip6_prefix_delegations->len) { + /* Allocate a delegation for new prefix. */ + g_array_set_size(priv->ip6_prefix_delegations, i + 1); + delegation = &g_array_index(priv->ip6_prefix_delegations, IP6PrefixDelegation, i); + delegation->subnets = g_hash_table_new(nm_direct_hash, NULL); + delegation->next_subnet = 0; + } + + delegation->device = device; + delegation->prefix = *prefix; + + /* The newly activated connections are added to the list beginning, + * so traversing it from the beginning makes it likely for newly + * activated connections that have no subnet assigned to be served + * first. That is a simple yet fair policy, which is good. */ + nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { + NMDevice *to_device; + + to_device = nm_active_connection_get_device(ac); + if (nm_device_needs_ip6_subnet(to_device)) + ip6_subnet_from_delegation(delegation, to_device); + } } static void -device_ip6_subnet_needed (NMDevice *device, - gpointer user_data) +device_ip6_subnet_needed(NMDevice *device, gpointer user_data) { - NMPolicyPrivate *priv = user_data; - NMPolicy *self = _PRIV_TO_SELF (priv); + NMPolicyPrivate *priv = user_data; + NMPolicy * self = _PRIV_TO_SELF(priv); - _LOGD (LOGD_IP6, "ipv6-pd: %s needs a subnet", - nm_device_get_iface (device)); + _LOGD(LOGD_IP6, "ipv6-pd: %s needs a subnet", nm_device_get_iface(device)); - if (!priv->default_ac6) { - /* We request the prefixes when the default IPv6 device is set. */ - _LOGI (LOGD_IP6, "ipv6-pd: no device to obtain a subnet to share on %s from", - nm_device_get_iface (device)); - return; - } - ip6_subnet_from_device (self, get_default_device (self, AF_INET6), device); - nm_device_copy_ip6_dns_config (device, get_default_device (self, AF_INET6)); + if (!priv->default_ac6) { + /* We request the prefixes when the default IPv6 device is set. */ + _LOGI(LOGD_IP6, + "ipv6-pd: no device to obtain a subnet to share on %s from", + nm_device_get_iface(device)); + return; + } + ip6_subnet_from_device(self, get_default_device(self, AF_INET6), device); + nm_device_copy_ip6_dns_config(device, get_default_device(self, AF_INET6)); } /*****************************************************************************/ static NMDevice * -get_default_device (NMPolicy *self, int addr_family) +get_default_device(NMPolicy *self, int addr_family) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - NMActiveConnection *ac; + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + NMActiveConnection *ac; - nm_assert_addr_family (addr_family); + nm_assert_addr_family(addr_family); - ac = (addr_family == AF_INET) ? priv->default_ac4 : priv->default_ac6; + ac = (addr_family == AF_INET) ? priv->default_ac4 : priv->default_ac6; - return ac ? nm_active_connection_get_device (ac) : NULL; + return ac ? nm_active_connection_get_device(ac) : NULL; } static NMActiveConnection * -get_best_active_connection (NMPolicy *self, - int addr_family, - gboolean fully_activated) -{ - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - const CList *tmp_lst; - NMDevice *device; - guint32 best_metric = G_MAXUINT32; - gboolean best_is_fully_activated = FALSE; - NMActiveConnection *best_ac, *prev_ac; - - nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6)); - - /* we prefer the current AC in case of identical metric. - * Hence, try that one first. */ - prev_ac = addr_family == AF_INET - ? (fully_activated ? priv->default_ac4 : priv->activating_ac4) - : (fully_activated ? priv->default_ac6 : priv->activating_ac6); - best_ac = NULL; - - nm_manager_for_each_device (priv->manager, device, tmp_lst) { - NMDeviceState state; - const NMPObject *r; - NMActiveConnection *ac; - NMConnection *connection; - guint32 metric; - gboolean is_fully_activated; - - state = nm_device_get_state (device); - if ( state <= NM_DEVICE_STATE_DISCONNECTED - || state >= NM_DEVICE_STATE_DEACTIVATING) - continue; - - if (nm_device_sys_iface_state_is_external (device)) - continue; - - r = nm_device_get_best_default_route (device, addr_family); - if (r) { - /* NOTE: the best route might have rt_source NM_IP_CONFIG_SOURCE_VPN, - * which means it was injected by a VPN, not added by device. - * - * In this case, is it really the best device? Why do we even need the best - * device?? */ - metric = NMP_OBJECT_CAST_IP_ROUTE (r)->metric; - is_fully_activated = TRUE; - } else if ( !fully_activated - && (connection = nm_device_get_applied_connection (device)) - && nm_utils_connection_has_default_route (connection, addr_family, NULL)) { - metric = nm_device_get_route_metric (device, addr_family); - is_fully_activated = FALSE; - } else - continue; - - ac = (NMActiveConnection *) nm_device_get_act_request (device); - nm_assert (ac); - - if ( !best_ac - || (!best_is_fully_activated && is_fully_activated) - || ( metric < best_metric - || (metric == best_metric && ac == prev_ac))) { - best_ac = ac; - best_metric = metric; - best_is_fully_activated = is_fully_activated; - } - } - - if ( !fully_activated - && best_ac - && best_is_fully_activated) { - /* There's a best activating AC only if the best device - * among all activating and already-activated devices is a - * still-activating one. */ - return NULL; - } - - return best_ac; +get_best_active_connection(NMPolicy *self, int addr_family, gboolean fully_activated) +{ + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + const CList * tmp_lst; + NMDevice * device; + guint32 best_metric = G_MAXUINT32; + gboolean best_is_fully_activated = FALSE; + NMActiveConnection *best_ac, *prev_ac; + + nm_assert(NM_IN_SET(addr_family, AF_INET, AF_INET6)); + + /* we prefer the current AC in case of identical metric. + * Hence, try that one first. */ + prev_ac = addr_family == AF_INET ? (fully_activated ? priv->default_ac4 : priv->activating_ac4) + : (fully_activated ? priv->default_ac6 : priv->activating_ac6); + best_ac = NULL; + + nm_manager_for_each_device (priv->manager, device, tmp_lst) { + NMDeviceState state; + const NMPObject * r; + NMActiveConnection *ac; + NMConnection * connection; + guint32 metric; + gboolean is_fully_activated; + + state = nm_device_get_state(device); + if (state <= NM_DEVICE_STATE_DISCONNECTED || state >= NM_DEVICE_STATE_DEACTIVATING) + continue; + + if (nm_device_sys_iface_state_is_external(device)) + continue; + + r = nm_device_get_best_default_route(device, addr_family); + if (r) { + /* NOTE: the best route might have rt_source NM_IP_CONFIG_SOURCE_VPN, + * which means it was injected by a VPN, not added by device. + * + * In this case, is it really the best device? Why do we even need the best + * device?? */ + metric = NMP_OBJECT_CAST_IP_ROUTE(r)->metric; + is_fully_activated = TRUE; + } else if (!fully_activated && (connection = nm_device_get_applied_connection(device)) + && nm_utils_connection_has_default_route(connection, addr_family, NULL)) { + metric = nm_device_get_route_metric(device, addr_family); + is_fully_activated = FALSE; + } else + continue; + + ac = (NMActiveConnection *) nm_device_get_act_request(device); + nm_assert(ac); + + if (!best_ac || (!best_is_fully_activated && is_fully_activated) + || (metric < best_metric || (metric == best_metric && ac == prev_ac))) { + best_ac = ac; + best_metric = metric; + best_is_fully_activated = is_fully_activated; + } + } + + if (!fully_activated && best_ac && best_is_fully_activated) { + /* There's a best activating AC only if the best device + * among all activating and already-activated devices is a + * still-activating one. */ + return NULL; + } + + return best_ac; } static gboolean -all_devices_not_active (NMPolicy *self) +all_devices_not_active(NMPolicy *self) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - const CList *tmp_lst; - NMDevice *device; + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); + const CList * tmp_lst; + NMDevice * device; - nm_manager_for_each_device (priv->manager, device, tmp_lst) { - NMDeviceState state; + nm_manager_for_each_device (priv->manager, device, tmp_lst) { + NMDeviceState state; - state = nm_device_get_state (device); - if ( state <= NM_DEVICE_STATE_DISCONNECTED - || state >= NM_DEVICE_STATE_DEACTIVATING) { - continue; - } - return FALSE; - } - return TRUE; + state = nm_device_get_state(device); + if (state <= NM_DEVICE_STATE_DISCONNECTED || state >= NM_DEVICE_STATE_DEACTIVATING) { + continue; + } + return FALSE; + } + return TRUE; } #define FALLBACK_HOSTNAME4 "localhost.localdomain" static void -settings_set_hostname_cb (const char *hostname, - gboolean result, - gpointer user_data) -{ - NMPolicy *self = NM_POLICY (user_data); - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - int ret = 0; - int errsv; - - if (!result) { - _LOGT (LOGD_DNS, "set-hostname: hostname set via dbus failed, fallback to \"sethostname\""); - ret = sethostname (hostname, strlen (hostname)); - if (ret != 0) { - errsv = errno; - _LOGW (LOGD_DNS, "set-hostname: couldn't set the system hostname to '%s': (%d) %s", - hostname, errsv, nm_strerror_native (errsv)); - if (errsv == EPERM) - _LOGW (LOGD_DNS, "set-hostname: you should use hostnamed when systemd hardening is in effect!"); - } - } - - priv->changing_hostname = FALSE; - if (!ret) - nm_dispatcher_call_hostname (NULL, NULL, NULL); - g_object_unref (self); +settings_set_hostname_cb(const char *hostname, gboolean result, gpointer user_data) +{ + NMPolicy * self = NM_POLICY(user_data); + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); + int ret = 0; + int errsv; + + if (!result) { + _LOGT(LOGD_DNS, "set-hostname: hostname set via dbus failed, fallback to \"sethostname\""); + ret = sethostname(hostname, strlen(hostname)); + if (ret != 0) { + errsv = errno; + _LOGW(LOGD_DNS, + "set-hostname: couldn't set the system hostname to '%s': (%d) %s", + hostname, + errsv, + nm_strerror_native(errsv)); + if (errsv == EPERM) + _LOGW( + LOGD_DNS, + "set-hostname: you should use hostnamed when systemd hardening is in effect!"); + } + } + + priv->changing_hostname = FALSE; + if (!ret) + nm_dispatcher_call_hostname(NULL, NULL, NULL); + g_object_unref(self); } #define HOST_NAME_BUFSIZE (HOST_NAME_MAX + 2) static char * -_get_hostname (NMPolicy *self) -{ - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - char *hostname = NULL; - int errsv; - - /* If there is an in-progress hostname change, return - * the last hostname set as would be set soon... - */ - if (priv->changing_hostname) { - _LOGT (LOGD_DNS, "get-hostname: \"%s\" (last on set)", priv->last_hostname); - return g_strdup (priv->last_hostname); - } - - /* try to get the hostname via dbus... */ - if (nm_hostname_manager_get_transient_hostname (priv->hostname_manager, &hostname)) { - _LOGT (LOGD_DNS, "get-hostname: \"%s\" (from dbus)", hostname); - return hostname; - } - - /* ...or retrieve it by yourself */ - hostname = g_malloc (HOST_NAME_BUFSIZE); - if (gethostname (hostname, HOST_NAME_BUFSIZE -1) != 0) { - errsv = errno; - _LOGT (LOGD_DNS, "get-hostname: couldn't get the system hostname: (%d) %s", - errsv, nm_strerror_native (errsv)); - g_free (hostname); - return NULL; - } - - /* the name may be truncated... */ - hostname[HOST_NAME_BUFSIZE - 1] = '\0'; - if (strlen (hostname) >= HOST_NAME_BUFSIZE -1) { - _LOGT (LOGD_DNS, "get-hostname: system hostname too long: \"%s\"", hostname); - g_free (hostname); - return NULL; - } - - _LOGT (LOGD_DNS, "get-hostname: \"%s\"", hostname); - return hostname; +_get_hostname(NMPolicy *self) +{ + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); + char * hostname = NULL; + int errsv; + + /* If there is an in-progress hostname change, return + * the last hostname set as would be set soon... + */ + if (priv->changing_hostname) { + _LOGT(LOGD_DNS, "get-hostname: \"%s\" (last on set)", priv->last_hostname); + return g_strdup(priv->last_hostname); + } + + /* try to get the hostname via dbus... */ + if (nm_hostname_manager_get_transient_hostname(priv->hostname_manager, &hostname)) { + _LOGT(LOGD_DNS, "get-hostname: \"%s\" (from dbus)", hostname); + return hostname; + } + + /* ...or retrieve it by yourself */ + hostname = g_malloc(HOST_NAME_BUFSIZE); + if (gethostname(hostname, HOST_NAME_BUFSIZE - 1) != 0) { + errsv = errno; + _LOGT(LOGD_DNS, + "get-hostname: couldn't get the system hostname: (%d) %s", + errsv, + nm_strerror_native(errsv)); + g_free(hostname); + return NULL; + } + + /* the name may be truncated... */ + hostname[HOST_NAME_BUFSIZE - 1] = '\0'; + if (strlen(hostname) >= HOST_NAME_BUFSIZE - 1) { + _LOGT(LOGD_DNS, "get-hostname: system hostname too long: \"%s\"", hostname); + g_free(hostname); + return NULL; + } + + _LOGT(LOGD_DNS, "get-hostname: \"%s\"", hostname); + return hostname; } static void -_set_hostname (NMPolicy *self, - const char *new_hostname, - const char *msg) -{ - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - gs_free char *old_hostname = NULL; - const char *name; - - /* The incoming hostname *can* be NULL, which will get translated to - * 'localhost.localdomain' or such in the hostname policy code, but we - * keep cur_hostname = NULL in the case because we need to know that - * there was no valid hostname to start with. - */ - - /* Clear lookup addresses if we have a hostname, so that we don't - * restart the reverse lookup thread later. - */ - if (new_hostname) - g_clear_object (&priv->lookup.addr); - - /* Update the DNS only if the hostname is actually - * going to change. - */ - if (!nm_streq0 (priv->cur_hostname, new_hostname)) { - g_free (priv->cur_hostname); - priv->cur_hostname = g_strdup (new_hostname); - - /* Notify the DNS manager of the hostname change so that the domain part, if - * present, can be added to the search list. - */ - nm_dns_manager_set_hostname (priv->dns_manager, priv->cur_hostname, - all_devices_not_active (self)); - } - - /* Finally, set kernel hostname */ - if (!new_hostname) - name = FALLBACK_HOSTNAME4; - else if (!new_hostname[0]) { - g_warn_if_reached (); - name = FALLBACK_HOSTNAME4; - } else - name = new_hostname; - - /* Don't set the hostname if it isn't actually changing */ - if ( (old_hostname = _get_hostname (self)) - && (nm_streq (name, old_hostname))) { - _LOGT (LOGD_DNS, "set-hostname: hostname already set to '%s' (%s)", name, msg); - return; - } - - /* Keep track of the last set hostname */ - g_free (priv->last_hostname); - priv->last_hostname = g_strdup (name); - priv->changing_hostname = TRUE; - - _LOGI (LOGD_DNS, "set-hostname: set hostname to '%s' (%s)", name, msg); - - /* Ask NMSettings to update the transient hostname using its - * systemd-hostnamed proxy */ - nm_hostname_manager_set_transient_hostname (priv->hostname_manager, - name, - settings_set_hostname_cb, - g_object_ref (self)); +_set_hostname(NMPolicy *self, const char *new_hostname, const char *msg) +{ + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); + gs_free char * old_hostname = NULL; + const char * name; + + /* The incoming hostname *can* be NULL, which will get translated to + * 'localhost.localdomain' or such in the hostname policy code, but we + * keep cur_hostname = NULL in the case because we need to know that + * there was no valid hostname to start with. + */ + + /* Clear lookup addresses if we have a hostname, so that we don't + * restart the reverse lookup thread later. + */ + if (new_hostname) + g_clear_object(&priv->lookup.addr); + + /* Update the DNS only if the hostname is actually + * going to change. + */ + if (!nm_streq0(priv->cur_hostname, new_hostname)) { + g_free(priv->cur_hostname); + priv->cur_hostname = g_strdup(new_hostname); + + /* Notify the DNS manager of the hostname change so that the domain part, if + * present, can be added to the search list. + */ + nm_dns_manager_set_hostname(priv->dns_manager, + priv->cur_hostname, + all_devices_not_active(self)); + } + + /* Finally, set kernel hostname */ + if (!new_hostname) + name = FALLBACK_HOSTNAME4; + else if (!new_hostname[0]) { + g_warn_if_reached(); + name = FALLBACK_HOSTNAME4; + } else + name = new_hostname; + + /* Don't set the hostname if it isn't actually changing */ + if ((old_hostname = _get_hostname(self)) && (nm_streq(name, old_hostname))) { + _LOGT(LOGD_DNS, "set-hostname: hostname already set to '%s' (%s)", name, msg); + return; + } + + /* Keep track of the last set hostname */ + g_free(priv->last_hostname); + priv->last_hostname = g_strdup(name); + priv->changing_hostname = TRUE; + + _LOGI(LOGD_DNS, "set-hostname: set hostname to '%s' (%s)", name, msg); + + /* Ask NMSettings to update the transient hostname using its + * systemd-hostnamed proxy */ + nm_hostname_manager_set_transient_hostname(priv->hostname_manager, + name, + settings_set_hostname_cb, + g_object_ref(self)); } static void -lookup_callback (GObject *source, - GAsyncResult *result, - gpointer user_data) +lookup_callback(GObject *source, GAsyncResult *result, gpointer user_data) { - NMPolicy *self; - NMPolicyPrivate *priv; - gs_free char *hostname = NULL; - gs_free_error GError *error = NULL; + NMPolicy * self; + NMPolicyPrivate *priv; + gs_free char * hostname = NULL; + gs_free_error GError *error = NULL; - hostname = g_resolver_lookup_by_address_finish (G_RESOLVER (source), result, &error); - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; + hostname = g_resolver_lookup_by_address_finish(G_RESOLVER(source), result, &error); + if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; - self = user_data; - priv = NM_POLICY_GET_PRIVATE (self); + self = user_data; + priv = NM_POLICY_GET_PRIVATE(self); - g_clear_object (&priv->lookup.cancellable); + g_clear_object(&priv->lookup.cancellable); - if (hostname) - _set_hostname (self, hostname, "from address lookup"); - else - _set_hostname (self, NULL, error->message); + if (hostname) + _set_hostname(self, hostname, "from address lookup"); + else + _set_hostname(self, NULL, error->message); } static void -lookup_by_address (NMPolicy *self) +lookup_by_address(NMPolicy *self) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); - nm_clear_g_cancellable (&priv->lookup.cancellable); - priv->lookup.cancellable = g_cancellable_new (); - g_resolver_lookup_by_address_async (priv->lookup.resolver, - priv->lookup.addr, - priv->lookup.cancellable, - lookup_callback, self); + nm_clear_g_cancellable(&priv->lookup.cancellable); + priv->lookup.cancellable = g_cancellable_new(); + g_resolver_lookup_by_address_async(priv->lookup.resolver, + priv->lookup.addr, + priv->lookup.cancellable, + lookup_callback, + self); } static void -update_system_hostname (NMPolicy *self, const char *msg) -{ - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - const char *configured_hostname; - gs_free char *temp_hostname = NULL; - const char *dhcp_hostname, *p; - NMIP4Config *ip4_config; - NMIP6Config *ip6_config; - gboolean external_hostname = FALSE; - const NMPlatformIP4Address *addr4; - const NMPlatformIP6Address *addr6; - NMDevice *device; - NMDhcpConfig *dhcp_config; - - g_return_if_fail (self != NULL); - - if (priv->hostname_mode == NM_POLICY_HOSTNAME_MODE_NONE) { - _LOGT (LOGD_DNS, "set-hostname: hostname is unmanaged"); - return; - } - - _LOGT (LOGD_DNS, "set-hostname: updating hostname (%s)", msg); - - nm_clear_g_cancellable (&priv->lookup.cancellable); - - /* Check if the hostname was set externally to NM, so that in that case - * we can avoid to fallback to the one we got when we started. - * Consider "not specific" hostnames as equal. */ - if ( (temp_hostname = _get_hostname (self)) - && !nm_streq0 (temp_hostname, priv->last_hostname) - && ( nm_utils_is_specific_hostname (temp_hostname) - || nm_utils_is_specific_hostname (priv->last_hostname))) { - external_hostname = TRUE; - _LOGI (LOGD_DNS, "set-hostname: current hostname was changed outside NetworkManager: '%s'", - temp_hostname); - priv->dhcp_hostname = FALSE; - - if (!nm_utils_is_specific_hostname (temp_hostname)) - nm_clear_g_free (&temp_hostname); - if (!nm_streq0 (temp_hostname, priv->orig_hostname)) { - /* Update original (fallback) hostname */ - g_free (priv->orig_hostname); - priv->orig_hostname = g_steal_pointer (&temp_hostname); - _LOGT (LOGD_DNS, "hostname-original: update to %s%s%s", - NM_PRINT_FMT_QUOTE_STRING (priv->orig_hostname)); - } - } - - /* Hostname precedence order: - * - * 1) a configured hostname (from settings) - * 2) automatic hostname from the default device's config (DHCP, VPN, etc) - * 3) the last hostname set outside NM - * 4) reverse-DNS of the best device's IPv4 address - * - */ - - /* Try a persistent hostname first */ - configured_hostname = nm_hostname_manager_get_hostname (priv->hostname_manager); - if (configured_hostname && nm_utils_is_specific_hostname (configured_hostname)) { - _set_hostname (self, configured_hostname, "from system configuration"); - priv->dhcp_hostname = FALSE; - return; - } - - if (priv->default_ac4) { - /* Grab a hostname out of the device's DHCP4 config */ - dhcp_config = nm_device_get_dhcp_config (get_default_device (self, AF_INET), AF_INET); - if (dhcp_config) { - dhcp_hostname = nm_dhcp_config_get_option (dhcp_config, "host_name"); - if (dhcp_hostname && dhcp_hostname[0]) { - p = nm_str_skip_leading_spaces (dhcp_hostname); - if (p[0]) { - _set_hostname (self, p, "from DHCPv4"); - priv->dhcp_hostname = TRUE; - return; - } - _LOGW (LOGD_DNS, "set-hostname: DHCPv4-provided hostname '%s' looks invalid; ignoring it", - dhcp_hostname); - } - } - } - - if (priv->default_ac6) { - /* Grab a hostname out of the device's DHCP6 config */ - dhcp_config = nm_device_get_dhcp_config (get_default_device (self, AF_INET6), AF_INET6); - if (dhcp_config) { - dhcp_hostname = nm_dhcp_config_get_option (dhcp_config, "fqdn_fqdn"); - if (dhcp_hostname && dhcp_hostname[0]) { - p = nm_str_skip_leading_spaces (dhcp_hostname); - if (p[0]) { - _set_hostname (self, p, "from DHCPv6"); - priv->dhcp_hostname = TRUE; - return; - } - _LOGW (LOGD_DNS, "set-hostname: DHCPv6-provided hostname '%s' looks invalid; ignoring it", - dhcp_hostname); - } - } - } - - /* If an hostname was set outside NetworkManager keep it */ - if (external_hostname) - return; - - if (priv->hostname_mode == NM_POLICY_HOSTNAME_MODE_DHCP) { - /* In dhcp hostname-mode, the hostname is updated only if it comes from - * a DHCP host-name option: if last set was from a host-name option and - * we are here than that connection is gone (with its host-name option), - * so reset the hostname to the previous value - */ - if (priv->dhcp_hostname) { - _set_hostname (self, priv->orig_hostname, "reset dhcp hostname"); - priv->dhcp_hostname = FALSE; - } - return; - } - - priv->dhcp_hostname = FALSE; - - if (!priv->default_ac4 && !priv->default_ac6) { - /* No best device; fall back to the last hostname set externally - * to NM or if there wasn't one, 'localhost.localdomain' - */ - _set_hostname (self, priv->orig_hostname, "no default device"); - return; - } - - /* If no automatically-configured hostname, try using the last hostname - * set externally to NM - */ - if (priv->orig_hostname) { - _set_hostname (self, priv->orig_hostname, "from system startup"); - return; - } - - /* No configured hostname, no automatically determined hostname, and no - * bootup hostname. Start reverse DNS of the current IPv4 or IPv6 address. - */ - device = get_default_device (self, AF_INET); - ip4_config = device ? nm_device_get_ip4_config (device) : NULL; - - device = get_default_device (self, AF_INET6); - ip6_config = device ? nm_device_get_ip6_config (device) : NULL; - - if ( ip4_config - && (addr4 = nm_ip4_config_get_first_address (ip4_config))) { - g_clear_object (&priv->lookup.addr); - priv->lookup.addr = g_inet_address_new_from_bytes ((guint8 *) &addr4->address, - G_SOCKET_FAMILY_IPV4); - } else if ( ip6_config - && (addr6 = nm_ip6_config_get_first_address (ip6_config))) { - g_clear_object (&priv->lookup.addr); - priv->lookup.addr = g_inet_address_new_from_bytes ((guint8 *) &addr6->address, - G_SOCKET_FAMILY_IPV6); - } else { - /* No valid IP config; fall back to localhost.localdomain */ - _set_hostname (self, NULL, "no IP config"); - return; - } - - lookup_by_address (self); +update_system_hostname(NMPolicy *self, const char *msg) +{ + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + const char * configured_hostname; + gs_free char * temp_hostname = NULL; + const char * dhcp_hostname, *p; + NMIP4Config * ip4_config; + NMIP6Config * ip6_config; + gboolean external_hostname = FALSE; + const NMPlatformIP4Address *addr4; + const NMPlatformIP6Address *addr6; + NMDevice * device; + NMDhcpConfig * dhcp_config; + + g_return_if_fail(self != NULL); + + if (priv->hostname_mode == NM_POLICY_HOSTNAME_MODE_NONE) { + _LOGT(LOGD_DNS, "set-hostname: hostname is unmanaged"); + return; + } + + _LOGT(LOGD_DNS, "set-hostname: updating hostname (%s)", msg); + + nm_clear_g_cancellable(&priv->lookup.cancellable); + + /* Check if the hostname was set externally to NM, so that in that case + * we can avoid to fallback to the one we got when we started. + * Consider "not specific" hostnames as equal. */ + if ((temp_hostname = _get_hostname(self)) && !nm_streq0(temp_hostname, priv->last_hostname) + && (nm_utils_is_specific_hostname(temp_hostname) + || nm_utils_is_specific_hostname(priv->last_hostname))) { + external_hostname = TRUE; + _LOGI(LOGD_DNS, + "set-hostname: current hostname was changed outside NetworkManager: '%s'", + temp_hostname); + priv->dhcp_hostname = FALSE; + + if (!nm_utils_is_specific_hostname(temp_hostname)) + nm_clear_g_free(&temp_hostname); + if (!nm_streq0(temp_hostname, priv->orig_hostname)) { + /* Update original (fallback) hostname */ + g_free(priv->orig_hostname); + priv->orig_hostname = g_steal_pointer(&temp_hostname); + _LOGT(LOGD_DNS, + "hostname-original: update to %s%s%s", + NM_PRINT_FMT_QUOTE_STRING(priv->orig_hostname)); + } + } + + /* Hostname precedence order: + * + * 1) a configured hostname (from settings) + * 2) automatic hostname from the default device's config (DHCP, VPN, etc) + * 3) the last hostname set outside NM + * 4) reverse-DNS of the best device's IPv4 address + * + */ + + /* Try a persistent hostname first */ + configured_hostname = nm_hostname_manager_get_hostname(priv->hostname_manager); + if (configured_hostname && nm_utils_is_specific_hostname(configured_hostname)) { + _set_hostname(self, configured_hostname, "from system configuration"); + priv->dhcp_hostname = FALSE; + return; + } + + if (priv->default_ac4) { + /* Grab a hostname out of the device's DHCP4 config */ + dhcp_config = nm_device_get_dhcp_config(get_default_device(self, AF_INET), AF_INET); + if (dhcp_config) { + dhcp_hostname = nm_dhcp_config_get_option(dhcp_config, "host_name"); + if (dhcp_hostname && dhcp_hostname[0]) { + p = nm_str_skip_leading_spaces(dhcp_hostname); + if (p[0]) { + _set_hostname(self, p, "from DHCPv4"); + priv->dhcp_hostname = TRUE; + return; + } + _LOGW(LOGD_DNS, + "set-hostname: DHCPv4-provided hostname '%s' looks invalid; ignoring it", + dhcp_hostname); + } + } + } + + if (priv->default_ac6) { + /* Grab a hostname out of the device's DHCP6 config */ + dhcp_config = nm_device_get_dhcp_config(get_default_device(self, AF_INET6), AF_INET6); + if (dhcp_config) { + dhcp_hostname = nm_dhcp_config_get_option(dhcp_config, "fqdn_fqdn"); + if (dhcp_hostname && dhcp_hostname[0]) { + p = nm_str_skip_leading_spaces(dhcp_hostname); + if (p[0]) { + _set_hostname(self, p, "from DHCPv6"); + priv->dhcp_hostname = TRUE; + return; + } + _LOGW(LOGD_DNS, + "set-hostname: DHCPv6-provided hostname '%s' looks invalid; ignoring it", + dhcp_hostname); + } + } + } + + /* If an hostname was set outside NetworkManager keep it */ + if (external_hostname) + return; + + if (priv->hostname_mode == NM_POLICY_HOSTNAME_MODE_DHCP) { + /* In dhcp hostname-mode, the hostname is updated only if it comes from + * a DHCP host-name option: if last set was from a host-name option and + * we are here than that connection is gone (with its host-name option), + * so reset the hostname to the previous value + */ + if (priv->dhcp_hostname) { + _set_hostname(self, priv->orig_hostname, "reset dhcp hostname"); + priv->dhcp_hostname = FALSE; + } + return; + } + + priv->dhcp_hostname = FALSE; + + if (!priv->default_ac4 && !priv->default_ac6) { + /* No best device; fall back to the last hostname set externally + * to NM or if there wasn't one, 'localhost.localdomain' + */ + _set_hostname(self, priv->orig_hostname, "no default device"); + return; + } + + /* If no automatically-configured hostname, try using the last hostname + * set externally to NM + */ + if (priv->orig_hostname) { + _set_hostname(self, priv->orig_hostname, "from system startup"); + return; + } + + /* No configured hostname, no automatically determined hostname, and no + * bootup hostname. Start reverse DNS of the current IPv4 or IPv6 address. + */ + device = get_default_device(self, AF_INET); + ip4_config = device ? nm_device_get_ip4_config(device) : NULL; + + device = get_default_device(self, AF_INET6); + ip6_config = device ? nm_device_get_ip6_config(device) : NULL; + + if (ip4_config && (addr4 = nm_ip4_config_get_first_address(ip4_config))) { + g_clear_object(&priv->lookup.addr); + priv->lookup.addr = + g_inet_address_new_from_bytes((guint8 *) &addr4->address, G_SOCKET_FAMILY_IPV4); + } else if (ip6_config && (addr6 = nm_ip6_config_get_first_address(ip6_config))) { + g_clear_object(&priv->lookup.addr); + priv->lookup.addr = + g_inet_address_new_from_bytes((guint8 *) &addr6->address, G_SOCKET_FAMILY_IPV6); + } else { + /* No valid IP config; fall back to localhost.localdomain */ + _set_hostname(self, NULL, "no IP config"); + return; + } + + lookup_by_address(self); } static void -update_default_ac (NMPolicy *self, - int addr_family, - NMActiveConnection *best) +update_default_ac(NMPolicy *self, int addr_family, NMActiveConnection *best) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - const CList *tmp_list; - NMActiveConnection *ac; + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + const CList * tmp_list; + NMActiveConnection *ac; - /* Clear the 'default[6]' flag on all active connections that aren't the new - * default active connection. We'll set the new default after; this ensures - * we don't ever have two marked 'default[6]' simultaneously. - */ - nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { - if (ac != best) - nm_active_connection_set_default (ac, addr_family, FALSE); - } + /* Clear the 'default[6]' flag on all active connections that aren't the new + * default active connection. We'll set the new default after; this ensures + * we don't ever have two marked 'default[6]' simultaneously. + */ + nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { + if (ac != best) + nm_active_connection_set_default(ac, addr_family, FALSE); + } - /* Mark new default active connection */ - if (best) - nm_active_connection_set_default (best, addr_family, TRUE); + /* Mark new default active connection */ + if (best) + nm_active_connection_set_default(best, addr_family, TRUE); } static gpointer -get_best_ip_config (NMPolicy *self, - int addr_family, - const char **out_ip_iface, - NMActiveConnection **out_ac, - NMDevice **out_device, - NMVpnConnection **out_vpn) -{ - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - gpointer conf, best_conf = NULL; - const CList *tmp_list; - NMActiveConnection *ac; - guint64 best_metric = G_MAXUINT64; - NMVpnConnection *best_vpn = NULL; - - nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6)); - - nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { - NMVpnConnection *candidate; - NMVpnConnectionState vpn_state; - const NMPObject *obj; - guint32 metric; - - if (!NM_IS_VPN_CONNECTION (ac)) - continue; - - candidate = NM_VPN_CONNECTION (ac); - - vpn_state = nm_vpn_connection_get_vpn_state (candidate); - if (vpn_state != NM_VPN_CONNECTION_STATE_ACTIVATED) - continue; - - if (addr_family == AF_INET) - conf = nm_vpn_connection_get_ip4_config (candidate); - else - conf = nm_vpn_connection_get_ip6_config (candidate); - if (!conf) - continue; - - if (addr_family == AF_INET) - obj = nm_ip4_config_best_default_route_get (conf); - else - obj = nm_ip6_config_best_default_route_get (conf); - if (!obj) - continue; - - metric = NMP_OBJECT_CAST_IPX_ROUTE (obj)->rx.metric; - if (metric <= best_metric) { - best_metric = metric; - best_conf = conf; - best_vpn = candidate; - } - } - - if (best_metric != G_MAXUINT64) { - NM_SET_OUT (out_device, NULL); - NM_SET_OUT (out_vpn, best_vpn); - NM_SET_OUT (out_ac, NM_ACTIVE_CONNECTION (best_vpn)); - NM_SET_OUT (out_ip_iface, nm_vpn_connection_get_ip_iface (best_vpn, TRUE)); - return best_conf; - } - - ac = get_best_active_connection (self, addr_family, TRUE); - if (ac) { - NMDevice *device = nm_active_connection_get_device (ac); - - nm_assert (device); - - if (addr_family == AF_INET) - conf = nm_device_get_ip4_config (device); - else - conf = nm_device_get_ip6_config (device); - - NM_SET_OUT (out_device, device); - NM_SET_OUT (out_vpn, NULL); - NM_SET_OUT (out_ac, ac); - NM_SET_OUT (out_ip_iface, nm_device_get_ip_iface (device)); - return conf; - } - - NM_SET_OUT (out_device, NULL); - NM_SET_OUT (out_vpn, NULL); - NM_SET_OUT (out_ac, NULL); - NM_SET_OUT (out_ip_iface, NULL); - return NULL; +get_best_ip_config(NMPolicy * self, + int addr_family, + const char ** out_ip_iface, + NMActiveConnection **out_ac, + NMDevice ** out_device, + NMVpnConnection ** out_vpn) +{ + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + gpointer conf, best_conf = NULL; + const CList * tmp_list; + NMActiveConnection *ac; + guint64 best_metric = G_MAXUINT64; + NMVpnConnection * best_vpn = NULL; + + nm_assert(NM_IN_SET(addr_family, AF_INET, AF_INET6)); + + nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { + NMVpnConnection * candidate; + NMVpnConnectionState vpn_state; + const NMPObject * obj; + guint32 metric; + + if (!NM_IS_VPN_CONNECTION(ac)) + continue; + + candidate = NM_VPN_CONNECTION(ac); + + vpn_state = nm_vpn_connection_get_vpn_state(candidate); + if (vpn_state != NM_VPN_CONNECTION_STATE_ACTIVATED) + continue; + + if (addr_family == AF_INET) + conf = nm_vpn_connection_get_ip4_config(candidate); + else + conf = nm_vpn_connection_get_ip6_config(candidate); + if (!conf) + continue; + + if (addr_family == AF_INET) + obj = nm_ip4_config_best_default_route_get(conf); + else + obj = nm_ip6_config_best_default_route_get(conf); + if (!obj) + continue; + + metric = NMP_OBJECT_CAST_IPX_ROUTE(obj)->rx.metric; + if (metric <= best_metric) { + best_metric = metric; + best_conf = conf; + best_vpn = candidate; + } + } + + if (best_metric != G_MAXUINT64) { + NM_SET_OUT(out_device, NULL); + NM_SET_OUT(out_vpn, best_vpn); + NM_SET_OUT(out_ac, NM_ACTIVE_CONNECTION(best_vpn)); + NM_SET_OUT(out_ip_iface, nm_vpn_connection_get_ip_iface(best_vpn, TRUE)); + return best_conf; + } + + ac = get_best_active_connection(self, addr_family, TRUE); + if (ac) { + NMDevice *device = nm_active_connection_get_device(ac); + + nm_assert(device); + + if (addr_family == AF_INET) + conf = nm_device_get_ip4_config(device); + else + conf = nm_device_get_ip6_config(device); + + NM_SET_OUT(out_device, device); + NM_SET_OUT(out_vpn, NULL); + NM_SET_OUT(out_ac, ac); + NM_SET_OUT(out_ip_iface, nm_device_get_ip_iface(device)); + return conf; + } + + NM_SET_OUT(out_device, NULL); + NM_SET_OUT(out_vpn, NULL); + NM_SET_OUT(out_ac, NULL); + NM_SET_OUT(out_ip_iface, NULL); + return NULL; } static void -update_ip4_routing (NMPolicy *self, gboolean force_update) -{ - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - NMDevice *best = NULL; - NMVpnConnection *vpn = NULL; - NMActiveConnection *best_ac = NULL; - const char *ip_iface = NULL; - const CList *tmp_list; - NMActiveConnection *ac; - - /* Note that we might have an IPv4 VPN tunneled over an IPv6-only device, - * so we can get (vpn != NULL && best == NULL). - */ - if (!get_best_ip_config (self, AF_INET, &ip_iface, &best_ac, &best, &vpn)) { - if (nm_clear_g_object (&priv->default_ac4)) { - _LOGt (LOGD_DNS, "set-default-ac-4: %p", NULL); - _notify (self, PROP_DEFAULT_IP4_AC); - } - return; - } - g_assert ((best || vpn) && best_ac); - - if ( !force_update - && best_ac - && best_ac == priv->default_ac4) - return; - - if (best) { - nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { - if ( NM_IS_VPN_CONNECTION (ac) - && nm_vpn_connection_get_ip4_config (NM_VPN_CONNECTION (ac)) - && !nm_active_connection_get_device (ac)) - nm_active_connection_set_device (ac, best); - } - } - - update_default_ac (self, AF_INET, best_ac); - - if (!nm_g_object_ref_set (&priv->default_ac4, best_ac)) - return; - _LOGt (LOGD_DNS, "set-default-ac-4: %p", priv->default_ac4); - - _LOGI (LOGD_CORE, "set '%s' (%s) as default for IPv4 routing and DNS", - nm_connection_get_id (nm_active_connection_get_applied_connection (best_ac)), - ip_iface); - _notify (self, PROP_DEFAULT_IP4_AC); +update_ip4_routing(NMPolicy *self, gboolean force_update) +{ + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + NMDevice * best = NULL; + NMVpnConnection * vpn = NULL; + NMActiveConnection *best_ac = NULL; + const char * ip_iface = NULL; + const CList * tmp_list; + NMActiveConnection *ac; + + /* Note that we might have an IPv4 VPN tunneled over an IPv6-only device, + * so we can get (vpn != NULL && best == NULL). + */ + if (!get_best_ip_config(self, AF_INET, &ip_iface, &best_ac, &best, &vpn)) { + if (nm_clear_g_object(&priv->default_ac4)) { + _LOGt(LOGD_DNS, "set-default-ac-4: %p", NULL); + _notify(self, PROP_DEFAULT_IP4_AC); + } + return; + } + g_assert((best || vpn) && best_ac); + + if (!force_update && best_ac && best_ac == priv->default_ac4) + return; + + if (best) { + nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { + if (NM_IS_VPN_CONNECTION(ac) && nm_vpn_connection_get_ip4_config(NM_VPN_CONNECTION(ac)) + && !nm_active_connection_get_device(ac)) + nm_active_connection_set_device(ac, best); + } + } + + update_default_ac(self, AF_INET, best_ac); + + if (!nm_g_object_ref_set(&priv->default_ac4, best_ac)) + return; + _LOGt(LOGD_DNS, "set-default-ac-4: %p", priv->default_ac4); + + _LOGI(LOGD_CORE, + "set '%s' (%s) as default for IPv4 routing and DNS", + nm_connection_get_id(nm_active_connection_get_applied_connection(best_ac)), + ip_iface); + _notify(self, PROP_DEFAULT_IP4_AC); } static void -update_ip6_prefix_delegation (NMPolicy *self) +update_ip6_prefix_delegation(NMPolicy *self) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - NMDevice *device; - NMActiveConnection *ac; - const CList *tmp_list; + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + NMDevice * device; + NMActiveConnection *ac; + const CList * tmp_list; - /* There's new default IPv6 connection, try to get a prefix for everyone. */ - nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { - device = nm_active_connection_get_device (ac); - if (device && nm_device_needs_ip6_subnet (device)) - ip6_subnet_from_device (self, get_default_device (self, AF_INET6), device); - } + /* There's new default IPv6 connection, try to get a prefix for everyone. */ + nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { + device = nm_active_connection_get_device(ac); + if (device && nm_device_needs_ip6_subnet(device)) + ip6_subnet_from_device(self, get_default_device(self, AF_INET6), device); + } } static void -update_ip6_routing (NMPolicy *self, gboolean force_update) -{ - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - NMDevice *best = NULL; - NMVpnConnection *vpn = NULL; - NMActiveConnection *best_ac = NULL; - const char *ip_iface = NULL; - NMActiveConnection *ac; - const CList *tmp_list; - - /* Note that we might have an IPv6 VPN tunneled over an IPv4-only device, - * so we can get (vpn != NULL && best == NULL). - */ - if (!get_best_ip_config (self, AF_INET6, &ip_iface, &best_ac, &best, &vpn)) { - if (nm_clear_g_object (&priv->default_ac6)) { - _LOGt (LOGD_DNS, "set-default-ac-6: %p", NULL); - _notify (self, PROP_DEFAULT_IP6_AC); - } - return; - } - g_assert ((best || vpn) && best_ac); - - if ( !force_update - && best_ac - && best_ac == priv->default_ac6) - return; - - if (best) { - nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { - if ( NM_IS_VPN_CONNECTION (ac) - && nm_vpn_connection_get_ip6_config (NM_VPN_CONNECTION (ac)) - && !nm_active_connection_get_device (ac)) - nm_active_connection_set_device (ac, best); - } - } - - update_default_ac (self, AF_INET6, best_ac); - - if (!nm_g_object_ref_set (&priv->default_ac6, best_ac)) - return; - _LOGt (LOGD_DNS, "set-default-ac-6: %p", priv->default_ac6); - - update_ip6_prefix_delegation (self); - - _LOGI (LOGD_CORE, "set '%s' (%s) as default for IPv6 routing and DNS", - nm_connection_get_id (nm_active_connection_get_applied_connection (best_ac)), - ip_iface); - _notify (self, PROP_DEFAULT_IP6_AC); +update_ip6_routing(NMPolicy *self, gboolean force_update) +{ + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + NMDevice * best = NULL; + NMVpnConnection * vpn = NULL; + NMActiveConnection *best_ac = NULL; + const char * ip_iface = NULL; + NMActiveConnection *ac; + const CList * tmp_list; + + /* Note that we might have an IPv6 VPN tunneled over an IPv4-only device, + * so we can get (vpn != NULL && best == NULL). + */ + if (!get_best_ip_config(self, AF_INET6, &ip_iface, &best_ac, &best, &vpn)) { + if (nm_clear_g_object(&priv->default_ac6)) { + _LOGt(LOGD_DNS, "set-default-ac-6: %p", NULL); + _notify(self, PROP_DEFAULT_IP6_AC); + } + return; + } + g_assert((best || vpn) && best_ac); + + if (!force_update && best_ac && best_ac == priv->default_ac6) + return; + + if (best) { + nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { + if (NM_IS_VPN_CONNECTION(ac) && nm_vpn_connection_get_ip6_config(NM_VPN_CONNECTION(ac)) + && !nm_active_connection_get_device(ac)) + nm_active_connection_set_device(ac, best); + } + } + + update_default_ac(self, AF_INET6, best_ac); + + if (!nm_g_object_ref_set(&priv->default_ac6, best_ac)) + return; + _LOGt(LOGD_DNS, "set-default-ac-6: %p", priv->default_ac6); + + update_ip6_prefix_delegation(self); + + _LOGI(LOGD_CORE, + "set '%s' (%s) as default for IPv6 routing and DNS", + nm_connection_get_id(nm_active_connection_get_applied_connection(best_ac)), + ip_iface); + _notify(self, PROP_DEFAULT_IP6_AC); } static void -update_ip_dns (NMPolicy *self, int addr_family, NMDevice *changed_device) -{ - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - gpointer ip_config; - const char *ip_iface = NULL; - NMVpnConnection *vpn = NULL; - NMDevice *device = NULL; - - nm_assert_addr_family (addr_family); - - ip_config = get_best_ip_config (self, addr_family, &ip_iface, NULL, &device, &vpn); - if (ip_config) { - /* Tell the DNS manager this config is preferred by re-adding it with - * a different IP config type. - */ - _dns_manager_set_ip_config (NM_POLICY_GET_PRIVATE (self)->dns_manager, - ip_config, - ( vpn - || (device && nm_device_is_vpn (device))) - ? NM_DNS_IP_CONFIG_TYPE_VPN - : NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE, - device); - } - - if (addr_family == AF_INET6) { - NMActiveConnection *ac; - const CList *tmp_list; - - /* Tell devices needing a subnet about the new DNS configuration */ - nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { - device = nm_active_connection_get_device (ac); - if ( device - && device != changed_device - && nm_device_needs_ip6_subnet (device)) - nm_device_copy_ip6_dns_config (device, get_default_device (self, AF_INET6)); - } - } +update_ip_dns(NMPolicy *self, int addr_family, NMDevice *changed_device) +{ + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); + gpointer ip_config; + const char * ip_iface = NULL; + NMVpnConnection *vpn = NULL; + NMDevice * device = NULL; + + nm_assert_addr_family(addr_family); + + ip_config = get_best_ip_config(self, addr_family, &ip_iface, NULL, &device, &vpn); + if (ip_config) { + /* Tell the DNS manager this config is preferred by re-adding it with + * a different IP config type. + */ + _dns_manager_set_ip_config(NM_POLICY_GET_PRIVATE(self)->dns_manager, + ip_config, + (vpn || (device && nm_device_is_vpn(device))) + ? NM_DNS_IP_CONFIG_TYPE_VPN + : NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE, + device); + } + + if (addr_family == AF_INET6) { + NMActiveConnection *ac; + const CList * tmp_list; + + /* Tell devices needing a subnet about the new DNS configuration */ + nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { + device = nm_active_connection_get_device(ac); + if (device && device != changed_device && nm_device_needs_ip6_subnet(device)) + nm_device_copy_ip6_dns_config(device, get_default_device(self, AF_INET6)); + } + } } static void -update_routing_and_dns (NMPolicy *self, - gboolean force_update, - NMDevice *changed_device) +update_routing_and_dns(NMPolicy *self, gboolean force_update, NMDevice *changed_device) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); - nm_dns_manager_begin_updates (priv->dns_manager, __func__); + nm_dns_manager_begin_updates(priv->dns_manager, __func__); - update_ip_dns (self, AF_INET, changed_device); - update_ip_dns (self, AF_INET6, changed_device); + update_ip_dns(self, AF_INET, changed_device); + update_ip_dns(self, AF_INET6, changed_device); - update_ip4_routing (self, force_update); - update_ip6_routing (self, force_update); + update_ip4_routing(self, force_update); + update_ip6_routing(self, force_update); - /* Update the system hostname */ - update_system_hostname (self, "routing and dns"); + /* Update the system hostname */ + update_system_hostname(self, "routing and dns"); - nm_dns_manager_end_updates (priv->dns_manager, __func__); + nm_dns_manager_end_updates(priv->dns_manager, __func__); } static void -check_activating_active_connections (NMPolicy *self) +check_activating_active_connections(NMPolicy *self) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - NMActiveConnection *best4, *best6 = NULL; + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + NMActiveConnection *best4, *best6 = NULL; - best4 = get_best_active_connection (self, AF_INET, FALSE); - best6 = get_best_active_connection (self, AF_INET6, FALSE); + best4 = get_best_active_connection(self, AF_INET, FALSE); + best6 = get_best_active_connection(self, AF_INET6, FALSE); - g_object_freeze_notify (G_OBJECT (self)); + g_object_freeze_notify(G_OBJECT(self)); - if (nm_g_object_ref_set (&priv->activating_ac4, best4)) { - _LOGt (LOGD_DNS, "set-activating-ac-4: %p", priv->activating_ac4); - _notify (self, PROP_ACTIVATING_IP4_AC); - } - if (nm_g_object_ref_set (&priv->activating_ac6, best6)) { - _LOGt (LOGD_DNS, "set-activating-ac-6: %p", priv->activating_ac6); - _notify (self, PROP_ACTIVATING_IP6_AC); - } + if (nm_g_object_ref_set(&priv->activating_ac4, best4)) { + _LOGt(LOGD_DNS, "set-activating-ac-4: %p", priv->activating_ac4); + _notify(self, PROP_ACTIVATING_IP4_AC); + } + if (nm_g_object_ref_set(&priv->activating_ac6, best6)) { + _LOGt(LOGD_DNS, "set-activating-ac-6: %p", priv->activating_ac6); + _notify(self, PROP_ACTIVATING_IP6_AC); + } - g_object_thaw_notify (G_OBJECT (self)); + g_object_thaw_notify(G_OBJECT(self)); } typedef struct { - CList pending_lst; - NMPolicy *policy; - NMDevice *device; - guint autoactivate_id; + CList pending_lst; + NMPolicy *policy; + NMDevice *device; + guint autoactivate_id; } ActivateData; static void -activate_data_free (ActivateData *data) +activate_data_free(ActivateData *data) { - nm_device_remove_pending_action (data->device, NM_PENDING_ACTION_AUTOACTIVATE, TRUE); - c_list_unlink_stale (&data->pending_lst); - nm_clear_g_source (&data->autoactivate_id); - g_object_unref (data->device); - g_slice_free (ActivateData, data); + nm_device_remove_pending_action(data->device, NM_PENDING_ACTION_AUTOACTIVATE, TRUE); + c_list_unlink_stale(&data->pending_lst); + nm_clear_g_source(&data->autoactivate_id); + g_object_unref(data->device); + g_slice_free(ActivateData, data); } static void -pending_ac_gone (gpointer data, GObject *where_the_object_was) +pending_ac_gone(gpointer data, GObject *where_the_object_was) { - NMPolicy *self = NM_POLICY (data); - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); + NMPolicy * self = NM_POLICY(data); + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); - /* Active connections should reach the DEACTIVATED state - * before disappearing. */ - nm_assert_not_reached(); + /* Active connections should reach the DEACTIVATED state + * before disappearing. */ + nm_assert_not_reached(); - if (g_hash_table_remove (priv->pending_active_connections, where_the_object_was)) - g_object_unref (self); + if (g_hash_table_remove(priv->pending_active_connections, where_the_object_was)) + g_object_unref(self); } static void -pending_ac_state_changed (NMActiveConnection *ac, guint state, guint reason, NMPolicy *self) -{ - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - NMSettingsConnection *con; - - if (state >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) { - /* The AC is being deactivated before the device had a chance - * to move to PREPARE. Schedule a new auto-activation on the - * device, but block the current connection to avoid an activation - * loop. - */ - if (reason != NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED) { - con = nm_active_connection_get_settings_connection (ac); - nm_settings_connection_autoconnect_blocked_reason_set (con, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED, TRUE); - schedule_activate_check (self, nm_active_connection_get_device (ac)); - } - - /* Cleanup */ - g_signal_handlers_disconnect_by_func (ac, pending_ac_state_changed, self); - if (!g_hash_table_remove (priv->pending_active_connections, ac)) - nm_assert_not_reached (); - g_object_weak_unref (G_OBJECT (ac), pending_ac_gone, self); - g_object_unref (self); - } +pending_ac_state_changed(NMActiveConnection *ac, guint state, guint reason, NMPolicy *self) +{ + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + NMSettingsConnection *con; + + if (state >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) { + /* The AC is being deactivated before the device had a chance + * to move to PREPARE. Schedule a new auto-activation on the + * device, but block the current connection to avoid an activation + * loop. + */ + if (reason != NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED) { + con = nm_active_connection_get_settings_connection(ac); + nm_settings_connection_autoconnect_blocked_reason_set( + con, + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED, + TRUE); + schedule_activate_check(self, nm_active_connection_get_device(ac)); + } + + /* Cleanup */ + g_signal_handlers_disconnect_by_func(ac, pending_ac_state_changed, self); + if (!g_hash_table_remove(priv->pending_active_connections, ac)) + nm_assert_not_reached(); + g_object_weak_unref(G_OBJECT(ac), pending_ac_gone, self); + g_object_unref(self); + } } static void -auto_activate_device (NMPolicy *self, - NMDevice *device) -{ - NMPolicyPrivate *priv; - NMSettingsConnection *best_connection; - gs_free char *specific_object = NULL; - gs_free NMSettingsConnection **connections = NULL; - guint i, len; - gs_free_error GError *error = NULL; - gs_unref_object NMAuthSubject *subject = NULL; - NMActiveConnection *ac; - - nm_assert (NM_IS_POLICY (self)); - nm_assert (NM_IS_DEVICE (device)); - - priv = NM_POLICY_GET_PRIVATE (self); - - // FIXME: if a device is already activating (or activated) with a connection - // but another connection now overrides the current one for that device, - // deactivate the device and activate the new connection instead of just - // bailing if the device is already active - if (nm_device_get_act_request (device)) - return; - - if (!nm_device_autoconnect_allowed (device)) - return; - - connections = nm_manager_get_activatable_connections (priv->manager, TRUE, TRUE, &len); - if (!connections[0]) - return; - - /* Find the first connection that should be auto-activated */ - best_connection = NULL; - for (i = 0; i < len; i++) { - NMSettingsConnection *candidate = connections[i]; - NMConnection *cand_conn; - NMSettingConnection *s_con; - const char *permission; - - if (nm_settings_connection_autoconnect_is_blocked (candidate)) - continue; - - cand_conn = nm_settings_connection_get_connection (candidate); - - s_con = nm_connection_get_setting_connection (cand_conn); - if (!nm_setting_connection_get_autoconnect (s_con)) - continue; - - permission = nm_utils_get_shared_wifi_permission (cand_conn); - if ( permission - && !nm_settings_connection_check_permission (candidate, permission)) - continue; - - if (nm_device_can_auto_connect (device, candidate, &specific_object)) { - best_connection = candidate; - break; - } - } - - if (!best_connection) - return; - - _LOGI (LOGD_DEVICE, "auto-activating connection '%s' (%s)", - nm_settings_connection_get_id (best_connection), - nm_settings_connection_get_uuid (best_connection)); - - subject = nm_auth_subject_new_internal (); - ac = nm_manager_activate_connection (priv->manager, - best_connection, - NULL, - specific_object, - device, - subject, - NM_ACTIVATION_TYPE_MANAGED, - NM_ACTIVATION_REASON_AUTOCONNECT, - NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY, - &error); - if (!ac) { - _LOGI (LOGD_DEVICE, "connection '%s' auto-activation failed: %s", - nm_settings_connection_get_id (best_connection), - error->message); - nm_settings_connection_autoconnect_blocked_reason_set (best_connection, - NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED, - TRUE); - schedule_activate_check (self, device); - return; - } - - /* Subscribe to AC state-changed signal to detect when the - * activation fails in early stages without changing device - * state. - */ - if (g_hash_table_add (priv->pending_active_connections, ac)) { - g_signal_connect (ac, NM_ACTIVE_CONNECTION_STATE_CHANGED, - G_CALLBACK (pending_ac_state_changed), g_object_ref (self)); - g_object_weak_ref (G_OBJECT (ac), (GWeakNotify) pending_ac_gone, self); - } +auto_activate_device(NMPolicy *self, NMDevice *device) +{ + NMPolicyPrivate * priv; + NMSettingsConnection *best_connection; + gs_free char * specific_object = NULL; + gs_free NMSettingsConnection **connections = NULL; + guint i, len; + gs_free_error GError *error = NULL; + gs_unref_object NMAuthSubject *subject = NULL; + NMActiveConnection * ac; + + nm_assert(NM_IS_POLICY(self)); + nm_assert(NM_IS_DEVICE(device)); + + priv = NM_POLICY_GET_PRIVATE(self); + + // FIXME: if a device is already activating (or activated) with a connection + // but another connection now overrides the current one for that device, + // deactivate the device and activate the new connection instead of just + // bailing if the device is already active + if (nm_device_get_act_request(device)) + return; + + if (!nm_device_autoconnect_allowed(device)) + return; + + connections = nm_manager_get_activatable_connections(priv->manager, TRUE, TRUE, &len); + if (!connections[0]) + return; + + /* Find the first connection that should be auto-activated */ + best_connection = NULL; + for (i = 0; i < len; i++) { + NMSettingsConnection *candidate = connections[i]; + NMConnection * cand_conn; + NMSettingConnection * s_con; + const char * permission; + + if (nm_settings_connection_autoconnect_is_blocked(candidate)) + continue; + + cand_conn = nm_settings_connection_get_connection(candidate); + + s_con = nm_connection_get_setting_connection(cand_conn); + if (!nm_setting_connection_get_autoconnect(s_con)) + continue; + + permission = nm_utils_get_shared_wifi_permission(cand_conn); + if (permission && !nm_settings_connection_check_permission(candidate, permission)) + continue; + + if (nm_device_can_auto_connect(device, candidate, &specific_object)) { + best_connection = candidate; + break; + } + } + + if (!best_connection) + return; + + _LOGI(LOGD_DEVICE, + "auto-activating connection '%s' (%s)", + nm_settings_connection_get_id(best_connection), + nm_settings_connection_get_uuid(best_connection)); + + subject = nm_auth_subject_new_internal(); + ac = nm_manager_activate_connection( + priv->manager, + best_connection, + NULL, + specific_object, + device, + subject, + NM_ACTIVATION_TYPE_MANAGED, + NM_ACTIVATION_REASON_AUTOCONNECT, + NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY, + &error); + if (!ac) { + _LOGI(LOGD_DEVICE, + "connection '%s' auto-activation failed: %s", + nm_settings_connection_get_id(best_connection), + error->message); + nm_settings_connection_autoconnect_blocked_reason_set( + best_connection, + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED, + TRUE); + schedule_activate_check(self, device); + return; + } + + /* Subscribe to AC state-changed signal to detect when the + * activation fails in early stages without changing device + * state. + */ + if (g_hash_table_add(priv->pending_active_connections, ac)) { + g_signal_connect(ac, + NM_ACTIVE_CONNECTION_STATE_CHANGED, + G_CALLBACK(pending_ac_state_changed), + g_object_ref(self)); + g_object_weak_ref(G_OBJECT(ac), (GWeakNotify) pending_ac_gone, self); + } } static gboolean -auto_activate_device_cb (gpointer user_data) +auto_activate_device_cb(gpointer user_data) { - ActivateData *data = user_data; + ActivateData *data = user_data; - g_assert (data); - g_assert (NM_IS_POLICY (data->policy)); - g_assert (NM_IS_DEVICE (data->device)); + g_assert(data); + g_assert(NM_IS_POLICY(data->policy)); + g_assert(NM_IS_DEVICE(data->device)); - data->autoactivate_id = 0; - auto_activate_device (data->policy, data->device); - activate_data_free (data); - return G_SOURCE_REMOVE; + data->autoactivate_id = 0; + auto_activate_device(data->policy, data->device); + activate_data_free(data); + return G_SOURCE_REMOVE; } static ActivateData * -find_pending_activation (NMPolicy *self, NMDevice *device) +find_pending_activation(NMPolicy *self, NMDevice *device) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - ActivateData *data; + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); + ActivateData * data; - c_list_for_each_entry (data, &priv->pending_activation_checks, pending_lst) { - if (data->device == device) - return data; - } - return NULL; + c_list_for_each_entry (data, &priv->pending_activation_checks, pending_lst) { + if (data->device == device) + return data; + } + return NULL; } /*****************************************************************************/ typedef struct { - NMDevice *device; - GSList *secondaries; + NMDevice *device; + GSList * secondaries; } PendingSecondaryData; static PendingSecondaryData * -pending_secondary_data_new (NMDevice *device, GSList *secondaries) +pending_secondary_data_new(NMDevice *device, GSList *secondaries) { - PendingSecondaryData *data; + PendingSecondaryData *data; - data = g_slice_new (PendingSecondaryData); - data->device = g_object_ref (device); - data->secondaries = secondaries; - return data; + data = g_slice_new(PendingSecondaryData); + data->device = g_object_ref(device); + data->secondaries = secondaries; + return data; } static void -pending_secondary_data_free (PendingSecondaryData *data) +pending_secondary_data_free(PendingSecondaryData *data) { - g_object_unref (data->device); - g_slist_free_full (data->secondaries, g_object_unref); - g_slice_free (PendingSecondaryData, data); + g_object_unref(data->device); + g_slist_free_full(data->secondaries, g_object_unref); + g_slice_free(PendingSecondaryData, data); } static void -process_secondaries (NMPolicy *self, - NMActiveConnection *active, - gboolean connected) -{ - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - GSList *iter, *iter2, *next, *next2; - - /* Loop through devices waiting for secondary connections to activate */ - for (iter = priv->pending_secondaries; iter; iter = next) { - PendingSecondaryData *secondary_data = (PendingSecondaryData *) iter->data; - NMDevice *item_device = secondary_data->device; - - next = g_slist_next (iter); - - /* Look for 'active' in each device's secondary connections list */ - for (iter2 = secondary_data->secondaries; iter2; iter2 = next2) { - NMActiveConnection *secondary_active = NM_ACTIVE_CONNECTION (iter2->data); - - next2 = g_slist_next (iter2); - - if (active != secondary_active) - continue; - - if (connected) { - _LOGD (LOGD_DEVICE, "secondary connection '%s' succeeded; active path '%s'", - nm_active_connection_get_settings_connection_id (active), - nm_dbus_object_get_path (NM_DBUS_OBJECT (active))); - - /* Secondary connection activated */ - secondary_data->secondaries = g_slist_remove (secondary_data->secondaries, secondary_active); - g_object_unref (secondary_active); - if (!secondary_data->secondaries) { - /* No secondary UUID remained -> remove the secondary data item */ - priv->pending_secondaries = g_slist_remove (priv->pending_secondaries, secondary_data); - pending_secondary_data_free (secondary_data); - if (nm_device_get_state (item_device) == NM_DEVICE_STATE_SECONDARIES) - nm_device_state_changed (item_device, NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_REASON_NONE); - break; - } - } else { - _LOGD (LOGD_DEVICE, "secondary connection '%s' failed; active path '%s'", - nm_active_connection_get_settings_connection_id (active), - nm_dbus_object_get_path (NM_DBUS_OBJECT (active))); - - /* Secondary connection failed -> do not watch other connections */ - priv->pending_secondaries = g_slist_remove (priv->pending_secondaries, secondary_data); - pending_secondary_data_free (secondary_data); - if ( nm_device_get_state (item_device) == NM_DEVICE_STATE_SECONDARIES - || nm_device_get_state (item_device) == NM_DEVICE_STATE_ACTIVATED) - nm_device_state_changed (item_device, NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED); - break; - } - } - } +process_secondaries(NMPolicy *self, NMActiveConnection *active, gboolean connected) +{ + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); + GSList * iter, *iter2, *next, *next2; + + /* Loop through devices waiting for secondary connections to activate */ + for (iter = priv->pending_secondaries; iter; iter = next) { + PendingSecondaryData *secondary_data = (PendingSecondaryData *) iter->data; + NMDevice * item_device = secondary_data->device; + + next = g_slist_next(iter); + + /* Look for 'active' in each device's secondary connections list */ + for (iter2 = secondary_data->secondaries; iter2; iter2 = next2) { + NMActiveConnection *secondary_active = NM_ACTIVE_CONNECTION(iter2->data); + + next2 = g_slist_next(iter2); + + if (active != secondary_active) + continue; + + if (connected) { + _LOGD(LOGD_DEVICE, + "secondary connection '%s' succeeded; active path '%s'", + nm_active_connection_get_settings_connection_id(active), + nm_dbus_object_get_path(NM_DBUS_OBJECT(active))); + + /* Secondary connection activated */ + secondary_data->secondaries = + g_slist_remove(secondary_data->secondaries, secondary_active); + g_object_unref(secondary_active); + if (!secondary_data->secondaries) { + /* No secondary UUID remained -> remove the secondary data item */ + priv->pending_secondaries = + g_slist_remove(priv->pending_secondaries, secondary_data); + pending_secondary_data_free(secondary_data); + if (nm_device_get_state(item_device) == NM_DEVICE_STATE_SECONDARIES) + nm_device_state_changed(item_device, + NM_DEVICE_STATE_ACTIVATED, + NM_DEVICE_STATE_REASON_NONE); + break; + } + } else { + _LOGD(LOGD_DEVICE, + "secondary connection '%s' failed; active path '%s'", + nm_active_connection_get_settings_connection_id(active), + nm_dbus_object_get_path(NM_DBUS_OBJECT(active))); + + /* Secondary connection failed -> do not watch other connections */ + priv->pending_secondaries = + g_slist_remove(priv->pending_secondaries, secondary_data); + pending_secondary_data_free(secondary_data); + if (nm_device_get_state(item_device) == NM_DEVICE_STATE_SECONDARIES + || nm_device_get_state(item_device) == NM_DEVICE_STATE_ACTIVATED) + nm_device_state_changed(item_device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED); + break; + } + } + } } static void -hostname_changed (NMHostnameManager *hostname_manager, GParamSpec *pspec, gpointer user_data) +hostname_changed(NMHostnameManager *hostname_manager, GParamSpec *pspec, gpointer user_data) { - NMPolicyPrivate *priv = user_data; - NMPolicy *self = _PRIV_TO_SELF (priv); + NMPolicyPrivate *priv = user_data; + NMPolicy * self = _PRIV_TO_SELF(priv); - update_system_hostname (self, "hostname changed"); + update_system_hostname(self, "hostname changed"); } static gboolean -reset_autoconnect_all (NMPolicy *self, - NMDevice *device, /* if present, only reset connections compatible with @device */ - gboolean only_no_secrets) -{ - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - NMSettingsConnection *const*connections = NULL; - guint i; - gboolean changed = FALSE; - - _LOGD (LOGD_DEVICE, "re-enabling autoconnect for all connections%s%s%s", - device ? " on " : "", - device ? nm_device_get_iface (device) : "", - only_no_secrets ? " (only clear no-secrets flag)" : ""); - - connections = nm_settings_get_connections (priv->settings, NULL); - for (i = 0; connections[i]; i++) { - NMSettingsConnection *sett_conn = connections[i]; - - if ( device - && !nm_device_check_connection_compatible (device, - nm_settings_connection_get_connection (sett_conn), - NULL)) - continue; - - if (only_no_secrets) { - /* we only reset the no-secrets blocked flag. */ - if (nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, - NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS, - FALSE)) { - /* maybe the connection is still blocked afterwards for other reasons - * and in the larger picture nothing changed. But it's too complicated - * to find out exactly. Just assume, something changed to be sure. */ - if (!nm_settings_connection_autoconnect_is_blocked (sett_conn)) - changed = TRUE; - } - } else { - /* we reset the tries-count and any blocked-reason */ - if (nm_settings_connection_autoconnect_retries_get (sett_conn) == 0) - changed = TRUE; - nm_settings_connection_autoconnect_retries_reset (sett_conn); - - if (nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, - NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_ALL - & ~NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST, - FALSE)) { - if (!nm_settings_connection_autoconnect_is_blocked (sett_conn)) - changed = TRUE; - } - } - } - return changed; +reset_autoconnect_all( + NMPolicy *self, + NMDevice *device, /* if present, only reset connections compatible with @device */ + gboolean only_no_secrets) +{ + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + NMSettingsConnection *const *connections = NULL; + guint i; + gboolean changed = FALSE; + + _LOGD(LOGD_DEVICE, + "re-enabling autoconnect for all connections%s%s%s", + device ? " on " : "", + device ? nm_device_get_iface(device) : "", + only_no_secrets ? " (only clear no-secrets flag)" : ""); + + connections = nm_settings_get_connections(priv->settings, NULL); + for (i = 0; connections[i]; i++) { + NMSettingsConnection *sett_conn = connections[i]; + + if (device + && !nm_device_check_connection_compatible( + device, + nm_settings_connection_get_connection(sett_conn), + NULL)) + continue; + + if (only_no_secrets) { + /* we only reset the no-secrets blocked flag. */ + if (nm_settings_connection_autoconnect_blocked_reason_set( + sett_conn, + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS, + FALSE)) { + /* maybe the connection is still blocked afterwards for other reasons + * and in the larger picture nothing changed. But it's too complicated + * to find out exactly. Just assume, something changed to be sure. */ + if (!nm_settings_connection_autoconnect_is_blocked(sett_conn)) + changed = TRUE; + } + } else { + /* we reset the tries-count and any blocked-reason */ + if (nm_settings_connection_autoconnect_retries_get(sett_conn) == 0) + changed = TRUE; + nm_settings_connection_autoconnect_retries_reset(sett_conn); + + if (nm_settings_connection_autoconnect_blocked_reason_set( + sett_conn, + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_ALL + & ~NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST, + FALSE)) { + if (!nm_settings_connection_autoconnect_is_blocked(sett_conn)) + changed = TRUE; + } + } + } + return changed; } static void -sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data) +sleeping_changed(NMManager *manager, GParamSpec *pspec, gpointer user_data) { - NMPolicyPrivate *priv = user_data; - NMPolicy *self = _PRIV_TO_SELF (priv); - gboolean sleeping = FALSE, enabled = FALSE; + NMPolicyPrivate *priv = user_data; + NMPolicy * self = _PRIV_TO_SELF(priv); + gboolean sleeping = FALSE, enabled = FALSE; - g_object_get (G_OBJECT (manager), NM_MANAGER_SLEEPING, &sleeping, NULL); - g_object_get (G_OBJECT (manager), NM_MANAGER_NETWORKING_ENABLED, &enabled, NULL); + g_object_get(G_OBJECT(manager), NM_MANAGER_SLEEPING, &sleeping, NULL); + g_object_get(G_OBJECT(manager), NM_MANAGER_NETWORKING_ENABLED, &enabled, NULL); - /* Reset retries on all connections so they'll checked on wakeup */ - if (sleeping || !enabled) - reset_autoconnect_all (self, NULL, FALSE); + /* Reset retries on all connections so they'll checked on wakeup */ + if (sleeping || !enabled) + reset_autoconnect_all(self, NULL, FALSE); } static void -schedule_activate_check (NMPolicy *self, NMDevice *device) +schedule_activate_check(NMPolicy *self, NMDevice *device) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - ActivateData *data; - NMActiveConnection *ac; - const CList *tmp_list; + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + ActivateData * data; + NMActiveConnection *ac; + const CList * tmp_list; - if (nm_manager_get_state (priv->manager) == NM_STATE_ASLEEP) - return; + if (nm_manager_get_state(priv->manager) == NM_STATE_ASLEEP) + return; - if (!nm_device_autoconnect_allowed (device)) - return; + if (!nm_device_autoconnect_allowed(device)) + return; - if (find_pending_activation (self, device)) - return; + if (find_pending_activation(self, device)) + return; - nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { - if (nm_active_connection_get_device (ac) == device) - return; - } + nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { + if (nm_active_connection_get_device(ac) == device) + return; + } - nm_device_add_pending_action (device, NM_PENDING_ACTION_AUTOACTIVATE, TRUE); + nm_device_add_pending_action(device, NM_PENDING_ACTION_AUTOACTIVATE, TRUE); - data = g_slice_new0 (ActivateData); - data->policy = self; - data->device = g_object_ref (device); - data->autoactivate_id = g_idle_add (auto_activate_device_cb, data); - c_list_link_tail (&priv->pending_activation_checks, &data->pending_lst); + data = g_slice_new0(ActivateData); + data->policy = self; + data->device = g_object_ref(device); + data->autoactivate_id = g_idle_add(auto_activate_device_cb, data); + c_list_link_tail(&priv->pending_activation_checks, &data->pending_lst); } static gboolean -reset_connections_retries (gpointer user_data) +reset_connections_retries(gpointer user_data) { - NMPolicy *self = (NMPolicy *) user_data; - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - NMSettingsConnection *const*connections = NULL; - guint i; - gint32 con_stamp, min_stamp, now; - gboolean changed = FALSE; + NMPolicy * self = (NMPolicy *) user_data; + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + NMSettingsConnection *const *connections = NULL; + guint i; + gint32 con_stamp, min_stamp, now; + gboolean changed = FALSE; - priv->reset_retries_id = 0; + priv->reset_retries_id = 0; - min_stamp = 0; - now = nm_utils_get_monotonic_timestamp_sec (); - connections = nm_settings_get_connections (priv->settings, NULL); - for (i = 0; connections[i]; i++) { - NMSettingsConnection *connection = connections[i]; + min_stamp = 0; + now = nm_utils_get_monotonic_timestamp_sec(); + connections = nm_settings_get_connections(priv->settings, NULL); + for (i = 0; connections[i]; i++) { + NMSettingsConnection *connection = connections[i]; - con_stamp = nm_settings_connection_autoconnect_retries_blocked_until (connection); - if (con_stamp == 0) - continue; + con_stamp = nm_settings_connection_autoconnect_retries_blocked_until(connection); + if (con_stamp == 0) + continue; - if (con_stamp <= now) { - nm_settings_connection_autoconnect_retries_reset (connection); - changed = TRUE; - } else if (min_stamp == 0 || min_stamp > con_stamp) - min_stamp = con_stamp; - } + if (con_stamp <= now) { + nm_settings_connection_autoconnect_retries_reset(connection); + changed = TRUE; + } else if (min_stamp == 0 || min_stamp > con_stamp) + min_stamp = con_stamp; + } - /* Schedule the handler again if there are some stamps left */ - if (min_stamp != 0) - priv->reset_retries_id = g_timeout_add_seconds (min_stamp - now, reset_connections_retries, self); + /* Schedule the handler again if there are some stamps left */ + if (min_stamp != 0) + priv->reset_retries_id = + g_timeout_add_seconds(min_stamp - now, reset_connections_retries, self); - /* If anything changed, try to activate the newly re-enabled connections */ - if (changed) - schedule_activate_all (self); + /* If anything changed, try to activate the newly re-enabled connections */ + if (changed) + schedule_activate_all(self); - return FALSE; + return FALSE; } static void -_connection_autoconnect_retries_set (NMPolicy *self, - NMSettingsConnection *connection, - int tries) +_connection_autoconnect_retries_set(NMPolicy *self, NMSettingsConnection *connection, int tries) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); - nm_assert (NM_IS_SETTINGS_CONNECTION (connection)); - nm_assert (tries >= 0); + nm_assert(NM_IS_SETTINGS_CONNECTION(connection)); + nm_assert(tries >= 0); - nm_settings_connection_autoconnect_retries_set (connection, tries); + nm_settings_connection_autoconnect_retries_set(connection, tries); - if (tries == 0) { - /* Schedule a handler to reset retries count */ - if (!priv->reset_retries_id) { - gint32 retry_time = nm_settings_connection_autoconnect_retries_blocked_until (connection); + if (tries == 0) { + /* Schedule a handler to reset retries count */ + if (!priv->reset_retries_id) { + gint32 retry_time = + nm_settings_connection_autoconnect_retries_blocked_until(connection); - g_warn_if_fail (retry_time != 0); - priv->reset_retries_id = g_timeout_add_seconds (MAX (0, retry_time - nm_utils_get_monotonic_timestamp_sec ()), reset_connections_retries, self); - } - } + g_warn_if_fail(retry_time != 0); + priv->reset_retries_id = + g_timeout_add_seconds(MAX(0, retry_time - nm_utils_get_monotonic_timestamp_sec()), + reset_connections_retries, + self); + } + } } static void -activate_slave_connections (NMPolicy *self, NMDevice *device) -{ - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - const char *master_device; - const char *master_uuid_settings = NULL; - const char *master_uuid_applied = NULL; - guint i; - NMActRequest *req; - gboolean internal_activation = FALSE; - NMSettingsConnection *const*connections; - gboolean changed; - - master_device = nm_device_get_iface (device); - g_assert (master_device); - - req = nm_device_get_act_request (device); - if (req) { - NMConnection *connection; - NMSettingsConnection *sett_conn; - NMAuthSubject *subject; - - connection = nm_active_connection_get_applied_connection (NM_ACTIVE_CONNECTION (req)); - if (connection) - master_uuid_applied = nm_connection_get_uuid (connection); - - sett_conn = nm_active_connection_get_settings_connection (NM_ACTIVE_CONNECTION (req)); - if (sett_conn) { - master_uuid_settings = nm_settings_connection_get_uuid (sett_conn); - if (nm_streq0 (master_uuid_settings, master_uuid_applied)) - master_uuid_settings = NULL; - } - - subject = nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (req)); - internal_activation = subject - && (nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_INTERNAL); - } - - changed = FALSE; - connections = nm_settings_get_connections (priv->settings, NULL); - for (i = 0; connections[i]; i++) { - NMSettingsConnection *sett_conn = connections[i]; - NMSettingConnection *s_slave_con; - const char *slave_master; - - s_slave_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (sett_conn)); - slave_master = nm_setting_connection_get_master (s_slave_con); - if (!slave_master) - continue; - if (!NM_IN_STRSET (slave_master, master_device, - master_uuid_applied, - master_uuid_settings)) - continue; - - if (!internal_activation) { - if (nm_settings_connection_autoconnect_retries_get (sett_conn) == 0) - changed = TRUE; - nm_settings_connection_autoconnect_retries_reset (sett_conn); - } - if (nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, - NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED, - FALSE)) { - if (!nm_settings_connection_autoconnect_is_blocked (sett_conn)) - changed = TRUE; - } - } - - if (changed) - schedule_activate_all (self); +activate_slave_connections(NMPolicy *self, NMDevice *device) +{ + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + const char * master_device; + const char * master_uuid_settings = NULL; + const char * master_uuid_applied = NULL; + guint i; + NMActRequest * req; + gboolean internal_activation = FALSE; + NMSettingsConnection *const *connections; + gboolean changed; + + master_device = nm_device_get_iface(device); + g_assert(master_device); + + req = nm_device_get_act_request(device); + if (req) { + NMConnection * connection; + NMSettingsConnection *sett_conn; + NMAuthSubject * subject; + + connection = nm_active_connection_get_applied_connection(NM_ACTIVE_CONNECTION(req)); + if (connection) + master_uuid_applied = nm_connection_get_uuid(connection); + + sett_conn = nm_active_connection_get_settings_connection(NM_ACTIVE_CONNECTION(req)); + if (sett_conn) { + master_uuid_settings = nm_settings_connection_get_uuid(sett_conn); + if (nm_streq0(master_uuid_settings, master_uuid_applied)) + master_uuid_settings = NULL; + } + + subject = nm_active_connection_get_subject(NM_ACTIVE_CONNECTION(req)); + internal_activation = + subject && (nm_auth_subject_get_subject_type(subject) == NM_AUTH_SUBJECT_TYPE_INTERNAL); + } + + changed = FALSE; + connections = nm_settings_get_connections(priv->settings, NULL); + for (i = 0; connections[i]; i++) { + NMSettingsConnection *sett_conn = connections[i]; + NMSettingConnection * s_slave_con; + const char * slave_master; + + s_slave_con = + nm_connection_get_setting_connection(nm_settings_connection_get_connection(sett_conn)); + slave_master = nm_setting_connection_get_master(s_slave_con); + if (!slave_master) + continue; + if (!NM_IN_STRSET(slave_master, master_device, master_uuid_applied, master_uuid_settings)) + continue; + + if (!internal_activation) { + if (nm_settings_connection_autoconnect_retries_get(sett_conn) == 0) + changed = TRUE; + nm_settings_connection_autoconnect_retries_reset(sett_conn); + } + if (nm_settings_connection_autoconnect_blocked_reason_set( + sett_conn, + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED, + FALSE)) { + if (!nm_settings_connection_autoconnect_is_blocked(sett_conn)) + changed = TRUE; + } + } + + if (changed) + schedule_activate_all(self); } static gboolean -activate_secondary_connections (NMPolicy *self, - NMConnection *connection, - NMDevice *device) -{ - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - NMSettingConnection *s_con; - NMActiveConnection *ac; - PendingSecondaryData *secondary_data; - GSList *secondary_ac_list = NULL; - GError *error = NULL; - guint32 i; - gboolean success = TRUE; - NMActivationStateFlags initial_state_flags; - - s_con = nm_connection_get_setting_connection (connection); - nm_assert (NM_IS_SETTING_CONNECTION (s_con)); - - /* we propagate the activation's state flags. */ - initial_state_flags = nm_device_get_activation_state_flags (device) - & NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY; - - for (i = 0; i < nm_setting_connection_get_num_secondaries (s_con); i++) { - NMSettingsConnection *sett_conn; - const char *sec_uuid = nm_setting_connection_get_secondary (s_con, i); - NMActRequest *req; - - sett_conn = nm_settings_get_connection_by_uuid (priv->settings, sec_uuid); - if (!sett_conn) { - _LOGW (LOGD_DEVICE, "secondary connection '%s' auto-activation failed: The connection doesn't exist.", - sec_uuid); - success = FALSE; - break; - } - - if (!nm_connection_is_type (nm_settings_connection_get_connection (sett_conn), - NM_SETTING_VPN_SETTING_NAME)) { - _LOGW (LOGD_DEVICE, "secondary connection '%s (%s)' auto-activation failed: The connection is not a VPN.", - nm_settings_connection_get_id (sett_conn), sec_uuid); - success = FALSE; - break; - } - - req = nm_device_get_act_request (device); - - _LOGD (LOGD_DEVICE, "activating secondary connection '%s (%s)' for base connection '%s (%s)'", - nm_settings_connection_get_id (sett_conn), sec_uuid, - nm_connection_get_id (connection), nm_connection_get_uuid (connection)); - ac = nm_manager_activate_connection (priv->manager, - sett_conn, - NULL, - nm_dbus_object_get_path (NM_DBUS_OBJECT (req)), - device, - nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (req)), - NM_ACTIVATION_TYPE_MANAGED, - nm_active_connection_get_activation_reason (NM_ACTIVE_CONNECTION (req)), - initial_state_flags, - &error); - if (ac) - secondary_ac_list = g_slist_append (secondary_ac_list, g_object_ref (ac)); - else { - _LOGW (LOGD_DEVICE, "secondary connection '%s (%s)' auto-activation failed: (%d) %s", - nm_settings_connection_get_id (sett_conn), sec_uuid, - error->code, - error->message); - g_clear_error (&error); - success = FALSE; - break; - } - } - - if (success && secondary_ac_list != NULL) { - secondary_data = pending_secondary_data_new (device, secondary_ac_list); - priv->pending_secondaries = g_slist_append (priv->pending_secondaries, secondary_data); - } else - g_slist_free_full (secondary_ac_list, g_object_unref); - - return success; +activate_secondary_connections(NMPolicy *self, NMConnection *connection, NMDevice *device) +{ + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + NMSettingConnection * s_con; + NMActiveConnection * ac; + PendingSecondaryData * secondary_data; + GSList * secondary_ac_list = NULL; + GError * error = NULL; + guint32 i; + gboolean success = TRUE; + NMActivationStateFlags initial_state_flags; + + s_con = nm_connection_get_setting_connection(connection); + nm_assert(NM_IS_SETTING_CONNECTION(s_con)); + + /* we propagate the activation's state flags. */ + initial_state_flags = nm_device_get_activation_state_flags(device) + & NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY; + + for (i = 0; i < nm_setting_connection_get_num_secondaries(s_con); i++) { + NMSettingsConnection *sett_conn; + const char * sec_uuid = nm_setting_connection_get_secondary(s_con, i); + NMActRequest * req; + + sett_conn = nm_settings_get_connection_by_uuid(priv->settings, sec_uuid); + if (!sett_conn) { + _LOGW(LOGD_DEVICE, + "secondary connection '%s' auto-activation failed: The connection doesn't exist.", + sec_uuid); + success = FALSE; + break; + } + + if (!nm_connection_is_type(nm_settings_connection_get_connection(sett_conn), + NM_SETTING_VPN_SETTING_NAME)) { + _LOGW(LOGD_DEVICE, + "secondary connection '%s (%s)' auto-activation failed: The connection is not a " + "VPN.", + nm_settings_connection_get_id(sett_conn), + sec_uuid); + success = FALSE; + break; + } + + req = nm_device_get_act_request(device); + + _LOGD(LOGD_DEVICE, + "activating secondary connection '%s (%s)' for base connection '%s (%s)'", + nm_settings_connection_get_id(sett_conn), + sec_uuid, + nm_connection_get_id(connection), + nm_connection_get_uuid(connection)); + ac = nm_manager_activate_connection( + priv->manager, + sett_conn, + NULL, + nm_dbus_object_get_path(NM_DBUS_OBJECT(req)), + device, + nm_active_connection_get_subject(NM_ACTIVE_CONNECTION(req)), + NM_ACTIVATION_TYPE_MANAGED, + nm_active_connection_get_activation_reason(NM_ACTIVE_CONNECTION(req)), + initial_state_flags, + &error); + if (ac) + secondary_ac_list = g_slist_append(secondary_ac_list, g_object_ref(ac)); + else { + _LOGW(LOGD_DEVICE, + "secondary connection '%s (%s)' auto-activation failed: (%d) %s", + nm_settings_connection_get_id(sett_conn), + sec_uuid, + error->code, + error->message); + g_clear_error(&error); + success = FALSE; + break; + } + } + + if (success && secondary_ac_list != NULL) { + secondary_data = pending_secondary_data_new(device, secondary_ac_list); + priv->pending_secondaries = g_slist_append(priv->pending_secondaries, secondary_data); + } else + g_slist_free_full(secondary_ac_list, g_object_unref); + + return success; } static void -device_state_changed (NMDevice *device, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason, - gpointer user_data) -{ - NMPolicyPrivate *priv = user_data; - NMPolicy *self = _PRIV_TO_SELF (priv); - NMActiveConnection *ac; - NMSettingsConnection *sett_conn = nm_device_get_settings_connection (device); - NMIP4Config *ip4_config; - NMIP6Config *ip6_config; - NMSettingConnection *s_con = NULL; - - switch (nm_device_state_reason_check (reason)) { - case NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED: - case NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED: - case NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT: - case NM_DEVICE_STATE_REASON_GSM_APN_FAILED: - /* Block autoconnection at settings level if there is any settings-specific - * error reported by the modem (e.g. wrong SIM-PIN or wrong APN). Do not block - * autoconnection at settings level for errors in the device domain (e.g. - * a missing SIM or wrong modem initialization). - */ - if (sett_conn) { - nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, - NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED, - TRUE); - } - break; - default: - break; - } - - switch (new_state) { - case NM_DEVICE_STATE_FAILED: - /* Mark the connection invalid if it failed during activation so that - * it doesn't get automatically chosen over and over and over again. - */ - if ( sett_conn - && old_state >= NM_DEVICE_STATE_PREPARE - && old_state <= NM_DEVICE_STATE_ACTIVATED) { - gboolean blocked = FALSE; - int tries; - guint64 con_v; - - if (nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_NO_SECRETS) { - /* we want to block the connection from auto-connect if it failed due to no-secrets. - * However, if a secret-agent registered, since the connection made the last - * secret-request, we do not block it. The new secret-agent might not yet - * been consulted, and it may be able to provide the secrets. - * - * We detect this by using a version-id of the agent-manager, which increments - * whenever new agents register. Note that the agent-manager's version-id is - * never zero and strictly increasing. - * - * A connection's version-id of zero means that the connection never tried to request secrets. - * That can happen when nm_settings_connection_get_secrets() fails early without actually - * consulting any agents. - */ - con_v = nm_settings_connection_get_last_secret_agent_version_id (sett_conn); - if ( con_v == 0 - || con_v == nm_agent_manager_get_agent_version_id (priv->agent_mgr)) { - _LOGD (LOGD_DEVICE, "connection '%s' now blocked from autoconnect due to no secrets", - nm_settings_connection_get_id (sett_conn)); - nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, - NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS, - TRUE); - blocked = TRUE; - } - } else if (nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED) { - /* A connection that fails due to dependency-failed is not - * able to reconnect until the master connection activates - * again; when this happens, the master clears the blocked - * reason for all its slaves in activate_slave_connections() - * and tries to reconnect them. For this to work, the slave - * should be marked as blocked when it fails with - * dependency-failed. - */ - _LOGD (LOGD_DEVICE, "connection '%s' now blocked from autoconnect due to failed dependency", - nm_settings_connection_get_id (sett_conn)); - nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, - NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED, - TRUE); - blocked = TRUE; - } - - if (!blocked) { - tries = nm_settings_connection_autoconnect_retries_get (sett_conn); - if (tries > 0) { - _LOGD (LOGD_DEVICE, "connection '%s' failed to autoconnect; %d tries left", - nm_settings_connection_get_id (sett_conn), tries - 1); - _connection_autoconnect_retries_set (self, sett_conn, tries - 1); - } else if (tries != 0) { - _LOGD (LOGD_DEVICE, "connection '%s' failed to autoconnect; infinite tries left", - nm_settings_connection_get_id (sett_conn)); - } - } - - nm_settings_connection_clear_secrets (sett_conn, FALSE, FALSE); - } - break; - case NM_DEVICE_STATE_ACTIVATED: - if (sett_conn) { - /* Reset auto retries back to default since connection was successful */ - nm_settings_connection_autoconnect_retries_reset (sett_conn); - - /* And clear secrets so they will always be requested from the - * settings service when the next connection is made. - */ - nm_settings_connection_clear_secrets (sett_conn, FALSE, FALSE); - } - - /* Add device's new IPv4 and IPv6 configs to DNS */ - - nm_dns_manager_begin_updates (priv->dns_manager, __func__); - - ip4_config = nm_device_get_ip4_config (device); - if (ip4_config) - _dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (ip4_config), NM_DNS_IP_CONFIG_TYPE_DEFAULT, device); - ip6_config = nm_device_get_ip6_config (device); - if (ip6_config) - _dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (ip6_config), NM_DNS_IP_CONFIG_TYPE_DEFAULT, device); - - update_routing_and_dns (self, FALSE, device); - - nm_dns_manager_end_updates (priv->dns_manager, __func__); - break; - case NM_DEVICE_STATE_UNMANAGED: - case NM_DEVICE_STATE_UNAVAILABLE: - if (old_state > NM_DEVICE_STATE_DISCONNECTED) - update_routing_and_dns (self, FALSE, device); - break; - case NM_DEVICE_STATE_DEACTIVATING: - if (sett_conn) { - NMSettingsAutoconnectBlockedReason blocked_reason = NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE; - - switch (nm_device_state_reason_check (reason)) { - case NM_DEVICE_STATE_REASON_USER_REQUESTED: - blocked_reason = NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST; - break; - case NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED: - blocked_reason = NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED; - break; - default: - break; - } - if (blocked_reason != NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE) { - _LOGD (LOGD_DEVICE, "blocking autoconnect of connection '%s': %s", - nm_settings_connection_get_id (sett_conn), - NM_UTILS_LOOKUP_STR_A (nm_device_state_reason_to_str, - nm_device_state_reason_check (reason))); - nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, blocked_reason, TRUE); - } - } - ip6_remove_device_prefix_delegations (self, device); - break; - case NM_DEVICE_STATE_DISCONNECTED: - /* Reset retry counts for a device's connections when carrier on; if cable - * was unplugged and plugged in again, we should try to reconnect. - */ - if ( nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_CARRIER - && old_state == NM_DEVICE_STATE_UNAVAILABLE) - reset_autoconnect_all (self, device, FALSE); - - if (old_state > NM_DEVICE_STATE_DISCONNECTED) - update_routing_and_dns (self, FALSE, device); - - /* Device is now available for auto-activation */ - schedule_activate_check (self, device); - break; - - case NM_DEVICE_STATE_PREPARE: - /* Reset auto-connect retries of all slaves and schedule them for - * activation. */ - activate_slave_connections (self, device); - - /* Now that the device state is progressing, we don't care - * anymore for the AC state. */ - ac = (NMActiveConnection *) nm_device_get_act_request (device); - if (ac && g_hash_table_remove (priv->pending_active_connections, ac)) { - g_signal_handlers_disconnect_by_func (ac, pending_ac_state_changed, self); - g_object_weak_unref (G_OBJECT (ac), pending_ac_gone, self); - g_object_unref (self); - } - break; - case NM_DEVICE_STATE_IP_CONFIG: - /* We must have secrets if we got here. */ - if (sett_conn) - nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_ALL, FALSE); - break; - case NM_DEVICE_STATE_SECONDARIES: - if (sett_conn) - s_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (sett_conn)); - if ( s_con - && nm_setting_connection_get_num_secondaries (s_con) > 0) { - /* Make routes and DNS up-to-date before activating dependent connections */ - update_routing_and_dns (self, FALSE, device); - - /* Activate secondary (VPN) connections */ - if (!activate_secondary_connections (self, - nm_settings_connection_get_connection (sett_conn), - device)) { - nm_device_queue_state (device, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED); - } - } else - nm_device_queue_state (device, NM_DEVICE_STATE_ACTIVATED, - NM_DEVICE_STATE_REASON_NONE); - break; - - default: - break; - } - - check_activating_active_connections (self); +device_state_changed(NMDevice * device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason, + gpointer user_data) +{ + NMPolicyPrivate * priv = user_data; + NMPolicy * self = _PRIV_TO_SELF(priv); + NMActiveConnection * ac; + NMSettingsConnection *sett_conn = nm_device_get_settings_connection(device); + NMIP4Config * ip4_config; + NMIP6Config * ip6_config; + NMSettingConnection * s_con = NULL; + + switch (nm_device_state_reason_check(reason)) { + case NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED: + case NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED: + case NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT: + case NM_DEVICE_STATE_REASON_GSM_APN_FAILED: + /* Block autoconnection at settings level if there is any settings-specific + * error reported by the modem (e.g. wrong SIM-PIN or wrong APN). Do not block + * autoconnection at settings level for errors in the device domain (e.g. + * a missing SIM or wrong modem initialization). + */ + if (sett_conn) { + nm_settings_connection_autoconnect_blocked_reason_set( + sett_conn, + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED, + TRUE); + } + break; + default: + break; + } + + switch (new_state) { + case NM_DEVICE_STATE_FAILED: + /* Mark the connection invalid if it failed during activation so that + * it doesn't get automatically chosen over and over and over again. + */ + if (sett_conn && old_state >= NM_DEVICE_STATE_PREPARE + && old_state <= NM_DEVICE_STATE_ACTIVATED) { + gboolean blocked = FALSE; + int tries; + guint64 con_v; + + if (nm_device_state_reason_check(reason) == NM_DEVICE_STATE_REASON_NO_SECRETS) { + /* we want to block the connection from auto-connect if it failed due to no-secrets. + * However, if a secret-agent registered, since the connection made the last + * secret-request, we do not block it. The new secret-agent might not yet + * been consulted, and it may be able to provide the secrets. + * + * We detect this by using a version-id of the agent-manager, which increments + * whenever new agents register. Note that the agent-manager's version-id is + * never zero and strictly increasing. + * + * A connection's version-id of zero means that the connection never tried to request secrets. + * That can happen when nm_settings_connection_get_secrets() fails early without actually + * consulting any agents. + */ + con_v = nm_settings_connection_get_last_secret_agent_version_id(sett_conn); + if (con_v == 0 || con_v == nm_agent_manager_get_agent_version_id(priv->agent_mgr)) { + _LOGD(LOGD_DEVICE, + "connection '%s' now blocked from autoconnect due to no secrets", + nm_settings_connection_get_id(sett_conn)); + nm_settings_connection_autoconnect_blocked_reason_set( + sett_conn, + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS, + TRUE); + blocked = TRUE; + } + } else if (nm_device_state_reason_check(reason) + == NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED) { + /* A connection that fails due to dependency-failed is not + * able to reconnect until the master connection activates + * again; when this happens, the master clears the blocked + * reason for all its slaves in activate_slave_connections() + * and tries to reconnect them. For this to work, the slave + * should be marked as blocked when it fails with + * dependency-failed. + */ + _LOGD(LOGD_DEVICE, + "connection '%s' now blocked from autoconnect due to failed dependency", + nm_settings_connection_get_id(sett_conn)); + nm_settings_connection_autoconnect_blocked_reason_set( + sett_conn, + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED, + TRUE); + blocked = TRUE; + } + + if (!blocked) { + tries = nm_settings_connection_autoconnect_retries_get(sett_conn); + if (tries > 0) { + _LOGD(LOGD_DEVICE, + "connection '%s' failed to autoconnect; %d tries left", + nm_settings_connection_get_id(sett_conn), + tries - 1); + _connection_autoconnect_retries_set(self, sett_conn, tries - 1); + } else if (tries != 0) { + _LOGD(LOGD_DEVICE, + "connection '%s' failed to autoconnect; infinite tries left", + nm_settings_connection_get_id(sett_conn)); + } + } + + nm_settings_connection_clear_secrets(sett_conn, FALSE, FALSE); + } + break; + case NM_DEVICE_STATE_ACTIVATED: + if (sett_conn) { + /* Reset auto retries back to default since connection was successful */ + nm_settings_connection_autoconnect_retries_reset(sett_conn); + + /* And clear secrets so they will always be requested from the + * settings service when the next connection is made. + */ + nm_settings_connection_clear_secrets(sett_conn, FALSE, FALSE); + } + + /* Add device's new IPv4 and IPv6 configs to DNS */ + + nm_dns_manager_begin_updates(priv->dns_manager, __func__); + + ip4_config = nm_device_get_ip4_config(device); + if (ip4_config) + _dns_manager_set_ip_config(priv->dns_manager, + NM_IP_CONFIG_CAST(ip4_config), + NM_DNS_IP_CONFIG_TYPE_DEFAULT, + device); + ip6_config = nm_device_get_ip6_config(device); + if (ip6_config) + _dns_manager_set_ip_config(priv->dns_manager, + NM_IP_CONFIG_CAST(ip6_config), + NM_DNS_IP_CONFIG_TYPE_DEFAULT, + device); + + update_routing_and_dns(self, FALSE, device); + + nm_dns_manager_end_updates(priv->dns_manager, __func__); + break; + case NM_DEVICE_STATE_UNMANAGED: + case NM_DEVICE_STATE_UNAVAILABLE: + if (old_state > NM_DEVICE_STATE_DISCONNECTED) + update_routing_and_dns(self, FALSE, device); + break; + case NM_DEVICE_STATE_DEACTIVATING: + if (sett_conn) { + NMSettingsAutoconnectBlockedReason blocked_reason = + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE; + + switch (nm_device_state_reason_check(reason)) { + case NM_DEVICE_STATE_REASON_USER_REQUESTED: + blocked_reason = NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST; + break; + case NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED: + blocked_reason = NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED; + break; + default: + break; + } + if (blocked_reason != NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE) { + _LOGD(LOGD_DEVICE, + "blocking autoconnect of connection '%s': %s", + nm_settings_connection_get_id(sett_conn), + NM_UTILS_LOOKUP_STR_A(nm_device_state_reason_to_str, + nm_device_state_reason_check(reason))); + nm_settings_connection_autoconnect_blocked_reason_set(sett_conn, + blocked_reason, + TRUE); + } + } + ip6_remove_device_prefix_delegations(self, device); + break; + case NM_DEVICE_STATE_DISCONNECTED: + /* Reset retry counts for a device's connections when carrier on; if cable + * was unplugged and plugged in again, we should try to reconnect. + */ + if (nm_device_state_reason_check(reason) == NM_DEVICE_STATE_REASON_CARRIER + && old_state == NM_DEVICE_STATE_UNAVAILABLE) + reset_autoconnect_all(self, device, FALSE); + + if (old_state > NM_DEVICE_STATE_DISCONNECTED) + update_routing_and_dns(self, FALSE, device); + + /* Device is now available for auto-activation */ + schedule_activate_check(self, device); + break; + + case NM_DEVICE_STATE_PREPARE: + /* Reset auto-connect retries of all slaves and schedule them for + * activation. */ + activate_slave_connections(self, device); + + /* Now that the device state is progressing, we don't care + * anymore for the AC state. */ + ac = (NMActiveConnection *) nm_device_get_act_request(device); + if (ac && g_hash_table_remove(priv->pending_active_connections, ac)) { + g_signal_handlers_disconnect_by_func(ac, pending_ac_state_changed, self); + g_object_weak_unref(G_OBJECT(ac), pending_ac_gone, self); + g_object_unref(self); + } + break; + case NM_DEVICE_STATE_IP_CONFIG: + /* We must have secrets if we got here. */ + if (sett_conn) + nm_settings_connection_autoconnect_blocked_reason_set( + sett_conn, + NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_ALL, + FALSE); + break; + case NM_DEVICE_STATE_SECONDARIES: + if (sett_conn) + s_con = nm_connection_get_setting_connection( + nm_settings_connection_get_connection(sett_conn)); + if (s_con && nm_setting_connection_get_num_secondaries(s_con) > 0) { + /* Make routes and DNS up-to-date before activating dependent connections */ + update_routing_and_dns(self, FALSE, device); + + /* Activate secondary (VPN) connections */ + if (!activate_secondary_connections(self, + nm_settings_connection_get_connection(sett_conn), + device)) { + nm_device_queue_state(device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED); + } + } else + nm_device_queue_state(device, NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_REASON_NONE); + break; + + default: + break; + } + + check_activating_active_connections(self); } static void -device_ip_config_changed (NMDevice *device, - NMIPConfig *new_config, - NMIPConfig *old_config, - gpointer user_data) -{ - NMPolicyPrivate *priv = user_data; - NMPolicy *self = _PRIV_TO_SELF (priv); - int addr_family; - - nm_assert (new_config || old_config); - nm_assert (!new_config || NM_IS_IP_CONFIG (new_config, AF_UNSPEC)); - nm_assert (!old_config || NM_IS_IP_CONFIG (old_config, AF_UNSPEC)); - - if (new_config) { - addr_family = nm_ip_config_get_addr_family (new_config); - nm_assert (!old_config || addr_family == nm_ip_config_get_addr_family (old_config)); - } else - addr_family = nm_ip_config_get_addr_family (old_config); - - nm_dns_manager_begin_updates (priv->dns_manager, __func__); - - /* We catch already all the IP events registering on the device state changes but - * the ones where the IP changes but the device state keep stable (i.e., activated): - * ignore IP config changes but when the device is in activated state. - * Prevents unnecessary changes to DNS information. - */ - if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) { - if (old_config != new_config) { - if (new_config) - _dns_manager_set_ip_config (priv->dns_manager, new_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT, device); - if (old_config) - nm_dns_manager_set_ip_config (priv->dns_manager, old_config, NM_DNS_IP_CONFIG_TYPE_REMOVED); - } - update_ip_dns (self, addr_family, device); - if (addr_family == AF_INET) - update_ip4_routing (self, TRUE); - else - update_ip6_routing (self, TRUE); - update_system_hostname (self, - addr_family == AF_INET - ? "ip4 conf" - : "ip6 conf"); - } else { - /* Old configs get removed immediately */ - if (old_config) - nm_dns_manager_set_ip_config (priv->dns_manager, old_config, NM_DNS_IP_CONFIG_TYPE_REMOVED); - } - - nm_dns_manager_end_updates (priv->dns_manager, __func__); +device_ip_config_changed(NMDevice * device, + NMIPConfig *new_config, + NMIPConfig *old_config, + gpointer user_data) +{ + NMPolicyPrivate *priv = user_data; + NMPolicy * self = _PRIV_TO_SELF(priv); + int addr_family; + + nm_assert(new_config || old_config); + nm_assert(!new_config || NM_IS_IP_CONFIG(new_config)); + nm_assert(!old_config || NM_IS_IP_CONFIG(old_config)); + + if (new_config) { + addr_family = nm_ip_config_get_addr_family(new_config); + nm_assert(!old_config || addr_family == nm_ip_config_get_addr_family(old_config)); + } else + addr_family = nm_ip_config_get_addr_family(old_config); + + nm_dns_manager_begin_updates(priv->dns_manager, __func__); + + /* We catch already all the IP events registering on the device state changes but + * the ones where the IP changes but the device state keep stable (i.e., activated): + * ignore IP config changes but when the device is in activated state. + * Prevents unnecessary changes to DNS information. + */ + if (nm_device_get_state(device) == NM_DEVICE_STATE_ACTIVATED) { + if (old_config != new_config) { + if (new_config) + _dns_manager_set_ip_config(priv->dns_manager, + new_config, + NM_DNS_IP_CONFIG_TYPE_DEFAULT, + device); + if (old_config) + nm_dns_manager_set_ip_config(priv->dns_manager, + old_config, + NM_DNS_IP_CONFIG_TYPE_REMOVED); + } + update_ip_dns(self, addr_family, device); + if (addr_family == AF_INET) + update_ip4_routing(self, TRUE); + else + update_ip6_routing(self, TRUE); + update_system_hostname(self, addr_family == AF_INET ? "ip4 conf" : "ip6 conf"); + } else { + /* Old configs get removed immediately */ + if (old_config) + nm_dns_manager_set_ip_config(priv->dns_manager, + old_config, + NM_DNS_IP_CONFIG_TYPE_REMOVED); + } + + nm_dns_manager_end_updates(priv->dns_manager, __func__); } /*****************************************************************************/ static void -device_autoconnect_changed (NMDevice *device, - GParamSpec *pspec, - gpointer user_data) +device_autoconnect_changed(NMDevice *device, GParamSpec *pspec, gpointer user_data) { - NMPolicyPrivate *priv = user_data; - NMPolicy *self = _PRIV_TO_SELF (priv); + NMPolicyPrivate *priv = user_data; + NMPolicy * self = _PRIV_TO_SELF(priv); - schedule_activate_check (self, device); + schedule_activate_check(self, device); } static void -device_recheck_auto_activate (NMDevice *device, gpointer user_data) +device_recheck_auto_activate(NMDevice *device, gpointer user_data) { - NMPolicyPrivate *priv = user_data; - NMPolicy *self = _PRIV_TO_SELF (priv); + NMPolicyPrivate *priv = user_data; + NMPolicy * self = _PRIV_TO_SELF(priv); - schedule_activate_check (self, device); + schedule_activate_check(self, device); } static void -devices_list_unregister (NMPolicy *self, NMDevice *device) +devices_list_unregister(NMPolicy *self, NMDevice *device) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); - g_signal_handlers_disconnect_by_data ((GObject *) device, priv); + g_signal_handlers_disconnect_by_data((GObject *) device, priv); } static void -devices_list_register (NMPolicy *self, NMDevice *device) -{ - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - - /* Connect state-changed with _after, so that the handler is invoked after other handlers. */ - g_signal_connect_after (device, NM_DEVICE_STATE_CHANGED, (GCallback) device_state_changed, priv); - g_signal_connect (device, NM_DEVICE_IP4_CONFIG_CHANGED, (GCallback) device_ip_config_changed, priv); - g_signal_connect (device, NM_DEVICE_IP6_CONFIG_CHANGED, (GCallback) device_ip_config_changed, priv); - g_signal_connect (device, NM_DEVICE_IP6_PREFIX_DELEGATED, (GCallback) device_ip6_prefix_delegated, priv); - g_signal_connect (device, NM_DEVICE_IP6_SUBNET_NEEDED, (GCallback) device_ip6_subnet_needed, priv); - g_signal_connect (device, "notify::" NM_DEVICE_AUTOCONNECT, (GCallback) device_autoconnect_changed, priv); - g_signal_connect (device, NM_DEVICE_RECHECK_AUTO_ACTIVATE, (GCallback) device_recheck_auto_activate, priv); +devices_list_register(NMPolicy *self, NMDevice *device) +{ + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); + + /* Connect state-changed with _after, so that the handler is invoked after other handlers. */ + g_signal_connect_after(device, NM_DEVICE_STATE_CHANGED, (GCallback) device_state_changed, priv); + g_signal_connect(device, + NM_DEVICE_IP4_CONFIG_CHANGED, + (GCallback) device_ip_config_changed, + priv); + g_signal_connect(device, + NM_DEVICE_IP6_CONFIG_CHANGED, + (GCallback) device_ip_config_changed, + priv); + g_signal_connect(device, + NM_DEVICE_IP6_PREFIX_DELEGATED, + (GCallback) device_ip6_prefix_delegated, + priv); + g_signal_connect(device, + NM_DEVICE_IP6_SUBNET_NEEDED, + (GCallback) device_ip6_subnet_needed, + priv); + g_signal_connect(device, + "notify::" NM_DEVICE_AUTOCONNECT, + (GCallback) device_autoconnect_changed, + priv); + g_signal_connect(device, + NM_DEVICE_RECHECK_AUTO_ACTIVATE, + (GCallback) device_recheck_auto_activate, + priv); } static void -device_added (NMManager *manager, NMDevice *device, gpointer user_data) +device_added(NMManager *manager, NMDevice *device, gpointer user_data) { - NMPolicyPrivate *priv = user_data; - NMPolicy *self = _PRIV_TO_SELF (priv); + NMPolicyPrivate *priv = user_data; + NMPolicy * self = _PRIV_TO_SELF(priv); - g_return_if_fail (NM_IS_POLICY (self)); + g_return_if_fail(NM_IS_POLICY(self)); - priv = NM_POLICY_GET_PRIVATE (self); + priv = NM_POLICY_GET_PRIVATE(self); - if (!g_hash_table_add (priv->devices, device)) - g_return_if_reached (); + if (!g_hash_table_add(priv->devices, device)) + g_return_if_reached(); - devices_list_register (self, device); + devices_list_register(self, device); } static void -device_removed (NMManager *manager, NMDevice *device, gpointer user_data) +device_removed(NMManager *manager, NMDevice *device, gpointer user_data) { - NMPolicyPrivate *priv = user_data; - NMPolicy *self = _PRIV_TO_SELF (priv); - ActivateData *data; + NMPolicyPrivate *priv = user_data; + NMPolicy * self = _PRIV_TO_SELF(priv); + ActivateData * data; - /* XXX is this needed? The delegations are cleaned up - * on transition to deactivated too. */ - ip6_remove_device_prefix_delegations (self, device); + /* TODO: is this needed? The delegations are cleaned up + * on transition to deactivated too. */ + ip6_remove_device_prefix_delegations(self, device); - /* Clear any idle callbacks for this device */ - data = find_pending_activation (self, device); - if (data && data->autoactivate_id) - activate_data_free (data); + /* Clear any idle callbacks for this device */ + data = find_pending_activation(self, device); + if (data && data->autoactivate_id) + activate_data_free(data); - if (g_hash_table_remove (priv->devices, device)) - devices_list_unregister (self, device); + if (g_hash_table_remove(priv->devices, device)) + devices_list_unregister(self, device); - /* Don't update routing and DNS here as we've already handled that - * for devices that need it when the device's state changed to UNMANAGED. - */ + /* Don't update routing and DNS here as we've already handled that + * for devices that need it when the device's state changed to UNMANAGED. + */ } /*****************************************************************************/ static void -vpn_connection_activated (NMPolicy *self, NMVpnConnection *vpn) +vpn_connection_activated(NMPolicy *self, NMVpnConnection *vpn) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - NMIP4Config *ip4_config; - NMIP6Config *ip6_config; + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); + NMIP4Config * ip4_config; + NMIP6Config * ip6_config; - nm_dns_manager_begin_updates (priv->dns_manager, __func__); + nm_dns_manager_begin_updates(priv->dns_manager, __func__); - ip4_config = nm_vpn_connection_get_ip4_config (vpn); - if (ip4_config) - nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (ip4_config), NM_DNS_IP_CONFIG_TYPE_VPN); + ip4_config = nm_vpn_connection_get_ip4_config(vpn); + if (ip4_config) + nm_dns_manager_set_ip_config(priv->dns_manager, + NM_IP_CONFIG_CAST(ip4_config), + NM_DNS_IP_CONFIG_TYPE_VPN); - ip6_config = nm_vpn_connection_get_ip6_config (vpn); - if (ip6_config) - nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (ip6_config), NM_DNS_IP_CONFIG_TYPE_VPN); + ip6_config = nm_vpn_connection_get_ip6_config(vpn); + if (ip6_config) + nm_dns_manager_set_ip_config(priv->dns_manager, + NM_IP_CONFIG_CAST(ip6_config), + NM_DNS_IP_CONFIG_TYPE_VPN); - update_routing_and_dns (self, TRUE, NULL); + update_routing_and_dns(self, TRUE, NULL); - nm_dns_manager_end_updates (priv->dns_manager, __func__); + nm_dns_manager_end_updates(priv->dns_manager, __func__); } static void -vpn_connection_deactivated (NMPolicy *self, NMVpnConnection *vpn) +vpn_connection_deactivated(NMPolicy *self, NMVpnConnection *vpn) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - NMIP4Config *ip4_config; - NMIP6Config *ip6_config; + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); + NMIP4Config * ip4_config; + NMIP6Config * ip6_config; - nm_dns_manager_begin_updates (priv->dns_manager, __func__); + nm_dns_manager_begin_updates(priv->dns_manager, __func__); - ip4_config = nm_vpn_connection_get_ip4_config (vpn); - if (ip4_config) - nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (ip4_config), NM_DNS_IP_CONFIG_TYPE_REMOVED); + ip4_config = nm_vpn_connection_get_ip4_config(vpn); + if (ip4_config) + nm_dns_manager_set_ip_config(priv->dns_manager, + NM_IP_CONFIG_CAST(ip4_config), + NM_DNS_IP_CONFIG_TYPE_REMOVED); - ip6_config = nm_vpn_connection_get_ip6_config (vpn); - if (ip6_config) - nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (ip6_config), NM_DNS_IP_CONFIG_TYPE_REMOVED); + ip6_config = nm_vpn_connection_get_ip6_config(vpn); + if (ip6_config) + nm_dns_manager_set_ip_config(priv->dns_manager, + NM_IP_CONFIG_CAST(ip6_config), + NM_DNS_IP_CONFIG_TYPE_REMOVED); - update_routing_and_dns (self, TRUE, NULL); + update_routing_and_dns(self, TRUE, NULL); - nm_dns_manager_end_updates (priv->dns_manager, __func__); + nm_dns_manager_end_updates(priv->dns_manager, __func__); } static void -vpn_connection_state_changed (NMVpnConnection *vpn, - NMVpnConnectionState new_state, - NMVpnConnectionState old_state, - NMActiveConnectionStateReason reason, - NMPolicy *self) -{ - if (new_state == NM_VPN_CONNECTION_STATE_ACTIVATED) - vpn_connection_activated (self, vpn); - else if (new_state >= NM_VPN_CONNECTION_STATE_FAILED) { - /* Only clean up IP/DNS if the connection ever got past IP_CONFIG */ - if (old_state >= NM_VPN_CONNECTION_STATE_IP_CONFIG_GET && - old_state <= NM_VPN_CONNECTION_STATE_ACTIVATED) - vpn_connection_deactivated (self, vpn); - } +vpn_connection_state_changed(NMVpnConnection * vpn, + NMVpnConnectionState new_state, + NMVpnConnectionState old_state, + NMActiveConnectionStateReason reason, + NMPolicy * self) +{ + if (new_state == NM_VPN_CONNECTION_STATE_ACTIVATED) + vpn_connection_activated(self, vpn); + else if (new_state >= NM_VPN_CONNECTION_STATE_FAILED) { + /* Only clean up IP/DNS if the connection ever got past IP_CONFIG */ + if (old_state >= NM_VPN_CONNECTION_STATE_IP_CONFIG_GET + && old_state <= NM_VPN_CONNECTION_STATE_ACTIVATED) + vpn_connection_deactivated(self, vpn); + } } static void -vpn_connection_retry_after_failure (NMVpnConnection *vpn, NMPolicy *self) -{ - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - NMActiveConnection *ac = NM_ACTIVE_CONNECTION (vpn); - NMSettingsConnection *connection = nm_active_connection_get_settings_connection (ac); - GError *error = NULL; - - /* Attempt to reconnect VPN connections that failed after being connected */ - if (!nm_manager_activate_connection (priv->manager, - connection, - NULL, - NULL, - NULL, - nm_active_connection_get_subject (ac), - NM_ACTIVATION_TYPE_MANAGED, - nm_active_connection_get_activation_reason (ac), - ( nm_active_connection_get_state_flags (ac) - & NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY), - &error)) { - _LOGW (LOGD_DEVICE, "VPN '%s' reconnect failed: %s", - nm_settings_connection_get_id (connection), - error->message ?: "unknown"); - g_clear_error (&error); - } +vpn_connection_retry_after_failure(NMVpnConnection *vpn, NMPolicy *self) +{ + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + NMActiveConnection * ac = NM_ACTIVE_CONNECTION(vpn); + NMSettingsConnection *connection = nm_active_connection_get_settings_connection(ac); + GError * error = NULL; + + /* Attempt to reconnect VPN connections that failed after being connected */ + if (!nm_manager_activate_connection( + priv->manager, + connection, + NULL, + NULL, + NULL, + nm_active_connection_get_subject(ac), + NM_ACTIVATION_TYPE_MANAGED, + nm_active_connection_get_activation_reason(ac), + (nm_active_connection_get_state_flags(ac) + & NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY), + &error)) { + _LOGW(LOGD_DEVICE, + "VPN '%s' reconnect failed: %s", + nm_settings_connection_get_id(connection), + error->message ?: "unknown"); + g_clear_error(&error); + } } static void -active_connection_state_changed (NMActiveConnection *active, - GParamSpec *pspec, - NMPolicy *self) +active_connection_state_changed(NMActiveConnection *active, GParamSpec *pspec, NMPolicy *self) { - NMActiveConnectionState state = nm_active_connection_get_state (active); + NMActiveConnectionState state = nm_active_connection_get_state(active); - if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) - process_secondaries (self, active, TRUE); - else if (state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) - process_secondaries (self, active, FALSE); + if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) + process_secondaries(self, active, TRUE); + else if (state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) + process_secondaries(self, active, FALSE); } static void -active_connection_keep_alive_changed (NMKeepAlive *keep_alive, - GParamSpec *pspec, - NMPolicy *self) +active_connection_keep_alive_changed(NMKeepAlive *keep_alive, GParamSpec *pspec, NMPolicy *self) { - NMPolicyPrivate *priv; - NMActiveConnection *ac; - GError *error = NULL; + NMPolicyPrivate * priv; + NMActiveConnection *ac; + GError * error = NULL; - nm_assert (NM_IS_POLICY (self)); - nm_assert (NM_IS_KEEP_ALIVE (keep_alive)); - nm_assert (NM_IS_ACTIVE_CONNECTION (nm_keep_alive_get_owner (keep_alive))); + nm_assert(NM_IS_POLICY(self)); + nm_assert(NM_IS_KEEP_ALIVE(keep_alive)); + nm_assert(NM_IS_ACTIVE_CONNECTION(nm_keep_alive_get_owner(keep_alive))); - if (nm_keep_alive_is_alive (keep_alive)) - return; + if (nm_keep_alive_is_alive(keep_alive)) + return; - ac = nm_keep_alive_get_owner (keep_alive); + ac = nm_keep_alive_get_owner(keep_alive); - if (nm_active_connection_get_state (ac) > NM_ACTIVE_CONNECTION_STATE_ACTIVATED) - return; + if (nm_active_connection_get_state(ac) > NM_ACTIVE_CONNECTION_STATE_ACTIVATED) + return; - priv = NM_POLICY_GET_PRIVATE (self); + priv = NM_POLICY_GET_PRIVATE(self); - if (!nm_manager_deactivate_connection (priv->manager, - ac, - NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, - &error)) { - _LOGW (LOGD_DEVICE, "connection '%s' is no longer kept alive, but error deactivating it: %s", - nm_active_connection_get_settings_connection_id (ac), - error->message); - g_clear_error (&error); - } + if (!nm_manager_deactivate_connection(priv->manager, + ac, + NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, + &error)) { + _LOGW(LOGD_DEVICE, + "connection '%s' is no longer kept alive, but error deactivating it: %s", + nm_active_connection_get_settings_connection_id(ac), + error->message); + g_clear_error(&error); + } } static void -active_connection_added (NMManager *manager, - NMActiveConnection *active, - gpointer user_data) -{ - NMPolicyPrivate *priv = user_data; - NMPolicy *self = _PRIV_TO_SELF (priv); - NMKeepAlive *keep_alive; - - if (NM_IS_VPN_CONNECTION (active)) { - g_signal_connect (active, NM_VPN_CONNECTION_INTERNAL_STATE_CHANGED, - G_CALLBACK (vpn_connection_state_changed), - self); - g_signal_connect (active, NM_VPN_CONNECTION_INTERNAL_RETRY_AFTER_FAILURE, - G_CALLBACK (vpn_connection_retry_after_failure), - self); - } - - keep_alive = nm_active_connection_get_keep_alive (active); - - nm_keep_alive_arm (keep_alive); - - g_signal_connect (active, "notify::" NM_ACTIVE_CONNECTION_STATE, - G_CALLBACK (active_connection_state_changed), - self); - g_signal_connect (keep_alive, - "notify::" NM_KEEP_ALIVE_ALIVE, - G_CALLBACK (active_connection_keep_alive_changed), - self); - active_connection_keep_alive_changed (keep_alive, NULL, self); +active_connection_added(NMManager *manager, NMActiveConnection *active, gpointer user_data) +{ + NMPolicyPrivate *priv = user_data; + NMPolicy * self = _PRIV_TO_SELF(priv); + NMKeepAlive * keep_alive; + + if (NM_IS_VPN_CONNECTION(active)) { + g_signal_connect(active, + NM_VPN_CONNECTION_INTERNAL_STATE_CHANGED, + G_CALLBACK(vpn_connection_state_changed), + self); + g_signal_connect(active, + NM_VPN_CONNECTION_INTERNAL_RETRY_AFTER_FAILURE, + G_CALLBACK(vpn_connection_retry_after_failure), + self); + } + + keep_alive = nm_active_connection_get_keep_alive(active); + + nm_keep_alive_arm(keep_alive); + + g_signal_connect(active, + "notify::" NM_ACTIVE_CONNECTION_STATE, + G_CALLBACK(active_connection_state_changed), + self); + g_signal_connect(keep_alive, + "notify::" NM_KEEP_ALIVE_ALIVE, + G_CALLBACK(active_connection_keep_alive_changed), + self); + active_connection_keep_alive_changed(keep_alive, NULL, self); } static void -active_connection_removed (NMManager *manager, - NMActiveConnection *active, - gpointer user_data) -{ - NMPolicyPrivate *priv = user_data; - NMPolicy *self = _PRIV_TO_SELF (priv); - - g_signal_handlers_disconnect_by_func (active, - vpn_connection_state_changed, - self); - g_signal_handlers_disconnect_by_func (active, - vpn_connection_retry_after_failure, - self); - g_signal_handlers_disconnect_by_func (active, - active_connection_state_changed, - self); - g_signal_handlers_disconnect_by_func (nm_active_connection_get_keep_alive (active), - active_connection_keep_alive_changed, - self); +active_connection_removed(NMManager *manager, NMActiveConnection *active, gpointer user_data) +{ + NMPolicyPrivate *priv = user_data; + NMPolicy * self = _PRIV_TO_SELF(priv); + + g_signal_handlers_disconnect_by_func(active, vpn_connection_state_changed, self); + g_signal_handlers_disconnect_by_func(active, vpn_connection_retry_after_failure, self); + g_signal_handlers_disconnect_by_func(active, active_connection_state_changed, self); + g_signal_handlers_disconnect_by_func(nm_active_connection_get_keep_alive(active), + active_connection_keep_alive_changed, + self); } /*****************************************************************************/ static gboolean -schedule_activate_all_cb (gpointer user_data) +schedule_activate_all_cb(gpointer user_data) { - NMPolicy *self = user_data; - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - const CList *tmp_lst; - NMDevice *device; + NMPolicy * self = user_data; + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); + const CList * tmp_lst; + NMDevice * device; - priv->schedule_activate_all_id = 0; + priv->schedule_activate_all_id = 0; - nm_manager_for_each_device (priv->manager, device, tmp_lst) - schedule_activate_check (self, device); + nm_manager_for_each_device (priv->manager, device, tmp_lst) + schedule_activate_check(self, device); - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; } static void -schedule_activate_all (NMPolicy *self) +schedule_activate_all(NMPolicy *self) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); - /* always restart the idle handler. That way, we settle - * all other events before restarting to activate them. */ - nm_clear_g_source (&priv->schedule_activate_all_id); - priv->schedule_activate_all_id = g_idle_add (schedule_activate_all_cb, self); + /* always restart the idle handler. That way, we settle + * all other events before restarting to activate them. */ + nm_clear_g_source(&priv->schedule_activate_all_id); + priv->schedule_activate_all_id = g_idle_add(schedule_activate_all_cb, self); } static void -connection_added (NMSettings *settings, - NMSettingsConnection *connection, - gpointer user_data) +connection_added(NMSettings *settings, NMSettingsConnection *connection, gpointer user_data) { - NMPolicyPrivate *priv = user_data; - NMPolicy *self = _PRIV_TO_SELF (priv); + NMPolicyPrivate *priv = user_data; + NMPolicy * self = _PRIV_TO_SELF(priv); - schedule_activate_all (self); + schedule_activate_all(self); } static void -firewall_state_changed (NMFirewallManager *manager, - gboolean initialized_now, - gpointer user_data) +firewall_state_changed(NMFirewallManager *manager, gboolean initialized_now, gpointer user_data) { - NMPolicy *self = (NMPolicy *) user_data; - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - const CList *tmp_lst; - NMDevice *device; + NMPolicy * self = (NMPolicy *) user_data; + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); + const CList * tmp_lst; + NMDevice * device; - if (initialized_now) { - /* the firewall manager was initializing, but all requests - * so fare were queued and are already sent. No need to - * re-update the firewall zone of the devices. */ - return; - } + if (initialized_now) { + /* the firewall manager was initializing, but all requests + * so fare were queued and are already sent. No need to + * re-update the firewall zone of the devices. */ + return; + } - if (!nm_firewall_manager_get_running (manager)) - return; + if (!nm_firewall_manager_get_running(manager)) + return; - /* add interface of each device to correct zone */ - nm_manager_for_each_device (priv->manager, device, tmp_lst) - nm_device_update_firewall_zone (device); + /* add interface of each device to correct zone */ + nm_manager_for_each_device (priv->manager, device, tmp_lst) + nm_device_update_firewall_zone(device); } static void -dns_config_changed (NMDnsManager *dns_manager, gpointer user_data) +dns_config_changed(NMDnsManager *dns_manager, gpointer user_data) { - NMPolicy *self = (NMPolicy *) user_data; - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); + NMPolicy * self = (NMPolicy *) user_data; + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); - /* Restart a thread for reverse-DNS lookup after we are signalled that - * DNS changed. Because the result from a previous run may not be right - * (race in updating DNS and doing the reverse lookup). - */ + /* Restart a thread for reverse-DNS lookup after we are signalled that + * DNS changed. Because the result from a previous run may not be right + * (race in updating DNS and doing the reverse lookup). + */ - nm_clear_g_cancellable (&priv->lookup.cancellable); + nm_clear_g_cancellable(&priv->lookup.cancellable); - /* Re-start the hostname lookup thread if we don't have hostname yet. */ - if (priv->lookup.addr) { - char *str = NULL; - gs_free char *hostname = NULL; + /* Re-start the hostname lookup thread if we don't have hostname yet. */ + if (priv->lookup.addr) { + char * str = NULL; + gs_free char *hostname = NULL; - /* Check if the hostname was externally set */ - if ( (hostname = _get_hostname (self)) - && nm_utils_is_specific_hostname (hostname) - && !nm_streq0 (hostname, priv->last_hostname)) { - g_clear_object (&priv->lookup.addr); - return; - } + /* Check if the hostname was externally set */ + if ((hostname = _get_hostname(self)) && nm_utils_is_specific_hostname(hostname) + && !nm_streq0(hostname, priv->last_hostname)) { + g_clear_object(&priv->lookup.addr); + return; + } - _LOGD (LOGD_DNS, "restarting reverse-lookup thread for address %s", - (str = g_inet_address_to_string (priv->lookup.addr))); - g_free (str); + _LOGD(LOGD_DNS, + "restarting reverse-lookup thread for address %s", + (str = g_inet_address_to_string(priv->lookup.addr))); + g_free(str); - lookup_by_address (self); - } + lookup_by_address(self); + } } static void -connection_updated (NMSettings *settings, - NMSettingsConnection *connection, - guint update_reason_u, - gpointer user_data) +connection_updated(NMSettings * settings, + NMSettingsConnection *connection, + guint update_reason_u, + gpointer user_data) { - NMPolicyPrivate *priv = user_data; - NMPolicy *self = _PRIV_TO_SELF (priv); - NMSettingsConnectionUpdateReason update_reason = update_reason_u; + NMPolicyPrivate * priv = user_data; + NMPolicy * self = _PRIV_TO_SELF(priv); + NMSettingsConnectionUpdateReason update_reason = update_reason_u; - if (NM_FLAGS_HAS (update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_REAPPLY_PARTIAL)) { - const CList *tmp_lst; - NMDevice *device; + if (NM_FLAGS_HAS(update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_REAPPLY_PARTIAL)) { + const CList *tmp_lst; + NMDevice * device; - /* find device with given connection */ - nm_manager_for_each_device (priv->manager, device, tmp_lst) { - if (nm_device_get_settings_connection (device) == connection) - nm_device_reapply_settings_immediately (device); - } - } + /* find device with given connection */ + nm_manager_for_each_device (priv->manager, device, tmp_lst) { + if (nm_device_get_settings_connection(device) == connection) + nm_device_reapply_settings_immediately(device); + } + } - schedule_activate_all (self); + schedule_activate_all(self); } static void -_deactivate_if_active (NMPolicy *self, NMSettingsConnection *connection) -{ - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - NMActiveConnection *ac; - const CList *tmp_list, *tmp_safe; - GError *error = NULL; - - nm_assert (NM_IS_SETTINGS_CONNECTION (connection)); - - nm_manager_for_each_active_connection_safe (priv->manager, ac, tmp_list, tmp_safe) { - - if ( nm_active_connection_get_settings_connection (ac) == connection - && (nm_active_connection_get_state (ac) <= NM_ACTIVE_CONNECTION_STATE_ACTIVATED)) { - if (!nm_manager_deactivate_connection (priv->manager, - ac, - NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, - &error)) { - _LOGW (LOGD_DEVICE, "connection '%s' disappeared, but error deactivating it: (%d) %s", - nm_settings_connection_get_id (connection), - error ? error->code : -1, - error ? error->message : "(unknown)"); - g_clear_error (&error); - } - } - } +_deactivate_if_active(NMPolicy *self, NMSettingsConnection *connection) +{ + NMPolicyPrivate * priv = NM_POLICY_GET_PRIVATE(self); + NMActiveConnection *ac; + const CList * tmp_list, *tmp_safe; + GError * error = NULL; + + nm_assert(NM_IS_SETTINGS_CONNECTION(connection)); + + nm_manager_for_each_active_connection_safe (priv->manager, ac, tmp_list, tmp_safe) { + if (nm_active_connection_get_settings_connection(ac) == connection + && (nm_active_connection_get_state(ac) <= NM_ACTIVE_CONNECTION_STATE_ACTIVATED)) { + if (!nm_manager_deactivate_connection(priv->manager, + ac, + NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, + &error)) { + _LOGW(LOGD_DEVICE, + "connection '%s' disappeared, but error deactivating it: (%d) %s", + nm_settings_connection_get_id(connection), + error ? error->code : -1, + error ? error->message : "(unknown)"); + g_clear_error(&error); + } + } + } } static void -connection_removed (NMSettings *settings, - NMSettingsConnection *connection, - gpointer user_data) +connection_removed(NMSettings *settings, NMSettingsConnection *connection, gpointer user_data) { - NMPolicyPrivate *priv = user_data; - NMPolicy *self = _PRIV_TO_SELF (priv); + NMPolicyPrivate *priv = user_data; + NMPolicy * self = _PRIV_TO_SELF(priv); - _deactivate_if_active (self, connection); + _deactivate_if_active(self, connection); } static void -connection_flags_changed (NMSettings *settings, - NMSettingsConnection *connection, - gpointer user_data) +connection_flags_changed(NMSettings *settings, NMSettingsConnection *connection, gpointer user_data) { - NMPolicyPrivate *priv = user_data; - NMPolicy *self = _PRIV_TO_SELF (priv); + NMPolicyPrivate *priv = user_data; + NMPolicy * self = _PRIV_TO_SELF(priv); - if (NM_FLAGS_HAS (nm_settings_connection_get_flags (connection), - NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE)) { - if (!nm_settings_connection_autoconnect_is_blocked (connection)) - schedule_activate_all (self); - } + if (NM_FLAGS_HAS(nm_settings_connection_get_flags(connection), + NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE)) { + if (!nm_settings_connection_autoconnect_is_blocked(connection)) + schedule_activate_all(self); + } } static void -secret_agent_registered (NMSettings *settings, - NMSecretAgent *agent, - gpointer user_data) +secret_agent_registered(NMSettings *settings, NMSecretAgent *agent, gpointer user_data) { - NMPolicy *self = NM_POLICY (user_data); + NMPolicy *self = NM_POLICY(user_data); - /* The registered secret agent may provide some missing secrets. Thus we - * reset retries count here and schedule activation, so that the - * connections failed due to missing secrets may re-try auto-connection. - */ - if (reset_autoconnect_all (self, NULL, TRUE)) - schedule_activate_all (self); + /* The registered secret agent may provide some missing secrets. Thus we + * reset retries count here and schedule activation, so that the + * connections failed due to missing secrets may re-try auto-connection. + */ + if (reset_autoconnect_all(self, NULL, TRUE)) + schedule_activate_all(self); } NMActiveConnection * -nm_policy_get_default_ip4_ac (NMPolicy *self) +nm_policy_get_default_ip4_ac(NMPolicy *self) { - return NM_POLICY_GET_PRIVATE (self)->default_ac4; + return NM_POLICY_GET_PRIVATE(self)->default_ac4; } NMActiveConnection * -nm_policy_get_default_ip6_ac (NMPolicy *self) +nm_policy_get_default_ip6_ac(NMPolicy *self) { - return NM_POLICY_GET_PRIVATE (self)->default_ac6; + return NM_POLICY_GET_PRIVATE(self)->default_ac6; } NMActiveConnection * -nm_policy_get_activating_ip4_ac (NMPolicy *self) +nm_policy_get_activating_ip4_ac(NMPolicy *self) { - return NM_POLICY_GET_PRIVATE (self)->activating_ac4; + return NM_POLICY_GET_PRIVATE(self)->activating_ac4; } NMActiveConnection * -nm_policy_get_activating_ip6_ac (NMPolicy *self) +nm_policy_get_activating_ip6_ac(NMPolicy *self) { - return NM_POLICY_GET_PRIVATE (self)->activating_ac6; + return NM_POLICY_GET_PRIVATE(self)->activating_ac6; } /*****************************************************************************/ -static -NM_UTILS_LOOKUP_STR_DEFINE (_hostname_mode_to_string, NMPolicyHostnameMode, - NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT ("unknown"), - NM_UTILS_LOOKUP_STR_ITEM (NM_POLICY_HOSTNAME_MODE_NONE, "none"), - NM_UTILS_LOOKUP_STR_ITEM (NM_POLICY_HOSTNAME_MODE_DHCP, "dhcp"), - NM_UTILS_LOOKUP_STR_ITEM (NM_POLICY_HOSTNAME_MODE_FULL, "full"), -); +static NM_UTILS_LOOKUP_STR_DEFINE(_hostname_mode_to_string, + NMPolicyHostnameMode, + NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT("unknown"), + NM_UTILS_LOOKUP_STR_ITEM(NM_POLICY_HOSTNAME_MODE_NONE, "none"), + NM_UTILS_LOOKUP_STR_ITEM(NM_POLICY_HOSTNAME_MODE_DHCP, "dhcp"), + NM_UTILS_LOOKUP_STR_ITEM(NM_POLICY_HOSTNAME_MODE_FULL, "full"), ); /*****************************************************************************/ static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - NMPolicy *self = NM_POLICY (object); - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - - switch (prop_id) { - case PROP_DEFAULT_IP4_AC: - g_value_set_object (value, priv->default_ac4); - break; - case PROP_DEFAULT_IP6_AC: - g_value_set_object (value, priv->default_ac6); - break; - case PROP_ACTIVATING_IP4_AC: - g_value_set_object (value, priv->activating_ac4); - break; - case PROP_ACTIVATING_IP6_AC: - g_value_set_object (value, priv->activating_ac6); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMPolicy * self = NM_POLICY(object); + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); + + switch (prop_id) { + case PROP_DEFAULT_IP4_AC: + g_value_set_object(value, priv->default_ac4); + break; + case PROP_DEFAULT_IP6_AC: + g_value_set_object(value, priv->default_ac6); + break; + case PROP_ACTIVATING_IP4_AC: + g_value_set_object(value, priv->activating_ac4); + break; + case PROP_ACTIVATING_IP6_AC: + g_value_set_object(value, priv->activating_ac6); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - NMPolicy *self = NM_POLICY (object); - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - - switch (prop_id) { - case PROP_MANAGER: - /* construct-only */ - priv->manager = g_value_get_object (value); - g_return_if_fail (NM_IS_MANAGER (priv->manager)); - break; - case PROP_SETTINGS: - /* construct-only */ - priv->settings = g_value_dup_object (value); - g_return_if_fail (NM_IS_SETTINGS (priv->settings)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMPolicy * self = NM_POLICY(object); + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); + + switch (prop_id) { + case PROP_MANAGER: + /* construct-only */ + priv->manager = g_value_get_object(value); + g_return_if_fail(NM_IS_MANAGER(priv->manager)); + break; + case PROP_SETTINGS: + /* construct-only */ + priv->settings = g_value_dup_object(value); + g_return_if_fail(NM_IS_SETTINGS(priv->settings)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } } /*****************************************************************************/ static void -nm_policy_init (NMPolicy *self) +nm_policy_init(NMPolicy *self) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - gs_free char *hostname_mode = NULL; + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); + gs_free char * hostname_mode = NULL; - c_list_init (&priv->pending_activation_checks); + c_list_init(&priv->pending_activation_checks); - priv->netns = g_object_ref (nm_netns_get ()); + priv->netns = g_object_ref(nm_netns_get()); - priv->hostname_manager = g_object_ref (nm_hostname_manager_get ()); + priv->hostname_manager = g_object_ref(nm_hostname_manager_get()); - hostname_mode = nm_config_data_get_value (NM_CONFIG_GET_DATA_ORIG, - NM_CONFIG_KEYFILE_GROUP_MAIN, - NM_CONFIG_KEYFILE_KEY_MAIN_HOSTNAME_MODE, - NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY); - if (nm_streq0 (hostname_mode, "none")) - priv->hostname_mode = NM_POLICY_HOSTNAME_MODE_NONE; - else if (nm_streq0 (hostname_mode, "dhcp")) - priv->hostname_mode = NM_POLICY_HOSTNAME_MODE_DHCP; - else /* default - full mode */ - priv->hostname_mode = NM_POLICY_HOSTNAME_MODE_FULL; + hostname_mode = + nm_config_data_get_value(NM_CONFIG_GET_DATA_ORIG, + NM_CONFIG_KEYFILE_GROUP_MAIN, + NM_CONFIG_KEYFILE_KEY_MAIN_HOSTNAME_MODE, + NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY); + if (nm_streq0(hostname_mode, "none")) + priv->hostname_mode = NM_POLICY_HOSTNAME_MODE_NONE; + else if (nm_streq0(hostname_mode, "dhcp")) + priv->hostname_mode = NM_POLICY_HOSTNAME_MODE_DHCP; + else /* default - full mode */ + priv->hostname_mode = NM_POLICY_HOSTNAME_MODE_FULL; - priv->devices = g_hash_table_new (nm_direct_hash, NULL); - priv->pending_active_connections = g_hash_table_new (nm_direct_hash, NULL); - priv->ip6_prefix_delegations = g_array_new (FALSE, FALSE, sizeof (IP6PrefixDelegation)); - g_array_set_clear_func (priv->ip6_prefix_delegations, clear_ip6_prefix_delegation); + priv->devices = g_hash_table_new(nm_direct_hash, NULL); + priv->pending_active_connections = g_hash_table_new(nm_direct_hash, NULL); + priv->ip6_prefix_delegations = g_array_new(FALSE, FALSE, sizeof(IP6PrefixDelegation)); + g_array_set_clear_func(priv->ip6_prefix_delegations, clear_ip6_prefix_delegation); } static void -constructed (GObject *object) -{ - NMPolicy *self = NM_POLICY (object); - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - char *hostname = NULL; - - /* Grab hostname on startup and use that if nothing provides one */ - if ((hostname = _get_hostname (self))) { - /* init last_hostname */ - priv->last_hostname = hostname; - - /* only cache it if it's a valid hostname */ - if (nm_utils_is_specific_hostname (hostname)) - priv->orig_hostname = g_strdup (hostname); - } - _LOGT (LOGD_DNS, "hostname-original: set to %s%s%s", - NM_PRINT_FMT_QUOTE_STRING (priv->orig_hostname)); - - priv->agent_mgr = g_object_ref (nm_agent_manager_get ()); - - priv->firewall_manager = g_object_ref (nm_firewall_manager_get ()); - g_signal_connect (priv->firewall_manager, NM_FIREWALL_MANAGER_STATE_CHANGED, - G_CALLBACK (firewall_state_changed), self); - - priv->dns_manager = g_object_ref (nm_dns_manager_get ()); - nm_dns_manager_set_initial_hostname (priv->dns_manager, priv->orig_hostname); - priv->config_changed_id = g_signal_connect (priv->dns_manager, NM_DNS_MANAGER_CONFIG_CHANGED, - G_CALLBACK (dns_config_changed), self); - - priv->lookup.resolver = g_resolver_get_default (); - - g_signal_connect (priv->hostname_manager, "notify::" NM_HOSTNAME_MANAGER_HOSTNAME, (GCallback) hostname_changed, priv); - - g_signal_connect (priv->manager, "notify::" NM_MANAGER_SLEEPING, (GCallback) sleeping_changed, priv); - g_signal_connect (priv->manager, "notify::" NM_MANAGER_NETWORKING_ENABLED, (GCallback) sleeping_changed, priv); - g_signal_connect (priv->manager, NM_MANAGER_INTERNAL_DEVICE_ADDED, (GCallback) device_added, priv); - g_signal_connect (priv->manager, NM_MANAGER_INTERNAL_DEVICE_REMOVED, (GCallback) device_removed, priv); - g_signal_connect (priv->manager, NM_MANAGER_ACTIVE_CONNECTION_ADDED, (GCallback) active_connection_added, priv); - g_signal_connect (priv->manager, NM_MANAGER_ACTIVE_CONNECTION_REMOVED, (GCallback) active_connection_removed, priv); - - g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED, (GCallback) connection_added, priv); - g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, (GCallback) connection_updated, priv); - g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, (GCallback) connection_removed, priv); - g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_FLAGS_CHANGED, (GCallback) connection_flags_changed, priv); - - g_signal_connect (priv->agent_mgr, NM_AGENT_MANAGER_AGENT_REGISTERED, G_CALLBACK (secret_agent_registered), self); - - G_OBJECT_CLASS (nm_policy_parent_class)->constructed (object); - - _LOGD (LOGD_DNS, "hostname-mode: %s", _hostname_mode_to_string (priv->hostname_mode)); +constructed(GObject *object) +{ + NMPolicy * self = NM_POLICY(object); + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); + char * hostname = NULL; + + /* Grab hostname on startup and use that if nothing provides one */ + if ((hostname = _get_hostname(self))) { + /* init last_hostname */ + priv->last_hostname = hostname; + + /* only cache it if it's a valid hostname */ + if (nm_utils_is_specific_hostname(hostname)) + priv->orig_hostname = g_strdup(hostname); + } + _LOGT(LOGD_DNS, + "hostname-original: set to %s%s%s", + NM_PRINT_FMT_QUOTE_STRING(priv->orig_hostname)); + + priv->agent_mgr = g_object_ref(nm_agent_manager_get()); + + priv->firewall_manager = g_object_ref(nm_firewall_manager_get()); + g_signal_connect(priv->firewall_manager, + NM_FIREWALL_MANAGER_STATE_CHANGED, + G_CALLBACK(firewall_state_changed), + self); + + priv->dns_manager = g_object_ref(nm_dns_manager_get()); + nm_dns_manager_set_initial_hostname(priv->dns_manager, priv->orig_hostname); + priv->config_changed_id = g_signal_connect(priv->dns_manager, + NM_DNS_MANAGER_CONFIG_CHANGED, + G_CALLBACK(dns_config_changed), + self); + + priv->lookup.resolver = g_resolver_get_default(); + + g_signal_connect(priv->hostname_manager, + "notify::" NM_HOSTNAME_MANAGER_HOSTNAME, + (GCallback) hostname_changed, + priv); + + g_signal_connect(priv->manager, + "notify::" NM_MANAGER_SLEEPING, + (GCallback) sleeping_changed, + priv); + g_signal_connect(priv->manager, + "notify::" NM_MANAGER_NETWORKING_ENABLED, + (GCallback) sleeping_changed, + priv); + g_signal_connect(priv->manager, + NM_MANAGER_INTERNAL_DEVICE_ADDED, + (GCallback) device_added, + priv); + g_signal_connect(priv->manager, + NM_MANAGER_INTERNAL_DEVICE_REMOVED, + (GCallback) device_removed, + priv); + g_signal_connect(priv->manager, + NM_MANAGER_ACTIVE_CONNECTION_ADDED, + (GCallback) active_connection_added, + priv); + g_signal_connect(priv->manager, + NM_MANAGER_ACTIVE_CONNECTION_REMOVED, + (GCallback) active_connection_removed, + priv); + + g_signal_connect(priv->settings, + NM_SETTINGS_SIGNAL_CONNECTION_ADDED, + (GCallback) connection_added, + priv); + g_signal_connect(priv->settings, + NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, + (GCallback) connection_updated, + priv); + g_signal_connect(priv->settings, + NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, + (GCallback) connection_removed, + priv); + g_signal_connect(priv->settings, + NM_SETTINGS_SIGNAL_CONNECTION_FLAGS_CHANGED, + (GCallback) connection_flags_changed, + priv); + + g_signal_connect(priv->agent_mgr, + NM_AGENT_MANAGER_AGENT_REGISTERED, + G_CALLBACK(secret_agent_registered), + self); + + G_OBJECT_CLASS(nm_policy_parent_class)->constructed(object); + + _LOGD(LOGD_DNS, "hostname-mode: %s", _hostname_mode_to_string(priv->hostname_mode)); } NMPolicy * -nm_policy_new (NMManager *manager, NMSettings *settings) +nm_policy_new(NMManager *manager, NMSettings *settings) { - g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); - g_return_val_if_fail (NM_IS_SETTINGS (settings), NULL); + g_return_val_if_fail(NM_IS_MANAGER(manager), NULL); + g_return_val_if_fail(NM_IS_SETTINGS(settings), NULL); - return g_object_new (NM_TYPE_POLICY, - NM_POLICY_MANAGER, manager, - NM_POLICY_SETTINGS, settings, - NULL); + return g_object_new(NM_TYPE_POLICY, + NM_POLICY_MANAGER, + manager, + NM_POLICY_SETTINGS, + settings, + NULL); } static void -dispose (GObject *object) -{ - NMPolicy *self = NM_POLICY (object); - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - GHashTableIter h_iter; - NMDevice *device; - ActivateData *data, *data_safe; - - nm_clear_g_cancellable (&priv->lookup.cancellable); - g_clear_object (&priv->lookup.addr); - g_clear_object (&priv->lookup.resolver); - - nm_clear_g_object (&priv->default_ac4); - nm_clear_g_object (&priv->default_ac6); - nm_clear_g_object (&priv->activating_ac4); - nm_clear_g_object (&priv->activating_ac6); - nm_clear_pointer (&priv->pending_active_connections, g_hash_table_unref); - - c_list_for_each_entry_safe (data, data_safe, &priv->pending_activation_checks, pending_lst) - activate_data_free (data); - - g_slist_free_full (priv->pending_secondaries, (GDestroyNotify) pending_secondary_data_free); - priv->pending_secondaries = NULL; - - if (priv->firewall_manager) { - g_signal_handlers_disconnect_by_func (priv->firewall_manager, firewall_state_changed, self); - g_clear_object (&priv->firewall_manager); - } - - if (priv->agent_mgr) { - g_signal_handlers_disconnect_by_func (priv->agent_mgr, secret_agent_registered, self); - g_clear_object (&priv->agent_mgr); - } - - if (priv->dns_manager) { - nm_clear_g_signal_handler (priv->dns_manager, &priv->config_changed_id); - g_clear_object (&priv->dns_manager); - } - - g_hash_table_iter_init (&h_iter, priv->devices); - if (g_hash_table_iter_next (&h_iter, (gpointer *) &device, NULL)) { - g_hash_table_iter_remove (&h_iter); - devices_list_unregister (self, device); - } - - /* The manager should have disposed of ActiveConnections already, which - * will have called active_connection_removed() and thus we don't need - * to clean anything up. Assert that this is TRUE. - */ - nm_assert (c_list_is_empty (nm_manager_get_active_connections (priv->manager))); - - nm_clear_g_source (&priv->reset_retries_id); - nm_clear_g_source (&priv->schedule_activate_all_id); - - nm_clear_g_free (&priv->orig_hostname); - nm_clear_g_free (&priv->cur_hostname); - nm_clear_g_free (&priv->last_hostname); - - if (priv->hostname_manager) { - g_signal_handlers_disconnect_by_data (priv->hostname_manager, priv); - g_clear_object (&priv->hostname_manager); - } - - if (priv->settings) { - g_signal_handlers_disconnect_by_data (priv->settings, priv); - g_clear_object (&priv->settings); - - /* we don't clear priv->manager as we don't own a reference to it, - * that is, NMManager must outlive NMPolicy anyway. - * - * Hence, we unsubscribe the signals here together with the signals - * for settings. */ - g_signal_handlers_disconnect_by_data (priv->manager, priv); - } - - if (priv->ip6_prefix_delegations) { - g_array_free (priv->ip6_prefix_delegations, TRUE); - priv->ip6_prefix_delegations = NULL; - } - - nm_assert (NM_IS_MANAGER (priv->manager)); - - G_OBJECT_CLASS (nm_policy_parent_class)->dispose (object); +dispose(GObject *object) +{ + NMPolicy * self = NM_POLICY(object); + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); + GHashTableIter h_iter; + NMDevice * device; + ActivateData * data, *data_safe; + + nm_clear_g_cancellable(&priv->lookup.cancellable); + g_clear_object(&priv->lookup.addr); + g_clear_object(&priv->lookup.resolver); + + nm_clear_g_object(&priv->default_ac4); + nm_clear_g_object(&priv->default_ac6); + nm_clear_g_object(&priv->activating_ac4); + nm_clear_g_object(&priv->activating_ac6); + nm_clear_pointer(&priv->pending_active_connections, g_hash_table_unref); + + c_list_for_each_entry_safe (data, data_safe, &priv->pending_activation_checks, pending_lst) + activate_data_free(data); + + g_slist_free_full(priv->pending_secondaries, (GDestroyNotify) pending_secondary_data_free); + priv->pending_secondaries = NULL; + + if (priv->firewall_manager) { + g_signal_handlers_disconnect_by_func(priv->firewall_manager, firewall_state_changed, self); + g_clear_object(&priv->firewall_manager); + } + + if (priv->agent_mgr) { + g_signal_handlers_disconnect_by_func(priv->agent_mgr, secret_agent_registered, self); + g_clear_object(&priv->agent_mgr); + } + + if (priv->dns_manager) { + nm_clear_g_signal_handler(priv->dns_manager, &priv->config_changed_id); + g_clear_object(&priv->dns_manager); + } + + g_hash_table_iter_init(&h_iter, priv->devices); + if (g_hash_table_iter_next(&h_iter, (gpointer *) &device, NULL)) { + g_hash_table_iter_remove(&h_iter); + devices_list_unregister(self, device); + } + + /* The manager should have disposed of ActiveConnections already, which + * will have called active_connection_removed() and thus we don't need + * to clean anything up. Assert that this is TRUE. + */ + nm_assert(c_list_is_empty(nm_manager_get_active_connections(priv->manager))); + + nm_clear_g_source(&priv->reset_retries_id); + nm_clear_g_source(&priv->schedule_activate_all_id); + + nm_clear_g_free(&priv->orig_hostname); + nm_clear_g_free(&priv->cur_hostname); + nm_clear_g_free(&priv->last_hostname); + + if (priv->hostname_manager) { + g_signal_handlers_disconnect_by_data(priv->hostname_manager, priv); + g_clear_object(&priv->hostname_manager); + } + + if (priv->settings) { + g_signal_handlers_disconnect_by_data(priv->settings, priv); + g_clear_object(&priv->settings); + + /* we don't clear priv->manager as we don't own a reference to it, + * that is, NMManager must outlive NMPolicy anyway. + * + * Hence, we unsubscribe the signals here together with the signals + * for settings. */ + g_signal_handlers_disconnect_by_data(priv->manager, priv); + } + + if (priv->ip6_prefix_delegations) { + g_array_free(priv->ip6_prefix_delegations, TRUE); + priv->ip6_prefix_delegations = NULL; + } + + nm_assert(NM_IS_MANAGER(priv->manager)); + + G_OBJECT_CLASS(nm_policy_parent_class)->dispose(object); } static void -finalize (GObject *object) +finalize(GObject *object) { - NMPolicy *self = NM_POLICY (object); - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); + NMPolicy * self = NM_POLICY(object); + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); - g_hash_table_unref (priv->devices); + g_hash_table_unref(priv->devices); - G_OBJECT_CLASS (nm_policy_parent_class)->finalize (object); + G_OBJECT_CLASS(nm_policy_parent_class)->finalize(object); - g_object_unref (priv->netns); + g_object_unref(priv->netns); } static void -nm_policy_class_init (NMPolicyClass *policy_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (policy_class); - - object_class->get_property = get_property; - object_class->set_property = set_property; - object_class->constructed = constructed; - object_class->dispose = dispose; - object_class->finalize = finalize; - - obj_properties[PROP_MANAGER] = - g_param_spec_object (NM_POLICY_MANAGER, "", "", - NM_TYPE_MANAGER, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_SETTINGS] = - g_param_spec_object (NM_POLICY_SETTINGS, "", "", - NM_TYPE_SETTINGS, - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_DEFAULT_IP4_AC] = - g_param_spec_object (NM_POLICY_DEFAULT_IP4_AC, "", "", - NM_TYPE_ACTIVE_CONNECTION, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_DEFAULT_IP6_AC] = - g_param_spec_object (NM_POLICY_DEFAULT_IP6_AC, "", "", - NM_TYPE_DEVICE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_ACTIVATING_IP4_AC] = - g_param_spec_object (NM_POLICY_ACTIVATING_IP4_AC, "", "", - NM_TYPE_DEVICE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_properties[PROP_ACTIVATING_IP6_AC] = - g_param_spec_object (NM_POLICY_ACTIVATING_IP6_AC, "", "", - NM_TYPE_DEVICE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); +nm_policy_class_init(NMPolicyClass *policy_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS(policy_class); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->constructed = constructed; + object_class->dispose = dispose; + object_class->finalize = finalize; + + obj_properties[PROP_MANAGER] = + g_param_spec_object(NM_POLICY_MANAGER, + "", + "", + NM_TYPE_MANAGER, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_SETTINGS] = + g_param_spec_object(NM_POLICY_SETTINGS, + "", + "", + NM_TYPE_SETTINGS, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_DEFAULT_IP4_AC] = + g_param_spec_object(NM_POLICY_DEFAULT_IP4_AC, + "", + "", + NM_TYPE_ACTIVE_CONNECTION, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_DEFAULT_IP6_AC] = + g_param_spec_object(NM_POLICY_DEFAULT_IP6_AC, + "", + "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_ACTIVATING_IP4_AC] = + g_param_spec_object(NM_POLICY_ACTIVATING_IP4_AC, + "", + "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_ACTIVATING_IP6_AC] = + g_param_spec_object(NM_POLICY_ACTIVATING_IP6_AC, + "", + "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } |