diff options
Diffstat (limited to 'src/core/devices/nm-device-bridge.c')
| -rw-r--r-- | src/core/devices/nm-device-bridge.c | 148 |
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; } /*****************************************************************************/ |