l3cfg: implement IPv4 DAD/ACD (address collision detection) in NML3Cfg

Currently, NMDevice does ACD. It intercepts certain NMIP4Config
instances, and tries to perform ACD on the addresses. I think this
functionality should be handled by NML3Cfg instead.

For one, NML3Cfg sees all configurations, and can perform ACD for all
(relevant) addresses. Also, it moves logic away from NMDevice and makes
the functionality available without an NMDevice. As such, it also will
allow that independent "controllers" contribute NML3ConfigData instances
and ACD will performed for all of them (as requested).

This will be our implementation for IPv4 ACD (https://tools.ietf.org/html/rfc5227)
based on nettools' n-acd library.

The code is not actually tested yes, because NMDevice did not yet switch
over to use NML3Cfg. Once that happens, surely issues with this patch
will be found that will need fixing.
This commit is contained in:
Thomas Haller 2020-08-03 17:33:31 +02:00
parent f81360bbbf
commit e4f04267bb
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
4 changed files with 1891 additions and 113 deletions

View file

@ -2470,7 +2470,9 @@ src_nm_iface_helper_LDADD = \
shared/nm-std-aux/libnm-std-aux.la \
src/libnm-systemd-core.la \
shared/systemd/libnm-systemd-shared.la \
shared/libnacd.la \
shared/libndhcp4.la \
shared/libcrbtree.la \
shared/libcsiphash.la \
$(GLIB_LIBS) \
$(LIBUDEV_LIBS) \

View file

@ -194,19 +194,16 @@ libnetwork_manager = static_library(
link_with: nm_links,
)
deps = [
daemon_nm_default_dep,
dl_dep,
libndp_dep,
libudev_dep,
]
name = 'nm-iface-helper'
executable(
name,
name + '.c',
dependencies: deps,
'nm-iface-helper',
'nm-iface-helper.c',
dependencies: [
daemon_nm_default_dep,
dl_dep,
libndp_dep,
libudev_dep,
libn_acd_dep,
],
c_args: daemon_c_flags,
link_with: nm_links,
link_args: ldflags_linker_script_binary,

File diff suppressed because it is too large Load diff

View file

@ -20,10 +20,26 @@
typedef enum {
NM_L3_CONFIG_NOTIFY_TYPE_ROUTES_TEMPORARY_NOT_AVAILABLE_EXPIRED,
NM_L3_CONFIG_NOTIFY_TYPE_ACD_FAILED,
NM_L3_CONFIG_NOTIFY_TYPE_ACD_COMPLETED,
_NM_L3_CONFIG_NOTIFY_TYPE_NUM,
} NML3ConfigNotifyType;
#define NM_L3_CONFIG_NOTIFY_TYPE_ROUTES_TEMPORARY_NOT_AVAILABLE_EXPIRED_DETAIL "routes-temporary-not-available"
typedef struct {
const NMPObject *obj;
const NML3ConfigData *l3cd;
gconstpointer tag;
} NML3ConfigNotifyPayloadAcdFailedSource;
typedef struct {
union {
struct {
in_addr_t addr;
guint sources_len;
const NML3ConfigNotifyPayloadAcdFailedSource *sources;
} acd_failed;
};
} NML3ConfigNotifyPayload;
struct _NML3CfgPrivate;
@ -87,6 +103,8 @@ nm_l3cfg_get_platform (const NML3Cfg *self)
return self->priv.platform;
}
gboolean nm_l3cfg_get_acd_is_pending (NML3Cfg *self);
/*****************************************************************************/
typedef enum {
@ -117,6 +135,7 @@ void nm_l3cfg_add_config (NML3Cfg *self,
int priority,
guint32 default_route_penalty_4,
guint32 default_route_penalty_6,
guint32 acd_timeout_msec,
NML3ConfigMergeFlags merge_flags);
void nm_l3cfg_remove_config (NML3Cfg *self,
@ -145,6 +164,7 @@ typedef enum {
/* 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;
gboolean nm_l3cfg_platform_commit (NML3Cfg *self,