diff options
| author | Michael Biebl <biebl@debian.org> | 2020-10-05 22:27:18 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2020-10-05 22:27:18 +0200 |
| commit | aafc1dbe4712c86189bbc1d4d54ad8cb4c69be7e (patch) | |
| tree | a2a9bb4d007339a0b1304540388230ccedac32bd /src/nm-l3cfg.h | |
| parent | e7b44ef4c80907346ec7492a09c45277459924fc (diff) | |
New upstream version 1.27.90 upstream/1.27.90
Diffstat (limited to 'src/nm-l3cfg.h')
| -rw-r--r-- | src/nm-l3cfg.h | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/src/nm-l3cfg.h b/src/nm-l3cfg.h new file mode 100644 index 00000000..9f957ae1 --- /dev/null +++ b/src/nm-l3cfg.h @@ -0,0 +1,276 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#ifndef __NM_L3CFG_H__ +#define __NM_L3CFG_H__ + +#include "platform/nmp-object.h" +#include "nm-l3-config-data.h" + +#define NM_TYPE_L3CFG (nm_l3cfg_get_type()) +#define NM_L3CFG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_L3CFG, NML3Cfg)) +#define NM_L3CFG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_L3CFG, NML3CfgClass)) +#define NM_IS_L3CFG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_L3CFG)) +#define NM_IS_L3CFG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_L3CFG)) +#define NM_L3CFG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_L3CFG, NML3CfgClass)) + +#define NM_L3CFG_NETNS "netns" +#define NM_L3CFG_IFINDEX "ifindex" + +#define NM_L3CFG_SIGNAL_NOTIFY "l3cfg-notify" + +typedef enum { + NM_L3_CONFIG_NOTIFY_TYPE_ROUTES_TEMPORARY_NOT_AVAILABLE_EXPIRED, + + NM_L3_CONFIG_NOTIFY_TYPE_ACD_COMPLETED, + + /* emitted at the end of nm_l3cfg_platform_commit(). */ + NM_L3_CONFIG_NOTIFY_TYPE_POST_COMMIT, + + /* NML3Cfg hooks to the NMPlatform signals for link, addresses and routes. + * It re-emits the platform signal. + * Contrary to NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE_ON_IDLE, this even + * is re-emitted synchronously. */ + NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE, + + /* NML3Cfg hooks to the NMPlatform signals for link, addresses and routes. + * It re-emits the signal on an idle handler. The purpose is for something + * like NMDevice which is already subscribed to these signals, it can get the + * notifications without also subscribing directly to the platform. */ + NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE_ON_IDLE, + + _NM_L3_CONFIG_NOTIFY_TYPE_NUM, +} NML3ConfigNotifyType; + +typedef struct { + const NMPObject * obj; + const NML3ConfigData *l3cd; + gconstpointer tag; +} NML3ConfigNotifyPayloadAcdFailedSource; + +typedef struct { + NML3ConfigNotifyType notify_type; + union { + struct { + in_addr_t addr; + guint sources_len; + bool probe_result : 1; + const NML3ConfigNotifyPayloadAcdFailedSource *sources; + } acd_completed; + + struct { + const NMPObject * obj; + NMPlatformSignalChangeType change_type; + } platform_change; + + struct { + guint32 obj_type_flags; + } platform_change_on_idle; + }; +} NML3ConfigNotifyData; + +struct _NML3CfgPrivate; + +struct _NML3Cfg { + GObject parent; + struct { + struct _NML3CfgPrivate *p; + NMNetns * netns; + NMPlatform * platform; + const NMPObject * plobj; + const NMPObject * plobj_next; + int ifindex; + bool changed_configs : 1; + } priv; +}; + +typedef struct _NML3CfgClass NML3CfgClass; + +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); + +void _nm_l3cfg_notify_platform_change(NML3Cfg * self, + NMPlatformSignalChangeType change_type, + const NMPObject * obj); + +/*****************************************************************************/ + +struct _NMDedupMultiIndex; + +struct _NMDedupMultiIndex *nm_netns_get_multi_idx(NMNetns *self); + +static inline struct _NMDedupMultiIndex * +nm_l3cfg_get_multi_idx(const NML3Cfg *self) +{ + return nm_netns_get_multi_idx(self->priv.netns); +} + +/*****************************************************************************/ + +static inline int +nm_l3cfg_get_ifindex(const NML3Cfg *self) +{ + nm_assert(NM_IS_L3CFG(self)); + + return self->priv.ifindex; +} + +static inline const NMPObject * +nm_l3cfg_get_plobj(const NML3Cfg *self, gboolean get_next) +{ + if (!self) + return NULL; + + nm_assert(NM_IS_L3CFG(self)); + + if (get_next) { + /* This is the instance that we just got reported in the last signal from + * the platform cache. It's probably exactly the same as if you would look + * into the platform cache. + * + * On the other hand, we pick up changes only on an idle handler. So the last + * decisions were not made based on this, but instead of "plobj". */ + return self->priv.plobj_next; + } + return self->priv.plobj; +} + +static inline const NMPlatformLink * +nm_l3cfg_get_pllink(const NML3Cfg *self, gboolean get_next) +{ + return NMP_OBJECT_CAST_LINK(nm_l3cfg_get_plobj(self, get_next)); +} + +static inline const char * +nm_l3cfg_get_ifname(const NML3Cfg *self, gboolean get_next) +{ + return nmp_object_link_get_ifname(nm_l3cfg_get_plobj(self, get_next)); +} + +static inline NMNetns * +nm_l3cfg_get_netns(const NML3Cfg *self) +{ + nm_assert(NM_IS_L3CFG(self)); + + return self->priv.netns; +} + +static inline NMPlatform * +nm_l3cfg_get_platform(const NML3Cfg *self) +{ + nm_assert(NM_IS_L3CFG(self)); + + return self->priv.platform; +} + +gboolean nm_l3cfg_get_acd_is_pending(NML3Cfg *self); + +/*****************************************************************************/ + +void _nm_l3cfg_emit_signal_notify(NML3Cfg *self, const NML3ConfigNotifyData *notify_data); + +/*****************************************************************************/ + +typedef enum { + NM_L3CFG_PROPERTY_EMIT_TYPE_ANY, + NM_L3CFG_PROPERTY_EMIT_TYPE_IP4_ROUTE, + NM_L3CFG_PROPERTY_EMIT_TYPE_IP6_ROUTE, +} NML3CfgPropertyEmitType; + +void nm_l3cfg_property_emit_register(NML3Cfg * self, + GObject * target_obj, + const GParamSpec * target_property, + NML3CfgPropertyEmitType emit_type); + +void nm_l3cfg_property_emit_unregister(NML3Cfg * self, + GObject * target_obj, + const GParamSpec *target_property); + +/*****************************************************************************/ + +void nm_l3cfg_mark_config_dirty(NML3Cfg *self, gconstpointer tag, gboolean dirty); + +gboolean nm_l3cfg_add_config(NML3Cfg * self, + gconstpointer tag, + gboolean replace_same_tag, + const NML3ConfigData *l3cd, + int priority, + guint32 default_route_table_4, + guint32 default_route_table_6, + guint32 default_route_metric_4, + guint32 default_route_metric_6, + guint32 default_route_penalty_4, + guint32 default_route_penalty_6, + guint32 acd_timeout_msec, + NML3ConfigMergeFlags merge_flags); + +gboolean nm_l3cfg_remove_config(NML3Cfg *self, gconstpointer tag, const NML3ConfigData *ifcfg); + +gboolean nm_l3cfg_remove_config_all(NML3Cfg *self, gconstpointer tag, gboolean only_dirty); + +/*****************************************************************************/ + +/* 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 + * should not change. */ + NM_L3_CFG_COMMIT_TYPE_ASSUME, + + /* UPDATE means to add new addresses/routes, while also removing addresses/routes + * that are no longer present (but were previously configured by NetworkManager). + * Routes/addresses that were removed externally won't be re-added, and routes/addresses + * that are added externally won't be removed. */ + NM_L3_CFG_COMMIT_TYPE_UPDATE, + + /* This is a full sync. It configures the IP addresses/routes that are indicated, + * while removing the existing ones from the interface. */ + NM_L3_CFG_COMMIT_TYPE_REAPPLY, + +} NML3CfgCommitType; + +void nm_l3cfg_commit(NML3Cfg *self, NML3CfgCommitType commit_type); + +void nm_l3cfg_commit_on_idle_schedule(NML3Cfg *self); + +/*****************************************************************************/ + +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); + +/*****************************************************************************/ + +const NML3ConfigData *nm_l3cfg_get_combined_l3cd(NML3Cfg *self, gboolean get_commited); + +const NMPObject * +nm_l3cfg_get_best_default_route(NML3Cfg *self, int addr_family, gboolean get_commited); + +/*****************************************************************************/ + +gboolean nm_l3cfg_has_commited_ip6_addresses_pending_dad(NML3Cfg *self); + +/*****************************************************************************/ + +#endif /* __NM_L3CFG_H__ */ |