mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-09 16:40:37 +01:00
l3cfg: notify NML3Cfg about NMPlatform changes in an idle handler
We need to react to platform changes. Also, we usually want to delay the reaction to an idle handler. Instead of subscribing each NML3Cfg instance itself to platform changes, let only NMNetns do that. The goal is of course that each platform event only needs to notify the NML3Cfg instance, which collects the events and schedules them on the idle handler.
This commit is contained in:
parent
ea1f0fc0a6
commit
b5c563329a
4 changed files with 92 additions and 2 deletions
|
|
@ -35,6 +35,13 @@ G_DEFINE_TYPE (NML3Cfg, nm_l3cfg, G_TYPE_OBJECT)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
_nm_l3cfg_notify_platform_change_on_idle (NML3Cfg *self, guint32 obj_type_flags)
|
||||
{
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
set_property (GObject *object,
|
||||
guint prop_id,
|
||||
|
|
|
|||
|
|
@ -28,6 +28,12 @@ GType nm_l3cfg_get_type (void);
|
|||
|
||||
NML3Cfg *nm_l3cfg_new (NMNetns *netns, int ifindex);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void _nm_l3cfg_notify_platform_change_on_idle (NML3Cfg *self, guint32 obj_type_flags);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline int
|
||||
nm_l3cfg_get_ifindex (const NML3Cfg *self)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,10 +23,13 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
|
|||
);
|
||||
|
||||
typedef struct {
|
||||
NMNetns *_self_signal_user_data;
|
||||
NMPlatform *platform;
|
||||
NMPNetns *platform_netns;
|
||||
NMPRulesManager *rules_manager;
|
||||
GHashTable *l3cfgs;
|
||||
CList l3cfg_signal_pending_lst_head;
|
||||
guint signal_pending_idle_id;
|
||||
} NMNetnsPrivate;
|
||||
|
||||
struct _NMNetns {
|
||||
|
|
@ -88,7 +91,9 @@ nm_netns_get_multi_idx (NMNetns *self)
|
|||
|
||||
typedef struct {
|
||||
int ifindex;
|
||||
guint32 signal_pending_flag;
|
||||
NML3Cfg *l3cfg;
|
||||
CList signal_pending_lst;
|
||||
} L3CfgData;
|
||||
|
||||
static void
|
||||
|
|
@ -96,6 +101,8 @@ _l3cfg_data_free (gpointer ptr)
|
|||
{
|
||||
L3CfgData *l3cfg_data = ptr;
|
||||
|
||||
c_list_unlink_stale (&l3cfg_data->signal_pending_lst);
|
||||
|
||||
nm_g_slice_free (l3cfg_data);
|
||||
}
|
||||
|
||||
|
|
@ -140,8 +147,9 @@ nm_netns_access_l3cfg (NMNetns *self,
|
|||
|
||||
l3cfg_data = g_slice_new (L3CfgData);
|
||||
*l3cfg_data = (L3CfgData) {
|
||||
.ifindex = ifindex,
|
||||
.l3cfg = nm_l3cfg_new (self, ifindex),
|
||||
.ifindex = ifindex,
|
||||
.l3cfg = nm_l3cfg_new (self, ifindex),
|
||||
.signal_pending_lst = C_LIST_INIT (l3cfg_data->signal_pending_lst),
|
||||
};
|
||||
|
||||
if (!g_hash_table_add (priv->l3cfgs, l3cfg_data))
|
||||
|
|
@ -160,6 +168,52 @@ nm_netns_access_l3cfg (NMNetns *self,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
_platform_signal_on_idle_cb (gpointer user_data)
|
||||
{
|
||||
gs_unref_object NMNetns *self = g_object_ref (NM_NETNS (user_data));
|
||||
NMNetnsPrivate *priv = NM_NETNS_GET_PRIVATE (self);
|
||||
L3CfgData *l3cfg_data;
|
||||
|
||||
while ((l3cfg_data = c_list_first_entry (&priv->l3cfg_signal_pending_lst_head, L3CfgData, signal_pending_lst))) {
|
||||
c_list_unlink (&l3cfg_data->signal_pending_lst);
|
||||
_nm_l3cfg_notify_platform_change_on_idle (l3cfg_data->l3cfg,
|
||||
nm_steal_int (&l3cfg_data->signal_pending_flag));
|
||||
}
|
||||
|
||||
priv->signal_pending_idle_id = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
_platform_signal_cb (NMPlatform *platform,
|
||||
int obj_type_i,
|
||||
int ifindex,
|
||||
gconstpointer platform_object,
|
||||
int change_type_i,
|
||||
NMNetns **p_self)
|
||||
{
|
||||
NMNetns *self = NM_NETNS (*p_self);
|
||||
NMNetnsPrivate *priv = NM_NETNS_GET_PRIVATE (self);
|
||||
const NMPObjectType obj_type = obj_type_i;
|
||||
L3CfgData *l3cfg_data;
|
||||
|
||||
l3cfg_data = g_hash_table_lookup (priv->l3cfgs, &ifindex);
|
||||
if (!l3cfg_data)
|
||||
return;
|
||||
|
||||
l3cfg_data->signal_pending_flag |= nmp_object_type_to_flags (obj_type);
|
||||
|
||||
if (!c_list_is_empty (&l3cfg_data->signal_pending_lst))
|
||||
return;
|
||||
|
||||
c_list_link_tail (&priv->l3cfg_signal_pending_lst_head, &l3cfg_data->signal_pending_lst);
|
||||
if (priv->signal_pending_idle_id == 0)
|
||||
priv->signal_pending_idle_id = g_idle_add (_platform_signal_on_idle_cb, self);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
|
|
@ -186,6 +240,10 @@ set_property (GObject *object, guint prop_id,
|
|||
static void
|
||||
nm_netns_init (NMNetns *self)
|
||||
{
|
||||
NMNetnsPrivate *priv = NM_NETNS_GET_PRIVATE (self);
|
||||
|
||||
priv->_self_signal_user_data = self;
|
||||
c_list_init (&priv->l3cfg_signal_pending_lst_head);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -226,6 +284,8 @@ constructed (GObject *object)
|
|||
NMP_RULES_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG);
|
||||
|
||||
G_OBJECT_CLASS (nm_netns_parent_class)->constructed (object);
|
||||
|
||||
g_signal_connect (priv->platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (_platform_signal_cb), &priv->_self_signal_user_data);
|
||||
}
|
||||
|
||||
NMNetns *
|
||||
|
|
@ -243,6 +303,12 @@ dispose (GObject *object)
|
|||
NMNetnsPrivate *priv = NM_NETNS_GET_PRIVATE (self);
|
||||
|
||||
nm_assert (nm_g_hash_table_size (priv->l3cfgs) == 0);
|
||||
nm_assert (c_list_is_empty (&priv->l3cfg_signal_pending_lst_head));
|
||||
|
||||
nm_clear_g_source (&priv->signal_pending_idle_id);
|
||||
|
||||
if (priv->platform)
|
||||
g_signal_handlers_disconnect_by_data (priv->platform, &priv->_self_signal_user_data);
|
||||
|
||||
g_clear_object (&priv->platform);
|
||||
g_clear_pointer (&priv->l3cfgs, g_hash_table_unref);
|
||||
|
|
|
|||
|
|
@ -236,6 +236,17 @@ typedef enum {
|
|||
NMP_OBJECT_TYPE_MAX = __NMP_OBJECT_TYPE_LAST - 1,
|
||||
} NMPObjectType;
|
||||
|
||||
static inline guint32
|
||||
nmp_object_type_to_flags (NMPObjectType obj_type)
|
||||
{
|
||||
G_STATIC_ASSERT_EXPR (NMP_OBJECT_TYPE_MAX < 32);
|
||||
|
||||
nm_assert (_NM_INT_NOT_NEGATIVE (obj_type));
|
||||
nm_assert (obj_type < NMP_OBJECT_TYPE_MAX);
|
||||
|
||||
return ((guint32) 1u) << obj_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* NMIPConfigMergeFlags:
|
||||
* @NM_IP_CONFIG_MERGE_DEFAULT: no flags set
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue