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