Blame src/nm-l3cfg.h

Packit Service a1bd4f
/* SPDX-License-Identifier: LGPL-2.1+ */
Packit 5756e2
Packit 5756e2
#ifndef __NM_L3CFG_H__
Packit 5756e2
#define __NM_L3CFG_H__
Packit 5756e2
Packit 5756e2
#include "platform/nmp-object.h"
Packit 5756e2
#include "nm-l3-config-data.h"
Packit 5756e2
Packit Service a1bd4f
#define NM_L3CFG_CONFIG_PRIORITY_IPV4LL 0
Packit Service a1bd4f
#define NM_ACD_TIMEOUT_RFC5227_MSEC     9000u
Packit Service a1bd4f
Packit Service a1bd4f
#define NM_TYPE_L3CFG            (nm_l3cfg_get_type())
Packit Service a1bd4f
#define NM_L3CFG(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_L3CFG, NML3Cfg))
Packit Service a1bd4f
#define NM_L3CFG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_L3CFG, NML3CfgClass))
Packit Service a1bd4f
#define NM_IS_L3CFG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_L3CFG))
Packit Service a1bd4f
#define NM_IS_L3CFG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_L3CFG))
Packit Service a1bd4f
#define NM_L3CFG_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_L3CFG, NML3CfgClass))
Packit 5756e2
Packit 5756e2
#define NM_L3CFG_NETNS   "netns"
Packit 5756e2
#define NM_L3CFG_IFINDEX "ifindex"
Packit 5756e2
Packit 5756e2
#define NM_L3CFG_SIGNAL_NOTIFY "l3cfg-notify"
Packit 5756e2
Packit Service a1bd4f
typedef enum _nm_packed {
Packit Service a1bd4f
    NM_L3_ACD_DEFEND_TYPE_NONE,
Packit Service a1bd4f
    NM_L3_ACD_DEFEND_TYPE_NEVER,
Packit Service a1bd4f
    NM_L3_ACD_DEFEND_TYPE_ONCE,
Packit Service a1bd4f
    NM_L3_ACD_DEFEND_TYPE_ALWAYS,
Packit Service a1bd4f
} NML3AcdDefendType;
Packit Service a1bd4f
Packit Service a1bd4f
typedef enum _nm_packed {
Packit Service a1bd4f
    NM_L3_ACD_ADDR_STATE_INIT,
Packit Service a1bd4f
    NM_L3_ACD_ADDR_STATE_PROBING,
Packit Service a1bd4f
    NM_L3_ACD_ADDR_STATE_USED,
Packit Service a1bd4f
    NM_L3_ACD_ADDR_STATE_READY,
Packit Service a1bd4f
    NM_L3_ACD_ADDR_STATE_DEFENDING,
Packit Service a1bd4f
    NM_L3_ACD_ADDR_STATE_CONFLICT,
Packit Service a1bd4f
    NM_L3_ACD_ADDR_STATE_EXTERNAL_REMOVED,
Packit Service a1bd4f
} NML3AcdAddrState;
Packit Service a1bd4f
Packit Service a1bd4f
typedef struct {
Packit Service a1bd4f
    const NMPObject *     obj;
Packit Service a1bd4f
    const NML3ConfigData *l3cd;
Packit Service a1bd4f
    gconstpointer         tag;
Packit Service a1bd4f
Packit Service a1bd4f
    struct {
Packit Service a1bd4f
        guint32           acd_timeout_msec_track;
Packit Service a1bd4f
        NML3AcdDefendType acd_defend_type_track;
Packit Service a1bd4f
        bool              acd_dirty_track : 1;
Packit Service a1bd4f
        bool              acd_failed_notified_track : 1;
Packit Service a1bd4f
    } _priv;
Packit Service a1bd4f
Packit Service a1bd4f
} NML3AcdAddrTrackInfo;
Packit Service a1bd4f
Packit Service a1bd4f
typedef struct {
Packit Service a1bd4f
    in_addr_t                   addr;
Packit Service a1bd4f
    guint                       n_track_infos;
Packit Service a1bd4f
    NML3AcdAddrState            state;
Packit Service a1bd4f
    NML3Cfg *                   l3cfg;
Packit Service a1bd4f
    const NML3AcdAddrTrackInfo *track_infos;
Packit Service a1bd4f
} NML3AcdAddrInfo;
Packit Service a1bd4f
Packit Service a1bd4f
static inline const NML3AcdAddrTrackInfo *
Packit Service a1bd4f
nm_l3_acd_addr_info_find_track_info(const NML3AcdAddrInfo *addr_info,
Packit Service a1bd4f
                                    gconstpointer          tag,
Packit Service a1bd4f
                                    const NML3ConfigData * l3cd,
Packit Service a1bd4f
                                    const NMPObject *      obj)
