about summary refs log tree commit diff
path: root/src/core/devices/nm-device-bridge.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/devices/nm-device-bridge.c')
-rw-r--r--src/core/devices/nm-device-bridge.c148
1 files changed, 113 insertions, 35 deletions
diff --git a/src/core/devices/nm-device-bridge.c b/src/core/devices/nm-device-bridge.c
index 9bf7ac01..31cf361e 100644
--- a/src/core/devices/nm-device-bridge.c
+++ b/src/core/devices/nm-device-bridge.c
@@ -836,30 +836,33 @@ _platform_lnk_bridge_init_from_setting(NMSettingBridge *s_bridge, NMPlatformLnkB
     to_sysfs_group_address_sys(nm_setting_bridge_get_group_address(s_bridge), &props->group_addr);
 }
 
-static NMActStageReturn
-act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
+static gboolean
+link_config(NMDevice *device, NMConnection *connection)
 {
-    NMConnection       *connection;
+    int                 ifindex = nm_device_get_ifindex(device);
     NMSettingBridge    *s_bridge;
     NMPlatformLnkBridge props;
-    int                 r;
-    int                 ifindex = nm_device_get_ifindex(device);
-
-    connection = nm_device_get_applied_connection(device);
-    g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE);
 
     s_bridge = nm_connection_get_setting_bridge(connection);
-    g_return_val_if_fail(s_bridge, NM_ACT_STAGE_RETURN_FAILURE);
+    g_return_val_if_fail(s_bridge, FALSE);
 
     _platform_lnk_bridge_init_from_setting(s_bridge, &props);
 
-    r = nm_platform_link_bridge_change(nm_device_get_platform(device), ifindex, &props);
-    if (r < 0) {
-        NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
-        return NM_ACT_STAGE_RETURN_FAILURE;
-    }
+    if (nm_platform_link_bridge_change(nm_device_get_platform(device), ifindex, &props) < 0)
+        return FALSE;
+
+    return bridge_set_vlan_options(device, s_bridge);
+}
+
+static NMActStageReturn
+act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
+{
+    NMConnection *connection;
+
+    connection = nm_device_get_applied_connection(device);
+    g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE);
 
-    if (!bridge_set_vlan_options(device, s_bridge)) {
+    if (!link_config(device, connection)) {
         NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
         return NM_ACT_STAGE_RETURN_FAILURE;
     }
@@ -974,8 +977,14 @@ deactivate(NMDevice *device)
     }
 }
 
-static gboolean
-enslave_slave(NMDevice *device, NMDevice *slave, NMConnection *connection, gboolean configure)
+static NMTernary
+attach_port(NMDevice                  *device,
+            NMDevice                  *port,
+            NMConnection              *connection,
+            gboolean                   configure,
+            GCancellable              *cancellable,
+            NMDeviceAttachPortCallback callback,
+            gpointer                   user_data)
 {
     NMDeviceBridge      *self = NM_DEVICE_BRIDGE(device);
     NMConnection        *master_connection;
@@ -985,7 +994,7 @@ enslave_slave(NMDevice *device, NMDevice *slave, NMConnection *connection, gbool
     if (configure) {
         if (!nm_platform_link_enslave(nm_device_get_platform(device),
                                       nm_device_get_ip_ifindex(device),
-                                      nm_device_get_ip_ifindex(slave)))
+                                      nm_device_get_ip_ifindex(port)))
             return FALSE;
 
         master_connection = nm_device_get_applied_connection(device);
@@ -1010,25 +1019,25 @@ enslave_slave(NMDevice *device, NMDevice *slave, NMConnection *connection, gbool
              * (except for the default one) and so there's no need to flush. */
 
             if (plat_vlans
-                && !nm_platform_link_set_bridge_vlans(nm_device_get_platform(slave),
-                                                      nm_device_get_ifindex(slave),
+                && !nm_platform_link_set_bridge_vlans(nm_device_get_platform(port),
+                                                      nm_device_get_ifindex(port),
                                                       TRUE,
                                                       plat_vlans))
                 return FALSE;
         }
 
-        commit_slave_options(slave, s_port);
+        commit_slave_options(port, s_port);
 
-        _LOGI(LOGD_BRIDGE, "attached bridge port %s", nm_device_get_ip_iface(slave));
+        _LOGI(LOGD_BRIDGE, "attached bridge port %s", nm_device_get_ip_iface(port));
     } else {
-        _LOGI(LOGD_BRIDGE, "bridge port %s was attached", nm_device_get_ip_iface(slave));
+        _LOGI(LOGD_BRIDGE, "bridge port %s was attached", nm_device_get_ip_iface(port));
     }
 
     return TRUE;
 }
 
 static void
