network: optionally bring up interface before joining bridge

Closes #34247.
This commit is contained in:
Yu Watanabe
2024-09-16 02:36:13 +09:00
parent 2bb7fe554f
commit 2dfde4b8f8
3 changed files with 37 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
# do not edit this file, it will be overwritten on update
ACTION=="remove", GOTO="net_bridge_end"
SUBSYSTEM!="net", GOTO="net_bridge_end"
# Some devices require the port to be up before joining the bridge.
# In such cases, set ID_NET_BRING_UP_BEFORE_JOINING_BRIDGE to "1".
# Texas Instruments Ethernet device with switchdev mode:
# https://docs.kernel.org/networking/device_drivers/ethernet/ti/am65_nuss_cpsw_switchdev.html#enabling-switch
ENV{ID_NET_DRIVER}=="am65-cpsw-nuss", SUBSYSTEMS=="platform", DRIVERS=="am65-cpsw-nuss", \
PROGRAM="/usr/sbin/devlink dev param show platform/%b name switch_mode", \
RESULT=="*cmode runtime value true*", \
ENV{ID_NET_BRING_UP_BEFORE_JOINING_BRIDGE}="1"
LABEL="net_bridge_end"

View File

@@ -29,6 +29,7 @@ rules = [
'75-probe_mtd.rules',
'78-sound-card.rules',
'80-net-setup-link.rules',
'81-net-bridge.rules',
'81-net-dhcp.rules',
'90-iocost.rules',
)],

View File

@@ -6,6 +6,7 @@
#include <linux/if_bridge.h>
#include <linux/ipv6.h>
#include "device-private.h"
#include "missing_network.h"
#include "netif-util.h"
#include "netlink-util.h"
@@ -581,6 +582,25 @@ static int link_is_ready_to_set_link(Link *link, Request *req) {
return r;
}
if (link->network->bridge && !FLAGS_SET(link->flags, IFF_UP) && link->dev) {
/* Some devices require the port to be up before joining the bridge.
*
* E.g. Texas Instruments SoC Ethernet running in switch mode:
* https://docs.kernel.org/networking/device_drivers/ethernet/ti/am65_nuss_cpsw_switchdev.html#enabling-switch
* > Ports netdev devices have to be in UP before joining to the bridge to avoid
* > overwriting of bridge configuration as CPSW switch driver completely reloads its
* > configuration when first port changes its state to UP. */
r = device_get_property_bool(link->dev, "ID_NET_BRING_UP_BEFORE_JOINING_BRIDGE");
if (r < 0 && r != -ENOENT)
log_link_warning_errno(link, r, "Failed to get or parse ID_NET_BRING_UP_BEFORE_JOINING_BRIDGE property, ignoring: %m");
else if (r > 0) {
r = link_up_now(link);
if (r < 0)
return r;
}
}
req->userdata = UINT32_TO_PTR(m);
break;
}