From 813b5dfb4b92bb6765cf4a518a9b25845155b100 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Mon, 13 Jun 2022 11:21:15 +0200 Subject: [PATCH] ppp: don't remove addresses from interface while IPCP/IPV6CP is running pppd also tries to configure addresses by itself through some ioctls. If we remove between those calls an address that was added, pppd fails and quits. To avoid this race condition, don't remove addresses while IPCP and IPV6CP are running. Once pppd sends an IP configuration, it has finished configuring the interface and we can proceed normally. https://bugzilla.redhat.com/show_bug.cgi?id=2085382 (cherry picked from commit b41b11d613a2ed466975eaf4b7a13ff67662a772) (cherry picked from commit e95b44bacbafe577111dcefc50f1775e3345214e) --- src/core/devices/nm-device-ppp.c | 37 +++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/core/devices/nm-device-ppp.c b/src/core/devices/nm-device-ppp.c index 61e32348c4..6615b65e02 100644 --- a/src/core/devices/nm-device-ppp.c +++ b/src/core/devices/nm-device-ppp.c @@ -23,6 +23,13 @@ typedef struct _NMDevicePppPrivate { NMPppMgr *ppp_mgr; + union { + struct { + NML3CfgBlockHandle *l3cfg_block_handle_6; + NML3CfgBlockHandle *l3cfg_block_handle_4; + }; + NML3CfgBlockHandle *l3cfg_block_handle_x[2]; + }; } NMDevicePppPrivate; struct _NMDevicePpp { @@ -69,8 +76,10 @@ _ppp_mgr_stage3_maybe_ready(NMDevicePpp *self) const NMPppMgrIPData *ip_data; ip_data = nm_ppp_mgr_get_ip_data(priv->ppp_mgr, addr_family); - if (ip_data->ip_received) + if (ip_data->ip_received) { + nm_clear_pointer(&priv->l3cfg_block_handle_x[IS_IPv4], nm_l3cfg_unblock_obj_pruning); nm_device_devip_set_state(device, addr_family, NM_DEVICE_IP_STATE_READY, ip_data->l3cd); + } } if (nm_ppp_mgr_get_state(priv->ppp_mgr) >= NM_PPP_MGR_STATE_HAVE_IP_CONFIG) @@ -80,9 +89,10 @@ _ppp_mgr_stage3_maybe_ready(NMDevicePpp *self) static void _ppp_mgr_callback(NMPppMgr *ppp_mgr, const NMPppMgrCallbackData *callback_data, gpointer user_data) { - NMDevicePpp *self = NM_DEVICE_PPP(user_data); - NMDevice *device = NM_DEVICE(self); - NMDeviceState device_state; + NMDevicePpp *self = NM_DEVICE_PPP(user_data); + NMDevice *device = NM_DEVICE(self); + NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE(self); + NMDeviceState device_state; if (callback_data->callback_type != NM_PPP_MGR_CALLBACK_TYPE_STATE_CHANGED) return; @@ -112,6 +122,19 @@ _ppp_mgr_callback(NMPppMgr *ppp_mgr, const NMPppMgrCallbackData *callback_data, return; } + /* pppd also tries to configure addresses by itself through some + * ioctls. If we remove between those calls an address that was added, + * pppd fails and quits. Temporarily block the removal of addresses + * and routes. */ + if (!priv->l3cfg_block_handle_4) { + priv->l3cfg_block_handle_4 = + nm_l3cfg_block_obj_pruning(nm_device_get_l3cfg(device), AF_INET); + } + if (!priv->l3cfg_block_handle_6) { + priv->l3cfg_block_handle_6 = + nm_l3cfg_block_obj_pruning(nm_device_get_l3cfg(device), AF_INET6); + } + if (old_name) nm_manager_remove_device(NM_MANAGER_GET, old_name, NM_DEVICE_TYPE_PPP); @@ -257,7 +280,11 @@ create_and_realize(NMDevice *device, static void deactivate(NMDevice *device) { - NMDevicePpp *self = NM_DEVICE_PPP(device); + NMDevicePpp *self = NM_DEVICE_PPP(device); + NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE(self); + + nm_clear_pointer(&priv->l3cfg_block_handle_4, nm_l3cfg_unblock_obj_pruning); + nm_clear_pointer(&priv->l3cfg_block_handle_6, nm_l3cfg_unblock_obj_pruning); _ppp_mgr_cleanup(self); }