core: merge branch 'th/assume-vs-unmanaged-bgo746440'

This branch only does part of what bgo#746440 is about.
But it's a large and necessary step towards the full
solution. It cleanups tracking of whether to assume
a device, treat it as external or fully manage it.

Future work will need to fine tune the behavior.

https://bugzilla.gnome.org/show_bug.cgi?id=746440
https://bugzilla.redhat.com/show_bug.cgi?id=1394579
This commit is contained in:
Thomas Haller
2017-03-16 18:27:44 +01:00
26 changed files with 908 additions and 514 deletions

View File

@@ -233,21 +233,34 @@ NM_G_ERROR_MSG (GError *error)
#define _NM_IN_SET_EVAL_16(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_15 (op, _x, __VA_ARGS__)
#define _NM_IN_SET_EVAL_N2(op, _x, n, ...) (_NM_IN_SET_EVAL_##n(op, _x, __VA_ARGS__))
#define _NM_IN_SET_EVAL_N(op, x, n, ...) \
#define _NM_IN_SET_EVAL_N(op, type, x, n, ...) \
({ \
typeof(x) _x = (x); \
type _x = (x); \
\
/* trigger a -Wenum-compare warning */ \
nm_assert (TRUE || _x == (x)); \
\
!!_NM_IN_SET_EVAL_N2(op, _x, n, __VA_ARGS__); \
})
#define _NM_IN_SET(op, type, x, ...) _NM_IN_SET_EVAL_N(op, type, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
/* Beware that this does short-circuit evaluation (use "||" instead of "|")
* which has a possibly unexpected non-function-like behavior.
* Use NM_IN_SET_SE if you need all arguments to be evaluted. */
#define NM_IN_SET(x, ...) _NM_IN_SET_EVAL_N(||, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
#define NM_IN_SET(x, ...) _NM_IN_SET(||, typeof (x), x, __VA_ARGS__)
/* "SE" stands for "side-effect". Contrary to NM_IN_SET(), this does not do
* short-circuit evaluation, which can make a difference if the arguments have
* side-effects. */
#define NM_IN_SET_SE(x, ...) _NM_IN_SET_EVAL_N(|, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
#define NM_IN_SET_SE(x, ...) _NM_IN_SET(|, typeof (x), x, __VA_ARGS__)
/* the *_TYPED forms allow to explicitly select the type of "x". This is useful
* if "x" doesn't support typeof (bitfields) or you want to gracefully convert
* a type using automatic type conversion rules (but not forcing the conversion
* with a cast). */
#define NM_IN_SET_TYPED(type, x, ...) _NM_IN_SET(||, type, x, __VA_ARGS__)
#define NM_IN_SET_SE_TYPED(type, x, ...) _NM_IN_SET(|, type, x, __VA_ARGS__)
/*****************************************************************************/
@@ -278,8 +291,8 @@ _NM_IN_STRSET_streq (const char *x, const char *s)
#define _NM_IN_STRSET_EVAL_N(op, x, n, ...) \
({ \
const char *_x = (x); \
( ((_x == NULL) && _NM_IN_SET_EVAL_N2 (op, (const char *) NULL, n, __VA_ARGS__)) \
|| ((_x != NULL) && _NM_IN_STRSET_EVAL_N2 (op, _x, n, __VA_ARGS__)) \
( ((_x == NULL) && _NM_IN_SET_EVAL_N2 (op, ((const char *) NULL), n, __VA_ARGS__)) \
|| ((_x != NULL) && _NM_IN_STRSET_EVAL_N2 (op, _x, n, __VA_ARGS__)) \
); \
})

View File

@@ -370,9 +370,9 @@ route_compare (NMIPRoute *route1, NMIPRoute *route2, gint64 default_metric)
}
static int
route_ptr_compare (const void *a, const void *b)
route_ptr_compare (const void *a, const void *b, gpointer metric)
{
return route_compare (*(NMIPRoute **) a, *(NMIPRoute **) b, -1);
return route_compare (*(NMIPRoute **) a, *(NMIPRoute **) b, *((gint64 *) metric));
}
static gboolean
@@ -384,6 +384,7 @@ check_ip_routes (NMConnection *orig,
{
gs_free NMIPRoute **routes1 = NULL, **routes2 = NULL;
NMSettingIPConfig *s_ip1, *s_ip2;
gint64 m;
const char *s_name;
GHashTable *props;
guint i, num;
@@ -415,8 +416,12 @@ check_ip_routes (NMConnection *orig,
routes2[i] = nm_setting_ip_config_get_route (s_ip2, i);
}
qsort (routes1, num, sizeof (NMIPRoute *), route_ptr_compare);
qsort (routes2, num, sizeof (NMIPRoute *), route_ptr_compare);
m = nm_setting_ip_config_get_route_metric (s_ip2);
if (m != -1)
default_metric = m;
g_qsort_with_data (routes1, num, sizeof (NMIPRoute *), route_ptr_compare, &default_metric);
g_qsort_with_data (routes2, num, sizeof (NMIPRoute *), route_ptr_compare, &default_metric);
for (i = 0; i < num; i++) {
if (route_compare (routes1[i], routes2[i], default_metric))
@@ -710,7 +715,7 @@ check_possible_match (NMConnection *orig,
* matches well enough.
*/
NMConnection *
nm_utils_match_connection (GSList *connections,
nm_utils_match_connection (NMConnection *const*connections,
NMConnection *original,
gboolean device_has_carrier,
gint64 default_v4_metric,
@@ -719,10 +724,12 @@ nm_utils_match_connection (GSList *connections,
gpointer match_filter_data)
{
NMConnection *best_match = NULL;
GSList *iter;
for (iter = connections; iter; iter = iter->next) {
NMConnection *candidate = NM_CONNECTION (iter->data);
if (!connections)
return NULL;
for (; *connections; connections++) {
NMConnection *candidate = NM_CONNECTION (*connections);
GHashTable *diffs = NULL;
if (match_filter_func) {

View File

@@ -39,7 +39,7 @@ void nm_utils_complete_generic (NMPlatform *platform,
typedef gboolean (NMUtilsMatchFilterFunc) (NMConnection *connection, gpointer user_data);
NMConnection *nm_utils_match_connection (GSList *connections,
NMConnection *nm_utils_match_connection (NMConnection *const*connections,
NMConnection *original,
gboolean device_has_carrier,
gint64 default_v4_metric,

View File

@@ -90,13 +90,14 @@ parent_hwaddr_maybe_changed (NMDevice *parent,
GParamSpec *pspec,
gpointer user_data)
{
NMDeviceVlan *self = NM_DEVICE_VLAN (user_data);
NMDevice *device = NM_DEVICE (user_data);
NMDeviceVlan *self = NM_DEVICE_VLAN (device);
NMConnection *connection;
const char *new_mac, *old_mac;
NMSettingIPConfig *s_ip6;
/* Never touch assumed devices */
if (nm_device_uses_assumed_connection ((NMDevice *) self))
if (nm_device_sys_iface_state_is_external_or_assume (device))
return;
connection = nm_device_get_applied_connection ((NMDevice *) self);

View File

@@ -206,6 +206,7 @@ typedef struct _NMDevicePrivate {
NMDeviceState state;
NMDeviceStateReason reason;
} queued_state;
guint queued_ip4_config_id;
guint queued_ip6_config_id;
GSList *pending_actions;
@@ -250,6 +251,8 @@ typedef struct _NMDevicePrivate {
NMUtilsStableType current_stable_id_type:3;
bool is_nm_owned:1; /* whether the device is a device owned and created by NM */
GHashTable * available_connections;
char * hw_addr;
char * hw_addr_perm;
@@ -259,7 +262,6 @@ typedef struct _NMDevicePrivate {
NMUnmanagedFlags unmanaged_mask;
NMUnmanagedFlags unmanaged_flags;
bool is_nm_owned; /* whether the device is a device owned and created by NM */
DeleteOnDeactivateData *delete_on_deactivate_data; /* data for scheduled cleanup when deleting link (g_idle_add) */
GCancellable *deactivating_cancellable;
@@ -289,15 +291,16 @@ typedef struct _NMDevicePrivate {
guint link_connected_id;
guint link_disconnected_id;
guint carrier_defer_id;
bool carrier;
guint carrier_wait_id;
bool ignore_carrier;
gulong ignore_carrier_id;
guint32 mtu;
guint32 ip6_mtu;
guint32 mtu_initial;
guint32 ip6_mtu_initial;
bool carrier:1;
bool ignore_carrier:1;
bool mtu_initialized:1;
bool up:1; /* IFF_UP */
@@ -305,6 +308,8 @@ typedef struct _NMDevicePrivate {
bool v4_commit_first_time:1;
bool v6_commit_first_time:1;
NMDeviceSysIfaceState sys_iface_state:2;
/* Generic DHCP stuff */
guint32 dhcp_timeout;
char * dhcp_anycast_address;
@@ -471,7 +476,7 @@ static gboolean nm_device_set_ip6_config (NMDevice *self,
static gboolean ip6_config_merge_and_apply (NMDevice *self,
gboolean commit);
static void nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure);
static gboolean nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure);
static void nm_device_slave_notify_enslave (NMDevice *self, gboolean success);
static void nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason);
@@ -498,7 +503,9 @@ static gboolean ip_config_valid (NMDeviceState state);
static NMActStageReturn dhcp4_start (NMDevice *self, NMConnection *connection);
static gboolean dhcp6_start (NMDevice *self, gboolean wait_for_ll);
static void nm_device_start_ip_check (NMDevice *self);
static void realize_start_setup (NMDevice *self, const NMPlatformLink *plink);
static void realize_start_setup (NMDevice *self,
const NMPlatformLink *plink,
NMUnmanFlagOp unmanaged_user_explicit);
static void _commit_mtu (NMDevice *self, const NMIP4Config *config);
static void dhcp_schedule_restart (NMDevice *self, int family, const char *reason);
static void _cancel_activation (NMDevice *self);
@@ -606,6 +613,69 @@ nm_device_get_settings (NMDevice *self)
return NM_DEVICE_GET_PRIVATE (self)->settings;
}
/*****************************************************************************/
NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_sys_iface_state_to_str, NMDeviceSysIfaceState,
NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT ("unknown"),
NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, "external"),
NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_SYS_IFACE_STATE_ASSUME, "assume"),
NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_SYS_IFACE_STATE_MANAGED, "managed"),
NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_SYS_IFACE_STATE_REMOVED, "removed"),
);
NMDeviceSysIfaceState
nm_device_sys_iface_state_get (NMDevice *self)
{
g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
return NM_DEVICE_GET_PRIVATE (self)->sys_iface_state;
}
gboolean
nm_device_sys_iface_state_is_external (NMDevice *self)
{
return NM_IN_SET (nm_device_sys_iface_state_get (self),
NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
}
gboolean
nm_device_sys_iface_state_is_external_or_assume (NMDevice *self)
{
return NM_IN_SET (nm_device_sys_iface_state_get (self),
NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
NM_DEVICE_SYS_IFACE_STATE_ASSUME);
}
void
nm_device_sys_iface_state_set (NMDevice *self,
NMDeviceSysIfaceState sys_iface_state)
{
NMDevicePrivate *priv;
g_return_if_fail (NM_IS_DEVICE (self));
g_return_if_fail (NM_IN_SET (sys_iface_state,
NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
NM_DEVICE_SYS_IFACE_STATE_ASSUME,
NM_DEVICE_SYS_IFACE_STATE_MANAGED,
NM_DEVICE_SYS_IFACE_STATE_REMOVED));
priv = NM_DEVICE_GET_PRIVATE (self);
if (priv->sys_iface_state != sys_iface_state) {
_LOGT (LOGD_DEVICE, "sys-iface-state: %s -> %s",
_sys_iface_state_to_str (priv->sys_iface_state),
_sys_iface_state_to_str (sys_iface_state));
priv->sys_iface_state = sys_iface_state;
}
/* this function only sets a flag, no immediate actions are initiated.
*
* If you change this, make sure that all callers are fine with such actions. */
nm_assert (priv->sys_iface_state == sys_iface_state);
}
/*****************************************************************************/
static void
init_ip4_config_dns_priority (NMDevice *self, NMIP4Config *config)
{
@@ -1532,7 +1602,7 @@ nm_device_has_carrier (NMDevice *self)
NMActRequest *
nm_device_get_act_request (NMDevice *self)
{
g_return_val_if_fail (self != NULL, NULL);
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
return NM_DEVICE_GET_PRIVATE (self)->act_request;
}
@@ -1593,33 +1663,6 @@ nm_device_get_physical_port_id (NMDevice *self)
/*****************************************************************************/
static gboolean
nm_device_uses_generated_assumed_connection (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMSettingsConnection *connection;
if ( priv->act_request
&& nm_active_connection_get_assumed (NM_ACTIVE_CONNECTION (priv->act_request))) {
connection = nm_act_request_get_settings_connection (priv->act_request);
if ( connection
&& nm_settings_connection_get_nm_generated_assumed (connection))
return TRUE;
}
return FALSE;
}
gboolean
nm_device_uses_assumed_connection (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
if ( priv->act_request
&& nm_active_connection_get_assumed (NM_ACTIVE_CONNECTION (priv->act_request)))
return TRUE;
return FALSE;
}
static SlaveInfo *
find_slave_info (NMDevice *self, NMDevice *slave)
{
@@ -1725,7 +1768,7 @@ nm_device_master_release_one_slave (NMDevice *self, NMDevice *slave, gboolean co
info = find_slave_info (self, slave);
_LOGt (LOGD_CORE, "master: release one slave %p/%s%s", slave, nm_device_get_iface (slave),
_LOGT (LOGD_CORE, "master: release one slave %p/%s%s", slave, nm_device_get_iface (slave),
!info ? " (not registered)" : "");
if (!info)
@@ -2371,6 +2414,8 @@ link_type_compatible (NMDevice *self,
* nm_device_realize_start():
* @self: the #NMDevice
* @plink: an existing platform link or %NULL
* @unmanaged_user_explicit: the user-explicit unmanaged flag to apply
* on the device initially.
* @out_compatible: %TRUE on return if @self is compatible with @plink
* @error: location to store error, or %NULL
*
@@ -2386,6 +2431,7 @@ link_type_compatible (NMDevice *self,
gboolean
nm_device_realize_start (NMDevice *self,
const NMPlatformLink *plink,
NMUnmanFlagOp unmanaged_user_explicit,
gboolean *out_compatible,
GError **error)
{
@@ -2409,7 +2455,7 @@ nm_device_realize_start (NMDevice *self,
plink_copy = *plink;
plink = &plink_copy;
}
realize_start_setup (self, plink);
realize_start_setup (self, plink, unmanaged_user_explicit);
return TRUE;
}
@@ -2449,7 +2495,7 @@ nm_device_create_and_realize (NMDevice *self,
plink = &plink_copy;
}
realize_start_setup (self, plink);
realize_start_setup (self, plink, NM_UNMAN_FLAG_OP_FORGET);
nm_device_realize_finish (self, plink);
if (nm_device_get_managed (self, FALSE)) {
@@ -2530,6 +2576,7 @@ realize_start_notify (NMDevice *self,
* realize_start_setup():
* @self: the #NMDevice
* @plink: the #NMPlatformLink if backed by a kernel netdevice
* @unmanaged_user_explicit: the user-explict unmanaged flag to set.
*
* Update the device from backing resource properties (like hardware
* addresses, carrier states, driver/firmware info, etc). This function
@@ -2538,7 +2585,9 @@ realize_start_notify (NMDevice *self,
* stuff).
*/
static void
realize_start_setup (NMDevice *self, const NMPlatformLink *plink)
realize_start_setup (NMDevice *self,
const NMPlatformLink *plink,
NMUnmanFlagOp unmanaged_user_explicit)
{
NMDevicePrivate *priv;
NMDeviceClass *klass;
@@ -2576,6 +2625,8 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink)
_notify (self, PROP_MTU);
}
nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
if (plink) {
g_return_if_fail (link_type_compatible (self, plink->type, NULL, NULL));
update_device_from_platform_link (self, plink);
@@ -2659,6 +2710,11 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink)
klass->realize_start_notify (self, plink);
nm_assert (!nm_device_get_unmanaged_mask (self, NM_UNMANAGED_USER_EXPLICIT));
nm_device_set_unmanaged_flags (self,
NM_UNMANAGED_USER_EXPLICIT,
unmanaged_user_explicit);
/* Do not manage externally created software devices until they are IFF_UP
* or have IP addressing */
nm_device_set_unmanaged_flags (self,
@@ -2944,7 +3000,6 @@ slave_state_changed (NMDevice *slave,
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
gboolean release = FALSE;
gboolean configure = TRUE;
_LOGD (LOGD_DEVICE, "slave %s state change %d (%s) -> %d (%s)",
nm_device_get_iface (slave),
@@ -2967,12 +3022,10 @@ slave_state_changed (NMDevice *slave,
release = TRUE;
}
/* Don't touch the device if its state changed externally. */
if (nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED)
configure = FALSE;
if (release) {
nm_device_master_release_one_slave (self, slave, configure, reason);
nm_device_master_release_one_slave (self, slave,
priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED,
reason);
/* Bridge/bond/team interfaces are left up until manually deactivated */
if (priv->slaves == NULL && priv->state == NM_DEVICE_STATE_ACTIVATED)
_LOGD (LOGD_DEVICE, "last slave removed; remaining activated");
@@ -2988,32 +3041,36 @@ slave_state_changed (NMDevice *slave,
*
* If @self is capable of enslaving other devices (ie it's a bridge, bond, team,
* etc) then this function adds @slave to the slave list for later enslavement.
*
* Returns: %TRUE if the slave was enslaved. %FALSE means, the slave was already
* enslaved and nothing was done.
*/
static void
static gboolean
nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure)
{
NMDevicePrivate *priv;
NMDevicePrivate *slave_priv;
SlaveInfo *info;
gboolean changed = FALSE;
g_return_if_fail (NM_IS_DEVICE (self));
g_return_if_fail (NM_IS_DEVICE (slave));
g_return_if_fail (NM_DEVICE_GET_CLASS (self)->enslave_slave != NULL);
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
g_return_val_if_fail (NM_IS_DEVICE (slave), FALSE);
g_return_val_if_fail (NM_DEVICE_GET_CLASS (self)->enslave_slave != NULL, FALSE);
priv = NM_DEVICE_GET_PRIVATE (self);
slave_priv = NM_DEVICE_GET_PRIVATE (slave);
info = find_slave_info (self, slave);
_LOGt (LOGD_CORE, "master: add one slave %p/%s%s", slave, nm_device_get_iface (slave),
_LOGT (LOGD_CORE, "master: add one slave %p/%s%s", slave, nm_device_get_iface (slave),
info ? " (already registered)" : "");
if (configure)
g_return_if_fail (nm_device_get_state (slave) >= NM_DEVICE_STATE_DISCONNECTED);
g_return_val_if_fail (nm_device_get_state (slave) >= NM_DEVICE_STATE_DISCONNECTED, FALSE);
if (!info) {
g_return_if_fail (!slave_priv->master);
g_return_if_fail (!slave_priv->is_enslaved);
g_return_val_if_fail (!slave_priv->master, FALSE);
g_return_val_if_fail (!slave_priv->is_enslaved, FALSE);
info = g_slice_new0 (SlaveInfo);
info->slave = g_object_ref (slave);
@@ -3033,13 +3090,15 @@ nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure)
g_warn_if_fail (!NM_FLAGS_HAS (slave_priv->unmanaged_mask, NM_UNMANAGED_IS_SLAVE));
nm_device_set_unmanaged_by_flags (slave, NM_UNMANAGED_IS_SLAVE, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
changed = TRUE;
} else
g_return_if_fail (slave_priv->master == self);
g_return_val_if_fail (slave_priv->master == self, FALSE);
nm_device_queue_recheck_assume (self);
nm_device_queue_recheck_assume (slave);
}
return changed;
}
/**
* nm_device_master_get_slaves:
@@ -3132,7 +3191,7 @@ nm_device_master_release_slaves (NMDevice *self)
gboolean configure = TRUE;
/* Don't release the slaves if this connection doesn't belong to NM. */
if (nm_device_uses_generated_assumed_connection (self))
if (nm_device_sys_iface_state_is_external (self))
return;
reason = priv->state_reason;
@@ -3210,6 +3269,14 @@ nm_device_slave_notify_enslave (NMDevice *self, gboolean success)
_LOGI (LOGD_DEVICE, "enslaved to %s", nm_device_get_iface (priv->master));
priv->is_enslaved = TRUE;
if ( NM_IN_SET_TYPED (NMDeviceSysIfaceState,
priv->sys_iface_state,
NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
NM_DEVICE_SYS_IFACE_STATE_ASSUME)
&& nm_device_sys_iface_state_get (priv->master) == NM_DEVICE_SYS_IFACE_STATE_MANAGED)
nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_MANAGED);
_notify (self, PROP_MASTER);
_notify (priv->master, PROP_SLAVES);
} else if (activating) {
@@ -3248,15 +3315,19 @@ nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason)
if ( priv->state > NM_DEVICE_STATE_DISCONNECTED
&& priv->state <= NM_DEVICE_STATE_ACTIVATED) {
if (nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED) {
switch (nm_device_state_reason_check (reason)) {
case NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED:
new_state = NM_DEVICE_STATE_FAILED;
master_status = "failed";
} else if (nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_USER_REQUESTED) {
break;
case NM_DEVICE_STATE_REASON_USER_REQUESTED:
new_state = NM_DEVICE_STATE_DEACTIVATING;
master_status = "deactivated by user request";
} else {
break;
default:
new_state = NM_DEVICE_STATE_DISCONNECTED;
master_status = "deactivated";
break;
}
_LOGD (LOGD_DEVICE, "Activation: connection '%s' master %s",
@@ -3920,12 +3991,14 @@ recheck_available (gpointer user_data)
{
NMDevice *self = NM_DEVICE (user_data);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
gboolean now_available = nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE);
gboolean now_available;
NMDeviceState state = nm_device_get_state (self);
NMDeviceState new_state = NM_DEVICE_STATE_UNKNOWN;
priv->recheck_available.call_id = 0;
now_available = nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE);
if (state == NM_DEVICE_STATE_UNAVAILABLE && now_available) {
new_state = NM_DEVICE_STATE_DISCONNECTED;
nm_device_queue_state (self, new_state, priv->recheck_available.available_reason);
@@ -4164,7 +4237,7 @@ master_ready (NMDevice *self,
/* If the master didn't change, add-slave only rechecks whether to assume a connection. */
nm_device_master_add_slave (master,
self,
nm_active_connection_get_assumed (active) ? FALSE : TRUE);
!nm_device_sys_iface_state_is_external_or_assume (self));
}
static void
@@ -4232,7 +4305,6 @@ activate_stage1_device_prepare (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request);
_set_ip_state (self, AF_INET, IP_NONE);
_set_ip_state (self, AF_INET6, IP_NONE);
@@ -4244,7 +4316,7 @@ activate_stage1_device_prepare (NMDevice *self)
nm_device_state_changed (self, NM_DEVICE_STATE_PREPARE, NM_DEVICE_STATE_REASON_NONE);
/* Assumed connections were already set up outside NetworkManager */
if (!nm_active_connection_get_assumed (active)) {
if (!nm_device_sys_iface_state_is_external_or_assume (self)) {
NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE;
ret = NM_DEVICE_GET_CLASS (self)->act_stage1_prepare (self, &failure_reason);
@@ -4336,13 +4408,12 @@ activate_stage2_device_config (NMDevice *self)
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMActStageReturn ret;
gboolean no_firmware = FALSE;
NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request);
GSList *iter;
nm_device_state_changed (self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE);
/* Assumed connections were already set up outside NetworkManager */
if (!nm_active_connection_get_assumed (active)) {
if (!nm_device_sys_iface_state_is_external_or_assume (self)) {
NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE;
if (!nm_device_bring_up (self, FALSE, &no_firmware)) {
@@ -4370,7 +4441,8 @@ activate_stage2_device_config (NMDevice *self)
if (slave_state == NM_DEVICE_STATE_IP_CONFIG)
nm_device_master_enslave_slave (self, info->slave, nm_device_get_applied_connection (info->slave));
else if ( nm_device_uses_generated_assumed_connection (self)
else if ( priv->act_request
&& nm_device_sys_iface_state_is_external (self)
&& slave_state <= NM_DEVICE_STATE_DISCONNECTED)
nm_device_queue_recheck_assume (info->slave);
}
@@ -4471,7 +4543,7 @@ check_ip_state (NMDevice *self, gboolean may_fail)
&& (priv->ip6_state == IP_FAIL || (ip6_ignore && priv->ip6_state == IP_DONE))) {
/* Either both methods failed, or only one failed and the other is
* disabled */
if (nm_device_uses_assumed_connection (self)) {
if (nm_device_sys_iface_state_is_external_or_assume (self)) {
/* We have assumed configuration, but couldn't redo it. No problem,
* move to check state. */
_set_ip_state (self, AF_INET, IP_DONE);
@@ -4663,7 +4735,7 @@ ipv4_dad_start (NMDevice *self, NMIP4Config **configs, ArpingCallback cb)
|| !hw_addr
|| !hw_addr_len
|| !addr_found
|| nm_device_uses_assumed_connection (self)) {
|| nm_device_sys_iface_state_is_external_or_assume (self)) {
/* DAD not needed, signal success */
cb (self, configs, TRUE);
@@ -4964,7 +5036,7 @@ ensure_con_ip4_config (NMDevice *self)
nm_connection_get_setting_ip4_config (connection),
nm_device_get_ip4_route_metric (self));
if (nm_device_uses_assumed_connection (self)) {
if (nm_device_sys_iface_state_is_external_or_assume (self)) {
/* For assumed connections ignore all addresses and routes. */
nm_ip4_config_reset_addresses (priv->con_ip4_config);
nm_ip4_config_reset_routes (priv->con_ip4_config);
@@ -4990,7 +5062,7 @@ ensure_con_ip6_config (NMDevice *self)
nm_connection_get_setting_ip6_config (connection),
nm_device_get_ip6_route_metric (self));
if (nm_device_uses_assumed_connection (self)) {
if (nm_device_sys_iface_state_is_external_or_assume (self)) {
/* For assumed connections ignore all addresses and routes. */
nm_ip6_config_reset_addresses (priv->con_ip6_config);
nm_ip6_config_reset_routes (priv->con_ip6_config);
@@ -5132,7 +5204,7 @@ ip4_config_merge_and_apply (NMDevice *self,
* but if the IP method is automatic we need to update the default route to
* maintain connectivity.
*/
if (nm_device_uses_generated_assumed_connection (self) && !auto_method)
if (nm_device_sys_iface_state_is_external (self) && !auto_method)
goto END_ADD_DEFAULT_ROUTE;
/* At this point, we treat assumed and non-assumed connections alike.
@@ -5208,7 +5280,7 @@ END_ADD_DEFAULT_ROUTE:
routes_full_sync = commit
&& priv->v4_commit_first_time
&& !nm_device_uses_assumed_connection (self);
&& !nm_device_sys_iface_state_is_external_or_assume (self);
success = nm_device_set_ip4_config (self, composite, default_route_metric, commit, routes_full_sync);
g_object_unref (composite);
@@ -5228,14 +5300,10 @@ dhcp4_lease_change (NMDevice *self, NMIP4Config *config)
return FALSE;
}
/* Notify dispatcher scripts of new DHCP4 config */
nm_dispatcher_call (DISPATCHER_ACTION_DHCP4_CHANGE,
nm_device_get_settings_connection (self),
nm_device_get_applied_connection (self),
self,
NULL,
NULL,
NULL);
nm_dispatcher_call_device (NM_DISPATCHER_ACTION_DHCP4_CHANGE,
self,
NULL,
NULL, NULL, NULL);
nm_device_remove_pending_action (self, NM_PENDING_ACTION_DHCP4, FALSE);
@@ -5285,7 +5353,7 @@ dhcp4_fail (NMDevice *self, gboolean timeout)
* device will transition to the ACTIVATED state without IP configuration),
* retry DHCP again.
*/
if (nm_device_uses_assumed_connection (self)) {
if (nm_device_sys_iface_state_is_external_or_assume (self)) {
dhcp_schedule_restart (self, AF_INET, "connection is assumed");
return;
}
@@ -5883,7 +5951,7 @@ ip6_config_merge_and_apply (NMDevice *self,
* but if the IP method is automatic we need to update the default route to
* maintain connectivity.
*/
if (nm_device_uses_generated_assumed_connection (self) && !auto_method)
if (nm_device_sys_iface_state_is_external (self) && !auto_method)
goto END_ADD_DEFAULT_ROUTE;
/* At this point, we treat assumed and non-assumed connections alike.
@@ -5965,7 +6033,7 @@ END_ADD_DEFAULT_ROUTE:
routes_full_sync = commit
&& priv->v6_commit_first_time
&& !nm_device_uses_assumed_connection (self);
&& !nm_device_sys_iface_state_is_external_or_assume (self);
success = nm_device_set_ip6_config (self, composite, commit, routes_full_sync);
g_object_unref (composite);
@@ -5996,11 +6064,10 @@ dhcp6_lease_change (NMDevice *self)
return FALSE;
}
/* Notify dispatcher scripts of new DHCPv6 config */
nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE,
settings_connection,
nm_device_get_applied_connection (self),
self, NULL, NULL, NULL);
nm_dispatcher_call_device (NM_DISPATCHER_ACTION_DHCP6_CHANGE,
self,
NULL,
NULL, NULL, NULL);
nm_device_remove_pending_action (self, NM_PENDING_ACTION_DHCP6, FALSE);
@@ -6080,7 +6147,7 @@ dhcp6_fail (NMDevice *self, gboolean timeout)
* device will transition to the ACTIVATED state without IP configuration),
* retry DHCP again.
*/
if (nm_device_uses_assumed_connection (self)) {
if (nm_device_sys_iface_state_is_external_or_assume (self)) {
dhcp_schedule_restart (self, AF_INET6, "connection is assumed");
return;
}
@@ -6665,7 +6732,7 @@ _commit_mtu (NMDevice *self, const NMIP4Config *config)
if (ifindex <= 0)
return;
if (nm_device_uses_assumed_connection (self)) {
if (nm_device_sys_iface_state_is_external_or_assume (self)) {
/* for assumed connections we don't tamper with the MTU. This is
* a bug and supposed to be fixed by the unmanaged/assumed rework. */
return;
@@ -7332,7 +7399,7 @@ act_stage3_ip6_config_start (NMDevice *self,
* IPv6LL if this is not an assumed connection, since assumed connections
* will already have IPv6 set up.
*/
if (!nm_device_uses_assumed_connection (self))
if (!nm_device_sys_iface_state_is_external_or_assume (self))
set_nm_ipv6ll (self, TRUE);
/* Re-enable IPv6 on the interface */
@@ -7362,7 +7429,7 @@ act_stage3_ip6_config_start (NMDevice *self,
_LOGW (LOGD_IP6, "unhandled IPv6 config method '%s'; will fail", method);
if ( ret != NM_ACT_STAGE_RETURN_FAILURE
&& !nm_device_uses_assumed_connection (self)) {
&& !nm_device_sys_iface_state_is_external_or_assume (self)) {
switch (ip6_privacy) {
case NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN:
case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED:
@@ -7605,7 +7672,7 @@ nm_device_activate_schedule_stage3_ip_config_start (NMDevice *self)
s_con = nm_connection_get_setting_connection (connection);
if (!priv->fw_ready) {
if (nm_device_uses_generated_assumed_connection (self))
if (nm_device_sys_iface_state_is_external (self))
priv->fw_ready = TRUE;
else {
if (!priv->fw_call) {
@@ -7907,7 +7974,7 @@ activate_stage5_ip4_config_commit (NMDevice *self)
/* Interface must be IFF_UP before IP config can be applied */
ip_ifindex = nm_device_get_ip_ifindex (self);
if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex) && !nm_device_uses_assumed_connection (self)) {
if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex) && !nm_device_sys_iface_state_is_external_or_assume (self)) {
nm_platform_link_set_up (NM_PLATFORM_GET, ip_ifindex, NULL);
if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex))
_LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self));
@@ -7937,14 +8004,10 @@ activate_stage5_ip4_config_commit (NMDevice *self)
if ( priv->dhcp4.client
&& nm_device_activate_ip4_state_in_conf (self)
&& (nm_device_get_state (self) > NM_DEVICE_STATE_IP_CONFIG)) {
/* Notify dispatcher scripts of new DHCP4 config */
nm_dispatcher_call (DISPATCHER_ACTION_DHCP4_CHANGE,
nm_device_get_settings_connection (self),
nm_device_get_applied_connection (self),
self,
NULL,
NULL,
NULL);
nm_dispatcher_call_device (NM_DISPATCHER_ACTION_DHCP4_CHANGE,
self,
NULL,
NULL, NULL, NULL);
}
arp_announce (self);
@@ -8060,7 +8123,7 @@ activate_stage5_ip6_config_commit (NMDevice *self)
/* Interface must be IFF_UP before IP config can be applied */
ip_ifindex = nm_device_get_ip_ifindex (self);
if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex) && !nm_device_uses_assumed_connection (self)) {
if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex) && !nm_device_sys_iface_state_is_external_or_assume (self)) {
nm_platform_link_set_up (NM_PLATFORM_GET, ip_ifindex, NULL);
if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex))
_LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self));
@@ -8073,13 +8136,10 @@ activate_stage5_ip6_config_commit (NMDevice *self)
/* If IPv6 wasn't the first IP to complete, and DHCP was used,
* then ensure dispatcher scripts get the DHCP lease information.
*/
nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE,
nm_device_get_settings_connection (self),
nm_device_get_applied_connection (self),
self,
NULL,
NULL,
NULL);
nm_dispatcher_call_device (NM_DISPATCHER_ACTION_DHCP6_CHANGE,
self,
NULL,
NULL, NULL, NULL);
} else {
/* still waiting for first dhcp6 lease. */
return;
@@ -8192,7 +8252,24 @@ act_request_set (NMDevice *self, NMActRequest *act_request)
"notify::"NM_EXPORTED_OBJECT_PATH,
G_CALLBACK (act_request_set_cb),
self);
switch (nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (act_request))) {
case NM_ACTIVATION_TYPE_EXTERNAL:
break;
case NM_ACTIVATION_TYPE_ASSUME:
if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_EXTERNAL)
nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_ASSUME);
break;
case NM_ACTIVATION_TYPE_MANAGED:
if (NM_IN_SET_TYPED (NMDeviceSysIfaceState,
priv->sys_iface_state,
NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
NM_DEVICE_SYS_IFACE_STATE_ASSUME))
nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_MANAGED);
break;
}
}
_notify (self, PROP_ACTIVE_CONNECTION);
}
@@ -9291,7 +9368,7 @@ nm_device_set_ip4_config (NMDevice *self,
/* Always commit to nm-platform to update lifetimes */
if (commit && new_config) {
gboolean assumed = nm_device_uses_assumed_connection (self);
gboolean assumed = nm_device_sys_iface_state_is_external_or_assume (self);
_commit_mtu (self, new_config);
/* For assumed devices we must not touch the kernel-routes, such as the device-route.
@@ -9333,6 +9410,8 @@ nm_device_set_ip4_config (NMDevice *self,
nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self);
if (has_changes) {
NMSettingsConnection *settings_connection;
_update_ip4_address (self);
if (old_config != priv->ip4_config)
@@ -9342,15 +9421,17 @@ nm_device_set_ip4_config (NMDevice *self,
if (old_config != priv->ip4_config)
nm_exported_object_clear_and_unexport (&old_config);
if (nm_device_uses_generated_assumed_connection (self)) {
NMConnection *settings_connection = NM_CONNECTION (nm_device_get_settings_connection (self));
if ( nm_device_sys_iface_state_is_external (self)
&& (settings_connection = nm_device_get_settings_connection (self))
&& nm_settings_connection_get_nm_generated (settings_connection)
&& nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (priv->act_request)) == NM_ACTIVATION_TYPE_EXTERNAL) {
NMSetting *s_ip4;
g_object_freeze_notify (G_OBJECT (settings_connection));
nm_connection_remove_setting (settings_connection, NM_TYPE_SETTING_IP4_CONFIG);
nm_connection_remove_setting (NM_CONNECTION (settings_connection), NM_TYPE_SETTING_IP4_CONFIG);
s_ip4 = nm_ip4_config_create_setting (priv->ip4_config);
nm_connection_add_setting (settings_connection, s_ip4);
nm_connection_add_setting (NM_CONNECTION (settings_connection), s_ip4);
g_object_thaw_notify (G_OBJECT (settings_connection));
}
@@ -9489,6 +9570,8 @@ nm_device_set_ip6_config (NMDevice *self,
nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), self);
if (has_changes) {
NMSettingsConnection *settings_connection;
if (old_config != priv->ip6_config)
_notify (self, PROP_IP6_CONFIG);
g_signal_emit (self, signals[IP6_CONFIG_CHANGED], 0, priv->ip6_config, old_config);
@@ -9496,15 +9579,17 @@ nm_device_set_ip6_config (NMDevice *self,
if (old_config != priv->ip6_config)
nm_exported_object_clear_and_unexport (&old_config);
if (nm_device_uses_generated_assumed_connection (self)) {
NMConnection *settings_connection = NM_CONNECTION (nm_device_get_settings_connection (self));
if ( nm_device_sys_iface_state_is_external (self)
&& (settings_connection = nm_device_get_settings_connection (self))
&& nm_settings_connection_get_nm_generated (settings_connection)
&& nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (priv->act_request)) == NM_ACTIVATION_TYPE_EXTERNAL) {
NMSetting *s_ip6;
g_object_freeze_notify (G_OBJECT (settings_connection));
nm_connection_remove_setting (settings_connection, NM_TYPE_SETTING_IP6_CONFIG);
nm_connection_remove_setting (NM_CONNECTION (settings_connection), NM_TYPE_SETTING_IP6_CONFIG);
s_ip6 = nm_ip6_config_create_setting (priv->ip6_config);
nm_connection_add_setting (settings_connection, s_ip6);
nm_connection_add_setting (NM_CONNECTION (settings_connection), s_ip6);
g_object_thaw_notify (G_OBJECT (settings_connection));
}
@@ -9608,13 +9693,12 @@ ip_check_pre_up (NMDevice *self)
priv->dispatcher.post_state = NM_DEVICE_STATE_SECONDARIES;
priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE;
if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_UP,
nm_device_get_settings_connection (self),
nm_device_get_applied_connection (self),
self,
dispatcher_complete_proceed_state,
self,
&priv->dispatcher.call_id)) {
if (!nm_dispatcher_call_device (NM_DISPATCHER_ACTION_PRE_UP,
self,
NULL,
dispatcher_complete_proceed_state,
self,
&priv->dispatcher.call_id)) {
/* Just proceed on errors */
dispatcher_complete_proceed_state (0, self);
}
@@ -10976,7 +11060,7 @@ nm_device_update_firewall_zone (NMDevice *self)
s_con = nm_connection_get_setting_connection (applied_connection);
if ( nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED
&& !nm_device_uses_generated_assumed_connection (self)) {
&& !nm_device_sys_iface_state_is_external (self)) {
nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (),
nm_device_get_ip_iface (self),
nm_setting_connection_get_zone (s_con),
@@ -11477,7 +11561,7 @@ _cleanup_generic_pre (NMDevice *self, CleanupType cleanup_type)
connection = nm_device_get_applied_connection (self);
if ( cleanup_type == CLEANUP_TYPE_DECONFIGURE
&& connection
&& !nm_device_uses_generated_assumed_connection (self)) {
&& !nm_device_sys_iface_state_is_external (self)) {
nm_firewall_manager_remove_from_zone (nm_firewall_manager_get (),
nm_device_get_ip_iface (self),
NULL,
@@ -11995,6 +12079,14 @@ _set_state_full (NMDevice *self,
/* Cache the activation request for the dispatcher */
req = nm_g_object_ref (priv->act_request);
if ( state > NM_DEVICE_STATE_UNMANAGED
&& nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_NOW_MANAGED
&& NM_IN_SET_TYPED (NMDeviceSysIfaceState,
priv->sys_iface_state,
NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
NM_DEVICE_SYS_IFACE_STATE_ASSUME))
nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_MANAGED);
if (state <= NM_DEVICE_STATE_UNAVAILABLE) {
if (available_connections_del_all (self))
_notify (self, PROP_AVAILABLE_CONNECTIONS);
@@ -12018,14 +12110,12 @@ _set_state_full (NMDevice *self,
case NM_DEVICE_STATE_UNMANAGED:
nm_device_set_firmware_missing (self, FALSE);
if (old_state > NM_DEVICE_STATE_UNMANAGED) {
switch (nm_device_state_reason_check (reason)) {
case NM_DEVICE_STATE_REASON_REMOVED:
nm_device_cleanup (self, reason, CLEANUP_TYPE_REMOVED);
break;
case NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED:
nm_device_cleanup (self, reason, CLEANUP_TYPE_KEEP);
break;
default:
if (priv->sys_iface_state != NM_DEVICE_SYS_IFACE_STATE_MANAGED) {
nm_device_cleanup (self, reason,
priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_REMOVED
? CLEANUP_TYPE_REMOVED
: CLEANUP_TYPE_KEEP);
} else {
/* Clean up if the device is now unmanaged but was activated */
if (nm_device_get_act_request (self))
nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE);
@@ -12040,11 +12130,11 @@ _set_state_full (NMDevice *self,
case NM_DEVICE_STATE_UNAVAILABLE:
if (old_state == NM_DEVICE_STATE_UNMANAGED) {
save_ip6_properties (self);
if (nm_device_state_reason_check (reason) != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED)
if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED)
ip6_managed_setup (self);
}
if (nm_device_state_reason_check (reason) != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) {
if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED) {
if (old_state == NM_DEVICE_STATE_UNMANAGED || priv->firmware_missing) {
if (!nm_device_bring_up (self, TRUE, &no_firmware) && no_firmware)
_LOGW (LOGD_PLATFORM, "firmware may be missing.");
@@ -12071,7 +12161,7 @@ _set_state_full (NMDevice *self,
nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE);
} else if (old_state < NM_DEVICE_STATE_DISCONNECTED) {
if (nm_device_state_reason_check (reason) != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) {
if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED) {
/* Ensure IPv6 is set up as it may not have been done when
* entering the UNAVAILABLE state depending on the reason.
*/
@@ -12130,20 +12220,17 @@ _set_state_full (NMDevice *self,
priv->ignore_carrier = nm_config_data_get_ignore_carrier (NM_CONFIG_GET_DATA, self);
if (quitting) {
nm_dispatcher_call_sync (DISPATCHER_ACTION_PRE_DOWN,
nm_act_request_get_settings_connection (req),
nm_act_request_get_applied_connection (req),
self);
nm_dispatcher_call_device_sync (NM_DISPATCHER_ACTION_PRE_DOWN,
self, req);
} else {
priv->dispatcher.post_state = NM_DEVICE_STATE_DISCONNECTED;
priv->dispatcher.post_state_reason = reason;
if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_DOWN,
nm_act_request_get_settings_connection (req),
nm_act_request_get_applied_connection (req),
self,
deactivate_dispatcher_complete,
self,
&priv->dispatcher.call_id)) {
if (!nm_dispatcher_call_device (NM_DISPATCHER_ACTION_PRE_DOWN,
self,
req,
deactivate_dispatcher_complete,
self,
&priv->dispatcher.call_id)) {
/* Just proceed on errors */
deactivate_dispatcher_complete (0, self);
}
@@ -12170,10 +12257,10 @@ _set_state_full (NMDevice *self,
case NM_DEVICE_STATE_ACTIVATED:
_LOGI (LOGD_DEVICE, "Activation: successful, device activated.");
nm_device_update_metered (self);
nm_dispatcher_call (DISPATCHER_ACTION_UP,
nm_act_request_get_settings_connection (req),
nm_act_request_get_applied_connection (req),
self, NULL, NULL, NULL);
nm_dispatcher_call_device (NM_DISPATCHER_ACTION_UP,
self,
req,
NULL, NULL, NULL);
if (priv->proxy_config) {
nm_pacrunner_manager_send (priv->pacrunner_manager,
@@ -12192,7 +12279,7 @@ _set_state_full (NMDevice *self,
*/
_cancel_activation (self);
if (nm_device_uses_assumed_connection (self)) {
if (nm_device_sys_iface_state_is_external_or_assume (self)) {
/* Avoid tearing down assumed connection, assume it's connected */
nm_device_queue_state (self,
NM_DEVICE_STATE_ACTIVATED,
@@ -12230,7 +12317,7 @@ _set_state_full (NMDevice *self,
if ( applied_connection
&& priv->ifindex != priv->ip_ifindex
&& !nm_device_uses_generated_assumed_connection (self)) {
&& !nm_device_sys_iface_state_is_external (self)) {
NMSettingConnection *s_con;
const char *zone;
@@ -12265,15 +12352,13 @@ _set_state_full (NMDevice *self,
if ( (old_state == NM_DEVICE_STATE_ACTIVATED || old_state == NM_DEVICE_STATE_DEACTIVATING)
&& (state != NM_DEVICE_STATE_DEACTIVATING)) {
if (quitting) {
nm_dispatcher_call_sync (DISPATCHER_ACTION_DOWN,
nm_act_request_get_settings_connection (req),
nm_act_request_get_applied_connection (req),
self);
nm_dispatcher_call_device_sync (NM_DISPATCHER_ACTION_DOWN,
self, req);
} else {
nm_dispatcher_call (DISPATCHER_ACTION_DOWN,
nm_act_request_get_settings_connection (req),
nm_act_request_get_applied_connection (req),
self, NULL, NULL, NULL);
nm_dispatcher_call_device (NM_DISPATCHER_ACTION_DOWN,
self,
req,
NULL, NULL, NULL);
}
}
@@ -13179,6 +13264,7 @@ nm_device_init (NMDevice *self)
priv->unmanaged_mask = priv->unmanaged_flags;
priv->available_connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL);
priv->ip6_saved_properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
priv->sys_iface_state = NM_DEVICE_SYS_IFACE_STATE_EXTERNAL;
priv->pacrunner_manager = g_object_ref (nm_pacrunner_manager_get ());

View File

@@ -30,6 +30,13 @@
#include "nm-rfkill-manager.h"
#include "NetworkManagerUtils.h"
typedef enum {
NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
NM_DEVICE_SYS_IFACE_STATE_ASSUME,
NM_DEVICE_SYS_IFACE_STATE_MANAGED,
NM_DEVICE_SYS_IFACE_STATE_REMOVED,
} NMDeviceSysIfaceState;
static inline NMDeviceStateReason
nm_device_state_reason_check (NMDeviceStateReason reason)
{
@@ -489,8 +496,6 @@ gboolean nm_device_complete_connection (NMDevice *device,
gboolean nm_device_check_connection_compatible (NMDevice *device, NMConnection *connection);
gboolean nm_device_check_slave_connection_compatible (NMDevice *device, NMConnection *connection);
gboolean nm_device_uses_assumed_connection (NMDevice *device);
gboolean nm_device_unmanage_on_quit (NMDevice *self);
gboolean nm_device_spec_match_list (NMDevice *device, const GSList *specs);
@@ -595,6 +600,7 @@ gboolean nm_device_has_capability (NMDevice *self, NMDeviceCapabilities caps);
gboolean nm_device_realize_start (NMDevice *device,
const NMPlatformLink *plink,
NMUnmanFlagOp unmanaged_user_explicit,
gboolean *out_compatible,
GError **error);
void nm_device_realize_finish (NMDevice *self,
@@ -611,6 +617,13 @@ gboolean nm_device_get_autoconnect (NMDevice *device);
void nm_device_set_autoconnect_intern (NMDevice *device, gboolean autoconnect);
void nm_device_emit_recheck_auto_activate (NMDevice *device);
NMDeviceSysIfaceState nm_device_sys_iface_state_get (NMDevice *device);
gboolean nm_device_sys_iface_state_is_external (NMDevice *self);
gboolean nm_device_sys_iface_state_is_external_or_assume (NMDevice *self);
void nm_device_sys_iface_state_set (NMDevice *device, NMDeviceSysIfaceState sys_iface_state);
void nm_device_state_changed (NMDevice *device,
NMDeviceState state,
NMDeviceStateReason reason);

View File

@@ -416,7 +416,7 @@ teamd_dbus_appeared (GDBusConnection *connection,
success = teamd_read_config (device);
if (success)
nm_device_activate_schedule_stage2_device_config (device);
else if (!nm_device_uses_assumed_connection (device))
else if (!nm_device_sys_iface_state_is_external_or_assume (device))
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED);
}
}

View File

@@ -543,6 +543,7 @@ nm_act_request_init (NMActRequest *req)
* @specific_object: the object path of the specific object (ie, WiFi access point,
* etc) that will be used to activate @connection and @device
* @subject: the #NMAuthSubject representing the requestor of the activation
* @activation_type: the #NMActivationType.
* @device: the device/interface to configure according to @connection
*
* Creates a new device-based activation request. If an applied connection is
@@ -555,6 +556,7 @@ nm_act_request_new (NMSettingsConnection *settings_connection,
NMConnection *applied_connection,
const char *specific_object,
NMAuthSubject *subject,
NMActivationType activation_type,
NMDevice *device)
{
g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL);
@@ -567,6 +569,7 @@ nm_act_request_new (NMSettingsConnection *settings_connection,
NM_ACTIVE_CONNECTION_INT_DEVICE, device,
NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, specific_object,
NM_ACTIVE_CONNECTION_INT_SUBJECT, subject,
NM_ACTIVE_CONNECTION_INT_ACTIVATION_TYPE, (int) activation_type,
NULL);
}

View File

@@ -40,6 +40,7 @@ NMActRequest *nm_act_request_new (NMSettingsConnection *settings_connec
NMConnection *applied_connection,
const char *specific_object,
NMAuthSubject *subject,
NMActivationType activation_type,
NMDevice *device);
NMSettingsConnection *nm_act_request_get_settings_connection (NMActRequest *req);

View File

@@ -44,20 +44,20 @@ typedef struct _NMActiveConnectionPrivate {
char *pending_activation_id;
gboolean is_default;
gboolean is_default6;
NMActiveConnectionState state;
gboolean state_set;
gboolean vpn;
bool is_default:1;
bool is_default6:1;
bool state_set:1;
bool vpn:1;
bool master_ready:1;
NMActivationType activation_type:3;
NMAuthSubject *subject;
NMActiveConnection *master;
gboolean master_ready;
NMActiveConnection *parent;
gboolean assumed;
NMAuthChain *chain;
const char *wifi_shared_permission;
NMActiveConnectionAuthResultFunc result_func;
@@ -88,6 +88,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMActiveConnection,
PROP_INT_SUBJECT,
PROP_INT_MASTER,
PROP_INT_MASTER_READY,
PROP_INT_ACTIVATION_TYPE,
);
enum {
@@ -102,8 +103,15 @@ G_DEFINE_ABSTRACT_TYPE (NMActiveConnection, nm_active_connection, NM_TYPE_EXPORT
#define NM_ACTIVE_CONNECTION_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMActiveConnection, NM_IS_ACTIVE_CONNECTION)
/*****************************************************************************/
static void check_master_ready (NMActiveConnection *self);
static void _device_cleanup (NMActiveConnection *self);
static void _settings_connection_notify_flags (NMSettingsConnection *settings_connection,
GParamSpec *param,
NMActiveConnection *self);
static void _set_activation_type (NMActiveConnection *self,
NMActivationType activation_type);
/*****************************************************************************/
@@ -181,12 +189,15 @@ _set_settings_connection (NMActiveConnection *self, NMSettingsConnection *connec
if (priv->settings_connection) {
g_signal_handlers_disconnect_by_func (priv->settings_connection, _settings_connection_updated, self);
g_signal_handlers_disconnect_by_func (priv->settings_connection, _settings_connection_removed, self);
g_signal_handlers_disconnect_by_func (priv->settings_connection, _settings_connection_notify_flags, self);
g_clear_object (&priv->settings_connection);
}
if (connection) {
priv->settings_connection = g_object_ref (connection);
g_signal_connect (connection, NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, (GCallback) _settings_connection_updated, self);
g_signal_connect (connection, NM_SETTINGS_CONNECTION_REMOVED, (GCallback) _settings_connection_removed, self);
if (nm_active_connection_get_activation_type (self) == NM_ACTIVATION_TYPE_EXTERNAL)
g_signal_connect (connection, "notify::"NM_SETTINGS_CONNECTION_FLAGS, (GCallback) _settings_connection_notify_flags, self);
}
}
@@ -214,6 +225,14 @@ nm_active_connection_set_state (NMActiveConnection *self,
state_to_string (new_state),
state_to_string (priv->state));
if ( new_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED
&& priv->activation_type == NM_ACTIVATION_TYPE_ASSUME) {
/* assuming connections mean to gracefully take over an externally
* configured device. Once activation is complete, an assumed
* activation *is* the same as a full activation. */
_set_activation_type (self, NM_ACTIVATION_TYPE_MANAGED);
}
old_state = priv->state;
priv->state = new_state;
priv->state_set = TRUE;
@@ -566,7 +585,7 @@ nm_active_connection_set_device (NMActiveConnection *self, NMDevice *device)
g_signal_connect (device, "notify::" NM_DEVICE_METERED,
G_CALLBACK (device_metered_changed), self);
if (!priv->assumed) {
if (priv->activation_type != NM_ACTIVATION_TYPE_EXTERNAL) {
priv->pending_activation_id = g_strdup_printf (NM_PENDING_ACTIONPREFIX_ACTIVATION"%p", (void *)self);
nm_device_add_pending_action (device, priv->pending_activation_id, TRUE);
}
@@ -712,24 +731,55 @@ nm_active_connection_set_master (NMActiveConnection *self, NMActiveConnection *m
check_master_ready (self);
}
void
nm_active_connection_set_assumed (NMActiveConnection *self, gboolean assumed)
NMActivationType
nm_active_connection_get_activation_type (NMActiveConnection *self)
{
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NM_ACTIVATION_TYPE_MANAGED);
return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->activation_type;
}
static void
_set_activation_type (NMActiveConnection *self,
NMActivationType activation_type)
{
NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
g_return_if_fail (priv->assumed == FALSE);
priv->assumed = assumed;
if (priv->activation_type == activation_type)
return;
if (priv->pending_activation_id) {
nm_device_remove_pending_action (priv->device, priv->pending_activation_id, TRUE);
g_clear_pointer (&priv->pending_activation_id, g_free);
}
_LOGD ("update activation type from %s to %s",
nm_activation_type_to_string (priv->activation_type),
nm_activation_type_to_string (activation_type));
priv->activation_type = activation_type;
if ( priv->activation_type == NM_ACTIVATION_TYPE_MANAGED
&& priv->device
&& self == NM_ACTIVE_CONNECTION (nm_device_get_act_request (priv->device))
&& NM_IN_SET (nm_device_sys_iface_state_get (priv->device),
NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
NM_DEVICE_SYS_IFACE_STATE_ASSUME))
nm_device_sys_iface_state_set (priv->device, NM_DEVICE_SYS_IFACE_STATE_MANAGED);
}
gboolean
nm_active_connection_get_assumed (NMActiveConnection *self)
/*****************************************************************************/
static void
_settings_connection_notify_flags (NMSettingsConnection *settings_connection,
GParamSpec *param,
NMActiveConnection *self)
{
return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->assumed;
nm_assert (NM_IS_ACTIVE_CONNECTION (self));
nm_assert (NM_IS_SETTINGS_CONNECTION (settings_connection));
nm_assert (nm_active_connection_get_activation_type (self) == NM_ACTIVATION_TYPE_EXTERNAL);
nm_assert (NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->settings_connection == settings_connection);
if (nm_settings_connection_get_nm_generated (settings_connection))
return;
g_signal_handlers_disconnect_by_func (settings_connection, _settings_connection_notify_flags, self);
_set_activation_type (self, NM_ACTIVATION_TYPE_MANAGED);
nm_device_reapply_settings_immediately (nm_active_connection_get_device (self));
}
/*****************************************************************************/
@@ -1058,6 +1108,7 @@ set_property (GObject *object, guint prop_id,
const char *tmp;
NMSettingsConnection *con;
NMConnection *acon;
int i;
switch (prop_id) {
case PROP_INT_SETTINGS_CONNECTION:
@@ -1082,6 +1133,15 @@ set_property (GObject *object, guint prop_id,
case PROP_INT_MASTER:
nm_active_connection_set_master (self, g_value_get_object (value));
break;
case PROP_INT_ACTIVATION_TYPE:
/* construct-only */
i = g_value_get_int (value);
if (!NM_IN_SET (i, NM_ACTIVATION_TYPE_MANAGED,
NM_ACTIVATION_TYPE_ASSUME,
NM_ACTIVATION_TYPE_EXTERNAL))
g_return_if_reached ();
priv->activation_type = (NMActivationType) i;
break;
case PROP_SPECIFIC_OBJECT:
tmp = g_value_get_string (value);
/* NM uses "/" to mean NULL */
@@ -1117,6 +1177,7 @@ nm_active_connection_init (NMActiveConnection *self)
_LOGT ("creating");
priv->activation_type = NM_ACTIVATION_TYPE_MANAGED;
priv->version_id = _version_id_new ();
}
@@ -1128,15 +1189,16 @@ constructed (GObject *object)
G_OBJECT_CLASS (nm_active_connection_parent_class)->constructed (object);
if (!priv->applied_connection && priv->settings_connection) {
priv->applied_connection =
nm_simple_connection_new_clone ((NMConnection *) priv->settings_connection);
}
if (!priv->applied_connection && priv->settings_connection)
priv->applied_connection = nm_simple_connection_new_clone (NM_CONNECTION (priv->settings_connection));
if (priv->applied_connection)
nm_connection_clear_secrets (priv->applied_connection);
_LOGD ("constructed (%s, version-id %llu)", G_OBJECT_TYPE_NAME (self), (unsigned long long) priv->version_id);
_LOGD ("constructed (%s, version-id %llu, type %s)",
G_OBJECT_TYPE_NAME (self),
(unsigned long long) priv->version_id,
nm_activation_type_to_string (priv->activation_type));
g_return_if_fail (priv->subject);
}
@@ -1321,6 +1383,15 @@ nm_active_connection_class_init (NMActiveConnectionClass *ac_class)
FALSE, G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
obj_properties[PROP_INT_ACTIVATION_TYPE] =
g_param_spec_int (NM_ACTIVE_CONNECTION_INT_ACTIVATION_TYPE, "", "",
NM_ACTIVATION_TYPE_MANAGED,
NM_ACTIVATION_TYPE_EXTERNAL,
NM_ACTIVATION_TYPE_MANAGED,
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
signals[DEVICE_CHANGED] =

View File

@@ -55,6 +55,7 @@
#define NM_ACTIVE_CONNECTION_INT_SUBJECT "int-subject"
#define NM_ACTIVE_CONNECTION_INT_MASTER "int-master"
#define NM_ACTIVE_CONNECTION_INT_MASTER_READY "int-master-ready"
#define NM_ACTIVE_CONNECTION_INT_ACTIVATION_TYPE "int-activation-type"
/* Internal signals*/
#define NM_ACTIVE_CONNECTION_DEVICE_CHANGED "device-changed"
@@ -158,10 +159,7 @@ void nm_active_connection_set_master (NMActiveConnection *self,
void nm_active_connection_set_parent (NMActiveConnection *self,
NMActiveConnection *parent);
void nm_active_connection_set_assumed (NMActiveConnection *self,
gboolean assumed);
gboolean nm_active_connection_get_assumed (NMActiveConnection *self);
NMActivationType nm_active_connection_get_activation_type (NMActiveConnection *self);
void nm_active_connection_clear_secrets (NMActiveConnection *self);

View File

@@ -281,6 +281,7 @@ activate:
NULL,
device,
subject,
NM_ACTIVATION_TYPE_MANAGED,
&local_error)) {
_LOGW ("rollback: reactivation of connection %s/%s failed: %s",
nm_connection_get_id ((NMConnection *) connection),

View File

@@ -105,8 +105,7 @@ update_state (NMConnectivity *self, NMConnectivityState state)
priv->state = state;
_notify (self, PROP_STATE);
/* Notify dispatcher scripts of a connectivity state change */
nm_dispatcher_call_connectivity (DISPATCHER_ACTION_CONNECTIVITY_CHANGE, state);
nm_dispatcher_call_connectivity (state, NULL, NULL, NULL);
}
}

View File

@@ -4339,3 +4339,12 @@ nm_utils_format_con_diff_for_audit (GHashTable *diff)
return g_string_free (str, FALSE);
}
/*****************************************************************************/
NM_UTILS_LOOKUP_STR_DEFINE (nm_activation_type_to_string, NMActivationType,
NM_UTILS_LOOKUP_DEFAULT_WARN ("(unknown)"),
NM_UTILS_LOOKUP_STR_ITEM (NM_ACTIVATION_TYPE_MANAGED, "managed"),
NM_UTILS_LOOKUP_STR_ITEM (NM_ACTIVATION_TYPE_ASSUME, "assume"),
NM_UTILS_LOOKUP_STR_ITEM (NM_ACTIVATION_TYPE_EXTERNAL, "external"),
)

View File

@@ -472,4 +472,10 @@ char **nm_utils_read_plugin_paths (const char *dirname, const char *prefix);
char *nm_utils_format_con_diff_for_audit (GHashTable *diff);
/*****************************************************************************/
const char *nm_activation_type_to_string (NMActivationType activation_type);
/*****************************************************************************/
#endif /* __NM_CORE_UTILS_H__ */

View File

@@ -21,14 +21,16 @@
#include "nm-default.h"
#include "nm-dispatcher.h"
#include <string.h>
#include <errno.h>
#include "nm-dispatcher.h"
#include "nm-dispatcher-api.h"
#include "NetworkManagerUtils.h"
#include "nm-utils.h"
#include "nm-connectivity.h"
#include "nm-act-request.h"
#include "devices/nm-device.h"
#include "nm-dhcp4-config.h"
#include "nm-dhcp6-config.h"
@@ -70,14 +72,14 @@ static Monitor monitors[3] = {
};
static const Monitor*
_get_monitor_by_action (DispatcherAction action)
_get_monitor_by_action (NMDispatcherAction action)
{
switch (action) {
case DISPATCHER_ACTION_PRE_UP:
case DISPATCHER_ACTION_VPN_PRE_UP:
case NM_DISPATCHER_ACTION_PRE_UP:
case NM_DISPATCHER_ACTION_VPN_PRE_UP:
return &monitors[MONITOR_INDEX_PRE_UP];
case DISPATCHER_ACTION_PRE_DOWN:
case DISPATCHER_ACTION_VPN_PRE_DOWN:
case NM_DISPATCHER_ACTION_PRE_DOWN:
case NM_DISPATCHER_ACTION_VPN_PRE_DOWN:
return &monitors[MONITOR_INDEX_PRE_DOWN];
default:
return &monitors[MONITOR_INDEX_DEFAULT];
@@ -311,9 +313,9 @@ fill_vpn_props (NMProxyConfig *proxy_config,
}
typedef struct {
DispatcherAction action;
NMDispatcherAction action;
guint request_id;
DispatcherFunc callback;
NMDispatcherFunc callback;
gpointer user_data;
guint idle_id;
} DispatchInfo;
@@ -362,7 +364,7 @@ dispatch_result_to_string (DispatchResult result)
}
static void
dispatcher_results_process (guint request_id, DispatcherAction action, GVariantIter *results)
dispatcher_results_process (guint request_id, NMDispatcherAction action, GVariantIter *results)
{
const char *script, *err;
guint32 result;
@@ -440,22 +442,22 @@ dispatcher_done_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
}
static const char *action_table[] = {
[DISPATCHER_ACTION_HOSTNAME] = NMD_ACTION_HOSTNAME,
[DISPATCHER_ACTION_PRE_UP] = NMD_ACTION_PRE_UP,
[DISPATCHER_ACTION_UP] = NMD_ACTION_UP,
[DISPATCHER_ACTION_PRE_DOWN] = NMD_ACTION_PRE_DOWN,
[DISPATCHER_ACTION_DOWN] = NMD_ACTION_DOWN,
[DISPATCHER_ACTION_VPN_PRE_UP] = NMD_ACTION_VPN_PRE_UP,
[DISPATCHER_ACTION_VPN_UP] = NMD_ACTION_VPN_UP,
[DISPATCHER_ACTION_VPN_PRE_DOWN] = NMD_ACTION_VPN_PRE_DOWN,
[DISPATCHER_ACTION_VPN_DOWN] = NMD_ACTION_VPN_DOWN,
[DISPATCHER_ACTION_DHCP4_CHANGE] = NMD_ACTION_DHCP4_CHANGE,
[DISPATCHER_ACTION_DHCP6_CHANGE] = NMD_ACTION_DHCP6_CHANGE,
[DISPATCHER_ACTION_CONNECTIVITY_CHANGE] = NMD_ACTION_CONNECTIVITY_CHANGE
[NM_DISPATCHER_ACTION_HOSTNAME] = NMD_ACTION_HOSTNAME,
[NM_DISPATCHER_ACTION_PRE_UP] = NMD_ACTION_PRE_UP,
[NM_DISPATCHER_ACTION_UP] = NMD_ACTION_UP,
[NM_DISPATCHER_ACTION_PRE_DOWN] = NMD_ACTION_PRE_DOWN,
[NM_DISPATCHER_ACTION_DOWN] = NMD_ACTION_DOWN,
[NM_DISPATCHER_ACTION_VPN_PRE_UP] = NMD_ACTION_VPN_PRE_UP,
[NM_DISPATCHER_ACTION_VPN_UP] = NMD_ACTION_VPN_UP,
[NM_DISPATCHER_ACTION_VPN_PRE_DOWN] = NMD_ACTION_VPN_PRE_DOWN,
[NM_DISPATCHER_ACTION_VPN_DOWN] = NMD_ACTION_VPN_DOWN,
[NM_DISPATCHER_ACTION_DHCP4_CHANGE] = NMD_ACTION_DHCP4_CHANGE,
[NM_DISPATCHER_ACTION_DHCP6_CHANGE] = NMD_ACTION_DHCP6_CHANGE,
[NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE] = NMD_ACTION_CONNECTIVITY_CHANGE
};
static const char *
action_to_string (DispatcherAction action)
action_to_string (NMDispatcherAction action)
{
g_assert ((gsize) action < G_N_ELEMENTS (action_table));
return action_table[action];
@@ -474,17 +476,18 @@ dispatcher_idle_cb (gpointer user_data)
}
static gboolean
_dispatcher_call (DispatcherAction action,
_dispatcher_call (NMDispatcherAction action,
gboolean blocking,
NMDevice *device,
NMSettingsConnection *settings_connection,
NMConnection *applied_connection,
NMDevice *device,
gboolean activation_type_external,
NMConnectivityState connectivity_state,
const char *vpn_iface,
NMProxyConfig *vpn_proxy_config,
NMIP4Config *vpn_ip4_config,
NMIP6Config *vpn_ip6_config,
DispatcherFunc callback,
NMDispatcherFunc callback,
gpointer user_data,
guint *out_call_id)
{
@@ -517,8 +520,8 @@ _dispatcher_call (DispatcherAction action,
_ensure_requests ();
/* All actions except 'hostname' and 'connectivity-change' require a device */
if ( action == DISPATCHER_ACTION_HOSTNAME
|| action == DISPATCHER_ACTION_CONNECTIVITY_CHANGE) {
if ( action == NM_DISPATCHER_ACTION_HOSTNAME
|| action == NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE) {
_LOGD ("(%u) dispatching action '%s'%s",
reqid, action_to_string (action),
blocking
@@ -573,7 +576,7 @@ _dispatcher_call (DispatcherAction action,
NMD_CONNECTION_PROPS_FILENAME,
g_variant_new_string (filename));
}
if (nm_settings_connection_get_nm_generated_assumed (settings_connection)) {
if (activation_type_external) {
g_variant_builder_add (&connection_props, "{sv}",
NMD_CONNECTION_PROPS_EXTERNAL,
g_variant_new_boolean (TRUE));
@@ -589,8 +592,8 @@ _dispatcher_call (DispatcherAction action,
g_variant_builder_init (&vpn_ip6_props, G_VARIANT_TYPE_VARDICT);
/* hostname and connectivity-change actions don't send device data */
if ( action != DISPATCHER_ACTION_HOSTNAME
&& action != DISPATCHER_ACTION_CONNECTIVITY_CHANGE) {
if ( action != NM_DISPATCHER_ACTION_HOSTNAME
&& action != NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE) {
fill_device_props (device,
&device_props,
&device_proxy_props,
@@ -694,41 +697,75 @@ done:
}
/**
* nm_dispatcher_call:
* @action: the %DispatcherAction
* @settings_connection: the #NMSettingsConnection the action applies to
* @applied_connection: the currently applied connection
* @device: the #NMDevice the action applies to
* nm_dispatcher_call_hostname:
* @callback: a caller-supplied callback to execute when done
* @user_data: caller-supplied pointer passed to @callback
* @out_call_id: on success, a call identifier which can be passed to
* nm_dispatcher_call_cancel()
*
* This method always invokes the dispatcher action asynchronously. To ignore
* This method always invokes the dispatcher action asynchronously.
*
* Returns: %TRUE if the action was dispatched, %FALSE on failure
*/
gboolean
nm_dispatcher_call_hostname (NMDispatcherFunc callback,
gpointer user_data,
guint *out_call_id)
{
return _dispatcher_call (NM_DISPATCHER_ACTION_HOSTNAME, FALSE,
NULL, NULL, NULL, FALSE,
NM_CONNECTIVITY_UNKNOWN,
NULL, NULL, NULL, NULL,
callback, user_data, out_call_id);
}
/**
* nm_dispatcher_call_device:
* @action: the %NMDispatcherAction
* @device: the #NMDevice the action applies to
* @act_request: the #NMActRequest for the action. If %NULL, use the
* current request of the device.
* @callback: a caller-supplied callback to execute when done
* @user_data: caller-supplied pointer passed to @callback
* @out_call_id: on success, a call identifier which can be passed to
* nm_dispatcher_call_cancel()
*
* This method always invokes the device dispatcher action asynchronously. To ignore
* the result, pass %NULL to @callback.
*
* Returns: %TRUE if the action was dispatched, %FALSE on failure
*/
gboolean
nm_dispatcher_call (DispatcherAction action,
NMSettingsConnection *settings_connection,
NMConnection *applied_connection,
NMDevice *device,
DispatcherFunc callback,
gpointer user_data,
guint *out_call_id)
nm_dispatcher_call_device (NMDispatcherAction action,
NMDevice *device,
NMActRequest *act_request,
NMDispatcherFunc callback,
gpointer user_data,
guint *out_call_id)
{
return _dispatcher_call (action, FALSE, settings_connection, applied_connection, device,
NM_CONNECTIVITY_UNKNOWN, NULL, NULL, NULL, NULL,
nm_assert (NM_IS_DEVICE (device));
if (!act_request) {
act_request = nm_device_get_act_request (device);
if (!act_request)
return FALSE;
}
nm_assert (NM_IN_SET (nm_active_connection_get_device (NM_ACTIVE_CONNECTION (act_request)), NULL, device));
return _dispatcher_call (action, FALSE,
device,
nm_act_request_get_settings_connection (act_request),
nm_act_request_get_applied_connection (act_request),
nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (act_request)) == NM_ACTIVATION_TYPE_EXTERNAL,
NM_CONNECTIVITY_UNKNOWN,
NULL, NULL, NULL, NULL,
callback, user_data, out_call_id);
}
/**
* nm_dispatcher_call_sync():
* @action: the %DispatcherAction
* @settings_connection: the #NMSettingsConnection the action applies to
* @applied_connection: the currently applied connection
* nm_dispatcher_call_device_sync():
* @action: the %NMDispatcherAction
* @device: the #NMDevice the action applies to
* @act_request: the #NMActRequest for the action. If %NULL, use the
* current request of the device.
*
* This method always invokes the dispatcher action synchronously and it may
* take a long time to return.
@@ -736,18 +773,30 @@ nm_dispatcher_call (DispatcherAction action,
* Returns: %TRUE if the action was dispatched, %FALSE on failure
*/
gboolean
nm_dispatcher_call_sync (DispatcherAction action,
NMSettingsConnection *settings_connection,
NMConnection *applied_connection,
NMDevice *device)
nm_dispatcher_call_device_sync (NMDispatcherAction action,
NMDevice *device,
NMActRequest *act_request)
{
return _dispatcher_call (action, TRUE, settings_connection, applied_connection, device,
NM_CONNECTIVITY_UNKNOWN, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
nm_assert (NM_IS_DEVICE (device));
if (!act_request) {
act_request = nm_device_get_act_request (device);
if (!act_request)
return FALSE;
}
nm_assert (NM_IN_SET (nm_active_connection_get_device (NM_ACTIVE_CONNECTION (act_request)), NULL, device));
return _dispatcher_call (action, TRUE,
device,
nm_act_request_get_settings_connection (act_request),
nm_act_request_get_applied_connection (act_request),
nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (act_request)) == NM_ACTIVATION_TYPE_EXTERNAL,
NM_CONNECTIVITY_UNKNOWN,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL);
}
/**
* nm_dispatcher_call_vpn():
* @action: the %DispatcherAction
* @action: the %NMDispatcherAction
* @settings_connection: the #NMSettingsConnection the action applies to
* @applied_connection: the currently applied connection
* @parent_device: the parent #NMDevice of the VPN connection
@@ -766,7 +815,7 @@ nm_dispatcher_call_sync (DispatcherAction action,
* Returns: %TRUE if the action was dispatched, %FALSE on failure
*/
gboolean
nm_dispatcher_call_vpn (DispatcherAction action,
nm_dispatcher_call_vpn (NMDispatcherAction action,
NMSettingsConnection *settings_connection,
NMConnection *applied_connection,
NMDevice *parent_device,
@@ -774,18 +823,23 @@ nm_dispatcher_call_vpn (DispatcherAction action,
NMProxyConfig *vpn_proxy_config,
NMIP4Config *vpn_ip4_config,
NMIP6Config *vpn_ip6_config,
DispatcherFunc callback,
NMDispatcherFunc callback,
gpointer user_data,
guint *out_call_id)
{
return _dispatcher_call (action, FALSE, settings_connection, applied_connection,
parent_device, NM_CONNECTIVITY_UNKNOWN, vpn_iface, vpn_proxy_config,
vpn_ip4_config, vpn_ip6_config, callback, user_data, out_call_id);
return _dispatcher_call (action, FALSE,
parent_device,
settings_connection,
applied_connection,
FALSE,
NM_CONNECTIVITY_UNKNOWN,
vpn_iface, vpn_proxy_config, vpn_ip4_config, vpn_ip6_config,
callback, user_data, out_call_id);
}
/**
* nm_dispatcher_call_vpn_sync():
* @action: the %DispatcherAction
* @action: the %NMDispatcherAction
* @settings_connection: the #NMSettingsConnection the action applies to
* @applied_connection: the currently applied connection
* @parent_device: the parent #NMDevice of the VPN connection
@@ -800,7 +854,7 @@ nm_dispatcher_call_vpn (DispatcherAction action,
* Returns: %TRUE if the action was dispatched, %FALSE on failure
*/
gboolean
nm_dispatcher_call_vpn_sync (DispatcherAction action,
nm_dispatcher_call_vpn_sync (NMDispatcherAction action,
NMSettingsConnection *settings_connection,
NMConnection *applied_connection,
NMDevice *parent_device,
@@ -809,26 +863,39 @@ nm_dispatcher_call_vpn_sync (DispatcherAction action,
NMIP4Config *vpn_ip4_config,
NMIP6Config *vpn_ip6_config)
{
return _dispatcher_call (action, TRUE, settings_connection, applied_connection,
parent_device, NM_CONNECTIVITY_UNKNOWN, vpn_iface, vpn_proxy_config,
vpn_ip4_config, vpn_ip6_config, NULL, NULL, NULL);
return _dispatcher_call (action, TRUE,
parent_device,
settings_connection,
applied_connection,
FALSE,
NM_CONNECTIVITY_UNKNOWN,
vpn_iface, vpn_proxy_config, vpn_ip4_config, vpn_ip6_config,
NULL, NULL, NULL);
}
/**
* nm_dispatcher_call_connectivity():
* @action: the %DispatcherAction
* @connectivity_state: the #NMConnectivityState value
* @callback: a caller-supplied callback to execute when done
* @user_data: caller-supplied pointer passed to @callback
* @out_call_id: on success, a call identifier which can be passed to
* nm_dispatcher_call_cancel()
*
* This method does not block the caller.
*
* Returns: %TRUE if the action was dispatched, %FALSE on failure
*/
gboolean
nm_dispatcher_call_connectivity (DispatcherAction action,
NMConnectivityState connectivity_state)
nm_dispatcher_call_connectivity (NMConnectivityState connectivity_state,
NMDispatcherFunc callback,
gpointer user_data,
guint *out_call_id)
{
return _dispatcher_call (action, FALSE, NULL, NULL, NULL, connectivity_state,
NULL, NULL, NULL, NULL, NULL, NULL, NULL);
return _dispatcher_call (NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE, FALSE,
NULL, NULL, NULL, FALSE,
connectivity_state,
NULL, NULL, NULL, NULL,
callback, user_data, out_call_id);
}
void

View File

@@ -19,44 +19,44 @@
* Copyright (C) 2005 - 2008 Novell, Inc.
*/
#ifndef __NETWORKMANAGER_DISPATCHER_H__
#define __NETWORKMANAGER_DISPATCHER_H__
#include <stdio.h>
#ifndef __NM_DISPATCHER_H__
#define __NM_DISPATCHER_H__
#include "nm-connection.h"
typedef enum {
DISPATCHER_ACTION_HOSTNAME,
DISPATCHER_ACTION_PRE_UP,
DISPATCHER_ACTION_UP,
DISPATCHER_ACTION_PRE_DOWN,
DISPATCHER_ACTION_DOWN,
DISPATCHER_ACTION_VPN_PRE_UP,
DISPATCHER_ACTION_VPN_UP,
DISPATCHER_ACTION_VPN_PRE_DOWN,
DISPATCHER_ACTION_VPN_DOWN,
DISPATCHER_ACTION_DHCP4_CHANGE,
DISPATCHER_ACTION_DHCP6_CHANGE,
DISPATCHER_ACTION_CONNECTIVITY_CHANGE
} DispatcherAction;
NM_DISPATCHER_ACTION_HOSTNAME,
NM_DISPATCHER_ACTION_PRE_UP,
NM_DISPATCHER_ACTION_UP,
NM_DISPATCHER_ACTION_PRE_DOWN,
NM_DISPATCHER_ACTION_DOWN,
NM_DISPATCHER_ACTION_VPN_PRE_UP,
NM_DISPATCHER_ACTION_VPN_UP,
NM_DISPATCHER_ACTION_VPN_PRE_DOWN,
NM_DISPATCHER_ACTION_VPN_DOWN,
NM_DISPATCHER_ACTION_DHCP4_CHANGE,
NM_DISPATCHER_ACTION_DHCP6_CHANGE,
NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE
} NMDispatcherAction;
typedef void (*DispatcherFunc) (guint call_id, gpointer user_data);
typedef void (*NMDispatcherFunc) (guint call_id, gpointer user_data);
gboolean nm_dispatcher_call (DispatcherAction action,
NMSettingsConnection *settings_connection,
NMConnection *applied_connection,
NMDevice *device,
DispatcherFunc callback,
gpointer user_data,
guint *out_call_id);
gboolean nm_dispatcher_call_hostname (NMDispatcherFunc callback,
gpointer user_data,
guint *out_call_id);
gboolean nm_dispatcher_call_sync (DispatcherAction action,
NMSettingsConnection *settings_connection,
NMConnection *applied_connection,
NMDevice *device);
gboolean nm_dispatcher_call_device (NMDispatcherAction action,
NMDevice *device,
NMActRequest *act_request,
NMDispatcherFunc callback,
gpointer user_data,
guint *out_call_id);
gboolean nm_dispatcher_call_vpn (DispatcherAction action,
gboolean nm_dispatcher_call_device_sync (NMDispatcherAction action,
NMDevice *device,
NMActRequest *act_request);
gboolean nm_dispatcher_call_vpn (NMDispatcherAction action,
NMSettingsConnection *settings_connection,
NMConnection *applied_connection,
NMDevice *parent_device,
@@ -64,11 +64,11 @@ gboolean nm_dispatcher_call_vpn (DispatcherAction action,
NMProxyConfig *vpn_proxy_config,
NMIP4Config *vpn_ip4_config,
NMIP6Config *vpn_ip6_config,
DispatcherFunc callback,
NMDispatcherFunc callback,
gpointer user_data,
guint *out_call_id);
gboolean nm_dispatcher_call_vpn_sync (DispatcherAction action,
gboolean nm_dispatcher_call_vpn_sync (NMDispatcherAction action,
NMSettingsConnection *settings_connection,
NMConnection *applied_connection,
NMDevice *parent_device,
@@ -77,11 +77,14 @@ gboolean nm_dispatcher_call_vpn_sync (DispatcherAction action,
NMIP4Config *vpn_ip4_config,
NMIP6Config *vpn_ip6_config);
gboolean nm_dispatcher_call_connectivity (DispatcherAction action,
NMConnectivityState state);
gboolean nm_dispatcher_call_connectivity (NMConnectivityState state,
NMDispatcherFunc callback,
gpointer user_data,
guint *out_call_id);
void nm_dispatcher_call_cancel (guint call_id);
void nm_dispatcher_init (void);
#endif /* __NETWORKMANAGER_DISPATCHER_H__ */
#endif /* __NM_DISPATCHER_H__ */

View File

@@ -67,6 +67,7 @@ static NMActiveConnection *_new_active_connection (NMManager *self,
const char *specific_object,
NMDevice *device,
NMAuthSubject *subject,
NMActivationType activation_type,
GError **error);
static void policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data);
@@ -270,20 +271,20 @@ active_connection_remove (NMManager *self, NMActiveConnection *active)
g_signal_handlers_disconnect_by_func (active, active_connection_default_changed, self);
g_signal_handlers_disconnect_by_func (active, active_connection_parent_active, self);
if ( nm_active_connection_get_assumed (active)
&& (connection = nm_active_connection_get_settings_connection (active))
&& nm_settings_connection_get_nm_generated_assumed (connection))
if ( (connection = nm_active_connection_get_settings_connection (active))
&& nm_settings_connection_get_volatile (connection))
g_object_ref (connection);
else
connection = NULL;
nm_exported_object_clear_and_unexport (&active);
if ( connection
&& nm_settings_has_connection (priv->settings, connection)) {
_LOGD (LOGD_DEVICE, "assumed connection disconnected. Deleting generated connection '%s' (%s)",
nm_settings_connection_get_id (connection), nm_settings_connection_get_uuid (connection));
nm_settings_connection_delete (NM_SETTINGS_CONNECTION (connection), NULL, NULL);
if (connection) {
if (nm_settings_has_connection (priv->settings, connection)) {
_LOGD (LOGD_DEVICE, "assumed connection disconnected. Deleting generated connection '%s' (%s)",
nm_settings_connection_get_id (connection), nm_settings_connection_get_uuid (connection));
nm_settings_connection_delete (connection, NULL, NULL);
}
g_object_unref (connection);
}
}
@@ -395,46 +396,60 @@ nm_manager_get_active_connections (NMManager *manager)
}
static NMActiveConnection *
find_ac_for_connection (NMManager *manager, NMConnection *connection)
active_connection_find_first (NMManager *self,
NMSettingsConnection *settings_connection,
const char *uuid,
NMActiveConnectionState max_state)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
NMManagerPrivate *priv;
GSList *iter;
const char *uuid = NULL;
gboolean is_settings_connection;
is_settings_connection = NM_IS_SETTINGS_CONNECTION (connection);
g_return_val_if_fail (NM_IS_MANAGER (self), NULL);
g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL);
if (!is_settings_connection)
uuid = nm_connection_get_uuid (connection);
priv = NM_MANAGER_GET_PRIVATE (self);
for (iter = priv->active_connections; iter; iter = iter->next) {
NMActiveConnection *ac = iter->data;
NMSettingsConnection *con;
con = nm_active_connection_get_settings_connection (ac);
/* depending on whether we have a NMSettingsConnection or a NMConnection,
* we lookup by UUID or by reference. */
if (is_settings_connection) {
if (con != (NMSettingsConnection *) connection)
continue;
} else {
if (strcmp (uuid, nm_connection_get_uuid (NM_CONNECTION (con))) != 0)
continue;
}
if (nm_active_connection_get_state (ac) < NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)
return ac;
if (settings_connection && con != settings_connection)
continue;
if (uuid && !nm_streq0 (uuid, nm_connection_get_uuid (NM_CONNECTION (con))))
continue;
if (nm_active_connection_get_state (ac) > max_state)
continue;
return ac;
}
return NULL;
}
static NMActiveConnection *
active_connection_find_first_by_connection (NMManager *self,
NMConnection *connection)
{
gboolean is_settings_connection;
nm_assert (NM_IS_MANAGER (self));
nm_assert (NM_IS_CONNECTION (connection));
is_settings_connection = NM_IS_SETTINGS_CONNECTION (connection);
/* Depending on whether connection is a settings connection,
* either lookup by object-identity of @connection, or compare the UUID */
return active_connection_find_first (self,
is_settings_connection ? NM_SETTINGS_CONNECTION (connection) : NULL,
is_settings_connection ? NULL : nm_connection_get_uuid (connection),
NM_ACTIVE_CONNECTION_STATE_DEACTIVATING);
}
static gboolean
_get_activatable_connections_filter (NMSettings *settings,
NMSettingsConnection *connection,
gpointer user_data)
{
return !find_ac_for_connection (user_data, NM_CONNECTION (connection));
return !active_connection_find_first (user_data, connection, NULL, NM_ACTIVE_CONNECTION_STATE_DEACTIVATING);
}
/* Filter out connections that are already active.
@@ -800,13 +815,17 @@ find_best_device_state (NMManager *manager, gboolean *force_connectivity_check)
}
break;
case NM_ACTIVE_CONNECTION_STATE_ACTIVATING:
if (!nm_active_connection_get_assumed (ac)) {
if (!NM_IN_SET (nm_active_connection_get_activation_type (ac),
NM_ACTIVATION_TYPE_EXTERNAL,
NM_ACTIVATION_TYPE_ASSUME)) {
if (best_state != NM_STATE_CONNECTED_GLOBAL)
best_state = NM_STATE_CONNECTING;
}
break;
case NM_ACTIVE_CONNECTION_STATE_DEACTIVATING:
if (!nm_active_connection_get_assumed (ac)) {
if (!NM_IN_SET (nm_active_connection_get_activation_type (ac),
NM_ACTIVATION_TYPE_EXTERNAL,
NM_ACTIVATION_TYPE_ASSUME)) {
if (best_state < NM_STATE_DISCONNECTING)
best_state = NM_STATE_DISCONNECTING;
}
@@ -1019,8 +1038,10 @@ remove_device (NMManager *self,
if (unmanage) {
if (quitting)
nm_device_set_unmanaged_by_quitting (device);
else
else {
nm_device_sys_iface_state_set (device, NM_DEVICE_SYS_IFACE_STATE_REMOVED);
nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_PLATFORM_INIT, TRUE, NM_DEVICE_STATE_REASON_REMOVED);
}
} else if (quitting && nm_config_get_configure_and_quit (priv->config)) {
nm_device_spawn_iface_helper (device);
}
@@ -1696,9 +1717,6 @@ done:
static gboolean
match_connection_filter (NMConnection *connection, gpointer user_data)
{
if (nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection)))
return FALSE;
return nm_device_check_connection_compatible (NM_DEVICE (user_data), connection);
}
@@ -1706,22 +1724,27 @@ match_connection_filter (NMConnection *connection, gpointer user_data)
* get_existing_connection:
* @manager: #NMManager instance
* @device: #NMDevice instance
* @assume_connection_uuid: if present, try to assume a connection with this
* UUID. If no uuid is given or no matching connection is found, we
* only do external activation.
* @out_generated: (allow-none): return TRUE, if the connection was generated.
*
* Returns: a #NMSettingsConnection to be assumed by the device, or %NULL if
* the device does not support assuming existing connections.
*/
static NMSettingsConnection *
get_existing_connection (NMManager *self, NMDevice *device, gboolean *out_generated)
get_existing_connection (NMManager *self,
NMDevice *device,
const char *assume_connection_uuid,
gboolean *out_generated)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
gs_free_slist GSList *connections = NULL;
NMConnection *connection = NULL;
NMSettingsConnection *matched;
NMSettingsConnection *added = NULL;
GError *error = NULL;
NMDevice *master = NULL;
int ifindex = nm_device_get_ifindex (device);
NMSettingsConnection *matched;
if (out_generated)
*out_generated = FALSE;
@@ -1765,30 +1788,29 @@ get_existing_connection (NMManager *self, NMDevice *device, gboolean *out_genera
* When no configured connection matches the generated connection, we keep
* the generated connection instead.
*/
{
gs_free NMSettingsConnection **cons = NULL;
guint i, len;
if ( assume_connection_uuid
&& (matched = nm_settings_get_connection_by_uuid (priv->settings, assume_connection_uuid))
&& !active_connection_find_first (self, matched, NULL,
NM_ACTIVE_CONNECTION_STATE_DEACTIVATING)) {
NMConnection *const connections[] = {
NM_CONNECTION (matched),
NULL,
};
/* XXX: this code will go away soon. Copy the array over to a GSList
* and don't bother for now. */
cons = nm_manager_get_activatable_connections (self, &len, FALSE);
for (i = len; i > 0; )
connections = g_slist_prepend (connections, cons[--i]);
connections = g_slist_sort (connections, (GCompareFunc) nm_settings_connection_cmp_timestamp);
}
matched = NM_SETTINGS_CONNECTION (nm_utils_match_connection (connections,
connection,
nm_device_has_carrier (device),
nm_device_get_ip4_route_metric (device),
nm_device_get_ip6_route_metric (device),
match_connection_filter,
device));
if (matched) {
_LOGI (LOGD_DEVICE, "(%s): found matching connection '%s'",
nm_device_get_iface (device),
nm_settings_connection_get_id (matched));
g_object_unref (connection);
return matched;
matched = NM_SETTINGS_CONNECTION (nm_utils_match_connection (connections,
connection,
nm_device_has_carrier (device),
nm_device_get_ip4_route_metric (device),
nm_device_get_ip6_route_metric (device),
match_connection_filter,
device));
if (matched) {
_LOGI (LOGD_DEVICE, "(%s): found matching connection '%s'",
nm_device_get_iface (device),
nm_settings_connection_get_id (matched));
g_object_unref (connection);
return matched;
}
}
_LOGD (LOGD_DEVICE, "(%s): generated connection '%s'",
@@ -1799,7 +1821,7 @@ get_existing_connection (NMManager *self, NMDevice *device, gboolean *out_genera
if (added) {
nm_settings_connection_set_flags (NM_SETTINGS_CONNECTION (added),
NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED |
NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED,
NM_SETTINGS_CONNECTION_FLAGS_VOLATILE,
TRUE);
if (out_generated)
*out_generated = TRUE;
@@ -1816,54 +1838,13 @@ get_existing_connection (NMManager *self, NMDevice *device, gboolean *out_genera
}
static gboolean
assume_connection (NMManager *self, NMDevice *device, NMSettingsConnection *connection)
{
NMActiveConnection *active, *master_ac;
NMAuthSubject *subject;
GError *error = NULL;
_LOGD (LOGD_DEVICE, "(%s): will attempt to assume connection",
nm_device_get_iface (device));
/* Move device to DISCONNECTED to activate the connection */
if (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE) {
nm_device_state_changed (device,
NM_DEVICE_STATE_DISCONNECTED,
NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
}
g_return_val_if_fail (nm_device_get_state (device) >= NM_DEVICE_STATE_DISCONNECTED, FALSE);
subject = nm_auth_subject_new_internal ();
active = _new_active_connection (self, NM_CONNECTION (connection), NULL, NULL, device, subject, &error);
g_object_unref (subject);
if (!active) {
_LOGW (LOGD_DEVICE, "assumed connection %s failed to activate: %s",
nm_connection_get_path (NM_CONNECTION (connection)),
error->message);
g_error_free (error);
return FALSE;
}
/* If the device is a slave or VLAN, find the master ActiveConnection */
master_ac = NULL;
if (find_master (self, NM_CONNECTION (connection), device, NULL, NULL, &master_ac, NULL) && master_ac)
nm_active_connection_set_master (active, master_ac);
nm_active_connection_set_assumed (active, TRUE);
nm_exported_object_export (NM_EXPORTED_OBJECT (active));
active_connection_add (self, active);
nm_device_queue_activation (device, NM_ACT_REQUEST (active));
g_object_unref (active);
return TRUE;
}
static gboolean
recheck_assume_connection (NMManager *self, NMDevice *device)
recheck_assume_connection (NMManager *self,
NMDevice *device,
const char *assume_connection_uuid)
{
NMSettingsConnection *connection;
gboolean was_unmanaged = FALSE, success, generated = FALSE;
gboolean was_unmanaged = FALSE;
gboolean generated = FALSE;
NMDeviceState state;
g_return_val_if_fail (NM_IS_MANAGER (self), FALSE);
@@ -1879,43 +1860,90 @@ recheck_assume_connection (NMManager *self, NMDevice *device)
if (state > NM_DEVICE_STATE_DISCONNECTED)
return FALSE;
connection = get_existing_connection (self, device, &generated);
if (nm_device_sys_iface_state_get (device) != NM_DEVICE_SYS_IFACE_STATE_EXTERNAL)
return FALSE;
connection = get_existing_connection (self, device, assume_connection_uuid, &generated);
if (!connection) {
_LOGD (LOGD_DEVICE, "(%s): can't assume; no connection",
nm_device_get_iface (device));
return FALSE;
}
_LOGD (LOGD_DEVICE, "(%s): will attempt to assume connection",
nm_device_get_iface (device));
if (!generated)
nm_device_sys_iface_state_set (device, NM_DEVICE_SYS_IFACE_STATE_ASSUME);
/* Move device to DISCONNECTED to activate the connection */
if (state == NM_DEVICE_STATE_UNMANAGED) {
was_unmanaged = TRUE;
nm_device_state_changed (device,
NM_DEVICE_STATE_UNAVAILABLE,
NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
}
success = assume_connection (self, device, connection);
if (!success) {
if (was_unmanaged) {
nm_device_state_changed (device,
NM_DEVICE_STATE_UNAVAILABLE,
NM_DEVICE_STATE_REASON_CONFIG_FAILED);
}
if (generated) {
_LOGD (LOGD_DEVICE, "(%s): connection assumption failed. Deleting generated connection",
nm_device_get_iface (device));
nm_settings_connection_delete (connection, NULL, NULL);
}
if (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE) {
nm_device_state_changed (device,
NM_DEVICE_STATE_DISCONNECTED,
NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
}
return success;
g_return_val_if_fail (nm_device_get_state (device) >= NM_DEVICE_STATE_DISCONNECTED, FALSE);
{
gs_unref_object NMActiveConnection *active = NULL;
gs_unref_object NMAuthSubject *subject = NULL;
NMActiveConnection *master_ac;
GError *error = NULL;
subject = nm_auth_subject_new_internal ();
active = _new_active_connection (self, NM_CONNECTION (connection), NULL, NULL,
device, subject,
generated ? NM_ACTIVATION_TYPE_EXTERNAL : NM_ACTIVATION_TYPE_ASSUME,
&error);
if (!active) {
_LOGW (LOGD_DEVICE, "assumed connection %s failed to activate: %s",
nm_connection_get_path (NM_CONNECTION (connection)),
error->message);
g_error_free (error);
if (was_unmanaged) {
nm_device_state_changed (device,
NM_DEVICE_STATE_UNAVAILABLE,
NM_DEVICE_STATE_REASON_CONFIG_FAILED);
}
if (generated) {
_LOGD (LOGD_DEVICE, "(%s): connection assumption failed. Deleting generated connection",
nm_device_get_iface (device));
nm_settings_connection_delete (connection, NULL, NULL);
} else {
if (nm_device_sys_iface_state_get (device) == NM_DEVICE_SYS_IFACE_STATE_ASSUME)
nm_device_sys_iface_state_set (device, NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
}
return FALSE;
}
/* If the device is a slave or VLAN, find the master ActiveConnection */
master_ac = NULL;
if (find_master (self, NM_CONNECTION (connection), device, NULL, NULL, &master_ac, NULL) && master_ac)
nm_active_connection_set_master (active, master_ac);
nm_exported_object_export (NM_EXPORTED_OBJECT (active));
active_connection_add (self, active);
nm_device_queue_activation (device, NM_ACT_REQUEST (active));
}
return TRUE;
}
static void
recheck_assume_connection_cb (NMDevice *device, gpointer user_data)
{
recheck_assume_connection (user_data, device);
recheck_assume_connection (user_data, device, NULL);
}
static void
@@ -1976,7 +2004,10 @@ device_realized (NMDevice *device,
}
static void
_device_realize_finish (NMManager *self, NMDevice *device, const NMPlatformLink *plink)
_device_realize_finish (NMManager *self,
NMDevice *device,
const NMPlatformLink *plink,
const char *connection_uuid_to_assume)
{
g_return_if_fail (NM_IS_MANAGER (self));
g_return_if_fail (NM_IS_DEVICE (device));
@@ -1986,7 +2017,7 @@ _device_realize_finish (NMManager *self, NMDevice *device, const NMPlatformLink
if (!nm_device_get_managed (device, FALSE))
return;
if (recheck_assume_connection (self, device))
if (recheck_assume_connection (self, device, connection_uuid_to_assume))
return;
/* if we failed to assume a connection for the managed device, but the device
@@ -2132,9 +2163,13 @@ factory_device_added_cb (NMDeviceFactory *factory,
g_return_if_fail (NM_IS_MANAGER (self));
if (nm_device_realize_start (device, NULL, NULL, &error)) {
if (nm_device_realize_start (device,
NULL,
NM_UNMAN_FLAG_OP_FORGET,
NULL,
&error)) {
add_device (self, device, NULL);
_device_realize_finish (self, device, NULL);
_device_realize_finish (self, device, NULL, NULL);
} else {
_LOGW (LOGD_DEVICE, "(%s): failed to realize device: %s",
nm_device_get_iface (device), error->message);
@@ -2205,9 +2240,13 @@ platform_link_added (NMManager *self,
* device with the link's name.
*/
return;
} else if (nm_device_realize_start (candidate, plink, &compatible, &error)) {
} else if (nm_device_realize_start (candidate,
plink,
NM_UNMAN_FLAG_OP_FORGET,
&compatible,
&error)) {
/* Success */
_device_realize_finish (self, candidate, plink);
_device_realize_finish (self, candidate, plink, NULL);
return;
}
@@ -2257,10 +2296,29 @@ platform_link_added (NMManager *self,
if (device) {
gs_free_error GError *error = NULL;
NMUnmanFlagOp unmanaged_user_explicit = NM_UNMAN_FLAG_OP_FORGET;
if (nm_device_realize_start (device, plink, NULL, &error)) {
if (dev_state) {
switch (dev_state->managed) {
case NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_MANAGED:
unmanaged_user_explicit = NM_UNMAN_FLAG_OP_SET_MANAGED;
break;
case NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_UNMANAGED:
unmanaged_user_explicit = NM_UNMAN_FLAG_OP_SET_UNMANAGED;
break;
case NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_UNKNOWN:
break;
}
}
if (nm_device_realize_start (device,
plink,
unmanaged_user_explicit,
NULL,
&error)) {
add_device (self, device, NULL);
_device_realize_finish (self, device, plink);
_device_realize_finish (self, device, plink,
dev_state ? dev_state->connection_uuid : NULL);
} else {
_LOGW (LOGD_DEVICE, "%s: failed to realize device: %s",
plink->name, error->message);
@@ -2407,28 +2465,22 @@ nm_manager_get_device_paths (NMManager *self)
return (const char **) g_ptr_array_free (paths, FALSE);
}
static NMDevice *
nm_manager_get_connection_device (NMManager *self,
NMConnection *connection)
{
NMActiveConnection *ac = find_ac_for_connection (self, connection);
if (ac == NULL)
return NULL;
return nm_active_connection_get_device (ac);
}
static NMDevice *
nm_manager_get_best_device_for_connection (NMManager *self,
NMConnection *connection,
gboolean for_user_request)
{
const GSList *devices, *iter;
NMDevice *act_device = nm_manager_get_connection_device (self, connection);
NMActiveConnection *ac;
NMDevice *act_device;
NMDeviceCheckConAvailableFlags flags;
if (act_device)
return act_device;
ac = active_connection_find_first_by_connection (self, connection);
if (ac) {
act_device = nm_active_connection_get_device (ac);
if (act_device)
return act_device;
}
flags = for_user_request ? NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST : NM_DEVICE_CHECK_CON_AVAILABLE_NONE;
@@ -2626,8 +2678,10 @@ find_master (NMManager *self,
*out_master_connection = master_connection;
if (out_master_device)
*out_master_device = master_device;
if (out_master_ac && master_connection)
*out_master_ac = find_ac_for_connection (self, NM_CONNECTION (master_connection));
if (out_master_ac && master_connection) {
*out_master_ac = active_connection_find_first (self, master_connection, NULL,
NM_ACTIVE_CONNECTION_STATE_DEACTIVATING);
}
if (master_device || master_connection)
return TRUE;
@@ -2735,6 +2789,7 @@ ensure_master_active_connection (NMManager *self,
NULL,
master_device,
subject,
NM_ACTIVATION_TYPE_MANAGED,
error);
return master_ac;
}
@@ -2780,6 +2835,7 @@ ensure_master_active_connection (NMManager *self,
NULL,
candidate,
subject,
NM_ACTIVATION_TYPE_MANAGED,
error);
return master_ac;
}
@@ -2926,6 +2982,7 @@ autoconnect_slaves (NMManager *self,
NULL,
nm_manager_get_best_device_for_connection (self, NM_CONNECTION (slave_connection), FALSE),
subject,
NM_ACTIVATION_TYPE_MANAGED,
&local_err);
if (local_err) {
_LOGW (LOGD_CORE, "Slave connection activation failed: %s", local_err->message);
@@ -3017,6 +3074,7 @@ static gboolean
_internal_activate_device (NMManager *self, NMActiveConnection *active, GError **error)
{
NMDevice *device, *existing, *master_device = NULL;
NMActiveConnection *existing_ac;
NMConnection *applied;
NMSettingsConnection *connection;
NMSettingsConnection *master_connection = NULL;
@@ -3083,7 +3141,8 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
return FALSE;
}
parent_ac = nm_manager_activate_connection (self, parent_con, NULL, NULL, parent, subject, error);
parent_ac = nm_manager_activate_connection (self, parent_con, NULL, NULL, parent,
subject, NM_ACTIVATION_TYPE_MANAGED, error);
if (!parent_ac) {
g_prefix_error (error, "%s failed to activate parent: ", nm_device_get_iface (device));
return FALSE;
@@ -3177,9 +3236,12 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
autoconnect_slaves (self, connection, device, nm_active_connection_get_subject (active));
/* Disconnect the connection if connected or queued on another device */
existing = nm_manager_get_connection_device (self, NM_CONNECTION (connection));
if (existing)
nm_device_steal_connection (existing, connection);
existing_ac = active_connection_find_first (self, connection, NULL, NM_ACTIVE_CONNECTION_STATE_DEACTIVATING);
if (existing_ac) {
existing = nm_active_connection_get_device (existing_ac);
if (existing)
nm_device_steal_connection (existing, connection);
}
/* If the device is there, we can ready it for the activation. */
if (nm_device_is_real (device))
@@ -3278,6 +3340,7 @@ _new_active_connection (NMManager *self,
const char *specific_object,
NMDevice *device,
NMAuthSubject *subject,
NMActivationType activation_type,
GError **error)
{
NMSettingsConnection *settings_connection = NULL;
@@ -3288,7 +3351,7 @@ _new_active_connection (NMManager *self,
g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL);
/* Can't create new AC for already-active connection */
existing_ac = find_ac_for_connection (self, connection);
existing_ac = active_connection_find_first_by_connection (self, connection);
if (NM_IS_VPN_CONNECTION (existing_ac)) {
g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE,
"Connection '%s' is already active",
@@ -3306,6 +3369,8 @@ _new_active_connection (NMManager *self,
settings_connection = (NMSettingsConnection *) connection;
if (is_vpn) {
if (activation_type != NM_ACTIVATION_TYPE_MANAGED)
g_return_val_if_reached (NULL);
return _new_vpn_active_connection (self,
settings_connection,
specific_object,
@@ -3317,6 +3382,7 @@ _new_active_connection (NMManager *self,
applied,
specific_object,
subject,
activation_type,
device);
}
@@ -3369,6 +3435,8 @@ _internal_activation_auth_done (NMActiveConnection *active,
* @specific_object: the specific object path, if any, for the activation
* @device: the #NMDevice to activate @connection on
* @subject: the subject which requested activation
* @activation_type: whether to assume the connection. That is, take over gracefully,
* non-destructible.
* @error: return location for an error
*
* Begins a new internally-initiated activation of @connection on @device.
@@ -3388,6 +3456,7 @@ nm_manager_activate_connection (NMManager *self,
const char *specific_object,
NMDevice *device,
NMAuthSubject *subject,
NMActivationType activation_type,
GError **error)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
@@ -3434,6 +3503,7 @@ nm_manager_activate_connection (NMManager *self,
specific_object,
device,
subject,
activation_type,
error);
if (active) {
priv->authorizing_connections = g_slist_prepend (priv->authorizing_connections, active);
@@ -3677,6 +3747,7 @@ impl_manager_activate_connection (NMManager *self,
specific_object_path,
device,
subject,
NM_ACTIVATION_TYPE_MANAGED,
&error);
if (!active)
goto error;
@@ -3896,6 +3967,7 @@ impl_manager_add_and_activate_connection (NMManager *self,
specific_object_path,
device,
subject,
NM_ACTIVATION_TYPE_MANAGED,
&error);
if (!active)
goto error;

View File

@@ -115,6 +115,7 @@ NMActiveConnection *nm_manager_activate_connection (NMManager *manager,
const char *specific_object,
NMDevice *device,
NMAuthSubject *subject,
NMActivationType activation_type,
GError **error);
gboolean nm_manager_deactivate_connection (NMManager *manager,

View File

@@ -428,7 +428,7 @@ settings_set_hostname_cb (const char *hostname,
}
if (!ret)
nm_dispatcher_call (DISPATCHER_ACTION_HOSTNAME, NULL, NULL, NULL, NULL, NULL, NULL);
nm_dispatcher_call_hostname (NULL, NULL, NULL);
}
static void
@@ -1023,6 +1023,7 @@ auto_activate_device (NMPolicy *self,
specific_object,
device,
subject,
NM_ACTIVATION_TYPE_MANAGED,
&error)) {
_LOGI (LOGD_DEVICE, "connection '%s' auto-activation failed: (%d) %s",
nm_settings_connection_get_id (best_connection),
@@ -1433,6 +1434,7 @@ activate_secondary_connections (NMPolicy *self,
nm_exported_object_get_path (NM_EXPORTED_OBJECT (req)),
device,
nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (req)),
NM_ACTIVATION_TYPE_MANAGED,
&error);
if (ac)
secondary_ac_list = g_slist_append (secondary_ac_list, g_object_ref (ac));
@@ -1846,6 +1848,7 @@ vpn_connection_retry_after_failure (NMVpnConnection *vpn, NMPolicy *self)
NULL,
NULL,
nm_active_connection_get_subject (ac),
NM_ACTIVATION_TYPE_MANAGED,
&error)) {
_LOGW (LOGD_DEVICE, "VPN '%s' reconnect failed: %s",
nm_settings_connection_get_id (connection),

View File

@@ -55,6 +55,22 @@ typedef struct _NMSleepMonitor NMSleepMonitor;
typedef struct _NMLldpListener NMLldpListener;
typedef struct _NMConfigDeviceStateData NMConfigDeviceStateData;
/*****************************************************************************/
typedef enum {
/* Do a full activation. */
NM_ACTIVATION_TYPE_MANAGED = 0,
/* gracefully/seamlessly take over the device. This leaves additional
* IP addresses and does not restore missing manual addresses. */
NM_ACTIVATION_TYPE_ASSUME = 1,
/* external activation. This device is not managed by NM, instead
* a in-memory connection is generated and NM pretends the device
* to be active, but it doesn't do anything really. */
NM_ACTIVATION_TYPE_EXTERNAL = 2,
} NMActivationType;
typedef enum {
/* In priority order; higher number == higher priority */

View File

@@ -498,7 +498,7 @@ set_unsaved (NMSettingsConnection *self, gboolean now_unsaved)
else {
flags &= ~(NM_SETTINGS_CONNECTION_FLAGS_UNSAVED |
NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED |
NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED);
NM_SETTINGS_CONNECTION_FLAGS_VOLATILE);
}
nm_settings_connection_set_flags_all (self, flags);
}
@@ -561,7 +561,7 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self,
_LOGD ("replace settings from connection %p (%s)", new_connection, nm_connection_get_id (NM_CONNECTION (self)));
nm_settings_connection_set_flags (self,
NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED | NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED,
NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED | NM_SETTINGS_CONNECTION_FLAGS_VOLATILE,
FALSE);
/* Cache the just-updated system secrets in case something calls
@@ -2641,18 +2641,18 @@ nm_settings_connection_get_nm_generated (NMSettingsConnection *self)
}
/**
* nm_settings_connection_get_nm_generated_assumed:
* nm_settings_connection_get_volatile:
* @self: an #NMSettingsConnection
*
* Gets the "nm-generated-assumed" flag on @self.
* Gets the "volatile" flag on @self.
*
* The connection is a generated connection especially
* generated for connection assumption.
* The connection is marked as volatile and will be removed when
* it disconnects.
*/
gboolean
nm_settings_connection_get_nm_generated_assumed (NMSettingsConnection *self)
nm_settings_connection_get_volatile (NMSettingsConnection *self)
{
return NM_FLAGS_HAS (nm_settings_connection_get_flags (self), NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED);
return NM_FLAGS_HAS (nm_settings_connection_get_flags (self), NM_SETTINGS_CONNECTION_FLAGS_VOLATILE);
}
gboolean

View File

@@ -58,9 +58,9 @@
* @NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED: A connection is "nm-generated" if
* it was generated by NetworkManger. If the connection gets modified or saved
* by the user, the flag gets cleared. A nm-generated is implicitly unsaved.
* @NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED: A special kind of "nm-generated"
* connection that was specifically created for connection assumption. "nm-generated-assumed"
* implies "nm-generated".
* @NM_SETTINGS_CONNECTION_FLAGS_VOLATILE: The connection will be deleted
* when it disconnects. That is for in-memory connections (unsaved), which are
* currently active but cleanup on disconnect.
* @NM_SETTINGS_CONNECTION_FLAGS_ALL: special mask, for all known flags
*
* #NMSettingsConnection flags.
@@ -70,7 +70,7 @@ typedef enum
NM_SETTINGS_CONNECTION_FLAGS_NONE = 0x00,
NM_SETTINGS_CONNECTION_FLAGS_UNSAVED = 0x01,
NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED = 0x02,
NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED = 0x04,
NM_SETTINGS_CONNECTION_FLAGS_VOLATILE = 0x04,
__NM_SETTINGS_CONNECTION_FLAGS_LAST,
NM_SETTINGS_CONNECTION_FLAGS_ALL = ((__NM_SETTINGS_CONNECTION_FLAGS_LAST - 1) << 1) - 1,
@@ -228,7 +228,7 @@ void nm_settings_connection_set_autoconnect_blocke
gboolean nm_settings_connection_can_autoconnect (NMSettingsConnection *self);
gboolean nm_settings_connection_get_nm_generated (NMSettingsConnection *self);
gboolean nm_settings_connection_get_nm_generated_assumed (NMSettingsConnection *self);
gboolean nm_settings_connection_get_volatile (NMSettingsConnection *self);
gboolean nm_settings_connection_get_ready (NMSettingsConnection *self);
void nm_settings_connection_set_ready (NMSettingsConnection *self,

View File

@@ -2143,7 +2143,7 @@ hostnamed_properties_changed (GDBusProxy *proxy,
g_free (priv->hostname.value);
priv->hostname.value = g_strdup (hostname);
_notify (self, PROP_HOSTNAME);
nm_dispatcher_call (DISPATCHER_ACTION_HOSTNAME, NULL, NULL, NULL, NULL, NULL, NULL);
nm_dispatcher_call_hostname (NULL, NULL, NULL);
}
g_variant_unref (v_hostname);

View File

@@ -309,6 +309,30 @@ _match_connection_new (void)
return connection;
}
static NMConnection *
_match_connection (GSList *connections,
NMConnection *original,
gboolean device_has_carrier,
gint64 default_v4_metric,
gint64 default_v6_metric)
{
NMConnection **list;
guint i, len;
len = g_slist_length (connections);
g_assert (len < 10);
list = g_alloca ((len + 1) * sizeof (NMConnection *));
for (i = 0; i < len; i++, connections = connections->next) {
g_assert (connections);
g_assert (connections->data);
list[i] = connections->data;
}
list[i] = NULL;
return nm_utils_match_connection (list, original, device_has_carrier, default_v4_metric, default_v6_metric, NULL, NULL);
}
static void
test_connection_match_basic (void)
{
@@ -320,7 +344,7 @@ test_connection_match_basic (void)
copy = nm_simple_connection_new_clone (orig);
connections = g_slist_append (connections, copy);
matched = nm_utils_match_connection (connections, orig, TRUE, 0, 0, NULL, NULL);
matched = _match_connection (connections, orig, TRUE, 0, 0);
g_assert (matched == copy);
/* Now change a material property like IPv4 method and ensure matching fails */
@@ -329,7 +353,7 @@ test_connection_match_basic (void)
g_object_set (G_OBJECT (s_ip4),
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL,
NULL);
matched = nm_utils_match_connection (connections, orig, TRUE, 0, 0, NULL, NULL);
matched = _match_connection (connections, orig, TRUE, 0, 0);
g_assert (matched == NULL);
g_slist_free (connections);
@@ -365,7 +389,7 @@ test_connection_match_ip6_method (void)
NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE,
NULL);
matched = nm_utils_match_connection (connections, orig, TRUE, 0, 0, NULL, NULL);
matched = _match_connection (connections, orig, TRUE, 0, 0);
g_assert (matched == copy);
g_slist_free (connections);
@@ -399,7 +423,7 @@ test_connection_match_ip6_method_ignore (void)
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
NULL);
matched = nm_utils_match_connection (connections, orig, TRUE, 0, 0, NULL, NULL);
matched = _match_connection (connections, orig, TRUE, 0, 0);
g_assert (matched == copy);
g_slist_free (connections);
@@ -433,7 +457,7 @@ test_connection_match_ip6_method_ignore_auto (void)
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
NULL);
matched = nm_utils_match_connection (connections, orig, TRUE, 0, 0, NULL, NULL);
matched = _match_connection (connections, orig, TRUE, 0, 0);
g_assert (matched == copy);
g_slist_free (connections);
@@ -469,11 +493,11 @@ test_connection_match_ip4_method (void)
NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE,
NULL);
matched = nm_utils_match_connection (connections, orig, FALSE, 0, 0, NULL, NULL);
matched = _match_connection (connections, orig, FALSE, 0, 0);
g_assert (matched == copy);
/* Ensure when carrier=true matching fails */
matched = nm_utils_match_connection (connections, orig, TRUE, 0, 0, NULL, NULL);
matched = _match_connection (connections, orig, TRUE, 0, 0);
g_assert (matched == NULL);
g_slist_free (connections);
@@ -507,7 +531,7 @@ test_connection_match_interface_name (void)
NM_SETTING_CONNECTION_INTERFACE_NAME, NULL,
NULL);
matched = nm_utils_match_connection (connections, orig, TRUE, 0, 0, NULL, NULL);
matched = _match_connection (connections, orig, TRUE, 0, 0);
g_assert (matched == copy);
g_slist_free (connections);
@@ -544,7 +568,7 @@ test_connection_match_wired (void)
NM_SETTING_WIRED_S390_NETTYPE, "qeth",
NULL);
matched = nm_utils_match_connection (connections, orig, TRUE, 0, 0, NULL, NULL);
matched = _match_connection (connections, orig, TRUE, 0, 0);
g_assert (matched == copy);
g_slist_free (connections);
@@ -576,7 +600,7 @@ test_connection_match_wired2 (void)
* the connections match. It can happen if assuming VLAN devices. */
nm_connection_remove_setting (orig, NM_TYPE_SETTING_WIRED);
matched = nm_utils_match_connection (connections, orig, TRUE, 0, 0, NULL, NULL);
matched = _match_connection (connections, orig, TRUE, 0, 0);
g_assert (matched == copy);
g_slist_free (connections);
@@ -601,7 +625,7 @@ test_connection_match_cloned_mac (void)
NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "52:54:00:ab:db:23",
NULL);
matched = nm_utils_match_connection (connections, orig, TRUE, 0, 0, NULL, NULL);
matched = _match_connection (connections, orig, TRUE, 0, 0);
g_assert (matched == fuzzy);
exact = nm_simple_connection_new_clone (orig);
@@ -612,14 +636,14 @@ test_connection_match_cloned_mac (void)
NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "52:54:00:ab:db:23",
NULL);
matched = nm_utils_match_connection (connections, orig, TRUE, 0, 0, NULL, NULL);
matched = _match_connection (connections, orig, TRUE, 0, 0);
g_assert (matched == exact);
g_object_set (G_OBJECT (s_wired),
NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "52:54:00:ab:db:24",
NULL);
matched = nm_utils_match_connection (connections, orig, TRUE, 0, 0, NULL, NULL);
matched = _match_connection (connections, orig, TRUE, 0, 0);
g_assert (matched == fuzzy);
g_slist_free (connections);
@@ -679,7 +703,7 @@ test_connection_no_match_ip4_addr (void)
nm_setting_ip_config_add_address (s_ip4, nm_addr);
nm_ip_address_unref (nm_addr);
matched = nm_utils_match_connection (connections, orig, TRUE, 0, 0, NULL, NULL);
matched = _match_connection (connections, orig, TRUE, 0, 0);
g_assert (matched != copy);
g_slist_free (connections);
@@ -725,7 +749,7 @@ test_connection_no_match_vlan (void)
NM_SETTING_VLAN_FLAGS, 0,
NULL);
matched = nm_utils_match_connection (connections, orig, TRUE, 0, 0, NULL, NULL);
matched = _match_connection (connections, orig, TRUE, 0, 0);
g_assert (matched != copy);
/* Check that the connections do not match if VLAN priorities differ */
@@ -735,7 +759,7 @@ test_connection_no_match_vlan (void)
g_object_set (G_OBJECT (s_vlan_copy), NM_SETTING_VLAN_FLAGS, 0, NULL);
nm_setting_vlan_add_priority_str (s_vlan_copy, NM_VLAN_INGRESS_MAP, "4:2");
matched = nm_utils_match_connection (connections, orig, TRUE, 0, 0, NULL, NULL);
matched = _match_connection (connections, orig, TRUE, 0, 0);
g_assert (matched != copy);
g_slist_free (connections);
@@ -775,7 +799,7 @@ test_connection_match_ip4_routes1 (void)
nmtst_setting_ip_config_add_route (s_ip4, "172.25.17.0", 24, "10.0.0.3", 20);
/* Try to match the connections */
matched = nm_utils_match_connection (connections, orig, FALSE, 100, 0, NULL, NULL);
matched = _match_connection (connections, orig, FALSE, 100, 0);
g_assert (matched == NULL);
}
@@ -812,9 +836,9 @@ test_connection_match_ip4_routes2 (void)
nmtst_setting_ip_config_add_route (s_ip4, "172.25.16.0", 24, "10.0.0.2", 100);
/* Try to match the connections using different default metrics */
matched = nm_utils_match_connection (connections, orig, FALSE, 100, 0, NULL, NULL);
matched = _match_connection (connections, orig, FALSE, 100, 0);
g_assert (matched == copy);
matched = nm_utils_match_connection (connections, orig, FALSE, 500, 0, NULL, NULL);
matched = _match_connection (connections, orig, FALSE, 500, 0);
g_assert (matched == NULL);
}
@@ -849,9 +873,9 @@ test_connection_match_ip6_routes (void)
nmtst_setting_ip_config_add_route (s_ip6, "2001:db8:a:b:0:0:0:0", 64, "fd01::16", 50);
/* Try to match the connections */
matched = nm_utils_match_connection (connections, orig, FALSE, 0, 100, NULL, NULL);
matched = _match_connection (connections, orig, FALSE, 0, 100);
g_assert (matched == NULL);
matched = nm_utils_match_connection (connections, orig, FALSE, 0, 50, NULL, NULL);
matched = _match_connection (connections, orig, FALSE, 0, 50);
g_assert (matched == copy);
}

View File

@@ -535,7 +535,7 @@ _set_vpn_state (NMVpnConnection *self,
*/
break;
case STATE_PRE_UP:
if (!nm_dispatcher_call_vpn (DISPATCHER_ACTION_VPN_PRE_UP,
if (!nm_dispatcher_call_vpn (NM_DISPATCHER_ACTION_VPN_PRE_UP,
_get_settings_connection (self, FALSE),
_get_applied_connection (self),
parent_dev,
@@ -555,7 +555,7 @@ _set_vpn_state (NMVpnConnection *self,
nm_active_connection_clear_secrets (NM_ACTIVE_CONNECTION (self));
/* Let dispatcher scripts know we're up and running */
nm_dispatcher_call_vpn (DISPATCHER_ACTION_VPN_UP,
nm_dispatcher_call_vpn (NM_DISPATCHER_ACTION_VPN_UP,
_get_settings_connection (self, FALSE),
_get_applied_connection (self),
parent_dev,
@@ -577,7 +577,7 @@ _set_vpn_state (NMVpnConnection *self,
break;
case STATE_DEACTIVATING:
if (quitting) {
nm_dispatcher_call_vpn_sync (DISPATCHER_ACTION_VPN_PRE_DOWN,
nm_dispatcher_call_vpn_sync (NM_DISPATCHER_ACTION_VPN_PRE_DOWN,
_get_settings_connection (self, FALSE),
_get_applied_connection (self),
parent_dev,
@@ -586,7 +586,7 @@ _set_vpn_state (NMVpnConnection *self,
priv->ip4_config,
priv->ip6_config);
} else {
if (!nm_dispatcher_call_vpn (DISPATCHER_ACTION_VPN_PRE_DOWN,
if (!nm_dispatcher_call_vpn (NM_DISPATCHER_ACTION_VPN_PRE_DOWN,
_get_settings_connection (self, FALSE),
_get_applied_connection (self),
parent_dev,
@@ -611,7 +611,7 @@ _set_vpn_state (NMVpnConnection *self,
&& old_vpn_state <= STATE_DEACTIVATING) {
/* Let dispatcher scripts know we're about to go down */
if (quitting) {
nm_dispatcher_call_vpn_sync (DISPATCHER_ACTION_VPN_DOWN,
nm_dispatcher_call_vpn_sync (NM_DISPATCHER_ACTION_VPN_DOWN,
_get_settings_connection (self, FALSE),
_get_applied_connection (self),
parent_dev,
@@ -620,7 +620,7 @@ _set_vpn_state (NMVpnConnection *self,
NULL,
NULL);
} else {
nm_dispatcher_call_vpn (DISPATCHER_ACTION_VPN_DOWN,
nm_dispatcher_call_vpn (NM_DISPATCHER_ACTION_VPN_DOWN,
_get_settings_connection (self, FALSE),
_get_applied_connection (self),
parent_dev,