-release_slave(NMDevice *device, NMDevice *slave, gboolean configure)
+detach_port(NMDevice *device, NMDevice *port, gboolean configure)
 {
     NMDeviceBridge *self = NM_DEVICE_BRIDGE(device);
     gboolean        success;
@@ -1041,10 +1050,10 @@ release_slave(NMDevice *device, NMDevice *slave, gboolean configure)
             configure = FALSE;
     }
 
-    ifindex_slave = nm_device_get_ip_ifindex(slave);
+    ifindex_slave = nm_device_get_ip_ifindex(port);
 
     if (ifindex_slave <= 0) {
-        _LOGD(LOGD_TEAM, "bond slave %s is already released", nm_device_get_ip_iface(slave));
+        _LOGD(LOGD_TEAM, "bridge port %s is already detached", nm_device_get_ip_iface(port));
         return;
     }
 
@@ -1054,12 +1063,12 @@ release_slave(NMDevice *device, NMDevice *slave, gboolean configure)
                                            ifindex_slave);
 
         if (success) {
-            _LOGI(LOGD_BRIDGE, "detached bridge port %s", nm_device_get_ip_iface(slave));
+            _LOGI(LOGD_BRIDGE, "detached bridge port %s", nm_device_get_ip_iface(port));
         } else {
-            _LOGW(LOGD_BRIDGE, "failed to detach bridge port %s", nm_device_get_ip_iface(slave));
+            _LOGW(LOGD_BRIDGE, "failed to detach bridge port %s", nm_device_get_ip_iface(port));
         }
     } else {
-        _LOGI(LOGD_BRIDGE, "bridge port %s was detached", nm_device_get_ip_iface(slave));
+        _LOGI(LOGD_BRIDGE, "bridge port %s was detached", nm_device_get_ip_iface(port));
     }
 }
 
