summary refs log tree commit diff
path: root/src/core/nm-l3cfg.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/nm-l3cfg.h')
-rw-r--r--src/core/nm-l3cfg.h131
1 files changed, 104 insertions, 27 deletions
diff --git a/src/core/nm-l3cfg.h b/src/core/nm-l3cfg.h
index 037f2178..19dec118 100644
--- a/src/core/nm-l3cfg.h
+++ b/src/core/nm-l3cfg.h
@@ -7,6 +7,7 @@
 #include "nm-l3-config-data.h"
 
 #define NM_L3CFG_CONFIG_PRIORITY_IPV4LL 0
+#define NM_L3CFG_CONFIG_PRIORITY_IPV6LL 0
 #define NM_ACD_TIMEOUT_RFC5227_MSEC     9000u
 
 #define NM_TYPE_L3CFG            (nm_l3cfg_get_type())
@@ -22,12 +23,43 @@
 #define NM_L3CFG_SIGNAL_NOTIFY "l3cfg-notify"
 
 typedef enum _nm_packed {
-    NM_L3_ACD_DEFEND_TYPE_NONE,
+    _NM_L3_ACD_DEFEND_TYPE_NONE,
     NM_L3_ACD_DEFEND_TYPE_NEVER,
     NM_L3_ACD_DEFEND_TYPE_ONCE,
     NM_L3_ACD_DEFEND_TYPE_ALWAYS,
 } NML3AcdDefendType;
 
