mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-09 06:10:29 +01:00
l3cfg: add nm_l3cfg_commit_type*() API for tracking the level for committing changes
NML3Cfg manages one ifindex. In the future, we may want that multiple NMDevice and/or NMVpnConnection instances independently contribute their NML3ConfigData to the NML3Cfg instance. That means, at any time somebody may want to call nm_l3cfg_platform_commit() to apply the changes. Even ACD internally may do that, when configuration changes (e.g. an IP address passes ACD check). We thus need to know whether we are assuming, updating or reapplying the settings. Add API so users can register their "commit" preference.
This commit is contained in:
parent
4c07d34505
commit
47e2ff0a71
2 changed files with 143 additions and 4 deletions
119
src/nm-l3cfg.c
119
src/nm-l3cfg.c
|
|
@ -95,6 +95,11 @@ typedef struct {
|
|||
bool announcing_failed_is_retrying:1;
|
||||
} AcdData;
|
||||
|
||||
struct _NML3CfgCommitTypeHandle {
|
||||
CList commit_type_lst;
|
||||
NML3CfgCommitType commit_type;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const NML3ConfigData *l3cd;
|
||||
NML3ConfigMergeFlags merge_flags;
|
||||
|
|
@ -131,6 +136,8 @@ typedef struct _NML3CfgPrivate {
|
|||
GArray *l3_config_datas;
|
||||
const NML3ConfigData *combined_l3cd;
|
||||
|
||||
CList commit_type_lst_head;
|
||||
|
||||
GHashTable *routes_temporary_not_available_hash;
|
||||
|
||||
GHashTable *externally_removed_objs_hash;
|
||||
|
|
@ -231,6 +238,8 @@ static AcdData *_l3_acd_data_find (NML3Cfg *self,
|
|||
|
||||
static
|
||||
NM_UTILS_ENUM2STR_DEFINE (_l3_cfg_commit_type_to_string, NML3CfgCommitType,
|
||||
NM_UTILS_ENUM2STR (NM_L3_CFG_COMMIT_TYPE_AUTO, "auto"),
|
||||
NM_UTILS_ENUM2STR (NM_L3_CFG_COMMIT_TYPE_NONE, "none"),
|
||||
NM_UTILS_ENUM2STR (NM_L3_CFG_COMMIT_TYPE_ASSUME, "assume"),
|
||||
NM_UTILS_ENUM2STR (NM_L3_CFG_COMMIT_TYPE_UPDATE, "update"),
|
||||
NM_UTILS_ENUM2STR (NM_L3_CFG_COMMIT_TYPE_REAPPLY, "reapply"),
|
||||
|
|
@ -878,7 +887,7 @@ _l3_acd_platform_commit_acd_update (NML3Cfg *self)
|
|||
_LOGT ("acd: acd update now");
|
||||
self->priv.changed_configs = TRUE;
|
||||
nm_l3cfg_platform_commit (self,
|
||||
NM_L3_CFG_COMMIT_TYPE_UPDATE,
|
||||
NM_L3_CFG_COMMIT_TYPE_AUTO,
|
||||
AF_INET,
|
||||
NULL);
|
||||
}
|
||||
|
|
@ -2756,7 +2765,8 @@ _platform_commit (NML3Cfg *self,
|
|||
gboolean success = TRUE;
|
||||
|
||||
nm_assert (NM_IS_L3CFG (self));
|
||||
nm_assert (NM_IN_SET (commit_type, NM_L3_CFG_COMMIT_TYPE_REAPPLY,
|
||||
nm_assert (NM_IN_SET (commit_type, NM_L3_CFG_COMMIT_TYPE_NONE,
|
||||
NM_L3_CFG_COMMIT_TYPE_REAPPLY,
|
||||
NM_L3_CFG_COMMIT_TYPE_UPDATE,
|
||||
NM_L3_CFG_COMMIT_TYPE_ASSUME));
|
||||
nm_assert_addr_family (addr_family);
|
||||
|
|
@ -2873,7 +2883,9 @@ nm_l3cfg_platform_commit (NML3Cfg *self,
|
|||
gboolean acd_was_pending;
|
||||
|
||||
g_return_val_if_fail (NM_IS_L3CFG (self), FALSE);
|
||||
nm_assert (NM_IN_SET (commit_type, NM_L3_CFG_COMMIT_TYPE_REAPPLY,
|
||||
nm_assert (NM_IN_SET (commit_type, NM_L3_CFG_COMMIT_TYPE_AUTO,
|
||||
NM_L3_CFG_COMMIT_TYPE_NONE,
|
||||
NM_L3_CFG_COMMIT_TYPE_REAPPLY,
|
||||
NM_L3_CFG_COMMIT_TYPE_UPDATE,
|
||||
NM_L3_CFG_COMMIT_TYPE_ASSUME));
|
||||
|
||||
|
|
@ -2884,6 +2896,9 @@ nm_l3cfg_platform_commit (NML3Cfg *self,
|
|||
if (NM_IN_SET (addr_family, AF_UNSPEC, AF_INET))
|
||||
nm_clear_g_source_inst (&self->priv.p->acd_ready_on_idle_source);
|
||||
|
||||
if (commit_type == NM_L3_CFG_COMMIT_TYPE_AUTO)
|
||||
commit_type = nm_l3cfg_commit_type_get (self);
|
||||
|
||||
if (commit_type == NM_L3_CFG_COMMIT_TYPE_REAPPLY)
|
||||
_l3cfg_externally_removed_objs_drop (self, addr_family);
|
||||
|
||||
|
|
@ -2908,6 +2923,101 @@ nm_l3cfg_platform_commit (NML3Cfg *self,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
NML3CfgCommitType
|
||||
nm_l3cfg_commit_type_get (NML3Cfg *self)
|
||||
{
|
||||
NML3CfgCommitTypeHandle *handle;
|
||||
|
||||
nm_assert (NM_IS_L3CFG (self));
|
||||
|
||||
handle = c_list_first_entry (&self->priv.p->commit_type_lst_head, NML3CfgCommitTypeHandle, commit_type_lst);
|
||||
return handle
|
||||
? handle->commit_type
|
||||
: NM_L3_CFG_COMMIT_TYPE_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_l3cfg_commit_type_register:
|
||||
* @self: the #NML3Cfg
|
||||
* @commit_type: the commit type to register
|
||||
* @existing_handle: instead of being a new registration, update an existing handle.
|
||||
* This may be %NULL, which is like having no previous registration.
|
||||
*
|
||||
* NML3Cfg needs to know whether it is in charge of an interface (and how "much").
|
||||
* By default, it is not in charge, but various users can register themself with
|
||||
* a certain @commit_type. The "higher" commit type is the used one when calling
|
||||
* nm_l3cfg_platform_commit() with %NM_L3_CFG_COMMIT_TYPE_AUTO.
|
||||
*
|
||||
* Returns: a handle tracking the registration, or %NULL of @commit_type
|
||||
* is %NM_L3_CFG_COMMIT_TYPE_NONE.
|
||||
*/
|
||||
NML3CfgCommitTypeHandle *
|
||||
nm_l3cfg_commit_type_register (NML3Cfg *self,
|
||||
NML3CfgCommitType commit_type,
|
||||
NML3CfgCommitTypeHandle *existing_handle)
|
||||
{
|
||||
NML3CfgCommitTypeHandle *handle;
|
||||
NML3CfgCommitTypeHandle *h;
|
||||
gboolean linked;
|
||||
|
||||
nm_assert (NM_IS_L3CFG (self));
|
||||
nm_assert (NM_IN_SET (commit_type, NM_L3_CFG_COMMIT_TYPE_NONE,
|
||||
NM_L3_CFG_COMMIT_TYPE_ASSUME,
|
||||
NM_L3_CFG_COMMIT_TYPE_UPDATE,
|
||||
NM_L3_CFG_COMMIT_TYPE_REAPPLY));
|
||||
nm_assert ( !existing_handle
|
||||
|| c_list_contains (&self->priv.p->commit_type_lst_head, &existing_handle->commit_type_lst));
|
||||
|
||||
if (existing_handle) {
|
||||
if (commit_type == NM_L3_CFG_COMMIT_TYPE_NONE) {
|
||||
nm_l3cfg_commit_type_unregister (self, existing_handle);
|
||||
return NULL;
|
||||
}
|
||||
if (existing_handle->commit_type == commit_type)
|
||||
return existing_handle;
|
||||
c_list_unlink_stale (&existing_handle->commit_type_lst);
|
||||
handle = existing_handle;
|
||||
} else {
|
||||
if (commit_type == NM_L3_CFG_COMMIT_TYPE_NONE)
|
||||
return NULL;
|
||||
handle = g_slice_new (NML3CfgCommitTypeHandle);
|
||||
handle->commit_type = commit_type;
|
||||
if (c_list_is_empty (&self->priv.p->commit_type_lst_head))
|
||||
g_object_ref (self);
|
||||
}
|
||||
|
||||
linked = FALSE;
|
||||
c_list_for_each_entry (h, &self->priv.p->commit_type_lst_head, commit_type_lst) {
|
||||
if (handle->commit_type >= h->commit_type) {
|
||||
c_list_link_before (&self->priv.p->commit_type_lst_head, &handle->commit_type_lst);
|
||||
linked = TRUE;
|
||||
}
|
||||
}
|
||||
if (!linked)
|
||||
c_list_link_tail (&self->priv.p->commit_type_lst_head, &handle->commit_type_lst);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void
|
||||
nm_l3cfg_commit_type_unregister (NML3Cfg *self,
|
||||
NML3CfgCommitTypeHandle *handle)
|
||||
{
|
||||
nm_assert (NM_IS_L3CFG (self));
|
||||
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
nm_assert (c_list_contains (&self->priv.p->commit_type_lst_head, &handle->commit_type_lst));
|
||||
|
||||
c_list_unlink_stale (&handle->commit_type_lst);
|
||||
if (c_list_is_empty (&self->priv.p->commit_type_lst_head))
|
||||
g_object_unref (self);
|
||||
nm_g_slice_free (handle);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
set_property (GObject *object,
|
||||
guint prop_id,
|
||||
|
|
@ -2941,6 +3051,7 @@ nm_l3cfg_init (NML3Cfg *self)
|
|||
self->priv.p = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_L3CFG, NML3CfgPrivate);
|
||||
|
||||
c_list_init (&self->priv.p->acd_lst_head);
|
||||
c_list_init (&self->priv.p->commit_type_lst_head);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2979,6 +3090,8 @@ finalize (GObject *object)
|
|||
{
|
||||
NML3Cfg *self = NM_L3CFG (object);
|
||||
|
||||
nm_assert (c_list_is_empty (&self->priv.p->commit_type_lst_head));
|
||||
|
||||
nm_clear_g_source_inst (&self->priv.p->acd_ready_on_idle_source);
|
||||
|
||||
nm_assert (nm_g_array_len (self->priv.p->property_emit_list) == 0u);
|
||||
|
|
|
|||
|
|
@ -148,7 +148,18 @@ gboolean nm_l3cfg_remove_config_all (NML3Cfg *self,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
/* The numeric values of the enum matters: higher number mean more "important".
|
||||
* E.g. "assume" tries to preserve the most settings, while "reapply" forces
|
||||
* all configuration to match. */
|
||||
typedef enum _nm_packed {
|
||||
|
||||
/* the NML3Cfg instance tracks with nm_l3cfg_commit_setup_register() the requested commit type.
|
||||
* Use _NM_L3_CFG_COMMIT_TYPE_AUTO to automatically choose the level as requested. */
|
||||
NM_L3_CFG_COMMIT_TYPE_AUTO,
|
||||
|
||||
/* Don't touch the interface. */
|
||||
NM_L3_CFG_COMMIT_TYPE_NONE,
|
||||
|
||||
/* ASSUME means to keep any pre-existing extra routes/addresses, while
|
||||
* also not adding routes/addresses that are not present yet. This is to
|
||||
* gracefully take over after restart, where the existing IP configuration
|
||||
|
|
@ -172,4 +183,19 @@ gboolean nm_l3cfg_platform_commit (NML3Cfg *self,
|
|||
int addr_family,
|
||||
gboolean *out_final_failure_for_temporary_not_available);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NML3CfgCommitType nm_l3cfg_commit_type_get (NML3Cfg *self);
|
||||
|
||||
typedef struct _NML3CfgCommitTypeHandle NML3CfgCommitTypeHandle;
|
||||
|
||||
NML3CfgCommitTypeHandle *nm_l3cfg_commit_type_register (NML3Cfg *self,
|
||||
NML3CfgCommitType commit_type,
|
||||
NML3CfgCommitTypeHandle *existing_handle);
|
||||
|
||||
void nm_l3cfg_commit_type_unregister (NML3Cfg *self,
|
||||
NML3CfgCommitTypeHandle *handle);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#endif /* __NM_L3CFG_H__ */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue