summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2021-02-03 11:37:16 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2021-02-04 10:50:15 +0100
commitafe600caae6f9b9e79b311843c0e1892df6682d3 (patch)
treea08a699405489ec8af695324c7e314ed8b1423b3
parenta980d9916dbd958813069cf305eab64380242557 (diff)
downloadNetworkManager-bg/no-fw-zone-without-ifindex-rh1921107.tar.gz
device: set firewall zone when re-entering stage3bg/no-fw-zone-without-ifindex-rh1921107
The ifindex of a virtual device is set when the kernel link appears. For OVS interfaces, this happens after NM has added the record to the ovsdb; since NM needs to know the related port and bridge when it adds ovs-interface record, and since interfaces are enslaved when they reach stage3, the ifindex is set during stage3. This means that the first time nm_device_activate_schedule_stage3_ip_config_start() is called, the ifindex is unset. Previously we would just set the firewall state as initialized and the zone would never be set again. Instead, allow the zone to be set when re-entering stage3. nm_device_activate_schedule_stage3_ip_config_start() now always check for the ifindex. This guarantees that we don't try to change zone for devices without a kernel link (for example, OVS bridges and ports). Upon reaching state ip-check, the device now changes the zone also if an ifindex is present and the zone was not set before. I'm not sure this can actually happen, because if the device has an ifindex it should be set during stage3. However I'm leaving this extra check for completeness. https://bugzilla.redhat.com/show_bug.cgi?id=1921107 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/737
-rw-r--r--src/core/devices/nm-device.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
index c7c459f499..a2d4788162 100644
--- a/src/core/devices/nm-device.c
+++ b/src/core/devices/nm-device.c
@@ -11483,28 +11483,31 @@ void
nm_device_activate_schedule_stage3_ip_config_start(NMDevice *self)
{
NMDevicePrivate *priv;
+ int ifindex;
g_return_if_fail(NM_IS_DEVICE(self));
priv = NM_DEVICE_GET_PRIVATE(self);
g_return_if_fail(priv->act_request.obj);
+ ifindex = nm_device_get_ip_ifindex(self);
/* Add the interface to the specified firewall zone */
if (priv->fw_state == FIREWALL_STATE_UNMANAGED) {
- if (!nm_device_sys_iface_state_is_external(self)) {
+ if (nm_device_sys_iface_state_is_external(self)) {
+ /* fake success */
+ priv->fw_state = FIREWALL_STATE_INITIALIZED;
+ } else if (ifindex > 0) {
priv->fw_state = FIREWALL_STATE_WAIT_STAGE_3;
fw_change_zone(self);
return;
}
-
- /* fake success. */
- priv->fw_state = FIREWALL_STATE_INITIALIZED;
+ /* no ifindex, nothing to do for now */
} else if (priv->fw_state == FIREWALL_STATE_WAIT_STAGE_3) {
/* a firewall call for stage3 is pending. Return and wait. */
return;
}
- nm_assert(priv->fw_state == FIREWALL_STATE_INITIALIZED);
+ nm_assert(ifindex <= 0 || priv->fw_state == FIREWALL_STATE_INITIALIZED);
activation_source_schedule(self, activate_stage3_ip_config_start, AF_INET);
}
@@ -16627,8 +16630,22 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
nm_device_queue_state(self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE);
break;
case NM_DEVICE_STATE_IP_CHECK:
- if (priv->fw_state >= FIREWALL_STATE_INITIALIZED && priv->ip_iface
- && !nm_device_sys_iface_state_is_external(self)) {
+ {
+ gboolean change_zone = FALSE;
+
+ if (!nm_device_sys_iface_state_is_external(self)) {
+ if (priv->ip_iface) {
+ /* The device now has a @ip_iface different from the
+ * @iface on which we previously set the zone. */
+ change_zone = TRUE;
+ } else if (priv->fw_state == FIREWALL_STATE_UNMANAGED && priv->ifindex > 0) {
+ /* We didn't set the zone earlier because there was
+ * no ifindex. */
+ change_zone = TRUE;
+ }
+ }
+
+ if (change_zone) {
priv->fw_state = FIREWALL_STATE_WAIT_IP_CONFIG;
fw_change_zone(self);
} else
@@ -16639,6 +16656,7 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
*/
notify_ip_properties(self);
break;
+ }
case NM_DEVICE_STATE_SECONDARIES:
ip_check_gw_ping_cleanup(self);
_LOGD(LOGD_DEVICE, "device entered SECONDARIES state");