+/**
+ * NML3CfgConfigFlags:
+ * @NM_L3CFG_CONFIG_FLAGS_NONE: no flags, the default.
+ * @NM_L3_CONFIG_MERGE_FLAGS_ONLY_FOR_ACD: if this merge flag is set,
+ *   the the NML3ConfigData doesn't get merged and it's information won't be
+ *   synced. The only purpose is to run ACD on its IPv4 addresses, but
+ *   regardless whether ACD succeeds/fails, the IP addresses won't be configured.
+ *   The point is to run ACD first (without configuring it), and only
+ *   commit the settings if requested. That can either happen by
+ *   nm_l3cfg_add_config() the same NML3Cfg again (with a different
+ *   tag), or by calling nm_l3cfg_add_config() again with this flag
+ *   cleared (and the same tag).
+ * @NM_L3CFG_CONFIG_FLAGS_ASSUME_CONFIG_ONCE: a commit with
+ *   %NM_L3_CFG_COMMIT_TYPE_ASSUME, means to not remove/add
+ *   addresses that are missing/already exist. The assume mode
+ *   is for taking over a device gracefully after restart, so
+ *   it aims to preserve whatever was configured (or not configured).
+ *   With this flag enabled, the first commit in assume mode will still
+ *   add the addresses/routes. This is necessary for example with IPv6LL.
+ *   Also while assuming a device, we want to configure things
+ *   (like an IPv6 address), so we need to bypass the common
+ *   "don't change" behavior. At least once. If the address/route
+ *   is still not (no longer) configured on the subsequent
+ *   commit, it's not getting added again.
+ */
+typedef enum _nm_packed {
+    NM_L3CFG_CONFIG_FLAGS_NONE               = 0,
+    NM_L3CFG_CONFIG_FLAGS_ONLY_FOR_ACD       = (1LL << 0),
+    NM_L3CFG_CONFIG_FLAGS_ASSUME_CONFIG_ONCE = (1LL << 1),
+} NML3CfgConfigFlags;
+
 typedef enum _nm_packed {
     NM_L3_ACD_ADDR_STATE_INIT,
     NM_L3_ACD_ADDR_STATE_PROBING,
@@ -98,6 +130,12 @@ typedef enum {
 
     NM_L3_CONFIG_NOTIFY_TYPE_ACD_EVENT,
 
+    /* emitted before the merged l3cd is committed to platform.
+     *
+     * This event also gets emitted "under unsafe circumstances".
+     * See NM_L3_CONFIG_NOTIFY_TYPE_L3CD_CHANGED. */
+    NM_L3_CONFIG_NOTIFY_TYPE_PRE_COMMIT,
+
     /* emitted at the end of nm_l3cfg_platform_commit(). This signals also that
      * nm_l3cfg_is_ready() might have switched to TRUE. */
     NM_L3_CONFIG_NOTIFY_TYPE_POST_COMMIT,
@@ -105,7 +143,9 @@ typedef enum {
     /* 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. */
+     * is re-emitted synchronously. You probably want to hook to the on-idle signal,
+     * unless you need to catch all intermediate changes too. Note that this
+     * event is not re-entrant safe (so beware what you are doing). */
     NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE,
 
     /* NML3Cfg hooks to the NMPlatform signals for link, addresses and routes.
@@ -235,6 +275,8 @@ nm_l3cfg_get_ifname(const NML3Cfg *self, gboolean get_next)
     return nmp_object_link_get_ifname(nm_l3cfg_get_plobj(self, get_next));
 }
 
+gboolean nm_l3cfg_is_vrf(const NML3Cfg *self);
+
 static inline NMNetns *
 nm_l3cfg_get_netns(const NML3Cfg *self)
 {
@@ -251,31 +293,12 @@ nm_l3cfg_get_platform(const NML3Cfg *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,
@@ -289,17 +312,39 @@ gboolean nm_l3cfg_add_config(NML3Cfg *             self,
                              guint32               default_route_metric_6,
                              guint32               default_route_penalty_4,
                              guint32               default_route_penalty_6,
+                             int                   default_dns_priority_4,
+                             int                   default_dns_priority_6,
                              NML3AcdDefendType     acd_defend_type,
                              guint32               acd_timeout_msec,
+                             NML3CfgConfigFlags    config_flags,
                              NML3ConfigMergeFlags  merge_flags);
 
-gboolean nm_l3cfg_remove_config(NML3Cfg *self, gconstpointer tag, const NML3ConfigData *ifcfg);
+gboolean nm_l3cfg_remove_config(NML3Cfg *self, gconstpointer tag, const NML3ConfigData *l3cd);
 
-gboolean nm_l3cfg_remove_config_all(NML3Cfg *self, gconstpointer tag, gboolean only_dirty);
+gboolean nm_l3cfg_remove_config_all(NML3Cfg *self, gconstpointer tag);
+gboolean nm_l3cfg_remove_config_all_dirty(NML3Cfg *self, gconstpointer tag);
 
 /*****************************************************************************/
 
-/* The numeric values of the enum matters: higher number mean more "important".
+/* DOC(l3cfg:commit-type):
+ *
+ * The major idea of NML3Cfg is that independent parties can register configuration
+ * (NML3ConfigData via nm_l3cfg_add_config()), and then nm_l3cfg_commit() will
+ * actually configure it. Usually we would not call the synchronous nm_l3cfg_commit(),
+ * but instead nm_l3cfg_commit_on_idle_schedule().
+ *
+ * We have different levels of "how much" we should sync during commit. That is
+ * NML3CfgCommitType. Since independent parties should be able to work together,
+ * they can only ask for their minimal required commit-type level. That means,
+ * during commit we will commit with the highest level of how much one of the
+ * users request the commit. To request a commit level, users can call
+ * nm_l3cfg_commit_type_register(). nm_l3cfg_commit_on_idle_schedule() also
+ * accepts a one-time commit-type argument.
+ *
+ * This is related to NMDevice's sys_iface_state, which we use to control whether
+ * to touch/assume/manage the interface.
+ *
+ * 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 {
@@ -314,7 +359,10 @@ typedef enum _nm_packed {
     /* 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. */
+     * should not change.
+     *
+     * The flag NM_L3CFG_CONFIG_FLAGS_ASSUME_CONFIG_ONCE can make certain addresses/
+     * routes commitable also during "assume". */
     NM_L3_CFG_COMMIT_TYPE_ASSUME,
 
     /* UPDATE means to add new addresses/routes, while also removing addresses/routes
@@ -331,24 +379,53 @@ typedef enum _nm_packed {
 
 void nm_l3cfg_commit(NML3Cfg *self, NML3CfgCommitType commit_type);
 
-gboolean nm_l3cfg_commit_on_idle_schedule(NML3Cfg *self);
+gboolean nm_l3cfg_commit_on_idle_schedule(NML3Cfg *self, NML3CfgCommitType commit_type);
+
+gboolean nm_l3cfg_commit_on_idle_is_scheduled(NML3Cfg *self);
 
 /*****************************************************************************/
 
+gboolean nm_l3cfg_get_acd_is_pending(NML3Cfg *self);
+
 const NML3AcdAddrInfo *nm_l3cfg_get_acd_addr_info(NML3Cfg *self, in_addr_t addr);
 
 /*****************************************************************************/
 
+typedef enum {
+    NM_L3CFG_CHECK_READY_FLAGS_NONE          = 0,
+    NM_L3CFG_CHECK_READY_FLAGS_IP4_ACD_READY = (1ull << 0),
+    NM_L3CFG_CHECK_READY_FLAGS_IP6_DAD_READY = (1ull << 1),
+} NML3CfgCheckReadyFlags;
+
+gboolean nm_l3cfg_check_ready(NML3Cfg *              self,
+                              const NML3ConfigData * l3cd,
+                              int                    addr_family,
+                              NML3CfgCheckReadyFlags flags,
+                              gboolean *             acd_used);
+
+/*****************************************************************************/
+
 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);
+                                                       NML3CfgCommitTypeHandle *existing_handle,
+                                                       const char *             source);
 
 void nm_l3cfg_commit_type_unregister(NML3Cfg *self, NML3CfgCommitTypeHandle *handle);
 
+static inline gboolean
+nm_l3cfg_commit_type_clear(NML3Cfg *self, NML3CfgCommitTypeHandle **handle)
+{
+    if (!handle || !*handle)
+        return FALSE;
+
+    nm_l3cfg_commit_type_unregister(self, g_steal_pointer(handle));
+    return TRUE;
+}
+
 /*****************************************************************************/
 
 const NML3ConfigData *nm_l3cfg_get_combined_l3cd(NML3Cfg *self, gboolean get_commited);