device: wait DAD before starting dnsmasq in IPv4 shared mode

Currently, IPv4 shared mode fails to start when DAD is enabled because
dnsmasq tries to bind to an address that is not yet configured on the
interface. Delay the start of dnsmasq until the shared4 l3cd is ready.

Fixes: 58287cbcc0 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
This commit is contained in:
Beniamino Galvani 2023-09-01 09:42:46 +02:00
parent 9b0b28acf7
commit e97ebb2441

View file

@ -4284,7 +4284,6 @@ _dev_l3_cfg_notify_cb(NML3Cfg *l3cfg, const NML3ConfigNotifyData *notify_data, N
if (priv->ipshared_data_4.state == NM_DEVICE_IP_STATE_PENDING
&& !priv->ipshared_data_4.v4.dnsmasq_manager && priv->ipshared_data_4.v4.l3cd) {
_dev_ipshared4_spawn_dnsmasq(self);
nm_clear_l3cd(&priv->ipshared_data_4.v4.l3cd);
}
_dev_ip_state_check_async(self, AF_UNSPEC);
_dev_ipmanual_check_ready(self);
@ -12732,18 +12731,32 @@ out_fail:
static void
_dev_ipshared4_spawn_dnsmasq(NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
const char *ip_iface;
gs_free_error GError *error = NULL;
NMSettingConnection *s_con;
gboolean announce_android_metered;
NMConnection *applied;
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
const char *ip_iface;
gs_free_error GError *error = NULL;
NMSettingConnection *s_con;
gboolean announce_android_metered;
NMConnection *applied;
gs_unref_array GArray *conflicts = NULL;
gboolean ready;
nm_assert(priv->ipshared_data_4.v4.firewall_config);
nm_assert(priv->ipshared_data_4.v4.dnsmasq_state_id == 0);
nm_assert(!priv->ipshared_data_4.v4.dnsmasq_manager);
nm_assert(priv->ipshared_data_4.v4.l3cd);
ready = nm_l3cfg_check_ready(priv->l3cfg,
priv->l3cds[L3_CONFIG_DATA_TYPE_SHARED_4].d,
AF_INET,
NM_L3CFG_CHECK_READY_FLAGS_IP4_ACD_READY,
&conflicts);
if (!ready) {
_LOGT_ipshared(AF_INET, "address not ready, wait");
return;
}
if (conflicts)
goto out_fail;
ip_iface = nm_device_get_ip_iface(self);
g_return_if_fail(ip_iface);
@ -12788,9 +12801,11 @@ _dev_ipshared4_spawn_dnsmasq(NMDevice *self)
_dev_ipsharedx_set_state(self, AF_INET, NM_DEVICE_IP_STATE_READY);
_dev_ip_state_check_async(self, AF_INET);
nm_clear_l3cd(&priv->ipshared_data_4.v4.l3cd);
return;
out_fail:
nm_clear_l3cd(&priv->ipshared_data_4.v4.l3cd);
_dev_ipsharedx_set_state(self, AF_INET, NM_DEVICE_IP_STATE_FAILED);
_dev_ip_state_check_async(self, AF_INET);
}