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_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_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__); \ !!_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 "|") /* Beware that this does short-circuit evaluation (use "||" instead of "|")
* which has a possibly unexpected non-function-like behavior. * which has a possibly unexpected non-function-like behavior.
* Use NM_IN_SET_SE if you need all arguments to be evaluted. */ * 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 /* "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 * short-circuit evaluation, which can make a difference if the arguments have
* side-effects. */ * 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, ...) \ #define _NM_IN_STRSET_EVAL_N(op, x, n, ...) \
({ \ ({ \
const char *_x = (x); \ const char *_x = (x); \
( ((_x == NULL) && _NM_IN_SET_EVAL_N2 (op, (const char *) NULL, 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__)) \ || ((_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 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 static gboolean
@@ -384,6 +384,7 @@ check_ip_routes (NMConnection *orig,
{ {
gs_free NMIPRoute **routes1 = NULL, **routes2 = NULL; gs_free NMIPRoute **routes1 = NULL, **routes2 = NULL;
NMSettingIPConfig *s_ip1, *s_ip2; NMSettingIPConfig *s_ip1, *s_ip2;
gint64 m;
const char *s_name; const char *s_name;
GHashTable *props; GHashTable *props;
guint i, num; guint i, num;
@@ -415,8 +416,12 @@ check_ip_routes (NMConnection *orig,
routes2[i] = nm_setting_ip_config_get_route (s_ip2, i); routes2[i] = nm_setting_ip_config_get_route (s_ip2, i);
} }
qsort (routes1, num, sizeof (NMIPRoute *), route_ptr_compare); m = nm_setting_ip_config_get_route_metric (s_ip2);
qsort (routes2, num, sizeof (NMIPRoute *), route_ptr_compare); 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++) { for (i = 0; i < num; i++) {
if (route_compare (routes1[i], routes2[i], default_metric)) if (route_compare (routes1[i], routes2[i], default_metric))
@@ -710,7 +715,7 @@ check_possible_match (NMConnection *orig,
* matches well enough. * matches well enough.
*/ */
NMConnection * NMConnection *
nm_utils_match_connection (GSList *connections, nm_utils_match_connection (NMConnection *const*connections,
NMConnection *original, NMConnection *original,
gboolean device_has_carrier, gboolean device_has_carrier,
gint64 default_v4_metric, gint64 default_v4_metric,
@@ -719,10 +724,12 @@ nm_utils_match_connection (GSList *connections,
gpointer match_filter_data) gpointer match_filter_data)
{ {
NMConnection *best_match = NULL; NMConnection *best_match = NULL;
GSList *iter;
for (iter = connections; iter; iter = iter->next) { if (!connections)
NMConnection *candidate = NM_CONNECTION (iter->data); return NULL;
for (; *connections; connections++) {
NMConnection *candidate = NM_CONNECTION (*connections);
GHashTable *diffs = NULL; GHashTable *diffs = NULL;
if (match_filter_func) { 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); 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, NMConnection *original,
gboolean device_has_carrier, gboolean device_has_carrier,
gint64 default_v4_metric, gint64 default_v4_metric,

View File

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

View File

@@ -206,6 +206,7 @@ typedef struct _NMDevicePrivate {
NMDeviceState state; NMDeviceState state;
NMDeviceStateReason reason; NMDeviceStateReason reason;
} queued_state; } queued_state;
guint queued_ip4_config_id; guint queued_ip4_config_id;
guint queued_ip6_config_id; guint queued_ip6_config_id;
GSList *pending_actions; GSList *pending_actions;
@@ -250,6 +251,8 @@ typedef struct _NMDevicePrivate {
NMUtilsStableType current_stable_id_type:3; 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; GHashTable * available_connections;
char * hw_addr; char * hw_addr;
char * hw_addr_perm; char * hw_addr_perm;
@@ -259,7 +262,6 @@ typedef struct _NMDevicePrivate {
NMUnmanagedFlags unmanaged_mask; NMUnmanagedFlags unmanaged_mask;
NMUnmanagedFlags unmanaged_flags; 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) */ DeleteOnDeactivateData *delete_on_deactivate_data; /* data for scheduled cleanup when deleting link (g_idle_add) */
GCancellable *deactivating_cancellable; GCancellable *deactivating_cancellable;
@@ -289,15 +291,16 @@ typedef struct _NMDevicePrivate {
guint link_connected_id; guint link_connected_id;
guint link_disconnected_id; guint link_disconnected_id;
guint carrier_defer_id; guint carrier_defer_id;
bool carrier;
guint carrier_wait_id; guint carrier_wait_id;
bool ignore_carrier;
gulong ignore_carrier_id; gulong ignore_carrier_id;
guint32 mtu; guint32 mtu;
guint32 ip6_mtu; guint32 ip6_mtu;
guint32 mtu_initial; guint32 mtu_initial;
guint32 ip6_mtu_initial; guint32 ip6_mtu_initial;
bool carrier:1;
bool ignore_carrier:1;
bool mtu_initialized:1; bool mtu_initialized:1;
bool up:1; /* IFF_UP */ bool up:1; /* IFF_UP */
@@ -305,6 +308,8 @@ typedef struct _NMDevicePrivate {
bool v4_commit_first_time:1; bool v4_commit_first_time:1;
bool v6_commit_first_time:1; bool v6_commit_first_time:1;
NMDeviceSysIfaceState sys_iface_state:2;
/* Generic DHCP stuff */ /* Generic DHCP stuff */
guint32 dhcp_timeout; guint32 dhcp_timeout;
char * dhcp_anycast_address; 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, static gboolean ip6_config_merge_and_apply (NMDevice *self,
gboolean commit); 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_enslave (NMDevice *self, gboolean success);
static void nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason); 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 NMActStageReturn dhcp4_start (NMDevice *self, NMConnection *connection);
static gboolean dhcp6_start (NMDevice *self, gboolean wait_for_ll); static gboolean dhcp6_start (NMDevice *self, gboolean wait_for_ll);
static void nm_device_start_ip_check (NMDevice *self); 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 _commit_mtu (NMDevice *self, const NMIP4Config *config);
static void dhcp_schedule_restart (NMDevice *self, int family, const char *reason); static void dhcp_schedule_restart (NMDevice *self, int family, const char *reason);
static void _cancel_activation (NMDevice *self); static void _cancel_activation (NMDevice *self);
@@ -606,6 +613,69 @@ nm_device_get_settings (NMDevice *self)
return NM_DEVICE_GET_PRIVATE (self)->settings; 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 static void
init_ip4_config_dns_priority (NMDevice *self, NMIP4Config *config) init_ip4_config_dns_priority (NMDevice *self, NMIP4Config *config)
{ {
@@ -1532,7 +1602,7 @@ nm_device_has_carrier (NMDevice *self)
NMActRequest * NMActRequest *
nm_device_get_act_request (NMDevice *self) 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; 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 * static SlaveInfo *
find_slave_info (NMDevice *self, NMDevice *slave) 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); 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)" : ""); !info ? " (not registered)" : "");
if (!info) if (!info)
@@ -2371,6 +2414,8 @@ link_type_compatible (NMDevice *self,
* nm_device_realize_start(): * nm_device_realize_start():
* @self: the #NMDevice * @self: the #NMDevice
* @plink: an existing platform link or %NULL * @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 * @out_compatible: %TRUE on return if @self is compatible with @plink
* @error: location to store error, or %NULL * @error: location to store error, or %NULL
* *
@@ -2386,6 +2431,7 @@ link_type_compatible (NMDevice *self,
gboolean gboolean
nm_device_realize_start (NMDevice *self, nm_device_realize_start (NMDevice *self,
const NMPlatformLink *plink, const NMPlatformLink *plink,
NMUnmanFlagOp unmanaged_user_explicit,
gboolean *out_compatible, gboolean *out_compatible,
GError **error) GError **error)
{ {
@@ -2409,7 +2455,7 @@ nm_device_realize_start (NMDevice *self,
plink_copy = *plink; plink_copy = *plink;
plink = &plink_copy; plink = &plink_copy;
} }
realize_start_setup (self, plink); realize_start_setup (self, plink, unmanaged_user_explicit);
return TRUE; return TRUE;
} }
@@ -2449,7 +2495,7 @@ nm_device_create_and_realize (NMDevice *self,
plink = &plink_copy; plink = &plink_copy;
} }
realize_start_setup (self, plink); realize_start_setup (self, plink, NM_UNMAN_FLAG_OP_FORGET);
nm_device_realize_finish (self, plink); nm_device_realize_finish (self, plink);
if (nm_device_get_managed (self, FALSE)) { if (nm_device_get_managed (self, FALSE)) {
@@ -2530,6 +2576,7 @@ realize_start_notify (NMDevice *self,
* realize_start_setup(): * realize_start_setup():
* @self: the #NMDevice * @self: the #NMDevice
* @plink: the #NMPlatformLink if backed by a kernel netdevice * @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 * Update the device from backing resource properties (like hardware
* addresses, carrier states, driver/firmware info, etc). This function * addresses, carrier states, driver/firmware info, etc). This function
@@ -2538,7 +2585,9 @@ realize_start_notify (NMDevice *self,
* stuff). * stuff).
*/ */
static void static void
realize_start_setup (NMDevice *self, const NMPlatformLink *plink) realize_start_setup (NMDevice *self,
const NMPlatformLink *plink,
NMUnmanFlagOp unmanaged_user_explicit)
{ {
NMDevicePrivate *priv; NMDevicePrivate *priv;
NMDeviceClass *klass; NMDeviceClass *klass;
@@ -2576,6 +2625,8 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink)
_notify (self, PROP_MTU); _notify (self, PROP_MTU);
} }
nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
if (plink) { if (plink) {
g_return_if_fail (link_type_compatible (self, plink->type, NULL, NULL)); g_return_if_fail (link_type_compatible (self, plink->type, NULL, NULL));
update_device_from_platform_link (self, plink); 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); 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 /* Do not manage externally created software devices until they are IFF_UP
* or have IP addressing */ * or have IP addressing */
nm_device_set_unmanaged_flags (self, nm_device_set_unmanaged_flags (self,
@@ -2944,7 +3000,6 @@ slave_state_changed (NMDevice *slave,
{ {
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
gboolean release = FALSE; gboolean release = FALSE;
gboolean configure = TRUE;
_LOGD (LOGD_DEVICE, "slave %s state change %d (%s) -> %d (%s)", _LOGD (LOGD_DEVICE, "slave %s state change %d (%s) -> %d (%s)",
nm_device_get_iface (slave), nm_device_get_iface (slave),
@@ -2967,12 +3022,10 @@ slave_state_changed (NMDevice *slave,
release = TRUE; 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) { 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 */ /* Bridge/bond/team interfaces are left up until manually deactivated */
if (priv->slaves == NULL && priv->state == NM_DEVICE_STATE_ACTIVATED) if (priv->slaves == NULL && priv->state == NM_DEVICE_STATE_ACTIVATED)
_LOGD (LOGD_DEVICE, "last slave removed; remaining 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, * 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. * 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) nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure)
{ {
NMDevicePrivate *priv; NMDevicePrivate *priv;
NMDevicePrivate *slave_priv; NMDevicePrivate *slave_priv;
SlaveInfo *info; SlaveInfo *info;
gboolean changed = FALSE;
g_return_if_fail (NM_IS_DEVICE (self)); g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
g_return_if_fail (NM_IS_DEVICE (slave)); g_return_val_if_fail (NM_IS_DEVICE (slave), FALSE);
g_return_if_fail (NM_DEVICE_GET_CLASS (self)->enslave_slave != NULL); g_return_val_if_fail (NM_DEVICE_GET_CLASS (self)->enslave_slave != NULL, FALSE);
priv = NM_DEVICE_GET_PRIVATE (self); priv = NM_DEVICE_GET_PRIVATE (self);
slave_priv = NM_DEVICE_GET_PRIVATE (slave); slave_priv = NM_DEVICE_GET_PRIVATE (slave);
info = find_slave_info (self, 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)" : ""); info ? " (already registered)" : "");
if (configure) 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) { if (!info) {
g_return_if_fail (!slave_priv->master); g_return_val_if_fail (!slave_priv->master, FALSE);
g_return_if_fail (!slave_priv->is_enslaved); g_return_val_if_fail (!slave_priv->is_enslaved, FALSE);
info = g_slice_new0 (SlaveInfo); info = g_slice_new0 (SlaveInfo);
info->slave = g_object_ref (slave); 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)); 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); nm_device_set_unmanaged_by_flags (slave, NM_UNMANAGED_IS_SLAVE, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
changed = TRUE;
} else } 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 (self);
nm_device_queue_recheck_assume (slave); nm_device_queue_recheck_assume (slave);
}
return changed;
}
/** /**
* nm_device_master_get_slaves: * nm_device_master_get_slaves:
@@ -3132,7 +3191,7 @@ nm_device_master_release_slaves (NMDevice *self)
gboolean configure = TRUE; gboolean configure = TRUE;
/* Don't release the slaves if this connection doesn't belong to NM. */ /* 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; return;
reason = priv->state_reason; 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)); _LOGI (LOGD_DEVICE, "enslaved to %s", nm_device_get_iface (priv->master));
priv->is_enslaved = TRUE; 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 (self, PROP_MASTER);
_notify (priv->master, PROP_SLAVES); _notify (priv->master, PROP_SLAVES);
} else if (activating) { } else if (activating) {
@@ -3248,15 +3315,19 @@ nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason)
if ( priv->state > NM_DEVICE_STATE_DISCONNECTED if ( priv->state > NM_DEVICE_STATE_DISCONNECTED
&& priv->state <= NM_DEVICE_STATE_ACTIVATED) { && 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; new_state = NM_DEVICE_STATE_FAILED;
master_status = "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; new_state = NM_DEVICE_STATE_DEACTIVATING;
master_status = "deactivated by user request"; master_status = "deactivated by user request";
} else { break;
default:
new_state = NM_DEVICE_STATE_DISCONNECTED; new_state = NM_DEVICE_STATE_DISCONNECTED;
master_status = "deactivated"; master_status = "deactivated";
break;
} }
_LOGD (LOGD_DEVICE, "Activation: connection '%s' master %s", _LOGD (LOGD_DEVICE, "Activation: connection '%s' master %s",
@@ -3920,12 +3991,14 @@ recheck_available (gpointer user_data)
{ {
NMDevice *self = NM_DEVICE (user_data); NMDevice *self = NM_DEVICE (user_data);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); 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 state = nm_device_get_state (self);
NMDeviceState new_state = NM_DEVICE_STATE_UNKNOWN; NMDeviceState new_state = NM_DEVICE_STATE_UNKNOWN;
priv->recheck_available.call_id = 0; 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) { if (state == NM_DEVICE_STATE_UNAVAILABLE && now_available) {
new_state = NM_DEVICE_STATE_DISCONNECTED; new_state = NM_DEVICE_STATE_DISCONNECTED;
nm_device_queue_state (self, new_state, priv->recheck_available.available_reason); 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. */ /* If the master didn't change, add-slave only rechecks whether to assume a connection. */
nm_device_master_add_slave (master, nm_device_master_add_slave (master,
self, self,
nm_active_connection_get_assumed (active) ? FALSE : TRUE); !nm_device_sys_iface_state_is_external_or_assume (self));
} }
static void static void
@@ -4232,7 +4305,6 @@ activate_stage1_device_prepare (NMDevice *self)
{ {
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; 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_INET, IP_NONE);
_set_ip_state (self, AF_INET6, 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); nm_device_state_changed (self, NM_DEVICE_STATE_PREPARE, NM_DEVICE_STATE_REASON_NONE);
/* Assumed connections were already set up outside NetworkManager */ /* 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; NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE;
ret = NM_DEVICE_GET_CLASS (self)->act_stage1_prepare (self, &failure_reason); 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); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMActStageReturn ret; NMActStageReturn ret;
gboolean no_firmware = FALSE; gboolean no_firmware = FALSE;
NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request);
GSList *iter; GSList *iter;
nm_device_state_changed (self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE); nm_device_state_changed (self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE);
/* Assumed connections were already set up outside NetworkManager */ /* 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; NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE;
if (!nm_device_bring_up (self, FALSE, &no_firmware)) { 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) if (slave_state == NM_DEVICE_STATE_IP_CONFIG)
nm_device_master_enslave_slave (self, info->slave, nm_device_get_applied_connection (info->slave)); 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) && slave_state <= NM_DEVICE_STATE_DISCONNECTED)
nm_device_queue_recheck_assume (info->slave); 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))) { && (priv->ip6_state == IP_FAIL || (ip6_ignore && priv->ip6_state == IP_DONE))) {
/* Either both methods failed, or only one failed and the other is /* Either both methods failed, or only one failed and the other is
* disabled */ * 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, /* We have assumed configuration, but couldn't redo it. No problem,
* move to check state. */ * move to check state. */
_set_ip_state (self, AF_INET, IP_DONE); _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
|| !hw_addr_len || !hw_addr_len
|| !addr_found || !addr_found
|| nm_device_uses_assumed_connection (self)) { || nm_device_sys_iface_state_is_external_or_assume (self)) {
/* DAD not needed, signal success */ /* DAD not needed, signal success */
cb (self, configs, TRUE); cb (self, configs, TRUE);
@@ -4964,7 +5036,7 @@ ensure_con_ip4_config (NMDevice *self)
nm_connection_get_setting_ip4_config (connection), nm_connection_get_setting_ip4_config (connection),
nm_device_get_ip4_route_metric (self)); 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. */ /* For assumed connections ignore all addresses and routes. */
nm_ip4_config_reset_addresses (priv->con_ip4_config); nm_ip4_config_reset_addresses (priv->con_ip4_config);
nm_ip4_config_reset_routes (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_connection_get_setting_ip6_config (connection),
nm_device_get_ip6_route_metric (self)); 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. */ /* For assumed connections ignore all addresses and routes. */
nm_ip6_config_reset_addresses (priv->con_ip6_config); nm_ip6_config_reset_addresses (priv->con_ip6_config);
nm_ip6_config_reset_routes (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 * but if the IP method is automatic we need to update the default route to
* maintain connectivity. * 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; goto END_ADD_DEFAULT_ROUTE;
/* At this point, we treat assumed and non-assumed connections alike. /* At this point, we treat assumed and non-assumed connections alike.
@@ -5208,7 +5280,7 @@ END_ADD_DEFAULT_ROUTE:
routes_full_sync = commit routes_full_sync = commit
&& priv->v4_commit_first_time && 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); success = nm_device_set_ip4_config (self, composite, default_route_metric, commit, routes_full_sync);
g_object_unref (composite); g_object_unref (composite);
@@ -5228,14 +5300,10 @@ dhcp4_lease_change (NMDevice *self, NMIP4Config *config)
return FALSE; return FALSE;
} }
/* Notify dispatcher scripts of new DHCP4 config */ nm_dispatcher_call_device (NM_DISPATCHER_ACTION_DHCP4_CHANGE,
nm_dispatcher_call (DISPATCHER_ACTION_DHCP4_CHANGE, self,
nm_device_get_settings_connection (self), NULL,
nm_device_get_applied_connection (self), NULL, NULL, NULL);
self,
NULL,
NULL,
NULL);
nm_device_remove_pending_action (self, NM_PENDING_ACTION_DHCP4, FALSE); 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), * device will transition to the ACTIVATED state without IP configuration),
* retry DHCP again. * 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"); dhcp_schedule_restart (self, AF_INET, "connection is assumed");
return; 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 * but if the IP method is automatic we need to update the default route to
* maintain connectivity. * 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; goto END_ADD_DEFAULT_ROUTE;
/* At this point, we treat assumed and non-assumed connections alike. /* At this point, we treat assumed and non-assumed connections alike.
@@ -5965,7 +6033,7 @@ END_ADD_DEFAULT_ROUTE:
routes_full_sync = commit routes_full_sync = commit
&& priv->v6_commit_first_time && 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); success = nm_device_set_ip6_config (self, composite, commit, routes_full_sync);
g_object_unref (composite); g_object_unref (composite);
@@ -5996,11 +6064,10 @@ dhcp6_lease_change (NMDevice *self)
return FALSE; return FALSE;
} }
/* Notify dispatcher scripts of new DHCPv6 config */ nm_dispatcher_call_device (NM_DISPATCHER_ACTION_DHCP6_CHANGE,
nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE, self,
settings_connection, NULL,
nm_device_get_applied_connection (self), NULL, NULL, NULL);
self, NULL, NULL, NULL);
nm_device_remove_pending_action (self, NM_PENDING_ACTION_DHCP6, FALSE); 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), * device will transition to the ACTIVATED state without IP configuration),
* retry DHCP again. * 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"); dhcp_schedule_restart (self, AF_INET6, "connection is assumed");
return; return;
} }
@@ -6665,7 +6732,7 @@ _commit_mtu (NMDevice *self, const NMIP4Config *config)
if (ifindex <= 0) if (ifindex <= 0)
return; 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 /* for assumed connections we don't tamper with the MTU. This is
* a bug and supposed to be fixed by the unmanaged/assumed rework. */ * a bug and supposed to be fixed by the unmanaged/assumed rework. */
return; return;
@@ -7332,7 +7399,7 @@ act_stage3_ip6_config_start (NMDevice *self,
* IPv6LL if this is not an assumed connection, since assumed connections * IPv6LL if this is not an assumed connection, since assumed connections
* will already have IPv6 set up. * 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); set_nm_ipv6ll (self, TRUE);
/* Re-enable IPv6 on the interface */ /* 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); _LOGW (LOGD_IP6, "unhandled IPv6 config method '%s'; will fail", method);
if ( ret != NM_ACT_STAGE_RETURN_FAILURE 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) { switch (ip6_privacy) {
case NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN: case NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN:
case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED: 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); s_con = nm_connection_get_setting_connection (connection);
if (!priv->fw_ready) { 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; priv->fw_ready = TRUE;
else { else {
if (!priv->fw_call) { 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 */ /* Interface must be IFF_UP before IP config can be applied */
ip_ifindex = nm_device_get_ip_ifindex (self); 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); nm_platform_link_set_up (NM_PLATFORM_GET, ip_ifindex, NULL);
if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex)) 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)); _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 if ( priv->dhcp4.client
&& nm_device_activate_ip4_state_in_conf (self) && nm_device_activate_ip4_state_in_conf (self)
&& (nm_device_get_state (self) > NM_DEVICE_STATE_IP_CONFIG)) { && (nm_device_get_state (self) > NM_DEVICE_STATE_IP_CONFIG)) {
/* Notify dispatcher scripts of new DHCP4 config */ nm_dispatcher_call_device (NM_DISPATCHER_ACTION_DHCP4_CHANGE,
nm_dispatcher_call (DISPATCHER_ACTION_DHCP4_CHANGE, self,
nm_device_get_settings_connection (self), NULL,
nm_device_get_applied_connection (self), NULL, NULL, NULL);
self,
NULL,
NULL,
NULL);
} }
arp_announce (self); 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 */ /* Interface must be IFF_UP before IP config can be applied */
ip_ifindex = nm_device_get_ip_ifindex (self); 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); nm_platform_link_set_up (NM_PLATFORM_GET, ip_ifindex, NULL);
if (!nm_platform_link_is_up (NM_PLATFORM_GET, ip_ifindex)) 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)); _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, /* If IPv6 wasn't the first IP to complete, and DHCP was used,
* then ensure dispatcher scripts get the DHCP lease information. * then ensure dispatcher scripts get the DHCP lease information.
*/ */
nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE, nm_dispatcher_call_device (NM_DISPATCHER_ACTION_DHCP6_CHANGE,
nm_device_get_settings_connection (self), self,
nm_device_get_applied_connection (self), NULL,
self, NULL, NULL, NULL);
NULL,
NULL,
NULL);
} else { } else {
/* still waiting for first dhcp6 lease. */ /* still waiting for first dhcp6 lease. */
return; return;
@@ -8192,7 +8252,24 @@ act_request_set (NMDevice *self, NMActRequest *act_request)
"notify::"NM_EXPORTED_OBJECT_PATH, "notify::"NM_EXPORTED_OBJECT_PATH,
G_CALLBACK (act_request_set_cb), G_CALLBACK (act_request_set_cb),
self); 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); _notify (self, PROP_ACTIVE_CONNECTION);
} }
@@ -9291,7 +9368,7 @@ nm_device_set_ip4_config (NMDevice *self,
/* Always commit to nm-platform to update lifetimes */ /* Always commit to nm-platform to update lifetimes */
if (commit && new_config) { 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); _commit_mtu (self, new_config);
/* For assumed devices we must not touch the kernel-routes, such as the device-route. /* 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); nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self);
if (has_changes) { if (has_changes) {
NMSettingsConnection *settings_connection;
_update_ip4_address (self); _update_ip4_address (self);
if (old_config != priv->ip4_config) if (old_config != priv->ip4_config)
@@ -9342,15 +9421,17 @@ nm_device_set_ip4_config (NMDevice *self,
if (old_config != priv->ip4_config) if (old_config != priv->ip4_config)
nm_exported_object_clear_and_unexport (&old_config); nm_exported_object_clear_and_unexport (&old_config);
if (nm_device_uses_generated_assumed_connection (self)) { if ( nm_device_sys_iface_state_is_external (self)
NMConnection *settings_connection = NM_CONNECTION (nm_device_get_settings_connection (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; NMSetting *s_ip4;
g_object_freeze_notify (G_OBJECT (settings_connection)); 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); 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)); 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); nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), self);
if (has_changes) { if (has_changes) {
NMSettingsConnection *settings_connection;
if (old_config != priv->ip6_config) if (old_config != priv->ip6_config)
_notify (self, PROP_IP6_CONFIG); _notify (self, PROP_IP6_CONFIG);
g_signal_emit (self, signals[IP6_CONFIG_CHANGED], 0, priv->ip6_config, old_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) if (old_config != priv->ip6_config)
nm_exported_object_clear_and_unexport (&old_config); nm_exported_object_clear_and_unexport (&old_config);
if (nm_device_uses_generated_assumed_connection (self)) { if ( nm_device_sys_iface_state_is_external (self)
NMConnection *settings_connection = NM_CONNECTION (nm_device_get_settings_connection (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; NMSetting *s_ip6;
g_object_freeze_notify (G_OBJECT (settings_connection)); 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); 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)); 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 = NM_DEVICE_STATE_SECONDARIES;
priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE; priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE;
if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_UP, if (!nm_dispatcher_call_device (NM_DISPATCHER_ACTION_PRE_UP,
nm_device_get_settings_connection (self), self,
nm_device_get_applied_connection (self), NULL,
self, dispatcher_complete_proceed_state,
dispatcher_complete_proceed_state, self,
self, &priv->dispatcher.call_id)) {
&priv->dispatcher.call_id)) {
/* Just proceed on errors */ /* Just proceed on errors */
dispatcher_complete_proceed_state (0, self); 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); s_con = nm_connection_get_setting_connection (applied_connection);
if ( nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED 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_firewall_manager_add_or_change_zone (nm_firewall_manager_get (),
nm_device_get_ip_iface (self), nm_device_get_ip_iface (self),
nm_setting_connection_get_zone (s_con), 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); connection = nm_device_get_applied_connection (self);
if ( cleanup_type == CLEANUP_TYPE_DECONFIGURE if ( cleanup_type == CLEANUP_TYPE_DECONFIGURE
&& connection && 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_firewall_manager_remove_from_zone (nm_firewall_manager_get (),
nm_device_get_ip_iface (self), nm_device_get_ip_iface (self),
NULL, NULL,
@@ -11995,6 +12079,14 @@ _set_state_full (NMDevice *self,
/* Cache the activation request for the dispatcher */ /* Cache the activation request for the dispatcher */
req = nm_g_object_ref (priv->act_request); 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 (state <= NM_DEVICE_STATE_UNAVAILABLE) {
if (available_connections_del_all (self)) if (available_connections_del_all (self))
_notify (self, PROP_AVAILABLE_CONNECTIONS); _notify (self, PROP_AVAILABLE_CONNECTIONS);
@@ -12018,14 +12110,12 @@ _set_state_full (NMDevice *self,
case NM_DEVICE_STATE_UNMANAGED: case NM_DEVICE_STATE_UNMANAGED:
nm_device_set_firmware_missing (self, FALSE); nm_device_set_firmware_missing (self, FALSE);
if (old_state > NM_DEVICE_STATE_UNMANAGED) { if (old_state > NM_DEVICE_STATE_UNMANAGED) {
switch (nm_device_state_reason_check (reason)) { if (priv->sys_iface_state != NM_DEVICE_SYS_IFACE_STATE_MANAGED) {
case NM_DEVICE_STATE_REASON_REMOVED: nm_device_cleanup (self, reason,
nm_device_cleanup (self, reason, CLEANUP_TYPE_REMOVED); priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_REMOVED
break; ? CLEANUP_TYPE_REMOVED
case NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED: : CLEANUP_TYPE_KEEP);
nm_device_cleanup (self, reason, CLEANUP_TYPE_KEEP); } else {
break;
default:
/* Clean up if the device is now unmanaged but was activated */ /* Clean up if the device is now unmanaged but was activated */
if (nm_device_get_act_request (self)) if (nm_device_get_act_request (self))
nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE); nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE);
@@ -12040,11 +12130,11 @@ _set_state_full (NMDevice *self,
case NM_DEVICE_STATE_UNAVAILABLE: case NM_DEVICE_STATE_UNAVAILABLE:
if (old_state == NM_DEVICE_STATE_UNMANAGED) { if (old_state == NM_DEVICE_STATE_UNMANAGED) {
save_ip6_properties (self); 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); 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 (old_state == NM_DEVICE_STATE_UNMANAGED || priv->firmware_missing) {
if (!nm_device_bring_up (self, TRUE, &no_firmware) && no_firmware) if (!nm_device_bring_up (self, TRUE, &no_firmware) && no_firmware)
_LOGW (LOGD_PLATFORM, "firmware may be missing."); _LOGW (LOGD_PLATFORM, "firmware may be missing.");
@@ -12071,7 +12161,7 @@ _set_state_full (NMDevice *self,
nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE); nm_device_cleanup (self, reason, CLEANUP_TYPE_DECONFIGURE);
} else if (old_state < NM_DEVICE_STATE_DISCONNECTED) { } 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 /* Ensure IPv6 is set up as it may not have been done when
* entering the UNAVAILABLE state depending on the reason. * 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); priv->ignore_carrier = nm_config_data_get_ignore_carrier (NM_CONFIG_GET_DATA, self);
if (quitting) { if (quitting) {
nm_dispatcher_call_sync (DISPATCHER_ACTION_PRE_DOWN, nm_dispatcher_call_device_sync (NM_DISPATCHER_ACTION_PRE_DOWN,
nm_act_request_get_settings_connection (req), self, req);
nm_act_request_get_applied_connection (req),
self);
} else { } else {
priv->dispatcher.post_state = NM_DEVICE_STATE_DISCONNECTED; priv->dispatcher.post_state = NM_DEVICE_STATE_DISCONNECTED;
priv->dispatcher.post_state_reason = reason; priv->dispatcher.post_state_reason = reason;
if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_DOWN, if (!nm_dispatcher_call_device (NM_DISPATCHER_ACTION_PRE_DOWN,
nm_act_request_get_settings_connection (req), self,
nm_act_request_get_applied_connection (req), req,
self, deactivate_dispatcher_complete,
deactivate_dispatcher_complete, self,
self, &priv->dispatcher.call_id)) {
&priv->dispatcher.call_id)) {
/* Just proceed on errors */ /* Just proceed on errors */
deactivate_dispatcher_complete (0, self); deactivate_dispatcher_complete (0, self);
} }
@@ -12170,10 +12257,10 @@ _set_state_full (NMDevice *self,
case NM_DEVICE_STATE_ACTIVATED: case NM_DEVICE_STATE_ACTIVATED:
_LOGI (LOGD_DEVICE, "Activation: successful, device activated."); _LOGI (LOGD_DEVICE, "Activation: successful, device activated.");
nm_device_update_metered (self); nm_device_update_metered (self);
nm_dispatcher_call (DISPATCHER_ACTION_UP, nm_dispatcher_call_device (NM_DISPATCHER_ACTION_UP,
nm_act_request_get_settings_connection (req), self,
nm_act_request_get_applied_connection (req), req,
self, NULL, NULL, NULL); NULL, NULL, NULL);
if (priv->proxy_config) { if (priv->proxy_config) {
nm_pacrunner_manager_send (priv->pacrunner_manager, nm_pacrunner_manager_send (priv->pacrunner_manager,
@@ -12192,7 +12279,7 @@ _set_state_full (NMDevice *self,
*/ */
_cancel_activation (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 */ /* Avoid tearing down assumed connection, assume it's connected */
nm_device_queue_state (self, nm_device_queue_state (self,
NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_ACTIVATED,
@@ -12230,7 +12317,7 @@ _set_state_full (NMDevice *self,
if ( applied_connection if ( applied_connection
&& priv->ifindex != priv->ip_ifindex && priv->ifindex != priv->ip_ifindex
&& !nm_device_uses_generated_assumed_connection (self)) { && !nm_device_sys_iface_state_is_external (self)) {
NMSettingConnection *s_con; NMSettingConnection *s_con;
const char *zone; 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) if ( (old_state == NM_DEVICE_STATE_ACTIVATED || old_state == NM_DEVICE_STATE_DEACTIVATING)
&& (state != NM_DEVICE_STATE_DEACTIVATING)) { && (state != NM_DEVICE_STATE_DEACTIVATING)) {
if (quitting) { if (quitting) {
nm_dispatcher_call_sync (DISPATCHER_ACTION_DOWN, nm_dispatcher_call_device_sync (NM_DISPATCHER_ACTION_DOWN,
nm_act_request_get_settings_connection (req), self, req);
nm_act_request_get_applied_connection (req),
self);
} else { } else {
nm_dispatcher_call (DISPATCHER_ACTION_DOWN, nm_dispatcher_call_device (NM_DISPATCHER_ACTION_DOWN,
nm_act_request_get_settings_connection (req), self,
nm_act_request_get_applied_connection (req), req,
self, NULL, NULL, NULL); NULL, NULL, NULL);
} }
} }
@@ -13179,6 +13264,7 @@ nm_device_init (NMDevice *self)
priv->unmanaged_mask = priv->unmanaged_flags; 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->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->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 ()); priv->pacrunner_manager = g_object_ref (nm_pacrunner_manager_get ());

View File

@@ -30,6 +30,13 @@
#include "nm-rfkill-manager.h" #include "nm-rfkill-manager.h"
#include "NetworkManagerUtils.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 static inline NMDeviceStateReason
nm_device_state_reason_check (NMDeviceStateReason reason) 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_connection_compatible (NMDevice *device, NMConnection *connection);
gboolean nm_device_check_slave_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_unmanage_on_quit (NMDevice *self);
gboolean nm_device_spec_match_list (NMDevice *device, const GSList *specs); 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, gboolean nm_device_realize_start (NMDevice *device,
const NMPlatformLink *plink, const NMPlatformLink *plink,
NMUnmanFlagOp unmanaged_user_explicit,
gboolean *out_compatible, gboolean *out_compatible,
GError **error); GError **error);
void nm_device_realize_finish (NMDevice *self, 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_set_autoconnect_intern (NMDevice *device, gboolean autoconnect);
void nm_device_emit_recheck_auto_activate (NMDevice *device); 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, void nm_device_state_changed (NMDevice *device,
NMDeviceState state, NMDeviceState state,
NMDeviceStateReason reason); NMDeviceStateReason reason);

View File

@@ -416,7 +416,7 @@ teamd_dbus_appeared (GDBusConnection *connection,
success = teamd_read_config (device); success = teamd_read_config (device);
if (success) if (success)
nm_device_activate_schedule_stage2_device_config (device); 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); 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, * @specific_object: the object path of the specific object (ie, WiFi access point,
* etc) that will be used to activate @connection and @device * etc) that will be used to activate @connection and @device
* @subject: the #NMAuthSubject representing the requestor of the activation * @subject: the #NMAuthSubject representing the requestor of the activation
* @activation_type: the #NMActivationType.
* @device: the device/interface to configure according to @connection * @device: the device/interface to configure according to @connection
* *
* Creates a new device-based activation request. If an applied connection is * 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, NMConnection *applied_connection,
const char *specific_object, const char *specific_object,
NMAuthSubject *subject, NMAuthSubject *subject,
NMActivationType activation_type,
NMDevice *device) NMDevice *device)
{ {
g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL); 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_INT_DEVICE, device,
NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, specific_object, NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, specific_object,
NM_ACTIVE_CONNECTION_INT_SUBJECT, subject, NM_ACTIVE_CONNECTION_INT_SUBJECT, subject,
NM_ACTIVE_CONNECTION_INT_ACTIVATION_TYPE, (int) activation_type,
NULL); NULL);
} }

View File

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

View File

@@ -44,20 +44,20 @@ typedef struct _NMActiveConnectionPrivate {
char *pending_activation_id; char *pending_activation_id;
gboolean is_default;
gboolean is_default6;
NMActiveConnectionState state; NMActiveConnectionState state;
gboolean state_set; bool is_default:1;
gboolean vpn; bool is_default6:1;
bool state_set:1;
bool vpn:1;
bool master_ready:1;
NMActivationType activation_type:3;
NMAuthSubject *subject; NMAuthSubject *subject;
NMActiveConnection *master; NMActiveConnection *master;
gboolean master_ready;
NMActiveConnection *parent; NMActiveConnection *parent;
gboolean assumed;
NMAuthChain *chain; NMAuthChain *chain;
const char *wifi_shared_permission; const char *wifi_shared_permission;
NMActiveConnectionAuthResultFunc result_func; NMActiveConnectionAuthResultFunc result_func;
@@ -88,6 +88,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMActiveConnection,
PROP_INT_SUBJECT, PROP_INT_SUBJECT,
PROP_INT_MASTER, PROP_INT_MASTER,
PROP_INT_MASTER_READY, PROP_INT_MASTER_READY,
PROP_INT_ACTIVATION_TYPE,
); );
enum { 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) #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 check_master_ready (NMActiveConnection *self);
static void _device_cleanup (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) { 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_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_removed, self);
g_signal_handlers_disconnect_by_func (priv->settings_connection, _settings_connection_notify_flags, self);
g_clear_object (&priv->settings_connection); g_clear_object (&priv->settings_connection);
} }
if (connection) { if (connection) {
priv->settings_connection = g_object_ref (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_UPDATED_INTERNAL, (GCallback) _settings_connection_updated, self);
g_signal_connect (connection, NM_SETTINGS_CONNECTION_REMOVED, (GCallback) _settings_connection_removed, 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 (new_state),
state_to_string (priv->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; old_state = priv->state;
priv->state = new_state; priv->state = new_state;
priv->state_set = TRUE; 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_signal_connect (device, "notify::" NM_DEVICE_METERED,
G_CALLBACK (device_metered_changed), self); 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); 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); 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); check_master_ready (self);
} }
void NMActivationType
nm_active_connection_set_assumed (NMActiveConnection *self, gboolean assumed) 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); NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
g_return_if_fail (priv->assumed == FALSE); if (priv->activation_type == activation_type)
priv->assumed = assumed; return;
if (priv->pending_activation_id) { _LOGD ("update activation type from %s to %s",
nm_device_remove_pending_action (priv->device, priv->pending_activation_id, TRUE); nm_activation_type_to_string (priv->activation_type),
g_clear_pointer (&priv->pending_activation_id, g_free); 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; const char *tmp;
NMSettingsConnection *con; NMSettingsConnection *con;
NMConnection *acon; NMConnection *acon;
int i;
switch (prop_id) { switch (prop_id) {
case PROP_INT_SETTINGS_CONNECTION: case PROP_INT_SETTINGS_CONNECTION:
@@ -1082,6 +1133,15 @@ set_property (GObject *object, guint prop_id,
case PROP_INT_MASTER: case PROP_INT_MASTER:
nm_active_connection_set_master (self, g_value_get_object (value)); nm_active_connection_set_master (self, g_value_get_object (value));
break; 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: case PROP_SPECIFIC_OBJECT:
tmp = g_value_get_string (value); tmp = g_value_get_string (value);
/* NM uses "/" to mean NULL */ /* NM uses "/" to mean NULL */
@@ -1117,6 +1177,7 @@ nm_active_connection_init (NMActiveConnection *self)
_LOGT ("creating"); _LOGT ("creating");
priv->activation_type = NM_ACTIVATION_TYPE_MANAGED;
priv->version_id = _version_id_new (); priv->version_id = _version_id_new ();
} }
@@ -1128,15 +1189,16 @@ constructed (GObject *object)
G_OBJECT_CLASS (nm_active_connection_parent_class)->constructed (object); G_OBJECT_CLASS (nm_active_connection_parent_class)->constructed (object);
if (!priv->applied_connection && priv->settings_connection) { if (!priv->applied_connection && priv->settings_connection)
priv->applied_connection = priv->applied_connection = nm_simple_connection_new_clone (NM_CONNECTION (priv->settings_connection));
nm_simple_connection_new_clone ((NMConnection *) priv->settings_connection);
}
if (priv->applied_connection) if (priv->applied_connection)
nm_connection_clear_secrets (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); g_return_if_fail (priv->subject);
} }
@@ -1321,6 +1383,15 @@ nm_active_connection_class_init (NMActiveConnectionClass *ac_class)
FALSE, G_PARAM_READABLE | FALSE, G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS); 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); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
signals[DEVICE_CHANGED] = signals[DEVICE_CHANGED] =

View File

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

View File

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

View File

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

View File

@@ -4339,3 +4339,12 @@ nm_utils_format_con_diff_for_audit (GHashTable *diff)
return g_string_free (str, FALSE); 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); 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__ */ #endif /* __NM_CORE_UTILS_H__ */

View File

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

View File

@@ -19,44 +19,44 @@
* Copyright (C) 2005 - 2008 Novell, Inc. * Copyright (C) 2005 - 2008 Novell, Inc.
*/ */
#ifndef __NETWORKMANAGER_DISPATCHER_H__ #ifndef __NM_DISPATCHER_H__
#define __NETWORKMANAGER_DISPATCHER_H__ #define __NM_DISPATCHER_H__
#include <stdio.h>
#include "nm-connection.h" #include "nm-connection.h"
typedef enum { typedef enum {
DISPATCHER_ACTION_HOSTNAME, NM_DISPATCHER_ACTION_HOSTNAME,
DISPATCHER_ACTION_PRE_UP, NM_DISPATCHER_ACTION_PRE_UP,
DISPATCHER_ACTION_UP, NM_DISPATCHER_ACTION_UP,
DISPATCHER_ACTION_PRE_DOWN, NM_DISPATCHER_ACTION_PRE_DOWN,
DISPATCHER_ACTION_DOWN, NM_DISPATCHER_ACTION_DOWN,
DISPATCHER_ACTION_VPN_PRE_UP, NM_DISPATCHER_ACTION_VPN_PRE_UP,
DISPATCHER_ACTION_VPN_UP, NM_DISPATCHER_ACTION_VPN_UP,
DISPATCHER_ACTION_VPN_PRE_DOWN, NM_DISPATCHER_ACTION_VPN_PRE_DOWN,
DISPATCHER_ACTION_VPN_DOWN, NM_DISPATCHER_ACTION_VPN_DOWN,
DISPATCHER_ACTION_DHCP4_CHANGE, NM_DISPATCHER_ACTION_DHCP4_CHANGE,
DISPATCHER_ACTION_DHCP6_CHANGE, NM_DISPATCHER_ACTION_DHCP6_CHANGE,
DISPATCHER_ACTION_CONNECTIVITY_CHANGE NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE
} DispatcherAction; } 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, gboolean nm_dispatcher_call_hostname (NMDispatcherFunc callback,
NMSettingsConnection *settings_connection, gpointer user_data,
NMConnection *applied_connection, guint *out_call_id);
NMDevice *device,
DispatcherFunc callback,
gpointer user_data,
guint *out_call_id);
gboolean nm_dispatcher_call_sync (DispatcherAction action, gboolean nm_dispatcher_call_device (NMDispatcherAction action,
NMSettingsConnection *settings_connection, NMDevice *device,
NMConnection *applied_connection, NMActRequest *act_request,
NMDevice *device); 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, NMSettingsConnection *settings_connection,
NMConnection *applied_connection, NMConnection *applied_connection,
NMDevice *parent_device, NMDevice *parent_device,
@@ -64,11 +64,11 @@ gboolean nm_dispatcher_call_vpn (DispatcherAction action,
NMProxyConfig *vpn_proxy_config, NMProxyConfig *vpn_proxy_config,
NMIP4Config *vpn_ip4_config, NMIP4Config *vpn_ip4_config,
NMIP6Config *vpn_ip6_config, NMIP6Config *vpn_ip6_config,
DispatcherFunc callback, NMDispatcherFunc callback,
gpointer user_data, gpointer user_data,
guint *out_call_id); guint *out_call_id);
gboolean nm_dispatcher_call_vpn_sync (DispatcherAction action, gboolean nm_dispatcher_call_vpn_sync (NMDispatcherAction action,
NMSettingsConnection *settings_connection, NMSettingsConnection *settings_connection,
NMConnection *applied_connection, NMConnection *applied_connection,
NMDevice *parent_device, NMDevice *parent_device,
@@ -77,11 +77,14 @@ gboolean nm_dispatcher_call_vpn_sync (DispatcherAction action,
NMIP4Config *vpn_ip4_config, NMIP4Config *vpn_ip4_config,
NMIP6Config *vpn_ip6_config); NMIP6Config *vpn_ip6_config);
gboolean nm_dispatcher_call_connectivity (DispatcherAction action, gboolean nm_dispatcher_call_connectivity (NMConnectivityState state,
NMConnectivityState state); NMDispatcherFunc callback,
gpointer user_data,
guint *out_call_id);
void nm_dispatcher_call_cancel (guint call_id); void nm_dispatcher_call_cancel (guint call_id);
void nm_dispatcher_init (void); 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, const char *specific_object,
NMDevice *device, NMDevice *device,
NMAuthSubject *subject, NMAuthSubject *subject,
NMActivationType activation_type,
GError **error); GError **error);
static void policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data); 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_default_changed, self);
g_signal_handlers_disconnect_by_func (active, active_connection_parent_active, self); g_signal_handlers_disconnect_by_func (active, active_connection_parent_active, self);
if ( nm_active_connection_get_assumed (active) if ( (connection = nm_active_connection_get_settings_connection (active))
&& (connection = nm_active_connection_get_settings_connection (active)) && nm_settings_connection_get_volatile (connection))
&& nm_settings_connection_get_nm_generated_assumed (connection))
g_object_ref (connection); g_object_ref (connection);
else else
connection = NULL; connection = NULL;
nm_exported_object_clear_and_unexport (&active); nm_exported_object_clear_and_unexport (&active);
if ( connection if (connection) {
&& nm_settings_has_connection (priv->settings, connection)) { if (nm_settings_has_connection (priv->settings, connection)) {
_LOGD (LOGD_DEVICE, "assumed connection disconnected. Deleting generated connection '%s' (%s)", _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_get_id (connection), nm_settings_connection_get_uuid (connection));
nm_settings_connection_delete (NM_SETTINGS_CONNECTION (connection), NULL, NULL); nm_settings_connection_delete (connection, NULL, NULL);
}
g_object_unref (connection); g_object_unref (connection);
} }
} }
@@ -395,46 +396,60 @@ nm_manager_get_active_connections (NMManager *manager)
} }
static NMActiveConnection * 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; 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) priv = NM_MANAGER_GET_PRIVATE (self);
uuid = nm_connection_get_uuid (connection);
for (iter = priv->active_connections; iter; iter = iter->next) { for (iter = priv->active_connections; iter; iter = iter->next) {
NMActiveConnection *ac = iter->data; NMActiveConnection *ac = iter->data;
NMSettingsConnection *con; NMSettingsConnection *con;
con = nm_active_connection_get_settings_connection (ac); con = nm_active_connection_get_settings_connection (ac);
if (settings_connection && con != settings_connection)
/* depending on whether we have a NMSettingsConnection or a NMConnection, continue;
* we lookup by UUID or by reference. */ if (uuid && !nm_streq0 (uuid, nm_connection_get_uuid (NM_CONNECTION (con))))
if (is_settings_connection) { continue;
if (con != (NMSettingsConnection *) connection) if (nm_active_connection_get_state (ac) > max_state)
continue; continue;
} else { return ac;
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;
} }
return NULL; 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 static gboolean
_get_activatable_connections_filter (NMSettings *settings, _get_activatable_connections_filter (NMSettings *settings,
NMSettingsConnection *connection, NMSettingsConnection *connection,
gpointer user_data) 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. /* Filter out connections that are already active.
@@ -800,13 +815,17 @@ find_best_device_state (NMManager *manager, gboolean *force_connectivity_check)
} }
break; break;
case NM_ACTIVE_CONNECTION_STATE_ACTIVATING: 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) if (best_state != NM_STATE_CONNECTED_GLOBAL)
best_state = NM_STATE_CONNECTING; best_state = NM_STATE_CONNECTING;
} }
break; break;
case NM_ACTIVE_CONNECTION_STATE_DEACTIVATING: 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) if (best_state < NM_STATE_DISCONNECTING)
best_state = NM_STATE_DISCONNECTING; best_state = NM_STATE_DISCONNECTING;
} }
@@ -1019,8 +1038,10 @@ remove_device (NMManager *self,
if (unmanage) { if (unmanage) {
if (quitting) if (quitting)
nm_device_set_unmanaged_by_quitting (device); 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); 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)) { } else if (quitting && nm_config_get_configure_and_quit (priv->config)) {
nm_device_spawn_iface_helper (device); nm_device_spawn_iface_helper (device);
} }
@@ -1696,9 +1717,6 @@ done:
static gboolean static gboolean
match_connection_filter (NMConnection *connection, gpointer user_data) 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); 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: * get_existing_connection:
* @manager: #NMManager instance * @manager: #NMManager instance
* @device: #NMDevice 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. * @out_generated: (allow-none): return TRUE, if the connection was generated.
* *
* Returns: a #NMSettingsConnection to be assumed by the device, or %NULL if * Returns: a #NMSettingsConnection to be assumed by the device, or %NULL if
* the device does not support assuming existing connections. * the device does not support assuming existing connections.
*/ */
static NMSettingsConnection * 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); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
gs_free_slist GSList *connections = NULL;
NMConnection *connection = NULL; NMConnection *connection = NULL;
NMSettingsConnection *matched;
NMSettingsConnection *added = NULL; NMSettingsConnection *added = NULL;
GError *error = NULL; GError *error = NULL;
NMDevice *master = NULL; NMDevice *master = NULL;
int ifindex = nm_device_get_ifindex (device); int ifindex = nm_device_get_ifindex (device);
NMSettingsConnection *matched;
if (out_generated) if (out_generated)
*out_generated = FALSE; *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 * When no configured connection matches the generated connection, we keep
* the generated connection instead. * the generated connection instead.
*/ */
{ if ( assume_connection_uuid
gs_free NMSettingsConnection **cons = NULL; && (matched = nm_settings_get_connection_by_uuid (priv->settings, assume_connection_uuid))
guint i, len; && !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 matched = NM_SETTINGS_CONNECTION (nm_utils_match_connection (connections,
* and don't bother for now. */ connection,
cons = nm_manager_get_activatable_connections (self, &len, FALSE); nm_device_has_carrier (device),
for (i = len; i > 0; ) nm_device_get_ip4_route_metric (device),
connections = g_slist_prepend (connections, cons[--i]); nm_device_get_ip6_route_metric (device),
connections = g_slist_sort (connections, (GCompareFunc) nm_settings_connection_cmp_timestamp); match_connection_filter,
} device));
matched = NM_SETTINGS_CONNECTION (nm_utils_match_connection (connections, if (matched) {
connection, _LOGI (LOGD_DEVICE, "(%s): found matching connection '%s'",
nm_device_has_carrier (device), nm_device_get_iface (device),
nm_device_get_ip4_route_metric (device), nm_settings_connection_get_id (matched));
nm_device_get_ip6_route_metric (device), g_object_unref (connection);
match_connection_filter, return matched;
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'", _LOGD (LOGD_DEVICE, "(%s): generated connection '%s'",
@@ -1799,7 +1821,7 @@ get_existing_connection (NMManager *self, NMDevice *device, gboolean *out_genera
if (added) { if (added) {
nm_settings_connection_set_flags (NM_SETTINGS_CONNECTION (added), nm_settings_connection_set_flags (NM_SETTINGS_CONNECTION (added),
NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED | NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED |
NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED, NM_SETTINGS_CONNECTION_FLAGS_VOLATILE,
TRUE); TRUE);
if (out_generated) if (out_generated)
*out_generated = TRUE; *out_generated = TRUE;
@@ -1816,54 +1838,13 @@ get_existing_connection (NMManager *self, NMDevice *device, gboolean *out_genera
} }
static gboolean static gboolean
assume_connection (NMManager *self, NMDevice *device, NMSettingsConnection *connection) recheck_assume_connection (NMManager *self,
{ NMDevice *device,
NMActiveConnection *active, *master_ac; const char *assume_connection_uuid)
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)
{ {
NMSettingsConnection *connection; NMSettingsConnection *connection;
gboolean was_unmanaged = FALSE, success, generated = FALSE; gboolean was_unmanaged = FALSE;
gboolean generated = FALSE;
NMDeviceState state; NMDeviceState state;
g_return_val_if_fail (NM_IS_MANAGER (self), FALSE); 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) if (state > NM_DEVICE_STATE_DISCONNECTED)
return FALSE; 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) { if (!connection) {
_LOGD (LOGD_DEVICE, "(%s): can't assume; no connection", _LOGD (LOGD_DEVICE, "(%s): can't assume; no connection",
nm_device_get_iface (device)); nm_device_get_iface (device));
return FALSE; 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) { if (state == NM_DEVICE_STATE_UNMANAGED) {
was_unmanaged = TRUE; was_unmanaged = TRUE;
nm_device_state_changed (device, nm_device_state_changed (device,
NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_UNAVAILABLE,
NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
} }
if (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE) {
success = assume_connection (self, device, connection); nm_device_state_changed (device,
if (!success) { NM_DEVICE_STATE_DISCONNECTED,
if (was_unmanaged) { NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
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);
}
} }
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 static void
recheck_assume_connection_cb (NMDevice *device, gpointer user_data) recheck_assume_connection_cb (NMDevice *device, gpointer user_data)
{ {
recheck_assume_connection (user_data, device); recheck_assume_connection (user_data, device, NULL);
} }
static void static void
@@ -1976,7 +2004,10 @@ device_realized (NMDevice *device,
} }
static void 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_MANAGER (self));
g_return_if_fail (NM_IS_DEVICE (device)); 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)) if (!nm_device_get_managed (device, FALSE))
return; return;
if (recheck_assume_connection (self, device)) if (recheck_assume_connection (self, device, connection_uuid_to_assume))
return; return;
/* if we failed to assume a connection for the managed device, but the device /* 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)); 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); add_device (self, device, NULL);
_device_realize_finish (self, device, NULL); _device_realize_finish (self, device, NULL, NULL);
} else { } else {
_LOGW (LOGD_DEVICE, "(%s): failed to realize device: %s", _LOGW (LOGD_DEVICE, "(%s): failed to realize device: %s",
nm_device_get_iface (device), error->message); nm_device_get_iface (device), error->message);
@@ -2205,9 +2240,13 @@ platform_link_added (NMManager *self,
* device with the link's name. * device with the link's name.
*/ */
return; 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 */ /* Success */
_device_realize_finish (self, candidate, plink); _device_realize_finish (self, candidate, plink, NULL);
return; return;
} }
@@ -2257,10 +2296,29 @@ platform_link_added (NMManager *self,
if (device) { if (device) {
gs_free_error GError *error = NULL; 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); 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 { } else {
_LOGW (LOGD_DEVICE, "%s: failed to realize device: %s", _LOGW (LOGD_DEVICE, "%s: failed to realize device: %s",
plink->name, error->message); plink->name, error->message);
@@ -2407,28 +2465,22 @@ nm_manager_get_device_paths (NMManager *self)
return (const char **) g_ptr_array_free (paths, FALSE); 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 * static NMDevice *
nm_manager_get_best_device_for_connection (NMManager *self, nm_manager_get_best_device_for_connection (NMManager *self,
NMConnection *connection, NMConnection *connection,
gboolean for_user_request) gboolean for_user_request)
{ {
const GSList *devices, *iter; const GSList *devices, *iter;
NMDevice *act_device = nm_manager_get_connection_device (self, connection); NMActiveConnection *ac;
NMDevice *act_device;
NMDeviceCheckConAvailableFlags flags; NMDeviceCheckConAvailableFlags flags;
if (act_device) ac = active_connection_find_first_by_connection (self, connection);
return act_device; 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; 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; *out_master_connection = master_connection;
if (out_master_device) if (out_master_device)
*out_master_device = master_device; *out_master_device = master_device;
if (out_master_ac && master_connection) if (out_master_ac && master_connection) {
*out_master_ac = find_ac_for_connection (self, NM_CONNECTION (master_connection)); *out_master_ac = active_connection_find_first (self, master_connection, NULL,
NM_ACTIVE_CONNECTION_STATE_DEACTIVATING);
}
if (master_device || master_connection) if (master_device || master_connection)
return TRUE; return TRUE;
@@ -2735,6 +2789,7 @@ ensure_master_active_connection (NMManager *self,
NULL, NULL,
master_device, master_device,
subject, subject,
NM_ACTIVATION_TYPE_MANAGED,
error); error);
return master_ac; return master_ac;
} }
@@ -2780,6 +2835,7 @@ ensure_master_active_connection (NMManager *self,
NULL, NULL,
candidate, candidate,
subject, subject,
NM_ACTIVATION_TYPE_MANAGED,
error); error);
return master_ac; return master_ac;
} }
@@ -2926,6 +2982,7 @@ autoconnect_slaves (NMManager *self,
NULL, NULL,
nm_manager_get_best_device_for_connection (self, NM_CONNECTION (slave_connection), FALSE), nm_manager_get_best_device_for_connection (self, NM_CONNECTION (slave_connection), FALSE),
subject, subject,
NM_ACTIVATION_TYPE_MANAGED,
&local_err); &local_err);
if (local_err) { if (local_err) {
_LOGW (LOGD_CORE, "Slave connection activation failed: %s", local_err->message); _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) _internal_activate_device (NMManager *self, NMActiveConnection *active, GError **error)
{ {
NMDevice *device, *existing, *master_device = NULL; NMDevice *device, *existing, *master_device = NULL;
NMActiveConnection *existing_ac;
NMConnection *applied; NMConnection *applied;
NMSettingsConnection *connection; NMSettingsConnection *connection;
NMSettingsConnection *master_connection = NULL; NMSettingsConnection *master_connection = NULL;
@@ -3083,7 +3141,8 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
return FALSE; 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) { if (!parent_ac) {
g_prefix_error (error, "%s failed to activate parent: ", nm_device_get_iface (device)); g_prefix_error (error, "%s failed to activate parent: ", nm_device_get_iface (device));
return FALSE; 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)); autoconnect_slaves (self, connection, device, nm_active_connection_get_subject (active));
/* Disconnect the connection if connected or queued on another device */ /* Disconnect the connection if connected or queued on another device */
existing = nm_manager_get_connection_device (self, NM_CONNECTION (connection)); existing_ac = active_connection_find_first (self, connection, NULL, NM_ACTIVE_CONNECTION_STATE_DEACTIVATING);
if (existing) if (existing_ac) {
nm_device_steal_connection (existing, connection); 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 the device is there, we can ready it for the activation. */
if (nm_device_is_real (device)) if (nm_device_is_real (device))
@@ -3278,6 +3340,7 @@ _new_active_connection (NMManager *self,
const char *specific_object, const char *specific_object,
NMDevice *device, NMDevice *device,
NMAuthSubject *subject, NMAuthSubject *subject,
NMActivationType activation_type,
GError **error) GError **error)
{ {
NMSettingsConnection *settings_connection = NULL; NMSettingsConnection *settings_connection = NULL;
@@ -3288,7 +3351,7 @@ _new_active_connection (NMManager *self,
g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL); g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL);
/* Can't create new AC for already-active connection */ /* 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)) { if (NM_IS_VPN_CONNECTION (existing_ac)) {
g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE, g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE,
"Connection '%s' is already active", "Connection '%s' is already active",
@@ -3306,6 +3369,8 @@ _new_active_connection (NMManager *self,
settings_connection = (NMSettingsConnection *) connection; settings_connection = (NMSettingsConnection *) connection;
if (is_vpn) { if (is_vpn) {
if (activation_type != NM_ACTIVATION_TYPE_MANAGED)
g_return_val_if_reached (NULL);
return _new_vpn_active_connection (self, return _new_vpn_active_connection (self,
settings_connection, settings_connection,
specific_object, specific_object,
@@ -3317,6 +3382,7 @@ _new_active_connection (NMManager *self,
applied, applied,
specific_object, specific_object,
subject, subject,
activation_type,
device); device);
} }
@@ -3369,6 +3435,8 @@ _internal_activation_auth_done (NMActiveConnection *active,
* @specific_object: the specific object path, if any, for the activation * @specific_object: the specific object path, if any, for the activation
* @device: the #NMDevice to activate @connection on * @device: the #NMDevice to activate @connection on
* @subject: the subject which requested activation * @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 * @error: return location for an error
* *
* Begins a new internally-initiated activation of @connection on @device. * Begins a new internally-initiated activation of @connection on @device.
@@ -3388,6 +3456,7 @@ nm_manager_activate_connection (NMManager *self,
const char *specific_object, const char *specific_object,
NMDevice *device, NMDevice *device,
NMAuthSubject *subject, NMAuthSubject *subject,
NMActivationType activation_type,
GError **error) GError **error)
{ {
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
@@ -3434,6 +3503,7 @@ nm_manager_activate_connection (NMManager *self,
specific_object, specific_object,
device, device,
subject, subject,
activation_type,
error); error);
if (active) { if (active) {
priv->authorizing_connections = g_slist_prepend (priv->authorizing_connections, active); priv->authorizing_connections = g_slist_prepend (priv->authorizing_connections, active);
@@ -3677,6 +3747,7 @@ impl_manager_activate_connection (NMManager *self,
specific_object_path, specific_object_path,
device, device,
subject, subject,
NM_ACTIVATION_TYPE_MANAGED,
&error); &error);
if (!active) if (!active)
goto error; goto error;
@@ -3896,6 +3967,7 @@ impl_manager_add_and_activate_connection (NMManager *self,
specific_object_path, specific_object_path,
device, device,
subject, subject,
NM_ACTIVATION_TYPE_MANAGED,
&error); &error);
if (!active) if (!active)
goto error; goto error;

View File

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

View File

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

View File

@@ -55,6 +55,22 @@ typedef struct _NMSleepMonitor NMSleepMonitor;
typedef struct _NMLldpListener NMLldpListener; typedef struct _NMLldpListener NMLldpListener;
typedef struct _NMConfigDeviceStateData NMConfigDeviceStateData; 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 { typedef enum {
/* In priority order; higher number == higher priority */ /* In priority order; higher number == higher priority */

View File

@@ -498,7 +498,7 @@ set_unsaved (NMSettingsConnection *self, gboolean now_unsaved)
else { else {
flags &= ~(NM_SETTINGS_CONNECTION_FLAGS_UNSAVED | flags &= ~(NM_SETTINGS_CONNECTION_FLAGS_UNSAVED |
NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED | 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); 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))); _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_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); FALSE);
/* Cache the just-updated system secrets in case something calls /* 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 * @self: an #NMSettingsConnection
* *
* Gets the "nm-generated-assumed" flag on @self. * Gets the "volatile" flag on @self.
* *
* The connection is a generated connection especially * The connection is marked as volatile and will be removed when
* generated for connection assumption. * it disconnects.
*/ */
gboolean 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 gboolean

View File

@@ -58,9 +58,9 @@
* @NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED: A connection is "nm-generated" if * @NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED: A connection is "nm-generated" if
* it was generated by NetworkManger. If the connection gets modified or saved * 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. * 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" * @NM_SETTINGS_CONNECTION_FLAGS_VOLATILE: The connection will be deleted
* connection that was specifically created for connection assumption. "nm-generated-assumed" * when it disconnects. That is for in-memory connections (unsaved), which are
* implies "nm-generated". * currently active but cleanup on disconnect.
* @NM_SETTINGS_CONNECTION_FLAGS_ALL: special mask, for all known flags * @NM_SETTINGS_CONNECTION_FLAGS_ALL: special mask, for all known flags
* *
* #NMSettingsConnection flags. * #NMSettingsConnection flags.
@@ -70,7 +70,7 @@ typedef enum
NM_SETTINGS_CONNECTION_FLAGS_NONE = 0x00, NM_SETTINGS_CONNECTION_FLAGS_NONE = 0x00,
NM_SETTINGS_CONNECTION_FLAGS_UNSAVED = 0x01, NM_SETTINGS_CONNECTION_FLAGS_UNSAVED = 0x01,
NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED = 0x02, 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_LAST,
NM_SETTINGS_CONNECTION_FLAGS_ALL = ((__NM_SETTINGS_CONNECTION_FLAGS_LAST - 1) << 1) - 1, 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_can_autoconnect (NMSettingsConnection *self);
gboolean nm_settings_connection_get_nm_generated (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); gboolean nm_settings_connection_get_ready (NMSettingsConnection *self);
void nm_settings_connection_set_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); g_free (priv->hostname.value);
priv->hostname.value = g_strdup (hostname); priv->hostname.value = g_strdup (hostname);
_notify (self, PROP_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); g_variant_unref (v_hostname);

View File

@@ -309,6 +309,30 @@ _match_connection_new (void)
return connection; 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 static void
test_connection_match_basic (void) test_connection_match_basic (void)
{ {
@@ -320,7 +344,7 @@ test_connection_match_basic (void)
copy = nm_simple_connection_new_clone (orig); copy = nm_simple_connection_new_clone (orig);
connections = g_slist_append (connections, copy); 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); g_assert (matched == copy);
/* Now change a material property like IPv4 method and ensure matching fails */ /* 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), g_object_set (G_OBJECT (s_ip4),
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL,
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 == NULL); g_assert (matched == NULL);
g_slist_free (connections); g_slist_free (connections);
@@ -365,7 +389,7 @@ test_connection_match_ip6_method (void)
NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE,
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_assert (matched == copy);
g_slist_free (connections); 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, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
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_assert (matched == copy);
g_slist_free (connections); 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, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
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_assert (matched == copy);
g_slist_free (connections); g_slist_free (connections);
@@ -469,11 +493,11 @@ test_connection_match_ip4_method (void)
NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE,
NULL); 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); g_assert (matched == copy);
/* Ensure when carrier=true matching fails */ /* 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_assert (matched == NULL);
g_slist_free (connections); g_slist_free (connections);
@@ -507,7 +531,7 @@ test_connection_match_interface_name (void)
NM_SETTING_CONNECTION_INTERFACE_NAME, NULL, NM_SETTING_CONNECTION_INTERFACE_NAME, NULL,
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_assert (matched == copy);
g_slist_free (connections); g_slist_free (connections);
@@ -544,7 +568,7 @@ test_connection_match_wired (void)
NM_SETTING_WIRED_S390_NETTYPE, "qeth", NM_SETTING_WIRED_S390_NETTYPE, "qeth",
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_assert (matched == copy);
g_slist_free (connections); g_slist_free (connections);
@@ -576,7 +600,7 @@ test_connection_match_wired2 (void)
* the connections match. It can happen if assuming VLAN devices. */ * the connections match. It can happen if assuming VLAN devices. */
nm_connection_remove_setting (orig, NM_TYPE_SETTING_WIRED); 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_assert (matched == copy);
g_slist_free (connections); 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", NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "52:54:00:ab:db:23",
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 == fuzzy); g_assert (matched == fuzzy);
exact = nm_simple_connection_new_clone (orig); 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", NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "52:54:00:ab:db:23",
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 == exact); g_assert (matched == exact);
g_object_set (G_OBJECT (s_wired), g_object_set (G_OBJECT (s_wired),
NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "52:54:00:ab:db:24", NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "52:54:00:ab:db:24",
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 == fuzzy); g_assert (matched == fuzzy);
g_slist_free (connections); 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_setting_ip_config_add_address (s_ip4, nm_addr);
nm_ip_address_unref (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_assert (matched != copy);
g_slist_free (connections); g_slist_free (connections);
@@ -725,7 +749,7 @@ test_connection_no_match_vlan (void)
NM_SETTING_VLAN_FLAGS, 0, NM_SETTING_VLAN_FLAGS, 0,
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_assert (matched != copy);
/* Check that the connections do not match if VLAN priorities differ */ /* 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); 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"); 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_assert (matched != copy);
g_slist_free (connections); 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); nmtst_setting_ip_config_add_route (s_ip4, "172.25.17.0", 24, "10.0.0.3", 20);
/* Try to match the connections */ /* 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); 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); 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 */ /* 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); 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); 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); 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 */ /* 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); 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); g_assert (matched == copy);
} }

View File

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