policy: track best active connections rather than best devices
If a VPN with default route is activated, the Manager's PrimaryConnection property is not updated to indicate the VPN as primary connection. This happens because the PrimaryConnection property gets updated when the default_ipX_device property of NMPolicy changes, and the primary connection is set to the activation request currently pending on the default device. We select the base (for example, ethernet) device as best device and therefore the NMActRequest active on it is selected as primary connection. This patch fixes the problem by properly selecting the VPN as primary. It seems a better choice to track best active connections directly from NMPolicy instead of going through two steps.
This commit is contained in:
@@ -319,7 +319,7 @@ static NMActiveConnection *_new_active_connection (NMManager *self,
|
|||||||
NMActivationReason activation_reason,
|
NMActivationReason activation_reason,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
static void policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data);
|
static void policy_activating_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_data);
|
||||||
|
|
||||||
static gboolean find_master (NMManager *self,
|
static gboolean find_master (NMManager *self,
|
||||||
NMConnection *connection,
|
NMConnection *connection,
|
||||||
@@ -4265,7 +4265,7 @@ _internal_activate_generic (NMManager *self, NMActiveConnection *active, GError
|
|||||||
* is exported, make sure the manager's activating-connection property
|
* is exported, make sure the manager's activating-connection property
|
||||||
* is up-to-date.
|
* is up-to-date.
|
||||||
*/
|
*/
|
||||||
policy_activating_device_changed (G_OBJECT (priv->policy), NULL, self);
|
policy_activating_ac_changed (G_OBJECT (priv->policy), NULL, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
@@ -6117,25 +6117,19 @@ connection_metered_changed (GObject *object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
policy_default_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
|
policy_default_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
|
||||||
{
|
{
|
||||||
NMManager *self = NM_MANAGER (user_data);
|
NMManager *self = NM_MANAGER (user_data);
|
||||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||||
NMDevice *best;
|
|
||||||
NMActiveConnection *ac;
|
NMActiveConnection *ac;
|
||||||
|
|
||||||
/* Note: this assumes that it's not possible for the IP4 default
|
/* Note: this assumes that it's not possible for the IP4 default
|
||||||
* route to be going over the default-ip6-device. If that changes,
|
* route to be going over the default-ip6-device. If that changes,
|
||||||
* we need something more complicated here.
|
* we need something more complicated here.
|
||||||
*/
|
*/
|
||||||
best = nm_policy_get_default_ip4_device (priv->policy);
|
ac = nm_policy_get_default_ip4_ac (priv->policy);
|
||||||
if (!best)
|
if (!ac)
|
||||||
best = nm_policy_get_default_ip6_device (priv->policy);
|
ac = nm_policy_get_default_ip6_ac (priv->policy);
|
||||||
|
|
||||||
if (best)
|
|
||||||
ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (best));
|
|
||||||
else
|
|
||||||
ac = NULL;
|
|
||||||
|
|
||||||
if (ac != priv->primary_connection) {
|
if (ac != priv->primary_connection) {
|
||||||
if (priv->primary_connection) {
|
if (priv->primary_connection) {
|
||||||
@@ -6148,10 +6142,12 @@ policy_default_device_changed (GObject *object, GParamSpec *pspec, gpointer user
|
|||||||
priv->primary_connection = ac ? g_object_ref (ac) : NULL;
|
priv->primary_connection = ac ? g_object_ref (ac) : NULL;
|
||||||
|
|
||||||
if (priv->primary_connection) {
|
if (priv->primary_connection) {
|
||||||
g_signal_connect (priv->primary_connection, NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED,
|
g_signal_connect (priv->primary_connection,
|
||||||
|
NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED,
|
||||||
G_CALLBACK (connection_metered_changed), self);
|
G_CALLBACK (connection_metered_changed), self);
|
||||||
}
|
}
|
||||||
_LOGD (LOGD_CORE, "PrimaryConnection now %s", ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)");
|
_LOGD (LOGD_CORE, "PrimaryConnection now %s",
|
||||||
|
ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)");
|
||||||
_notify (self, PROP_PRIMARY_CONNECTION);
|
_notify (self, PROP_PRIMARY_CONNECTION);
|
||||||
_notify (self, PROP_PRIMARY_CONNECTION_TYPE);
|
_notify (self, PROP_PRIMARY_CONNECTION_TYPE);
|
||||||
nm_manager_update_metered (self);
|
nm_manager_update_metered (self);
|
||||||
@@ -6159,34 +6155,29 @@ policy_default_device_changed (GObject *object, GParamSpec *pspec, gpointer user
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
|
policy_activating_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
|
||||||
{
|
{
|
||||||
NMManager *self = NM_MANAGER (user_data);
|
NMManager *self = NM_MANAGER (user_data);
|
||||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||||
NMDevice *activating, *best;
|
NMActiveConnection *activating, *best;
|
||||||
NMActiveConnection *ac;
|
|
||||||
|
|
||||||
/* We only look at activating-ip6-device if activating-ip4-device
|
/* We only look at activating-ip6-ac if activating-ip4-ac
|
||||||
* AND default-ip4-device are NULL; if default-ip4-device is
|
* AND default-ip4-ac are NULL; if default-ip4-ac is
|
||||||
* non-NULL, then activating-ip6-device is irrelevant, since while
|
* non-NULL, then activating-ip6-ac is irrelevant, since while
|
||||||
* that device might become the new default-ip6-device, it can't
|
* that AC might become the new default-ip6-ac, it can't
|
||||||
* become primary-connection while default-ip4-device is set to
|
* become primary-connection while default-ip4-ac is set to
|
||||||
* something else.
|
* something else.
|
||||||
*/
|
*/
|
||||||
activating = nm_policy_get_activating_ip4_device (priv->policy);
|
activating = nm_policy_get_activating_ip4_ac (priv->policy);
|
||||||
best = nm_policy_get_default_ip4_device (priv->policy);
|
best = nm_policy_get_default_ip4_ac (priv->policy);
|
||||||
if (!activating && !best)
|
if (!activating && !best)
|
||||||
activating = nm_policy_get_activating_ip6_device (priv->policy);
|
activating = nm_policy_get_activating_ip6_ac (priv->policy);
|
||||||
|
|
||||||
if (activating)
|
if (nm_g_object_ref_set (&priv->activating_connection, activating)) {
|
||||||
ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (activating));
|
_LOGD (LOGD_CORE, "ActivatingConnection now %s",
|
||||||
else
|
activating
|
||||||
ac = NULL;
|
? nm_active_connection_get_settings_connection_id (activating)
|
||||||
|
: "(none)");
|
||||||
if (ac != priv->activating_connection) {
|
|
||||||
g_clear_object (&priv->activating_connection);
|
|
||||||
priv->activating_connection = ac ? g_object_ref (ac) : NULL;
|
|
||||||
_LOGD (LOGD_CORE, "ActivatingConnection now %s", ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)");
|
|
||||||
_notify (self, PROP_ACTIVATING_CONNECTION);
|
_notify (self, PROP_ACTIVATING_CONNECTION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6777,14 +6768,14 @@ constructed (GObject *object)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
priv->policy = nm_policy_new (self, priv->settings);
|
priv->policy = nm_policy_new (self, priv->settings);
|
||||||
g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP4_DEVICE,
|
g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP4_AC,
|
||||||
G_CALLBACK (policy_default_device_changed), self);
|
G_CALLBACK (policy_default_ac_changed), self);
|
||||||
g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP6_DEVICE,
|
g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP6_AC,
|
||||||
G_CALLBACK (policy_default_device_changed), self);
|
G_CALLBACK (policy_default_ac_changed), self);
|
||||||
g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP4_DEVICE,
|
g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP4_AC,
|
||||||
G_CALLBACK (policy_activating_device_changed), self);
|
G_CALLBACK (policy_activating_ac_changed), self);
|
||||||
g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP6_DEVICE,
|
g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP6_AC,
|
||||||
G_CALLBACK (policy_activating_device_changed), self);
|
G_CALLBACK (policy_activating_ac_changed), self);
|
||||||
|
|
||||||
priv->config = g_object_ref (nm_config_get ());
|
priv->config = g_object_ref (nm_config_get ());
|
||||||
g_signal_connect (G_OBJECT (priv->config),
|
g_signal_connect (G_OBJECT (priv->config),
|
||||||
@@ -7122,8 +7113,8 @@ dispose (GObject *object)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (priv->policy) {
|
if (priv->policy) {
|
||||||
g_signal_handlers_disconnect_by_func (priv->policy, policy_default_device_changed, self);
|
g_signal_handlers_disconnect_by_func (priv->policy, policy_default_ac_changed, self);
|
||||||
g_signal_handlers_disconnect_by_func (priv->policy, policy_activating_device_changed, self);
|
g_signal_handlers_disconnect_by_func (priv->policy, policy_activating_ac_changed, self);
|
||||||
g_clear_object (&priv->policy);
|
g_clear_object (&priv->policy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
243
src/nm-policy.c
243
src/nm-policy.c
@@ -56,10 +56,10 @@
|
|||||||
NM_GOBJECT_PROPERTIES_DEFINE (NMPolicy,
|
NM_GOBJECT_PROPERTIES_DEFINE (NMPolicy,
|
||||||
PROP_MANAGER,
|
PROP_MANAGER,
|
||||||
PROP_SETTINGS,
|
PROP_SETTINGS,
|
||||||
PROP_DEFAULT_IP4_DEVICE,
|
PROP_DEFAULT_IP4_AC,
|
||||||
PROP_DEFAULT_IP6_DEVICE,
|
PROP_DEFAULT_IP6_AC,
|
||||||
PROP_ACTIVATING_IP4_DEVICE,
|
PROP_ACTIVATING_IP4_AC,
|
||||||
PROP_ACTIVATING_IP6_DEVICE,
|
PROP_ACTIVATING_IP6_AC,
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -79,8 +79,8 @@ typedef struct {
|
|||||||
|
|
||||||
NMHostnameManager *hostname_manager;
|
NMHostnameManager *hostname_manager;
|
||||||
|
|
||||||
NMDevice *default_device4, *activating_device4;
|
NMActiveConnection *default_ac4, *activating_ac4;
|
||||||
NMDevice *default_device6, *activating_device6;
|
NMActiveConnection *default_ac6, *activating_ac6;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
GInetAddress *addr;
|
GInetAddress *addr;
|
||||||
@@ -146,6 +146,7 @@ _PRIV_TO_SELF (NMPolicyPrivate *priv)
|
|||||||
|
|
||||||
static void schedule_activate_all (NMPolicy *self);
|
static void schedule_activate_all (NMPolicy *self);
|
||||||
static void schedule_activate_check (NMPolicy *self, NMDevice *device);
|
static void schedule_activate_check (NMPolicy *self, NMDevice *device);
|
||||||
|
static NMDevice *get_default_device (NMPolicy *self, int addr_family);
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
@@ -367,43 +368,56 @@ device_ip6_subnet_needed (NMDevice *device,
|
|||||||
_LOGD (LOGD_IP6, "ipv6-pd: %s needs a subnet",
|
_LOGD (LOGD_IP6, "ipv6-pd: %s needs a subnet",
|
||||||
nm_device_get_iface (device));
|
nm_device_get_iface (device));
|
||||||
|
|
||||||
if (!priv->default_device6) {
|
if (!priv->default_ac6) {
|
||||||
/* We request the prefixes when the default IPv6 device is set. */
|
/* We request the prefixes when the default IPv6 device is set. */
|
||||||
_LOGI (LOGD_IP6, "ipv6-pd: no device to obtain a subnet to share on %s from",
|
_LOGI (LOGD_IP6, "ipv6-pd: no device to obtain a subnet to share on %s from",
|
||||||
nm_device_get_iface (device));
|
nm_device_get_iface (device));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ip6_subnet_from_device (self, priv->default_device6, device);
|
ip6_subnet_from_device (self, get_default_device (self, AF_INET6), device);
|
||||||
nm_device_copy_ip6_dns_config (device, priv->default_device6);
|
nm_device_copy_ip6_dns_config (device, get_default_device (self, AF_INET6));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static NMDevice *
|
static NMDevice *
|
||||||
get_best_ip_device (NMPolicy *self,
|
get_default_device (NMPolicy *self, int addr_family)
|
||||||
int addr_family,
|
{
|
||||||
gboolean fully_activated)
|
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
|
||||||
|
NMActiveConnection *ac;
|
||||||
|
|
||||||
|
nm_assert_addr_family (addr_family);
|
||||||
|
|
||||||
|
ac = (addr_family == AF_INET) ? priv->default_ac4 : priv->default_ac6;
|
||||||
|
|
||||||
|
return ac ? nm_active_connection_get_device (ac) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NMActiveConnection *
|
||||||
|
get_best_active_connection (NMPolicy *self,
|
||||||
|
int addr_family,
|
||||||
|
gboolean fully_activated)
|
||||||
{
|
{
|
||||||
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
|
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
|
||||||
const CList *tmp_lst;
|
const CList *tmp_lst;
|
||||||
NMDevice *device;
|
NMDevice *device;
|
||||||
NMDevice *best_device;
|
|
||||||
NMDevice *prev_device;
|
|
||||||
guint32 best_metric = G_MAXUINT32;
|
guint32 best_metric = G_MAXUINT32;
|
||||||
gboolean best_is_fully_activated = FALSE;
|
gboolean best_is_fully_activated = FALSE;
|
||||||
|
NMActiveConnection *best_ac, *prev_ac;
|
||||||
|
|
||||||
nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6));
|
nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6));
|
||||||
|
|
||||||
/* we prefer the current device in case of identical metric.
|
/* we prefer the current AC in case of identical metric.
|
||||||
* Hence, try that one first.*/
|
* Hence, try that one first. */
|
||||||
best_device = NULL;
|
prev_ac = addr_family == AF_INET
|
||||||
prev_device = addr_family == AF_INET
|
? (fully_activated ? priv->default_ac4 : priv->activating_ac4)
|
||||||
? (fully_activated ? priv->default_device4 : priv->activating_device4)
|
: (fully_activated ? priv->default_ac6 : priv->activating_ac6);
|
||||||
: (fully_activated ? priv->default_device6 : priv->activating_device6);
|
best_ac = NULL;
|
||||||
|
|
||||||
nm_manager_for_each_device (priv->manager, device, tmp_lst) {
|
nm_manager_for_each_device (priv->manager, device, tmp_lst) {
|
||||||
NMDeviceState state;
|
NMDeviceState state;
|
||||||
const NMPObject *r;
|
const NMPObject *r;
|
||||||
|
NMActiveConnection *ac;
|
||||||
NMConnection *connection;
|
NMConnection *connection;
|
||||||
guint32 metric;
|
guint32 metric;
|
||||||
gboolean is_fully_activated;
|
gboolean is_fully_activated;
|
||||||
@@ -435,26 +449,29 @@ get_best_ip_device (NMPolicy *self,
|
|||||||
} else
|
} else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ( !best_device
|
ac = (NMActiveConnection *) nm_device_get_act_request (device);
|
||||||
|
nm_assert (ac);
|
||||||
|
|
||||||
|
if ( !best_ac
|
||||||
|| (!best_is_fully_activated && is_fully_activated)
|
|| (!best_is_fully_activated && is_fully_activated)
|
||||||
|| ( metric < best_metric
|
|| ( metric < best_metric
|
||||||
|| (metric == best_metric && device == prev_device))) {
|
|| (metric == best_metric && ac == prev_ac))) {
|
||||||
best_device = device;
|
best_ac = ac;
|
||||||
best_metric = metric;
|
best_metric = metric;
|
||||||
best_is_fully_activated = is_fully_activated;
|
best_is_fully_activated = is_fully_activated;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !fully_activated
|
if ( !fully_activated
|
||||||
&& best_device
|
&& best_ac
|
||||||
&& best_is_fully_activated) {
|
&& best_is_fully_activated) {
|
||||||
/* There's only a best activating device if the best device
|
/* There's a best activating AC only if the best device
|
||||||
* among all activating and already-activated devices is a
|
* among all activating and already-activated devices is a
|
||||||
* still-activating one. */
|
* still-activating one. */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return best_device;
|
return best_ac;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -668,6 +685,7 @@ update_system_hostname (NMPolicy *self, const char *msg)
|
|||||||
gboolean external_hostname = FALSE;
|
gboolean external_hostname = FALSE;
|
||||||
const NMPlatformIP4Address *addr4;
|
const NMPlatformIP4Address *addr4;
|
||||||
const NMPlatformIP6Address *addr6;
|
const NMPlatformIP6Address *addr6;
|
||||||
|
NMDevice *device;
|
||||||
|
|
||||||
g_return_if_fail (self != NULL);
|
g_return_if_fail (self != NULL);
|
||||||
|
|
||||||
@@ -720,11 +738,11 @@ update_system_hostname (NMPolicy *self, const char *msg)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->default_device4) {
|
if (priv->default_ac4) {
|
||||||
NMDhcp4Config *dhcp4_config;
|
NMDhcp4Config *dhcp4_config;
|
||||||
|
|
||||||
/* Grab a hostname out of the device's DHCP4 config */
|
/* Grab a hostname out of the device's DHCP4 config */
|
||||||
dhcp4_config = nm_device_get_dhcp4_config (priv->default_device4);
|
dhcp4_config = nm_device_get_dhcp4_config (get_default_device (self, AF_INET));
|
||||||
if (dhcp4_config) {
|
if (dhcp4_config) {
|
||||||
dhcp_hostname = nm_dhcp4_config_get_option (dhcp4_config, "host_name");
|
dhcp_hostname = nm_dhcp4_config_get_option (dhcp4_config, "host_name");
|
||||||
if (dhcp_hostname && dhcp_hostname[0]) {
|
if (dhcp_hostname && dhcp_hostname[0]) {
|
||||||
@@ -740,11 +758,11 @@ update_system_hostname (NMPolicy *self, const char *msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->default_device6) {
|
if (priv->default_ac6) {
|
||||||
NMDhcp6Config *dhcp6_config;
|
NMDhcp6Config *dhcp6_config;
|
||||||
|
|
||||||
/* Grab a hostname out of the device's DHCP6 config */
|
/* Grab a hostname out of the device's DHCP6 config */
|
||||||
dhcp6_config = nm_device_get_dhcp6_config (priv->default_device6);
|
dhcp6_config = nm_device_get_dhcp6_config (get_default_device (self, AF_INET6));
|
||||||
if (dhcp6_config) {
|
if (dhcp6_config) {
|
||||||
dhcp_hostname = nm_dhcp6_config_get_option (dhcp6_config, "host_name");
|
dhcp_hostname = nm_dhcp6_config_get_option (dhcp6_config, "host_name");
|
||||||
if (dhcp_hostname && dhcp_hostname[0]) {
|
if (dhcp_hostname && dhcp_hostname[0]) {
|
||||||
@@ -779,7 +797,7 @@ update_system_hostname (NMPolicy *self, const char *msg)
|
|||||||
|
|
||||||
priv->dhcp_hostname = FALSE;
|
priv->dhcp_hostname = FALSE;
|
||||||
|
|
||||||
if (!priv->default_device4 && !priv->default_device6) {
|
if (!priv->default_ac4 && !priv->default_ac6) {
|
||||||
/* No best device; fall back to the last hostname set externally
|
/* No best device; fall back to the last hostname set externally
|
||||||
* to NM or if there wasn't one, 'localhost.localdomain'
|
* to NM or if there wasn't one, 'localhost.localdomain'
|
||||||
*/
|
*/
|
||||||
@@ -798,8 +816,11 @@ update_system_hostname (NMPolicy *self, const char *msg)
|
|||||||
/* No configured hostname, no automatically determined hostname, and no
|
/* No configured hostname, no automatically determined hostname, and no
|
||||||
* bootup hostname. Start reverse DNS of the current IPv4 or IPv6 address.
|
* bootup hostname. Start reverse DNS of the current IPv4 or IPv6 address.
|
||||||
*/
|
*/
|
||||||
ip4_config = priv->default_device4 ? nm_device_get_ip4_config (priv->default_device4) : NULL;
|
device = get_default_device (self, AF_INET);
|
||||||
ip6_config = priv->default_device6 ? nm_device_get_ip6_config (priv->default_device6) : NULL;
|
ip4_config = device ? nm_device_get_ip4_config (device) : NULL;
|
||||||
|
|
||||||
|
device = get_default_device (self, AF_INET6);
|
||||||
|
ip6_config = device ? nm_device_get_ip6_config (device) : NULL;
|
||||||
|
|
||||||
if ( ip4_config
|
if ( ip4_config
|
||||||
&& (addr4 = nm_ip4_config_get_first_address (ip4_config))) {
|
&& (addr4 = nm_ip4_config_get_first_address (ip4_config))) {
|
||||||
@@ -852,7 +873,6 @@ get_best_ip_config (NMPolicy *self,
|
|||||||
NMVpnConnection **out_vpn)
|
NMVpnConnection **out_vpn)
|
||||||
{
|
{
|
||||||
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
|
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
|
||||||
NMDevice *device;
|
|
||||||
gpointer conf, best_conf = NULL;
|
gpointer conf, best_conf = NULL;
|
||||||
const CList *tmp_list;
|
const CList *tmp_list;
|
||||||
NMActiveConnection *ac;
|
NMActiveConnection *ac;
|
||||||
@@ -906,23 +926,22 @@ get_best_ip_config (NMPolicy *self,
|
|||||||
return best_conf;
|
return best_conf;
|
||||||
}
|
}
|
||||||
|
|
||||||
device = get_best_ip_device (self, addr_family, TRUE);
|
ac = get_best_active_connection (self, addr_family, TRUE);
|
||||||
if (device) {
|
if (ac) {
|
||||||
NMActRequest *req;
|
NMDevice *device = nm_active_connection_get_device (ac);
|
||||||
|
|
||||||
|
nm_assert (device);
|
||||||
|
|
||||||
if (addr_family == AF_INET)
|
if (addr_family == AF_INET)
|
||||||
conf = nm_device_get_ip4_config (device);
|
conf = nm_device_get_ip4_config (device);
|
||||||
else
|
else
|
||||||
conf = nm_device_get_ip6_config (device);
|
conf = nm_device_get_ip6_config (device);
|
||||||
req = nm_device_get_act_request (device);
|
|
||||||
|
|
||||||
if (conf && req) {
|
NM_SET_OUT (out_device, device);
|
||||||
NM_SET_OUT (out_device, device);
|
NM_SET_OUT (out_vpn, NULL);
|
||||||
NM_SET_OUT (out_vpn, NULL);
|
NM_SET_OUT (out_ac, ac);
|
||||||
NM_SET_OUT (out_ac, NM_ACTIVE_CONNECTION (req));
|
NM_SET_OUT (out_ip_iface, nm_device_get_ip_iface (device));
|
||||||
NM_SET_OUT (out_ip_iface, nm_device_get_ip_iface (device));
|
return conf;
|
||||||
return conf;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NM_SET_OUT (out_device, NULL);
|
NM_SET_OUT (out_device, NULL);
|
||||||
@@ -947,17 +966,17 @@ update_ip4_routing (NMPolicy *self, gboolean force_update)
|
|||||||
* so we can get (vpn != NULL && best == NULL).
|
* so we can get (vpn != NULL && best == NULL).
|
||||||
*/
|
*/
|
||||||
if (!get_best_ip_config (self, AF_INET, &ip_iface, &best_ac, &best, &vpn)) {
|
if (!get_best_ip_config (self, AF_INET, &ip_iface, &best_ac, &best, &vpn)) {
|
||||||
if (nm_clear_g_object (&priv->default_device4)) {
|
if (nm_clear_g_object (&priv->default_ac4)) {
|
||||||
_LOGt (LOGD_DNS, "set-default-device-4: %p", NULL);
|
_LOGt (LOGD_DNS, "set-default-ac-4: %p", NULL);
|
||||||
_notify (self, PROP_DEFAULT_IP4_DEVICE);
|
_notify (self, PROP_DEFAULT_IP4_AC);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g_assert ((best || vpn) && best_ac);
|
g_assert ((best || vpn) && best_ac);
|
||||||
|
|
||||||
if ( !force_update
|
if ( !force_update
|
||||||
&& best
|
&& best_ac
|
||||||
&& best == priv->default_device4)
|
&& best_ac == priv->default_ac4)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (best) {
|
if (best) {
|
||||||
@@ -969,19 +988,16 @@ update_ip4_routing (NMPolicy *self, gboolean force_update)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vpn)
|
|
||||||
best = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn));
|
|
||||||
|
|
||||||
update_default_ac (self, AF_INET, best_ac);
|
update_default_ac (self, AF_INET, best_ac);
|
||||||
|
|
||||||
if (!nm_g_object_ref_set (&priv->default_device4, best))
|
if (!nm_g_object_ref_set (&priv->default_ac4, best_ac))
|
||||||
return;
|
return;
|
||||||
_LOGt (LOGD_DNS, "set-default-device-4: %p", priv->default_device4);
|
_LOGt (LOGD_DNS, "set-default-ac-4: %p", priv->default_ac4);
|
||||||
|
|
||||||
_LOGI (LOGD_CORE, "set '%s' (%s) as default for IPv4 routing and DNS",
|
_LOGI (LOGD_CORE, "set '%s' (%s) as default for IPv4 routing and DNS",
|
||||||
nm_connection_get_id (nm_active_connection_get_applied_connection (best_ac)),
|
nm_connection_get_id (nm_active_connection_get_applied_connection (best_ac)),
|
||||||
ip_iface);
|
ip_iface);
|
||||||
_notify (self, PROP_DEFAULT_IP4_DEVICE);
|
_notify (self, PROP_DEFAULT_IP4_AC);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -995,7 +1011,7 @@ update_ip6_dns_delegation (NMPolicy *self)
|
|||||||
nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
|
nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
|
||||||
device = nm_active_connection_get_device (ac);
|
device = nm_active_connection_get_device (ac);
|
||||||
if (device && nm_device_needs_ip6_subnet (device))
|
if (device && nm_device_needs_ip6_subnet (device))
|
||||||
nm_device_copy_ip6_dns_config (device, priv->default_device6);
|
nm_device_copy_ip6_dns_config (device, get_default_device (self, AF_INET6));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1011,7 +1027,7 @@ update_ip6_prefix_delegation (NMPolicy *self)
|
|||||||
nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
|
nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
|
||||||
device = nm_active_connection_get_device (ac);
|
device = nm_active_connection_get_device (ac);
|
||||||
if (device && nm_device_needs_ip6_subnet (device))
|
if (device && nm_device_needs_ip6_subnet (device))
|
||||||
ip6_subnet_from_device (self, priv->default_device6, device);
|
ip6_subnet_from_device (self, get_default_device (self, AF_INET6), device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1030,17 +1046,17 @@ update_ip6_routing (NMPolicy *self, gboolean force_update)
|
|||||||
* so we can get (vpn != NULL && best == NULL).
|
* so we can get (vpn != NULL && best == NULL).
|
||||||
*/
|
*/
|
||||||
if (!get_best_ip_config (self, AF_INET6, &ip_iface, &best_ac, &best, &vpn)) {
|
if (!get_best_ip_config (self, AF_INET6, &ip_iface, &best_ac, &best, &vpn)) {
|
||||||
if (nm_clear_g_object (&priv->default_device6)) {
|
if (nm_clear_g_object (&priv->default_ac6)) {
|
||||||
_LOGt (LOGD_DNS, "set-default-device-6: %p", NULL);
|
_LOGt (LOGD_DNS, "set-default-ac-6: %p", NULL);
|
||||||
_notify (self, PROP_DEFAULT_IP6_DEVICE);
|
_notify (self, PROP_DEFAULT_IP6_AC);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g_assert ((best || vpn) && best_ac);
|
g_assert ((best || vpn) && best_ac);
|
||||||
|
|
||||||
if ( !force_update
|
if ( !force_update
|
||||||
&& best
|
&& best_ac
|
||||||
&& best == priv->default_device6)
|
&& best_ac == priv->default_ac6)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (best) {
|
if (best) {
|
||||||
@@ -1052,21 +1068,18 @@ update_ip6_routing (NMPolicy *self, gboolean force_update)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vpn)
|
|
||||||
best = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn));
|
|
||||||
|
|
||||||
update_default_ac (self, AF_INET6, best_ac);
|
update_default_ac (self, AF_INET6, best_ac);
|
||||||
|
|
||||||
if (!nm_g_object_ref_set (&priv->default_device6, best))
|
if (!nm_g_object_ref_set (&priv->default_ac6, best_ac))
|
||||||
return;
|
return;
|
||||||
_LOGt (LOGD_DNS, "set-default-device-6: %p", priv->default_device6);
|
_LOGt (LOGD_DNS, "set-default-ac-6: %p", priv->default_ac6);
|
||||||
|
|
||||||
update_ip6_prefix_delegation (self);
|
update_ip6_prefix_delegation (self);
|
||||||
|
|
||||||
_LOGI (LOGD_CORE, "set '%s' (%s) as default for IPv6 routing and DNS",
|
_LOGI (LOGD_CORE, "set '%s' (%s) as default for IPv6 routing and DNS",
|
||||||
nm_connection_get_id (nm_active_connection_get_applied_connection (best_ac)),
|
nm_connection_get_id (nm_active_connection_get_applied_connection (best_ac)),
|
||||||
ip_iface);
|
ip_iface);
|
||||||
_notify (self, PROP_DEFAULT_IP6_DEVICE);
|
_notify (self, PROP_DEFAULT_IP6_AC);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1114,23 +1127,23 @@ update_routing_and_dns (NMPolicy *self, gboolean force_update)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
check_activating_devices (NMPolicy *self)
|
check_activating_active_connections (NMPolicy *self)
|
||||||
{
|
{
|
||||||
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
|
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
|
||||||
NMDevice *best4, *best6 = NULL;
|
NMActiveConnection *best4, *best6 = NULL;
|
||||||
|
|
||||||
best4 = get_best_ip_device (self, AF_INET, FALSE);
|
best4 = get_best_active_connection (self, AF_INET, FALSE);
|
||||||
best6 = get_best_ip_device (self, AF_INET6, FALSE);
|
best6 = get_best_active_connection (self, AF_INET6, FALSE);
|
||||||
|
|
||||||
g_object_freeze_notify (G_OBJECT (self));
|
g_object_freeze_notify (G_OBJECT (self));
|
||||||
|
|
||||||
if (nm_g_object_ref_set (&priv->activating_device4, best4)) {
|
if (nm_g_object_ref_set (&priv->activating_ac4, best4)) {
|
||||||
_LOGt (LOGD_DNS, "set-activating-device-4: %p", priv->activating_device4);
|
_LOGt (LOGD_DNS, "set-activating-ac-4: %p", priv->activating_ac4);
|
||||||
_notify (self, PROP_ACTIVATING_IP4_DEVICE);
|
_notify (self, PROP_ACTIVATING_IP4_AC);
|
||||||
}
|
}
|
||||||
if (nm_g_object_ref_set (&priv->activating_device6, best6)) {
|
if (nm_g_object_ref_set (&priv->activating_ac6, best6)) {
|
||||||
_LOGt (LOGD_DNS, "set-activating-device-6: %p", priv->activating_device6);
|
_LOGt (LOGD_DNS, "set-activating-ac-6: %p", priv->activating_ac6);
|
||||||
_notify (self, PROP_ACTIVATING_IP6_DEVICE);
|
_notify (self, PROP_ACTIVATING_IP6_AC);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_thaw_notify (G_OBJECT (self));
|
g_object_thaw_notify (G_OBJECT (self));
|
||||||
@@ -1910,7 +1923,7 @@ device_state_changed (NMDevice *device,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
check_activating_devices (self);
|
check_activating_active_connections (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -2392,28 +2405,28 @@ secret_agent_registered (NMSettings *settings,
|
|||||||
schedule_activate_all (self);
|
schedule_activate_all (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
NMDevice *
|
NMActiveConnection *
|
||||||
nm_policy_get_default_ip4_device (NMPolicy *self)
|
nm_policy_get_default_ip4_ac (NMPolicy *self)
|
||||||
{
|
{
|
||||||
return NM_POLICY_GET_PRIVATE (self)->default_device4;
|
return NM_POLICY_GET_PRIVATE (self)->default_ac4;
|
||||||
}
|
}
|
||||||
|
|
||||||
NMDevice *
|
NMActiveConnection *
|
||||||
nm_policy_get_default_ip6_device (NMPolicy *self)
|
nm_policy_get_default_ip6_ac (NMPolicy *self)
|
||||||
{
|
{
|
||||||
return NM_POLICY_GET_PRIVATE (self)->default_device6;
|
return NM_POLICY_GET_PRIVATE (self)->default_ac6;
|
||||||
}
|
}
|
||||||
|
|
||||||
NMDevice *
|
NMActiveConnection *
|
||||||
nm_policy_get_activating_ip4_device (NMPolicy *self)
|
nm_policy_get_activating_ip4_ac (NMPolicy *self)
|
||||||
{
|
{
|
||||||
return NM_POLICY_GET_PRIVATE (self)->activating_device4;
|
return NM_POLICY_GET_PRIVATE (self)->activating_ac4;
|
||||||
}
|
}
|
||||||
|
|
||||||
NMDevice *
|
NMActiveConnection *
|
||||||
nm_policy_get_activating_ip6_device (NMPolicy *self)
|
nm_policy_get_activating_ip6_ac (NMPolicy *self)
|
||||||
{
|
{
|
||||||
return NM_POLICY_GET_PRIVATE (self)->activating_device6;
|
return NM_POLICY_GET_PRIVATE (self)->activating_ac6;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -2435,17 +2448,17 @@ get_property (GObject *object, guint prop_id,
|
|||||||
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
|
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_DEFAULT_IP4_DEVICE:
|
case PROP_DEFAULT_IP4_AC:
|
||||||
g_value_set_object (value, priv->default_device4);
|
g_value_set_object (value, priv->default_ac4);
|
||||||
break;
|
break;
|
||||||
case PROP_DEFAULT_IP6_DEVICE:
|
case PROP_DEFAULT_IP6_AC:
|
||||||
g_value_set_object (value, priv->default_device6);
|
g_value_set_object (value, priv->default_ac6);
|
||||||
break;
|
break;
|
||||||
case PROP_ACTIVATING_IP4_DEVICE:
|
case PROP_ACTIVATING_IP4_AC:
|
||||||
g_value_set_object (value, priv->activating_device4);
|
g_value_set_object (value, priv->activating_ac4);
|
||||||
break;
|
break;
|
||||||
case PROP_ACTIVATING_IP6_DEVICE:
|
case PROP_ACTIVATING_IP6_AC:
|
||||||
g_value_set_object (value, priv->activating_device6);
|
g_value_set_object (value, priv->activating_ac6);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
@@ -2586,10 +2599,10 @@ dispose (GObject *object)
|
|||||||
g_clear_object (&priv->lookup.addr);
|
g_clear_object (&priv->lookup.addr);
|
||||||
g_clear_object (&priv->lookup.resolver);
|
g_clear_object (&priv->lookup.resolver);
|
||||||
|
|
||||||
nm_clear_g_object (&priv->default_device4);
|
nm_clear_g_object (&priv->default_ac4);
|
||||||
nm_clear_g_object (&priv->default_device6);
|
nm_clear_g_object (&priv->default_ac6);
|
||||||
nm_clear_g_object (&priv->activating_device4);
|
nm_clear_g_object (&priv->activating_ac4);
|
||||||
nm_clear_g_object (&priv->activating_device6);
|
nm_clear_g_object (&priv->activating_ac6);
|
||||||
g_clear_pointer (&priv->pending_active_connections, g_hash_table_unref);
|
g_clear_pointer (&priv->pending_active_connections, g_hash_table_unref);
|
||||||
|
|
||||||
c_list_for_each_entry_safe (data, data_safe, &priv->pending_activation_checks, pending_lst)
|
c_list_for_each_entry_safe (data, data_safe, &priv->pending_activation_checks, pending_lst)
|
||||||
@@ -2695,23 +2708,23 @@ nm_policy_class_init (NMPolicyClass *policy_class)
|
|||||||
G_PARAM_WRITABLE |
|
G_PARAM_WRITABLE |
|
||||||
G_PARAM_CONSTRUCT_ONLY |
|
G_PARAM_CONSTRUCT_ONLY |
|
||||||
G_PARAM_STATIC_STRINGS);
|
G_PARAM_STATIC_STRINGS);
|
||||||
obj_properties[PROP_DEFAULT_IP4_DEVICE] =
|
obj_properties[PROP_DEFAULT_IP4_AC] =
|
||||||
g_param_spec_object (NM_POLICY_DEFAULT_IP4_DEVICE, "", "",
|
g_param_spec_object (NM_POLICY_DEFAULT_IP4_AC, "", "",
|
||||||
|
NM_TYPE_ACTIVE_CONNECTION,
|
||||||
|
G_PARAM_READABLE |
|
||||||
|
G_PARAM_STATIC_STRINGS);
|
||||||
|
obj_properties[PROP_DEFAULT_IP6_AC] =
|
||||||
|
g_param_spec_object (NM_POLICY_DEFAULT_IP6_AC, "", "",
|
||||||
NM_TYPE_DEVICE,
|
NM_TYPE_DEVICE,
|
||||||
G_PARAM_READABLE |
|
G_PARAM_READABLE |
|
||||||
G_PARAM_STATIC_STRINGS);
|
G_PARAM_STATIC_STRINGS);
|
||||||
obj_properties[PROP_DEFAULT_IP6_DEVICE] =
|
obj_properties[PROP_ACTIVATING_IP4_AC] =
|
||||||
g_param_spec_object (NM_POLICY_DEFAULT_IP6_DEVICE, "", "",
|
g_param_spec_object (NM_POLICY_ACTIVATING_IP4_AC, "", "",
|
||||||
NM_TYPE_DEVICE,
|
NM_TYPE_DEVICE,
|
||||||
G_PARAM_READABLE |
|
G_PARAM_READABLE |
|
||||||
G_PARAM_STATIC_STRINGS);
|
G_PARAM_STATIC_STRINGS);
|
||||||
obj_properties[PROP_ACTIVATING_IP4_DEVICE] =
|
obj_properties[PROP_ACTIVATING_IP6_AC] =
|
||||||
g_param_spec_object (NM_POLICY_ACTIVATING_IP4_DEVICE, "", "",
|
g_param_spec_object (NM_POLICY_ACTIVATING_IP6_AC, "", "",
|
||||||
NM_TYPE_DEVICE,
|
|
||||||
G_PARAM_READABLE |
|
|
||||||
G_PARAM_STATIC_STRINGS);
|
|
||||||
obj_properties[PROP_ACTIVATING_IP6_DEVICE] =
|
|
||||||
g_param_spec_object (NM_POLICY_ACTIVATING_IP6_DEVICE, "", "",
|
|
||||||
NM_TYPE_DEVICE,
|
NM_TYPE_DEVICE,
|
||||||
G_PARAM_READABLE |
|
G_PARAM_READABLE |
|
||||||
G_PARAM_STATIC_STRINGS);
|
G_PARAM_STATIC_STRINGS);
|
||||||
|
@@ -31,10 +31,10 @@
|
|||||||
|
|
||||||
#define NM_POLICY_MANAGER "manager"
|
#define NM_POLICY_MANAGER "manager"
|
||||||
#define NM_POLICY_SETTINGS "settings"
|
#define NM_POLICY_SETTINGS "settings"
|
||||||
#define NM_POLICY_DEFAULT_IP4_DEVICE "default-ip4-device"
|
#define NM_POLICY_DEFAULT_IP4_AC "default-ip4-ac"
|
||||||
#define NM_POLICY_DEFAULT_IP6_DEVICE "default-ip6-device"
|
#define NM_POLICY_DEFAULT_IP6_AC "default-ip6-ac"
|
||||||
#define NM_POLICY_ACTIVATING_IP4_DEVICE "activating-ip4-device"
|
#define NM_POLICY_ACTIVATING_IP4_AC "activating-ip4-ac"
|
||||||
#define NM_POLICY_ACTIVATING_IP6_DEVICE "activating-ip6-device"
|
#define NM_POLICY_ACTIVATING_IP6_AC "activating-ip6-ac"
|
||||||
|
|
||||||
typedef struct _NMPolicyClass NMPolicyClass;
|
typedef struct _NMPolicyClass NMPolicyClass;
|
||||||
|
|
||||||
@@ -42,10 +42,10 @@ GType nm_policy_get_type (void);
|
|||||||
|
|
||||||
NMPolicy *nm_policy_new (NMManager *manager, NMSettings *settings);
|
NMPolicy *nm_policy_new (NMManager *manager, NMSettings *settings);
|
||||||
|
|
||||||
NMDevice *nm_policy_get_default_ip4_device (NMPolicy *policy);
|
NMActiveConnection *nm_policy_get_default_ip4_ac (NMPolicy *policy);
|
||||||
NMDevice *nm_policy_get_default_ip6_device (NMPolicy *policy);
|
NMActiveConnection *nm_policy_get_default_ip6_ac (NMPolicy *policy);
|
||||||
NMDevice *nm_policy_get_activating_ip4_device (NMPolicy *policy);
|
NMActiveConnection *nm_policy_get_activating_ip4_ac (NMPolicy *policy);
|
||||||
NMDevice *nm_policy_get_activating_ip6_device (NMPolicy *policy);
|
NMActiveConnection *nm_policy_get_activating_ip6_ac (NMPolicy *policy);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NMPolicyHostnameMode
|
* NMPolicyHostnameMode
|
||||||
|
Reference in New Issue
Block a user