@@ -1085,10 +1094,6 @@ create_and_realize(NMDevice              *device,
     s_bridge = nm_connection_get_setting_bridge(connection);
     nm_assert(s_bridge);
 
-    s_wired = nm_connection_get_setting_wired(connection);
-    if (s_wired)
-        mtu = nm_setting_wired_get_mtu(s_wired);
-
     hwaddr = nm_setting_bridge_get_mac_address(s_bridge);
     if (!hwaddr
         && nm_device_hw_addr_get_cloned(device, connection, FALSE, &hwaddr_cloned, NULL, NULL)) {
@@ -1113,6 +1118,11 @@ create_and_realize(NMDevice              *device,
 
     _platform_lnk_bridge_init_from_setting(s_bridge, &props);
 
+    s_wired = nm_connection_get_setting_wired(connection);
+    nm_assert(s_wired);
+
+    mtu = nm_setting_wired_get_mtu(s_wired);
+
     /* If mtu != 0, we set the MTU of the new bridge at creation time. However, kernel will still
      * automatically adjust the MTU of the bridge based on the minimum of the slave's MTU.
      * We don't want this automatism as the user asked for a fixed MTU.
@@ -1142,6 +1152,72 @@ create_and_realize(NMDevice              *device,
 
 /*****************************************************************************/
 
+static gboolean
+can_reapply_change(NMDevice   *device,
+                   const char *setting_name,
+                   NMSetting  *s_old,
+                   NMSetting  *s_new,
+                   GHashTable *diffs,
+                   GError    **error)
+{
+    /* Delegate changes to other settings to parent class */
+    if (!nm_streq(setting_name, NM_SETTING_BRIDGE_SETTING_NAME)) {
+        return NM_DEVICE_CLASS(nm_device_bridge_parent_class)
+            ->can_reapply_change(device, setting_name, s_old, s_new, diffs, error);
+    }
+
+    return nm_device_hash_check_invalid_keys(diffs,
+                                             NM_SETTING_BRIDGE_SETTING_NAME,
+                                             error,
+                                             NM_SETTING_BRIDGE_STP,
+                                             NM_SETTING_BRIDGE_PRIORITY,
+                                             NM_SETTING_BRIDGE_FORWARD_DELAY,
+                                             NM_SETTING_BRIDGE_HELLO_TIME,
+                                             NM_SETTING_BRIDGE_MAX_AGE,
+                                             NM_SETTING_BRIDGE_AGEING_TIME,
+                                             NM_SETTING_BRIDGE_GROUP_FORWARD_MASK,
+                                             NM_SETTING_BRIDGE_MULTICAST_HASH_MAX,
+                                             NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_COUNT,
+                                             NM_SETTING_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL,
+                                             NM_SETTING_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL,
+                                             NM_SETTING_BRIDGE_MULTICAST_SNOOPING,
+                                             NM_SETTING_BRIDGE_MULTICAST_ROUTER,
+                                             NM_SETTING_BRIDGE_MULTICAST_QUERIER,
+                                             NM_SETTING_BRIDGE_MULTICAST_QUERIER_INTERVAL,
+                                             NM_SETTING_BRIDGE_MULTICAST_QUERY_INTERVAL,
+                                             NM_SETTING_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL,
+                                             NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR,
+                                             NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT,
+                                             NM_SETTING_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL,
+                                             NM_SETTING_BRIDGE_GROUP_ADDRESS,
+                                             NM_SETTING_BRIDGE_VLAN_PROTOCOL,
+                                             NM_SETTING_BRIDGE_VLAN_STATS_ENABLED,
+                                             NM_SETTING_BRIDGE_VLAN_FILTERING,
+                                             NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID,
+                                             NM_SETTING_BRIDGE_VLANS);
+}
+
+static void
+reapply_connection(NMDevice *device, NMConnection *con_old, NMConnection *con_new)
+{
+    NMDeviceBridge  *self = NM_DEVICE_BRIDGE(device);
+    NMSettingBridge *s_bridge;
+
+    NM_DEVICE_CLASS(nm_device_bridge_parent_class)->reapply_connection(device, con_old, con_new);
+
+    _LOGD(LOGD_BRIDGE, "reapplying bridge settings");
+    s_bridge = nm_connection_get_setting_bridge(con_new);
+    g_return_if_fail(s_bridge);
+
+    /* Make sure bridge_set_vlan_options() called by link_config()
+     * sets vlan_filtering and default_pvid anew. */
+    self->vlan_configured = FALSE;
+
+    link_config(device, con_new);
+}
+
+/*****************************************************************************/
+
 static void
 nm_device_bridge_init(NMDeviceBridge *self)
 {
@@ -1183,9 +1259,11 @@ nm_device_bridge_class_init(NMDeviceBridgeClass *klass)
     device_class->act_stage1_prepare                     = act_stage1_prepare;
     device_class->act_stage2_config                      = act_stage2_config;
     device_class->deactivate                             = deactivate;
-    device_class->enslave_slave                          = enslave_slave;
-    device_class->release_slave                          = release_slave;
+    device_class->attach_port                            = attach_port;
+    device_class->detach_port                            = detach_port;
     device_class->get_configured_mtu                     = nm_device_get_configured_mtu_for_wired;
+    device_class->can_reapply_change                     = can_reapply_change;
+    device_class->reapply_connection                     = reapply_connection;
 }
 
 /*****************************************************************************/