Packit Service a1bd4f
{
Packit Service a1bd4f
    guint                       i;
Packit Service a1bd4f
    const NML3AcdAddrTrackInfo *ti;
Packit Service a1bd4f
Packit Service a1bd4f
    nm_assert(addr_info);
Packit Service a1bd4f
Packit Service a1bd4f
    /* we always expect that the number n_track_infos is reasonably small. Hence,
Packit Service a1bd4f
     * a naive linear search is simplest and fastest (e.g. we don't have a hash table). */
Packit Service a1bd4f
Packit Service a1bd4f
    for (i = 0, ti = addr_info->track_infos; i < addr_info->n_track_infos; i++, ti++) {
Packit Service a1bd4f
        if (l3cd && ti->l3cd != l3cd)
Packit Service a1bd4f
            continue;
Packit Service a1bd4f
        if (tag && ti->tag != tag)
Packit Service a1bd4f
            continue;
Packit Service a1bd4f
        if (obj && ti->obj != obj)
Packit Service a1bd4f
            continue;
Packit Service a1bd4f
        return ti;
Packit Service a1bd4f
    }
Packit Service a1bd4f
Packit Service a1bd4f
    return NULL;
Packit Service a1bd4f
}
Packit Service a1bd4f
Packit 5756e2
typedef enum {
Packit Service a1bd4f
    NM_L3_CONFIG_NOTIFY_TYPE_ROUTES_TEMPORARY_NOT_AVAILABLE_EXPIRED,
Packit Service a1bd4f
Packit Service a1bd4f
    NM_L3_CONFIG_NOTIFY_TYPE_ACD_EVENT,
Packit Service a1bd4f
Packit Service a1bd4f
    /* emitted at the end of nm_l3cfg_platform_commit(). */
Packit Service a1bd4f
    NM_L3_CONFIG_NOTIFY_TYPE_POST_COMMIT,
Packit Service a1bd4f
Packit Service a1bd4f
    /* NML3Cfg hooks to the NMPlatform signals for link, addresses and routes.
Packit Service a1bd4f
     * It re-emits the platform signal.
Packit Service a1bd4f
     * Contrary to NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE_ON_IDLE, this even
Packit Service a1bd4f
     * is re-emitted synchronously. */
Packit Service a1bd4f
    NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE,
Packit Service a1bd4f
Packit Service a1bd4f
    /* NML3Cfg hooks to the NMPlatform signals for link, addresses and routes.
Packit Service a1bd4f
     * It re-emits the signal on an idle handler. The purpose is for something
Packit Service a1bd4f
     * like NMDevice which is already subscribed to these signals, it can get the
Packit Service a1bd4f
     * notifications without also subscribing directly to the platform. */
Packit Service a1bd4f
    NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE_ON_IDLE,
Packit Service a1bd4f
Packit Service a1bd4f
    NM_L3_CONFIG_NOTIFY_TYPE_IPV4LL_EVENT,
Packit Service a1bd4f
Packit Service a1bd4f
    _NM_L3_CONFIG_NOTIFY_TYPE_NUM,
Packit 5756e2
} NML3ConfigNotifyType;
Packit 5756e2
Packit Service a1bd4f
struct _NML3IPv4LL;
Packit 5756e2
Packit 5756e2
typedef struct {
Packit Service a1bd4f
    NML3ConfigNotifyType notify_type;
Packit Service a1bd4f
    union {
Packit Service a1bd4f
        struct {
Packit Service a1bd4f
            NML3AcdAddrInfo info;
Packit Service a1bd4f
        } acd_event;
Packit Service a1bd4f
Packit Service a1bd4f
        struct {
Packit Service a1bd4f
            const NMPObject *          obj;
Packit Service a1bd4f
            NMPlatformSignalChangeType change_type;
Packit Service a1bd4f
        } platform_change;
Packit Service a1bd4f
Packit Service a1bd4f
        struct {
Packit Service a1bd4f
            guint32 obj_type_flags;
Packit Service a1bd4f
        } platform_change_on_idle;
Packit Service a1bd4f
Packit Service a1bd4f
        struct {
Packit Service a1bd4f
            struct _NML3IPv4LL *ipv4ll;
Packit Service a1bd4f
        } ipv4ll_event;
Packit Service a1bd4f
    };
Packit Service a1bd4f
} NML3ConfigNotifyData;
Packit 5756e2
Packit 5756e2
struct _NML3CfgPrivate;
Packit 5756e2
Packit 5756e2
struct _NML3Cfg {
Packit Service a1bd4f
    GObject parent;
Packit Service a1bd4f
    struct {
Packit Service a1bd4f
        struct _NML3CfgPrivate *p;
Packit Service a1bd4f
        NMNetns *               netns;
Packit Service a1bd4f
        NMPlatform *            platform;
Packit Service a1bd4f
        const NMPObject *       plobj;
Packit Service a1bd4f
        const NMPObject *       plobj_next;
Packit Service a1bd4f
        int                     ifindex;
Packit Service a1bd4f
    } priv;
Packit 5756e2
};
Packit 5756e2
Packit 5756e2
typedef struct _NML3CfgClass NML3CfgClass;
Packit 5756e2
Packit Service a1bd4f
GType nm_l3cfg_get_type(void);
Packit 5756e2
Packit Service a1bd4f
NML3Cfg *nm_l3cfg_new(NMNetns *netns, int ifindex);
Packit 5756e2
Packit 5756e2
/*****************************************************************************/
Packit 5756e2
Packit Service a1bd4f
void _nm_l3cfg_notify_platform_change_on_idle(NML3Cfg *self, guint32 obj_type_flags);
Packit 5756e2
Packit Service a1bd4f
void _nm_l3cfg_notify_platform_change(NML3Cfg *                  self,
Packit Service a1bd4f
                                      NMPlatformSignalChangeType change_type,
Packit Service a1bd4f
                                      const NMPObject *          obj);
