summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2022-01-26 14:57:43 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2022-01-26 14:57:43 +0100
commitdd4386d5c6a66943c1d1aad93bcb8025d81d8b6b (patch)
tree87c7ff104ee1f0ff4a71f281434dcbd15d2f4040
parent62b2aa85e875d9c842f878cac896dd1fa7c5d988 (diff)
parentce0a36d20fa6a49723e8a630be3106ffe5e793fc (diff)
downloadNetworkManager-dd4386d5c6a66943c1d1aad93bcb8025d81d8b6b.tar.gz
merge: branch 'bg/500vlans'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1066 https://bugzilla.redhat.com/show_bug.cgi?id=2028849
-rw-r--r--src/core/devices/nm-device.c95
-rw-r--r--src/core/dhcp/nm-dhcp-client.c124
-rw-r--r--src/core/dhcp/nm-dhcp-client.h1
-rw-r--r--src/core/dns/nm-dns-manager.c25
-rw-r--r--src/core/nm-l3-config-data.c282
-rw-r--r--src/core/nm-l3-config-data.h15
-rw-r--r--src/core/nm-policy.c23
7 files changed, 408 insertions, 157 deletions
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
index 3786ba211f..3bb78c4b4a 100644
--- a/src/core/devices/nm-device.c
+++ b/src/core/devices/nm-device.c
@@ -815,8 +815,6 @@ static void _dev_ipdhcpx_set_state(NMDevice *self, int addr_family, NMDeviceIPSt
static void _dev_ipdhcpx_restart(NMDevice *self, int addr_family, gboolean release);
-static void _dev_ipdhcpx_handle_accept(NMDevice *self, int addr_family, const NML3ConfigData *l3cd);
-
static gboolean
_dev_ipac6_grace_period_start(NMDevice *self, guint32 timeout_sec, gboolean force_restart);
@@ -9916,63 +9914,6 @@ _dev_ipdhcpx_handle_fail(NMDevice *self, int addr_family, const char *reason)
}
static void
-_dev_ipdhcpx_handle_accept(NMDevice *self, int addr_family, const NML3ConfigData *l3cd)
-{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
- const int IS_IPv4 = NM_IS_IPv4(addr_family);
- gs_free_error GError *error = NULL;
-
- nm_assert(NM_IS_L3_CONFIG_DATA(l3cd));
-
- nm_dhcp_config_set_lease(priv->ipdhcp_data_x[IS_IPv4].config, l3cd);
- _dev_l3_register_l3cds_set_one_full(self,
- L3_CONFIG_DATA_TYPE_DHCP_X(IS_IPv4),
- l3cd,
- NM_L3CFG_CONFIG_FLAGS_FORCE_ONCE,
- TRUE);
-
- /* FIXME(l3cfg:dhcp): accept also should be handled by NMDhcpClient transparently.
- * NMDhcpClient should do ACD (if enabled), and only after that passes, it exposes
- * the lease to the user (NMDevice). NMDevice then may choose to configure the address.
- * NMDhcpClient then checks in NM_L3_CONFIG_NOTIFY_TYPE_POST_COMMIT whether the requested
- * address is to be configured by NML3Cfg (here, the intent is what matters, not
- * whether the address is actually visible in NMPlatform -- that is because while NML3Cfg
- * configures the address (in platform), the user might delete it right away. Also,
- * depending on the commit type, NML3Cfg may even choose not to configure it right now
- * (which arguably will be odd). Anyway, what matters is whether the user configured
- * the address in NML3Cfg (by checking the ObjStateData).
- *
- * If yes, then NMDhcpClient needs to accept automatically.
- *
- * Doing it here is wrong for two reasons:
- *
- * - NMDevice already has enough to do, it should not be concerned with telling
- * NMDhcpClient to accept the lease, it should only configure the address.
- *
- * - we should only accept the lease *after* configuring the address (see n_dhcp4_client_lease_accept().
- * Currently this only works by passing commit_sync=TRUE to _dev_l3_register_l3cds_set_one(), but
- * doing that is wrong (see FIXME why commit_sync needs to go away). */
- if (priv->ipdhcp_data_x[IS_IPv4].state != NM_DEVICE_IP_STATE_READY
- && !nm_dhcp_client_accept(priv->ipdhcp_data_x[IS_IPv4].client, &error)) {
- _LOGW(LOGD_DHCPX(IS_IPv4), "error accepting lease: %s", error->message);
- _dev_ipdhcpx_set_state(self, addr_family, NM_DEVICE_IP_STATE_FAILED);
- _dev_ip_state_check_async(self, addr_family);
- return;
- }
-
- _dev_ipdhcpx_set_state(self, addr_family, NM_DEVICE_IP_STATE_READY);
-
- nm_dispatcher_call_device(NM_DISPATCHER_ACTION_DHCP_CHANGE_X(IS_IPv4),
- self,
- NULL,
- NULL,
- NULL,
- NULL);
-
- _dev_ip_state_check_async(self, addr_family);
-}
-
-static void
_dev_ipdhcpx_notify(NMDhcpClient *client, const NMDhcpClientNotifyData *notify_data, NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
@@ -10015,8 +9956,32 @@ _dev_ipdhcpx_notify(NMDhcpClient *client, const NMDhcpClientNotifyData *notify_d
return;
}
+ if (notify_data->lease_update.accepted) {
+ _LOGT_ipdhcp(addr_family, "lease accepted");
+ if (priv->ipdhcp_data_x[IS_IPv4].state != NM_DEVICE_IP_STATE_READY) {
+ _dev_ipdhcpx_set_state(self, addr_family, NM_DEVICE_IP_STATE_READY);
+ nm_dispatcher_call_device(NM_DISPATCHER_ACTION_DHCP_CHANGE_X(IS_IPv4),
+ self,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ _dev_ip_state_check_async(self, addr_family);
+ }
+ return;
+ }
+
+ /* Schedule a commit of the configuration. The DHCP client
+ * will accept the lease once the address is committed, and
+ * will send a LEASE_UPDATE notification with accepted=1. */
_LOGT_ipdhcp(addr_family, "lease update");
- _dev_ipdhcpx_handle_accept(self, addr_family, notify_data->lease_update.l3cd);
+ nm_dhcp_config_set_lease(priv->ipdhcp_data_x[IS_IPv4].config,
+ notify_data->lease_update.l3cd);
+ _dev_l3_register_l3cds_set_one_full(self,
+ L3_CONFIG_DATA_TYPE_DHCP_X(IS_IPv4),
+ notify_data->lease_update.l3cd,
+ NM_L3CFG_CONFIG_FLAGS_FORCE_ONCE,
+ FALSE);
return;
}
@@ -10213,8 +10178,14 @@ _dev_ipdhcpx_start(NMDevice *self, int addr_family)
priv->ipdhcp_data_x[IS_IPv4].config = nm_dhcp_config_new(addr_family, previous_lease);
_notify(self, PROP_DHCPX_CONFIG(IS_IPv4));
}
- if (previous_lease)
- _dev_ipdhcpx_handle_accept(self, addr_family, previous_lease);
+ if (previous_lease) {
+ nm_dhcp_config_set_lease(priv->ipdhcp_data_x[IS_IPv4].config, previous_lease);
+ _dev_l3_register_l3cds_set_one_full(self,
+ L3_CONFIG_DATA_TYPE_DHCP_X(IS_IPv4),
+ previous_lease,
+ NM_L3CFG_CONFIG_FLAGS_FORCE_ONCE,
+ FALSE);
+ }
return;
diff --git a/src/core/dhcp/nm-dhcp-client.c b/src/core/dhcp/nm-dhcp-client.c
index f7c095fb8f..54f9ee59fd 100644
--- a/src/core/dhcp/nm-dhcp-client.c
+++ b/src/core/dhcp/nm-dhcp-client.c
@@ -43,12 +43,17 @@ typedef struct _NMDhcpClientPrivate {
const NML3ConfigData *l3cd;
GSource *no_lease_timeout_source;
GSource *ipv6_lladdr_timeout_source;
+ GBytes *effective_client_id;
pid_t pid;
guint watch_id;
NMDhcpState state;
bool iaid_explicit : 1;
bool is_stopped : 1;
- GBytes *effective_client_id;
+ struct {
+ gulong id;
+ bool wait_dhcp_commit : 1;
+ bool wait_ll_address : 1;
+ } l3cfg_notify;
} NMDhcpClientPrivate;
G_DEFINE_ABSTRACT_TYPE(NMDhcpClient, nm_dhcp_client, G_TYPE_OBJECT)
@@ -57,6 +62,11 @@ G_DEFINE_ABSTRACT_TYPE(NMDhcpClient, nm_dhcp_client, G_TYPE_OBJECT)
/*****************************************************************************/
+static void
+l3_cfg_notify_cb(NML3Cfg *l3cfg, const NML3ConfigNotifyData *notify_data, NMDhcpClient *self);
+
+/*****************************************************************************/
+
/* we use pid=-1 for invalid PIDs. Ensure that pid_t can hold negative values. */
G_STATIC_ASSERT(!(((pid_t) -1) > 0));
@@ -70,6 +80,27 @@ _emit_notify(NMDhcpClient *self, const NMDhcpClientNotifyData *notify_data)
/*****************************************************************************/
+static void
+connect_l3cfg_notify(NMDhcpClient *self)
+{
+ NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self);
+ gboolean do_connect;
+
+ do_connect = priv->l3cfg_notify.wait_dhcp_commit | priv->l3cfg_notify.wait_ll_address;
+
+ if (!do_connect) {
+ nm_clear_g_signal_handler(priv->config.l3cfg, &priv->l3cfg_notify.id);
+ return;
+ }
+
+ if (priv->l3cfg_notify.id == 0) {
+ priv->l3cfg_notify.id = g_signal_connect(priv->config.l3cfg,
+ NM_L3CFG_SIGNAL_NOTIFY,
+ G_CALLBACK(l3_cfg_notify_cb),
+ self);
+ }
+}
+
pid_t
nm_dhcp_client_get_pid(NMDhcpClient *self)
{
@@ -357,6 +388,9 @@ nm_dhcp_client_set_state(NMDhcpClient *self, NMDhcpState new_state, const NML3Co
},
};
+ priv->l3cfg_notify.wait_dhcp_commit = (new_state == NM_DHCP_STATE_BOUND);
+ connect_l3cfg_notify(self);
+
_emit_notify(self, &notify_data);
}
}
@@ -523,14 +557,20 @@ l3_cfg_notify_cb(NML3Cfg *l3cfg, const NML3ConfigNotifyData *notify_data, NMDhcp
nm_assert(l3cfg == priv->config.l3cfg);
- if (notify_data->notify_type == NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE_ON_IDLE) {
+ switch (notify_data->notify_type) {
+ case NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE_ON_IDLE:
+ {
const NMPlatformIP6Address *addr;
gs_free_error GError *error = NULL;
+ if (!priv->l3cfg_notify.wait_ll_address)
+ return;
+
addr = ipv6_lladdr_find(self);
if (addr) {
_LOGD("got IPv6LL address, starting transaction");
- g_signal_handlers_disconnect_by_func(l3cfg, l3_cfg_notify_cb, self);
+ priv->l3cfg_notify.wait_ll_address = FALSE;
+ connect_l3cfg_notify(self);
nm_clear_g_source_inst(&priv->ipv6_lladdr_timeout_source);
schedule_no_lease_timeout(self);
@@ -543,6 +583,74 @@ l3_cfg_notify_cb(NML3Cfg *l3cfg, const NML3ConfigNotifyData *notify_data, NMDhcp
}));
}
}
+
+ break;
+ }
+ case NM_L3_CONFIG_NOTIFY_TYPE_POST_COMMIT:
+ {
+ const NML3ConfigData *committed_l3cd;
+ NMDedupMultiIter ipconf_iter;
+ const NMPlatformIPAddress *lease_address;
+ gs_free_error GError *error = NULL;
+
+ /* A new configuration was committed to the interface. If we previously
+ * got a lease, check whether we are waiting for the address to be
+ * configured. If the address was added, we can proceed accepting the
+ * lease and notifying NMDevice. */
+
+ if (!priv->l3cfg_notify.wait_dhcp_commit)
+ return;
+
+ nm_l3_config_data_iter_ip_address_for_each (&ipconf_iter,
+ priv->l3cd,
+ priv->config.addr_family,
+ &lease_address)
+ break;
+ nm_assert(lease_address);
+ committed_l3cd = nm_l3cfg_get_combined_l3cd(l3cfg, TRUE);
+
+ if (priv->config.addr_family == AF_INET) {
+ const NMPlatformIP4Address *address4 = (const NMPlatformIP4Address *) lease_address;
+
+ if (!nm_l3_config_data_lookup_address_4(committed_l3cd,
+ address4->address,
+ address4->plen,
+ address4->peer_address))
+ return;
+ } else {
+ const NMPlatformIP6Address *address6 = (const NMPlatformIP6Address *) lease_address;
+
+ if (!nm_l3_config_data_lookup_address_6(committed_l3cd, &address6->address))
+ return;
+ }
+
+ priv->l3cfg_notify.wait_dhcp_commit = FALSE;
+ connect_l3cfg_notify(self);
+
+ _LOGD("accept address");
+
+ if (!nm_dhcp_client_accept(self, &error)) {
+ gs_free char *reason = g_strdup_printf("error accepting lease: %s", error->message);
+
+ _emit_notify(self,
+ &((NMDhcpClientNotifyData){
+ .notify_type = NM_DHCP_CLIENT_NOTIFY_TYPE_IT_LOOKS_BAD,
+ .it_looks_bad.reason = reason,
+ }));
+ return;
+ }
+
+ _emit_notify(
+ self,
+ &((NMDhcpClientNotifyData){.notify_type = NM_DHCP_CLIENT_NOTIFY_TYPE_LEASE_UPDATE,
+ .lease_update = {
+ .l3cd = priv->l3cd,
+ .accepted = TRUE,
+ }}));
+ break;
+ };
+ default:
+ /* ignore */;
}
}
@@ -569,10 +677,8 @@ nm_dhcp_client_start_ip6(NMDhcpClient *self, GError **error)
addr = ipv6_lladdr_find(self);
if (!addr) {
_LOGD("waiting for IPv6LL address");
- g_signal_connect(priv->config.l3cfg,
- NM_L3CFG_SIGNAL_NOTIFY,
- G_CALLBACK(l3_cfg_notify_cb),
- self);
+ priv->l3cfg_notify.wait_ll_address = TRUE;
+ connect_l3cfg_notify(self);
priv->ipv6_lladdr_timeout_source =
nm_g_timeout_add_seconds_source(10, ipv6_lladdr_timeout, self);
return TRUE;
@@ -657,7 +763,9 @@ nm_dhcp_client_stop(NMDhcpClient *self, gboolean release)
priv->is_stopped = TRUE;
- g_signal_handlers_disconnect_by_func(priv->config.l3cfg, l3_cfg_notify_cb, self);
+ priv->l3cfg_notify.wait_dhcp_commit = FALSE;
+ priv->l3cfg_notify.wait_ll_address = FALSE;
+ connect_l3cfg_notify(self);
/* Kill the DHCP client */
old_pid = priv->pid;
diff --git a/src/core/dhcp/nm-dhcp-client.h b/src/core/dhcp/nm-dhcp-client.h
index d8f659fa4a..249bd013ff 100644
--- a/src/core/dhcp/nm-dhcp-client.h
+++ b/src/core/dhcp/nm-dhcp-client.h
@@ -71,6 +71,7 @@ typedef struct {
* or NULL (if a previous lease timed out). It can also be the
* previous lease, that was injected. */
const NML3ConfigData *l3cd;
+ bool accepted;
} lease_update;
struct {
const NMPlatformIP6Address *prefix;
diff --git a/src/core/dns/nm-dns-manager.c b/src/core/dns/nm-dns-manager.c
index 8a8ab9eb06..efbf847b71 100644
--- a/src/core/dns/nm-dns-manager.c
+++ b/src/core/dns/nm-dns-manager.c
@@ -1862,6 +1862,7 @@ nm_dns_manager_set_ip_config(NMDnsManager *self,
gboolean changed = FALSE;
NMDnsConfigIPData *ip_data = NULL;
int dns_priority;
+ gboolean any_removed = FALSE;
g_return_val_if_fail(NM_IS_DNS_MANAGER(self), FALSE);
g_return_val_if_fail(!l3cd || NM_IS_L3_CONFIG_DATA(l3cd), FALSE);
@@ -1919,7 +1920,16 @@ nm_dns_manager_set_ip_config(NMDnsManager *self,
if (!replace_all && l3cd && ip_data_iter->l3cd != l3cd)
continue;
- changed = TRUE;
+ if (!l3cd || ip_config_type == NM_DNS_IP_CONFIG_TYPE_REMOVED
+ || nm_l3_config_data_cmp_full(l3cd,
+ ip_data_iter->l3cd,
+ NM_L3_CONFIG_CMP_FLAGS_DNS
+ | NM_L3_CONFIG_CMP_FLAGS_ROUTES_ID)
+ != 0) {
+ changed = TRUE;
+ }
+
+ any_removed = TRUE;
_dns_config_ip_data_free(ip_data_iter);
}
}
@@ -1941,8 +1951,6 @@ nm_dns_manager_set_ip_config(NMDnsManager *self,
goto done;
}
- changed = TRUE;
-
if (!data) {
data = g_slice_new(NMDnsConfigData);
*data = (NMDnsConfigData){
@@ -1956,12 +1964,17 @@ nm_dns_manager_set_ip_config(NMDnsManager *self,
priv->configs_lst_need_sort = TRUE;
}
- if (!ip_data)
+ if (!ip_data) {
ip_data = _dns_config_ip_data_new(data, addr_family, source_tag, l3cd, ip_config_type);
- else
+ if (!any_removed)
+ changed = TRUE;
+ } else {
ip_data->ip_config_type = ip_config_type;
+ changed = TRUE;
+ }
- priv->ip_data_lst_need_sort = TRUE;
+ if (changed)
+ priv->ip_data_lst_need_sort = TRUE;
nm_assert(l3cd);
nm_assert(ip_config_type != NM_DNS_IP_CONFIG_TYPE_REMOVED);
diff --git a/src/core/nm-l3-config-data.c b/src/core/nm-l3-config-data.c
index 8d6ac09e92..226ccd0025 100644
--- a/src/core/nm-l3-config-data.c
+++ b/src/core/nm-l3-config-data.c
@@ -634,7 +634,7 @@ _route_valid(int addr_family, gconstpointer r)
static gboolean
_NM_IS_L3_CONFIG_DATA(const NML3ConfigData *self, gboolean allow_sealed)
{
- nm_assert(!self || (self->ifindex > 0 && self->multi_idx && self->ref_count > 0));
+ nm_assert(!self || (self->ifindex >= 0 && self->multi_idx && self->ref_count > 0));
return self && self->ref_count > 0 && (allow_sealed || !self->is_sealed);
}
@@ -2081,7 +2081,8 @@ static int
_dedup_multi_index_cmp(const NML3ConfigData *a,
const NML3ConfigData *b,
NMPObjectType obj_type,
- gboolean ignore_ifindex)
+ gboolean cmp_ifindex,
+ gboolean cmp_full)
{
const NMDedupMultiHeadEntry *h_a = nm_l3_config_data_lookup_objs(a, obj_type);
const NMDedupMultiHeadEntry *h_b = nm_l3_config_data_lookup_objs(b, obj_type);
@@ -2120,93 +2121,221 @@ _dedup_multi_index_cmp(const NML3ConfigData *a,
have_b = nm_platform_dedup_multi_iter_next_obj(&iter_b, &obj_b, obj_type);
nm_assert(have_b);
- NM_CMP_RETURN(nmp_object_cmp_full(obj_a,
- obj_b,
- ignore_ifindex ? NMP_OBJECT_CMP_FLAGS_IGNORE_IFINDEX
- : NMP_OBJECT_CMP_FLAGS_NONE));
+ if (cmp_full) {
+ NM_CMP_RETURN(nmp_object_cmp_full(obj_a,
+ obj_b,
+ cmp_ifindex ? NMP_OBJECT_CMP_FLAGS_NONE
+ : NMP_OBJECT_CMP_FLAGS_IGNORE_IFINDEX));
+ } else {
+ if (cmp_ifindex) {
+ NM_CMP_DIRECT(obj_a->obj_with_ifindex.ifindex, obj_b->obj_with_ifindex.ifindex);
+ }
+
+ switch (obj_type) {
+ case NMP_OBJECT_TYPE_IP4_ADDRESS:
+ NM_CMP_DIRECT(obj_a->ip4_address.plen, obj_b->ip4_address.plen);
+ NM_CMP_DIRECT(obj_b->ip4_address.address, obj_b->ip4_address.address);
+ NM_CMP_DIRECT(obj_b->ip4_address.peer_address, obj_b->ip4_address.peer_address);
+ break;
+ case NMP_OBJECT_TYPE_IP6_ADDRESS:
+ NM_CMP_DIRECT(obj_a->ip6_address.plen, obj_b->ip6_address.plen);
+ NM_CMP_DIRECT_IN6ADDR(&obj_a->ip6_address.address, &obj_b->ip6_address.address);
+ break;
+ case NMP_OBJECT_TYPE_IP4_ROUTE:
+ {
+ NMPlatformIP4Route ra = obj_a->ip4_route;
+ NMPlatformIP4Route rb = obj_b->ip4_route;
+
+ NM_CMP_DIRECT(ra.metric, rb.metric);
+ NM_CMP_DIRECT(ra.plen, rb.plen);
+ NM_CMP_RETURN_DIRECT(
+ nm_utils_ip4_address_same_prefix_cmp(ra.network, rb.network, ra.plen));
+ break;
+ }
+ case NMP_OBJECT_TYPE_IP6_ROUTE:
+ {
+ NMPlatformIP6Route ra = obj_a->ip6_route;
+ NMPlatformIP6Route rb = obj_b->ip6_route;
+
+ NM_CMP_DIRECT(ra.metric, rb.metric);
+ NM_CMP_DIRECT(ra.plen, rb.plen);
+ NM_CMP_RETURN_DIRECT(
+ nm_utils_ip6_address_same_prefix_cmp(&ra.network, &rb.network, ra.plen));
+ break;
+ }
+ default:
+ nm_assert_not_reached();
+ }
+ }
}
}
+static const NML3ConfigData *
+get_empty_l3cd(void)
+{
+ static NML3ConfigData *empty_l3cd;
+
+ if (!empty_l3cd) {
+ empty_l3cd =
+ nm_l3_config_data_new(nm_dedup_multi_index_new(), 1, NM_IP_CONFIG_SOURCE_UNKNOWN);
+ empty_l3cd->ifindex = 0;
+ }
+
+ return empty_l3cd;
+}
+
int
nm_l3_config_data_cmp_full(const NML3ConfigData *a,
const NML3ConfigData *b,
- NML3ConfigCmpFlags cmp_flags)
+ NML3ConfigCmpFlags flags)
{
- int IS_IPv4;
- gboolean ignore_ifindex;
+ int IS_IPv4;
- NM_CMP_SELF(a, b);
+ if (a == b)
+ return 0;
- ignore_ifindex = NM_FLAGS_HAS(cmp_flags, NM_L3_CONFIG_CMP_FLAGS_IGNORE_IFINDEX);
+ if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ADDRESSES))
+ flags |= NM_L3_CONFIG_CMP_FLAGS_ADDRESSES_ID;
+ if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ROUTES))
+ flags |= NM_L3_CONFIG_CMP_FLAGS_ROUTES_ID;
- if (!ignore_ifindex)
- NM_CMP_DIRECT(a->ifindex, b->ifindex);
+ if (!a)
+ a = get_empty_l3cd();
+ if (!b)
+ b = get_empty_l3cd();
- NM_CMP_DIRECT(a->flags, b->flags);
+ if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_IFINDEX))
+ NM_CMP_DIRECT(a->ifindex, b->ifindex);
- NM_CMP_RETURN(_dedup_multi_index_cmp(a, b, NMP_OBJECT_TYPE_IP4_ADDRESS, ignore_ifindex));
- NM_CMP_RETURN(_dedup_multi_index_cmp(a, b, NMP_OBJECT_TYPE_IP6_ADDRESS, ignore_ifindex));
- NM_CMP_RETURN(_dedup_multi_index_cmp(a, b, NMP_OBJECT_TYPE_IP4_ROUTE, ignore_ifindex));
- NM_CMP_RETURN(_dedup_multi_index_cmp(a, b, NMP_OBJECT_TYPE_IP6_ROUTE, ignore_ifindex));
+ if (NM_FLAGS_ANY(flags,
+ NM_L3_CONFIG_CMP_FLAGS_ADDRESSES | NM_L3_CONFIG_CMP_FLAGS_ADDRESSES_ID)) {
+ NM_CMP_RETURN(
+ _dedup_multi_index_cmp(a,
+ b,
+ NMP_OBJECT_TYPE_IP4_ADDRESS,
+ NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_IFINDEX),
+ NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ADDRESSES)));
+ NM_CMP_RETURN(
+ _dedup_multi_index_cmp(a,
+ b,
+ NMP_OBJECT_TYPE_IP6_ADDRESS,
+ NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_IFINDEX),
+ NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ADDRESSES)));
+ }
+
+ if (NM_FLAGS_ANY(flags, NM_L3_CONFIG_CMP_FLAGS_ROUTES | NM_L3_CONFIG_CMP_FLAGS_ROUTES_ID)) {
+ NM_CMP_RETURN(_dedup_multi_index_cmp(a,
+ b,
+ NMP_OBJECT_TYPE_IP4_ROUTE,
+ NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_IFINDEX),
+ NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ROUTES)));
+ NM_CMP_RETURN(_dedup_multi_index_cmp(a,
+ b,
+ NMP_OBJECT_TYPE_IP6_ROUTE,
+ NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_IFINDEX),
+ NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ROUTES)));
+ }
for (IS_IPv4 = 1; IS_IPv4 >= 0; IS_IPv4--) {
- const int addr_family = IS_IPv4 ? AF_INET : AF_INET6;
+ const int addr_family = IS_IPv4 ? AF_INET : AF_INET6;
+ const NMPObject *def_route_a = a->best_default_route_x[IS_IPv4];
+ const NMPObject *def_route_b = b->best_default_route_x[IS_IPv4];
+
+ NM_CMP_SELF(def_route_a, def_route_b);
+
+ if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ROUTES)) {
+ NM_CMP_RETURN(nmp_object_cmp_full(def_route_a,
+ def_route_b,
+ NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_IFINDEX)
+ ? NMP_OBJECT_CMP_FLAGS_NONE
+ : NMP_OBJECT_CMP_FLAGS_IGNORE_IFINDEX));
+ } else if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ROUTES_ID)) {
+ if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_IFINDEX)) {
+ NM_CMP_DIRECT(def_route_a->obj_with_ifindex.ifindex,
+ def_route_b->obj_with_ifindex.ifindex);
+ }
- NM_CMP_RETURN(nmp_object_cmp_full(a->best_default_route_x[IS_IPv4],
- b->best_default_route_x[IS_IPv4],
- ignore_ifindex ? NMP_OBJECT_CMP_FLAGS_IGNORE_IFINDEX
- : NMP_OBJECT_CMP_FLAGS_NONE));
+ if (IS_IPv4) {
+ NMPlatformIP4Route ra = def_route_a->ip4_route;
+ NMPlatformIP4Route rb = def_route_b->ip4_route;
+
+ NM_CMP_DIRECT(ra.metric, rb.metric);
+ NM_CMP_DIRECT(ra.plen, rb.plen);
+ NM_CMP_RETURN_DIRECT(
+ nm_utils_ip4_address_same_prefix_cmp(ra.network, rb.network, ra.plen));
+ } else {
+ NMPlatformIP6Route ra = def_route_a->ip6_route;
+ NMPlatformIP6Route rb = def_route_b->ip6_route;
+
+ NM_CMP_DIRECT(ra.metric, rb.metric);
+ NM_CMP_DIRECT(ra.plen, rb.plen);
+ NM_CMP_RETURN_DIRECT(
+ nm_utils_ip6_address_same_prefix_cmp(&ra.network, &rb.network, ra.plen));
+ }
+ }
- NM_CMP_RETURN(
- _garray_inaddr_cmp(a->nameservers_x[IS_IPv4], b->nameservers_x[IS_IPv4], addr_family));
-
- NM_CMP_RETURN(nm_utils_hashtable_cmp(nm_dhcp_lease_get_options(a->dhcp_lease_x[IS_IPv4]),
- nm_dhcp_lease_get_options(b->dhcp_lease_x[IS_IPv4]),
- TRUE,
- nm_strcmp_with_data,
- nm_strcmp_with_data,
- NULL));
-
- NM_CMP_RETURN(nm_strv_ptrarray_cmp(a->domains_x[IS_IPv4], b->domains_x[IS_IPv4]));
- NM_CMP_RETURN(nm_strv_ptrarray_cmp(a->searches_x[IS_IPv4], b->searches_x[IS_IPv4]));
- NM_CMP_RETURN(nm_strv_ptrarray_cmp(a->dns_options_x[IS_IPv4], b->dns_options_x[IS_IPv4]));
-
- if (NM_FLAGS_ANY(a->flags, NM_L3_CONFIG_DAT_FLAGS_HAS_DNS_PRIORITY(IS_IPv4)))
- NM_CMP_DIRECT(a->dns_priority_x[IS_IPv4], b->dns_priority_x[IS_IPv4]);
-
- NM_CMP_DIRECT(a->route_table_sync_x[IS_IPv4], b->route_table_sync_x[IS_IPv4]);
- NM_CMP_DIRECT(a->never_default_x[IS_IPv4], b->never_default_x[IS_IPv4]);
- }
-
- NM_CMP_RETURN(_garray_inaddr_cmp(a->wins, b->wins, AF_INET));
- NM_CMP_RETURN(_garray_inaddr_cmp(a->nis_servers, b->nis_servers, AF_INET));
- NM_CMP_DIRECT_REF_STRING(a->nis_domain, b->nis_domain);
- NM_CMP_DIRECT(a->mdns, b->mdns);
- NM_CMP_DIRECT(a->llmnr, b->llmnr);
- NM_CMP_DIRECT(a->dns_over_tls, b->dns_over_tls);
- NM_CMP_DIRECT(a->ip6_token.id, b->ip6_token.id);
- NM_CMP_DIRECT(a->mtu, b->mtu);
- NM_CMP_DIRECT(a->ip6_mtu, b->ip6_mtu);
- NM_CMP_DIRECT_UNSAFE(a->metered, b->metered);
- NM_CMP_DIRECT_UNSAFE(a->proxy_browser_only, b->proxy_browser_only);
- NM_CMP_DIRECT_UNSAFE(a->proxy_method, b->proxy_method);
- NM_CMP_DIRECT_REF_STRING(a->proxy_pac_url, b->proxy_pac_url);
- NM_CMP_DIRECT_REF_STRING(a->proxy_pac_script, b->proxy_pac_script);
- NM_CMP_DIRECT_UNSAFE(a->ip6_privacy, b->ip6_privacy);
-
- NM_CMP_DIRECT_UNSAFE(a->ndisc_hop_limit_set, b->ndisc_hop_limit_set);
- if (a->ndisc_hop_limit_set)
- NM_CMP_DIRECT(a->ndisc_hop_limit_val, b->ndisc_hop_limit_val);
-
- NM_CMP_DIRECT_UNSAFE(a->ndisc_reachable_time_msec_set, b->ndisc_reachable_time_msec_set);
- if (a->ndisc_reachable_time_msec_set)
- NM_CMP_DIRECT(a->ndisc_reachable_time_msec_val, b->ndisc_reachable_time_msec_val);
-
- NM_CMP_DIRECT_UNSAFE(a->ndisc_retrans_timer_msec_set, b->ndisc_retrans_timer_msec_set);
- if (a->ndisc_retrans_timer_msec_set)
- NM_CMP_DIRECT(a->ndisc_retrans_timer_msec_val, b->ndisc_retrans_timer_msec_val);
-
- NM_CMP_FIELD(a, b, source);
+ if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_DNS)) {
+ NM_CMP_RETURN(_garray_inaddr_cmp(a->nameservers_x[IS_IPv4],
+ b->nameservers_x[IS_IPv4],
+ addr_family));
+ NM_CMP_RETURN(nm_strv_ptrarray_cmp(a->domains_x[IS_IPv4], b->domains_x[IS_IPv4]));
+ NM_CMP_RETURN(nm_strv_ptrarray_cmp(a->searches_x[IS_IPv4], b->searches_x[IS_IPv4]));
+ NM_CMP_RETURN(
+ nm_strv_ptrarray_cmp(a->dns_options_x[IS_IPv4], b->dns_options_x[IS_IPv4]));
+
+ if (NM_FLAGS_ANY(a->flags, NM_L3_CONFIG_DAT_FLAGS_HAS_DNS_PRIORITY(IS_IPv4)))
+ NM_CMP_DIRECT(a->dns_priority_x[IS_IPv4], b->dns_priority_x[IS_IPv4]);
+ }
+
+ if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_OTHER)) {
+ NM_CMP_RETURN(
+ nm_utils_hashtable_cmp(nm_dhcp_lease_get_options(a->dhcp_lease_x[IS_IPv4]),
+ nm_dhcp_lease_get_options(b->dhcp_lease_x[IS_IPv4]),
+ TRUE,
+ nm_strcmp_with_data,
+ nm_strcmp_with_data,
+ NULL));
+
+ NM_CMP_DIRECT(a->route_table_sync_x[IS_IPv4], b->route_table_sync_x[IS_IPv4]);
+ NM_CMP_DIRECT(a->never_default_x[IS_IPv4], b->never_default_x[IS_IPv4]);
+ }
+ }
+
+ if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_DNS)) {
+ NM_CMP_RETURN(_garray_inaddr_cmp(a->wins, b->wins, AF_INET));
+ NM_CMP_RETURN(_garray_inaddr_cmp(a->nis_servers, b->nis_servers, AF_INET));
+ NM_CMP_DIRECT_REF_STRING(a->nis_domain, b->nis_domain);
+ NM_CMP_DIRECT(a->mdns, b->mdns);
+ NM_CMP_DIRECT(a->llmnr, b->llmnr);
+ NM_CMP_DIRECT(a->dns_over_tls, b->dns_over_tls);
+ }
+
+ if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_OTHER)) {
+ NM_CMP_DIRECT(a->flags, b->flags);
+ NM_CMP_DIRECT(a->ip6_token.id, b->ip6_token.id);
+ NM_CMP_DIRECT(a->mtu, b->mtu);
+ NM_CMP_DIRECT(a->ip6_mtu, b->ip6_mtu);
+ NM_CMP_DIRECT_UNSAFE(a->metered, b->metered);
+ NM_CMP_DIRECT_UNSAFE(a->proxy_browser_only, b->proxy_browser_only);
+ NM_CMP_DIRECT_UNSAFE(a->proxy_method, b->proxy_method);
+ NM_CMP_DIRECT_REF_STRING(a->proxy_pac_url, b->proxy_pac_url);
+ NM_CMP_DIRECT_REF_STRING(a->proxy_pac_script, b->proxy_pac_script);
+ NM_CMP_DIRECT_UNSAFE(a->ip6_privacy, b->ip6_privacy);
+
+ NM_CMP_DIRECT_UNSAFE(a->ndisc_hop_limit_set, b->ndisc_hop_limit_set);
+ if (a->ndisc_hop_limit_set)
+ NM_CMP_DIRECT(a->ndisc_hop_limit_val, b->ndisc_hop_limit_val);
+
+ NM_CMP_DIRECT_UNSAFE(a->ndisc_reachable_time_msec_set, b->ndisc_reachable_time_msec_set);
+ if (a->ndisc_reachable_time_msec_set)
+ NM_CMP_DIRECT(a->ndisc_reachable_time_msec_val, b->ndisc_reachable_time_msec_val);
+
+ NM_CMP_DIRECT_UNSAFE(a->ndisc_retrans_timer_msec_set, b->ndisc_retrans_timer_msec_set);
+ if (a->ndisc_retrans_timer_msec_set)
+ NM_CMP_DIRECT(a->ndisc_retrans_timer_msec_val, b->ndisc_retrans_timer_msec_val);
+
+ NM_CMP_FIELD(a, b, source);
+ }
/* these fields are not considered by cmp():
*
@@ -3180,9 +3309,10 @@ nm_l3_config_data_new_clone(const NML3ConfigData *src, int ifindex)
nm_assert(nm_l3_config_data_cmp_full(src,
self,
- src->ifindex != ifindex
- ? NM_L3_CONFIG_CMP_FLAGS_IGNORE_IFINDEX
- : NM_L3_CONFIG_CMP_FLAGS_NONE)
+ src->ifindex == ifindex
+ ? NM_L3_CONFIG_CMP_FLAGS_ALL
+ : NM_L3_CONFIG_CMP_FLAGS_ALL
+ & ~(NM_L3_CONFIG_CMP_FLAGS_IFINDEX))
== 0);
nm_assert(nm_l3_config_data_get_ifindex(self) == ifindex);
diff --git a/src/core/nm-l3-config-data.h b/src/core/nm-l3-config-data.h
index 1c776d4edb..b7a1bb32f5 100644
--- a/src/core/nm-l3-config-data.h
+++ b/src/core/nm-l3-config-data.h
@@ -198,18 +198,25 @@ NMDedupMultiIndex *nm_l3_config_data_get_multi_idx(const NML3ConfigData *self);
/*****************************************************************************/
typedef enum {
- NM_L3_CONFIG_CMP_FLAGS_NONE,
- NM_L3_CONFIG_CMP_FLAGS_IGNORE_IFINDEX = (1LL << 0),
+ NM_L3_CONFIG_CMP_FLAGS_NONE = 0,
+ NM_L3_CONFIG_CMP_FLAGS_IFINDEX = (1LL << 0),
+ NM_L3_CONFIG_CMP_FLAGS_ADDRESSES_ID = (1LL << 1),
+ NM_L3_CONFIG_CMP_FLAGS_ADDRESSES = (1LL << 2),
+ NM_L3_CONFIG_CMP_FLAGS_ROUTES_ID = (1LL << 3),
+ NM_L3_CONFIG_CMP_FLAGS_ROUTES = (1LL << 4),
+ NM_L3_CONFIG_CMP_FLAGS_DNS = (1LL << 5),
+ NM_L3_CONFIG_CMP_FLAGS_OTHER = (1LL << 6),
+ NM_L3_CONFIG_CMP_FLAGS_ALL = (1LL << 7) - 1,
} NML3ConfigCmpFlags;
int nm_l3_config_data_cmp_full(const NML3ConfigData *a,
const NML3ConfigData *b,
- NML3ConfigCmpFlags cmp_flags);
+ NML3ConfigCmpFlags flags);
static inline int
nm_l3_config_data_cmp(const NML3ConfigData *a, const NML3ConfigData *b)
{
- return nm_l3_config_data_cmp_full(a, b, NM_L3_CONFIG_CMP_FLAGS_NONE);
+ return nm_l3_config_data_cmp_full(a, b, NM_L3_CONFIG_CMP_FLAGS_ALL);
}
static inline gboolean
diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c
index c4ae8e2abb..cb5b543e9d 100644
--- a/src/core/nm-policy.c
+++ b/src/core/nm-policy.c
@@ -1995,6 +1995,26 @@ device_state_changed(NMDevice *device,
/* Reset auto retries back to default since connection was successful */
nm_settings_connection_autoconnect_retries_reset(sett_conn);
}
+
+ /* Since there is no guarantee that device_l3cd_changed() is called
+ * again when the device becomes ACTIVATED, we need also to update
+ * routing and DNS here. */
+ nm_dns_manager_begin_updates(priv->dns_manager, __func__);
+ if (!nm_device_sys_iface_state_is_external(device)) {
+ nm_dns_manager_set_ip_config(priv->dns_manager,
+ AF_UNSPEC,
+ device,
+ nm_device_get_l3cd(device, TRUE),
+ NM_DNS_IP_CONFIG_TYPE_DEFAULT,
+ TRUE);
+ }
+ update_ip_dns(self, AF_INET, device);
+ update_ip_dns(self, AF_INET6, device);
+ update_ip4_routing(self, TRUE);
+ update_ip6_routing(self, TRUE);
+ update_system_hostname(self, "routing and dns");
+ nm_dns_manager_end_updates(priv->dns_manager, __func__);
+
break;
case NM_DEVICE_STATE_UNMANAGED:
case NM_DEVICE_STATE_UNAVAILABLE:
@@ -2122,7 +2142,7 @@ device_l3cd_changed(NMDevice *device,
* now.
*/
state = nm_device_get_state(device);
- if (l3cd_new && state > NM_DEVICE_STATE_DISCONNECTED && state < NM_DEVICE_STATE_DEACTIVATING) {
+ if (l3cd_new && state > NM_DEVICE_STATE_IP_CONFIG && state < NM_DEVICE_STATE_DEACTIVATING) {
nm_dns_manager_set_ip_config(priv->dns_manager,
AF_UNSPEC,
device,
@@ -2800,6 +2820,7 @@ constructed(GObject *object)
G_OBJECT_CLASS(nm_policy_parent_class)->constructed(object);
_LOGD(LOGD_DNS, "hostname-mode: %s", _hostname_mode_to_string(priv->hostname_mode));
+ update_system_hostname(self, "initial hostname");
}
NMPolicy *