device: restart DHCP when the MAC changes

If the MAC changes there is the possibility that the DHCP client will
not be able to renew the address because it uses the old MAC as
CHADDR. Depending on the implementation, the DHCP server might use
CHADDR (so, the old address) as the destination MAC for DHCP replies,
and those packets will be lost.

To avoid this problem, restart the DHCP client when the MAC changes.

https://bugzilla.redhat.com/show_bug.cgi?id=2110000
This commit is contained in:
Beniamino Galvani
2022-08-24 16:52:52 +02:00
committed by Thomas Haller
parent 6cd69fde33
commit 905adabdba

View File

@@ -6646,6 +6646,7 @@ device_link_changed(gpointer user_data)
NMDeviceClass *klass = NM_DEVICE_GET_CLASS(self); NMDeviceClass *klass = NM_DEVICE_GET_CLASS(self);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
gboolean ip_ifname_changed = FALSE; gboolean ip_ifname_changed = FALSE;
gboolean hw_addr_changed;
nm_auto_nmpobj const NMPObject *pllink_keep_alive = NULL; nm_auto_nmpobj const NMPObject *pllink_keep_alive = NULL;
const NMPlatformLink *pllink; const NMPlatformLink *pllink;
const char *str; const char *str;
@@ -6692,9 +6693,9 @@ device_link_changed(gpointer user_data)
if (ifindex == nm_device_get_ip_ifindex(self)) if (ifindex == nm_device_get_ip_ifindex(self))
_stats_update_counters_from_pllink(self, pllink); _stats_update_counters_from_pllink(self, pllink);
had_hw_addr = (priv->hw_addr != NULL); had_hw_addr = (priv->hw_addr != NULL);
nm_device_update_hw_address(self); hw_addr_changed = nm_device_update_hw_address(self);
got_hw_addr = (!had_hw_addr && priv->hw_addr); got_hw_addr = (!had_hw_addr && priv->hw_addr);
nm_device_update_permanent_hw_address(self, FALSE); nm_device_update_permanent_hw_address(self, FALSE);
if (pllink->name[0] && !nm_streq(priv->iface, pllink->name)) { if (pllink->name[0] && !nm_streq(priv->iface, pllink->name)) {
@@ -6745,6 +6746,8 @@ device_link_changed(gpointer user_data)
/* Update DHCP, etc, if needed */ /* Update DHCP, etc, if needed */
if (ip_ifname_changed) if (ip_ifname_changed)
nm_device_update_dynamic_ip_setup(self, "IP interface changed"); nm_device_update_dynamic_ip_setup(self, "IP interface changed");
else if (hw_addr_changed)
nm_device_update_dynamic_ip_setup(self, "hw-address changed");
was_up = priv->up; was_up = priv->up;
priv->up = NM_FLAGS_HAS(pllink->n_ifi_flags, IFF_UP); priv->up = NM_FLAGS_HAS(pllink->n_ifi_flags, IFF_UP);