Packit 5756e2
Packit 5756e2
/*****************************************************************************/
Packit 5756e2
Packit Service a1bd4f
struct _NMDedupMultiIndex;
Packit Service a1bd4f
Packit Service a1bd4f
struct _NMDedupMultiIndex *nm_netns_get_multi_idx(NMNetns *self);
Packit 5756e2
Packit Service a1bd4f
static inline struct _NMDedupMultiIndex *
Packit Service a1bd4f
nm_l3cfg_get_multi_idx(const NML3Cfg *self)
Packit Service a1bd4f
{
Packit Service a1bd4f
    return nm_netns_get_multi_idx(self->priv.netns);
Packit 5756e2
}
Packit 5756e2
Packit Service a1bd4f
/*****************************************************************************/
Packit Service a1bd4f
Packit Service a1bd4f
static inline int
Packit Service a1bd4f
nm_l3cfg_get_ifindex(const NML3Cfg *self)
Packit 5756e2
{
Packit Service a1bd4f
    nm_assert(NM_IS_L3CFG(self));
Packit 5756e2
Packit Service a1bd4f
    return self->priv.ifindex;
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
static inline const NMPObject *
Packit Service a1bd4f
nm_l3cfg_get_plobj(const NML3Cfg *self, gboolean get_next)
Packit 5756e2
{
Packit Service a1bd4f
    if (!self)
Packit Service a1bd4f
        return NULL;
Packit Service a1bd4f
Packit Service a1bd4f
    nm_assert(NM_IS_L3CFG(self));
Packit Service a1bd4f
Packit Service a1bd4f
    if (get_next) {
Packit Service a1bd4f
        /* This is the instance that we just got reported in the last signal from
Packit Service a1bd4f
         * the platform cache. It's probably exactly the same as if you would look
Packit Service a1bd4f
         * into the platform cache.
Packit Service a1bd4f
         *
Packit Service a1bd4f
         * On the other hand, we pick up changes only on an idle handler. So the last
Packit Service a1bd4f
         * decisions were not made based on this, but instead of "plobj". */
Packit Service a1bd4f
        return self->priv.plobj_next;
Packit Service a1bd4f
    }
Packit Service a1bd4f
    return self->priv.plobj;
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
static inline const NMPlatformLink *
Packit Service a1bd4f
nm_l3cfg_get_pllink(const NML3Cfg *self, gboolean get_next)
Packit 5756e2
{
Packit Service a1bd4f
    return NMP_OBJECT_CAST_LINK(nm_l3cfg_get_plobj(self, get_next));
Packit Service a1bd4f
}
Packit 5756e2
Packit Service a1bd4f
static inline const char *
Packit Service a1bd4f
nm_l3cfg_get_ifname(const NML3Cfg *self, gboolean get_next)
Packit Service a1bd4f
{
Packit Service a1bd4f
    return nmp_object_link_get_ifname(nm_l3cfg_get_plobj(self, get_next));
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
static inline NMNetns *
Packit Service a1bd4f
nm_l3cfg_get_netns(const NML3Cfg *self)
Packit 5756e2
{
Packit Service a1bd4f
    nm_assert(NM_IS_L3CFG(self));
Packit 5756e2
Packit Service a1bd4f
    return self->priv.netns;
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
static inline NMPlatform *
Packit Service a1bd4f
nm_l3cfg_get_platform(const NML3Cfg *self)
Packit 5756e2
{
Packit Service a1bd4f
    nm_assert(NM_IS_L3CFG(self));
Packit 5756e2
Packit Service a1bd4f
    return self->priv.platform;
Packit 5756e2
}
Packit 5756e2
Packit Service a1bd4f
gboolean nm_l3cfg_get_acd_is_pending(NML3Cfg *self);
Packit Service a1bd4f
Packit Service a1bd4f
/*****************************************************************************/
Packit Service a1bd4f
Packit Service a1bd4f
void _nm_l3cfg_emit_signal_notify(NML3Cfg *self, const NML3ConfigNotifyData *notify_data);
Packit 5756e2
Packit 5756e2
/*****************************************************************************/
Packit 5756e2
Packit 5756e2
typedef enum {
Packit Service a1bd4f
    NM_L3CFG_PROPERTY_EMIT_TYPE_ANY,
Packit Service a1bd4f
    NM_L3CFG_PROPERTY_EMIT_TYPE_IP4_ROUTE,
Packit Service a1bd4f
    NM_L3CFG_PROPERTY_EMIT_TYPE_IP6_ROUTE,
Packit 5756e2
} NML3CfgPropertyEmitType;
Packit 5756e2
Packit Service a1bd4f
void nm_l3cfg_property_emit_register(NML3Cfg *               self,
Packit Service a1bd4f
                                     GObject *               target_obj,
Packit Service a1bd4f
                                     const GParamSpec *      target_property,
Packit Service a1bd4f
                                     NML3CfgPropertyEmitType emit_type);
Packit 5756e2
Packit Service a1bd4f
void nm_l3cfg_property_emit_unregister(NML3Cfg *         self,
Packit Service a1bd4f
                                       GObject *         target_obj,
Packit Service a1bd4f
                                       const GParamSpec *target_property);
Packit 5756e2
Packit 5756e2
/*****************************************************************************/
Packit 5756e2
Packit Service a1bd4f
void nm_l3cfg_mark_config_dirty(NML3Cfg *self, gconstpointer tag, gboolean dirty);
Packit 5756e2
Packit Service a1bd4f
gboolean nm_l3cfg_add_config(NML3Cfg *             self,
Packit Service a1bd4f
                             gconstpointer         tag,
Packit Service a1bd4f
                             gboolean              replace_same_tag,
Packit Service a1bd4f
                             const NML3ConfigData *l3cd,
Packit Service a1bd4f
                             int                   priority,
Packit Service a1bd4f
                             guint32               default_route_table_4,
Packit Service a1bd4f
                             guint32               default_route_table_6,
Packit Service a1bd4f
                             guint32               default_route_metric_4,
Packit Service a1bd4f
                             guint32               default_route_metric_6,
Packit Service a1bd4f
                             guint32               default_route_penalty_4,
Packit Service a1bd4f
                             guint32               default_route_penalty_6,
Packit Service a1bd4f
                             NML3AcdDefendType     acd_defend_type,
Packit Service a1bd4f
                             guint32               acd_timeout_msec,
Packit Service a1bd4f
                             NML3ConfigMergeFlags  merge_flags);
Packit 5756e2
Packit Service a1bd4f
gboolean nm_l3cfg_remove_config(NML3Cfg *self, gconstpointer tag, const NML3ConfigData *ifcfg);
Packit 5756e2
Packit Service a1bd4f
gboolean nm_l3cfg_remove_config_all(NML3Cfg *self, gconstpointer tag, gboolean only_dirty);
Packit 5756e2
Packit 5756e2
/*****************************************************************************/
Packit 5756e2
Packit 5756e2
/* The numeric values of the enum matters: higher number mean more "important".
Packit 5756e2
 * E.g. "assume" tries to preserve the most settings, while "reapply" forces
Packit 5756e2
 * all configuration to match. */
Packit 5756e2
typedef enum _nm_packed {
Packit 5756e2
Packit Service a1bd4f
    /* the NML3Cfg instance tracks with nm_l3cfg_commit_setup_register() the requested commit type.
Packit Service a1bd4f
     * Use _NM_L3_CFG_COMMIT_TYPE_AUTO to automatically choose the level as requested. */
Packit Service a1bd4f
    NM_L3_CFG_COMMIT_TYPE_AUTO,
Packit 5756e2
Packit Service a1bd4f
    /* Don't touch the interface. */
Packit Service a1bd4f
    NM_L3_CFG_COMMIT_TYPE_NONE,
Packit 5756e2
Packit Service a1bd4f
    /* ASSUME means to keep any pre-existing extra routes/addresses, while
Packit Service a1bd4f
     * also not adding routes/addresses that are not present yet. This is to
Packit Service a1bd4f
     * gracefully take over after restart, where the existing IP configuration
Packit Service a1bd4f
     * should not change. */
Packit Service a1bd4f
    NM_L3_CFG_COMMIT_TYPE_ASSUME,
Packit 5756e2
Packit Service a1bd4f
    /* UPDATE means to add new addresses/routes, while also removing addresses/routes
Packit Service a1bd4f
     * that are no longer present (but were previously configured by NetworkManager).
Packit Service a1bd4f
     * Routes/addresses that were removed externally won't be re-added, and routes/addresses
Packit Service a1bd4f
     * that are added externally won't be removed. */
Packit Service a1bd4f
    NM_L3_CFG_COMMIT_TYPE_UPDATE,
Packit 5756e2
Packit Service a1bd4f
    /* This is a full sync. It configures the IP addresses/routes that are indicated,
Packit Service a1bd4f
     * while removing the existing ones from the interface. */
Packit Service a1bd4f
    NM_L3_CFG_COMMIT_TYPE_REAPPLY,
Packit 5756e2
Packit 5756e2
} NML3CfgCommitType;
Packit 5756e2
Packit Service a1bd4f
void nm_l3cfg_commit(NML3Cfg *self, NML3CfgCommitType commit_type);
Packit Service a1bd4f
Packit Service a1bd4f
void nm_l3cfg_commit_on_idle_schedule(NML3Cfg *self);
Packit 5756e2
Packit 5756e2
/*****************************************************************************/
Packit 5756e2
Packit Service a1bd4f
const NML3AcdAddrInfo *nm_l3cfg_get_acd_addr_info(NML3Cfg *self, in_addr_t addr);
Packit Service a1bd4f
Packit Service a1bd4f
/*****************************************************************************/
Packit Service a1bd4f
Packit Service a1bd4f
NML3CfgCommitType nm_l3cfg_commit_type_get(NML3Cfg *self);
Packit 5756e2
Packit 5756e2
typedef struct _NML3CfgCommitTypeHandle NML3CfgCommitTypeHandle;
Packit 5756e2
Packit Service a1bd4f
NML3CfgCommitTypeHandle *nm_l3cfg_commit_type_register(NML3Cfg *                self,
Packit Service a1bd4f
                                                       NML3CfgCommitType        commit_type,
Packit Service a1bd4f
                                                       NML3CfgCommitTypeHandle *existing_handle);
Packit 5756e2
Packit Service a1bd4f
void nm_l3cfg_commit_type_unregister(NML3Cfg *self, NML3CfgCommitTypeHandle *handle);
Packit 5756e2
Packit 5756e2
/*****************************************************************************/
Packit 5756e2
Packit Service a1bd4f
const NML3ConfigData *nm_l3cfg_get_combined_l3cd(NML3Cfg *self, gboolean get_commited);
Packit Service a1bd4f
Packit Service a1bd4f
const NMPObject *
Packit Service a1bd4f
nm_l3cfg_get_best_default_route(NML3Cfg *self, int addr_family, gboolean get_commited);
Packit Service a1bd4f
Packit Service a1bd4f
/*****************************************************************************/
Packit Service a1bd4f
Packit Service a1bd4f
gboolean nm_l3cfg_has_commited_ip6_addresses_pending_dad(NML3Cfg *self);
Packit Service a1bd4f
Packit Service a1bd4f
/*****************************************************************************/
Packit Service a1bd4f
Packit Service a1bd4f
struct _NML3IPv4LL *nm_l3cfg_get_ipv4ll(NML3Cfg *self);
Packit Service a1bd4f
Packit Service a1bd4f
struct _NML3IPv4LL *nm_l3cfg_access_ipv4ll(NML3Cfg *self);
Packit 5756e2
Packit Service a1bd4f
void _nm_l3cfg_unregister_ipv4ll(NML3Cfg *self);
Packit 5756e2
Packit 5756e2
/*****************************************************************************/
Packit 5756e2
Packit 5756e2
#endif /* __NM_L3CFG_H__ */