从用户空间配置 DSA 交换机

目前,DSA 交换机配置尚未集成到主要的的用户空间网络配置套件中,必须手动执行。

配置示例

要配置 DSA 交换机,需要执行几个命令。本文档将一些常见的配置场景作为示例进行处理。

单端口

每个交换机端口都充当不同的可配置以太网端口。

桥接

每个交换机端口都是一个可配置以太网桥的一部分。

网关

除一个上游端口外的每个交换机端口都是可配置以太网桥的一部分。上游端口充当不同的可配置以太网端口。

所有配置都使用 iproute2 中的工具执行,该工具可在 https://linuxkernel.org.cn/pub/linux/utils/net/iproute2/ 获取。

通过 DSA,交换机的每个端口都像普通的 Linux 以太网接口一样处理。CPU 端口是连接到以太网 MAC 芯片的交换机端口。相应的 Linux 以太网接口称为导管接口。所有其他相应的 Linux 接口称为用户接口。

用户接口依赖于导管接口的启动才能发送或接收流量。在内核 v5.12 之前,导管接口的状态必须由用户显式管理。从内核 v5.12 开始,行为如下:

  • 当 DSA 用户接口启动时,导管接口会自动启动。

  • 当导管接口关闭时,所有 DSA 用户接口都会自动关闭。

本文档中使用以下以太网接口:

eth0

导管接口

eth1

另一个导管接口

lan1

用户接口

lan2

另一个用户接口

lan3

第三个用户接口

wan

专用于上游流量的用户接口

可以类似地配置其他以太网接口。配置的 IP 和网络是:

单端口
  • lan1: 192.0.2.1/30 (192.0.2.0 - 192.0.2.3)

  • lan2: 192.0.2.5/30 (192.0.2.4 - 192.0.2.7)

  • lan3: 192.0.2.9/30 (192.0.2.8 - 192.0.2.11)

桥接
  • br0: 192.0.2.129/25 (192.0.2.128 - 192.0.2.255)

网关
  • br0: 192.0.2.129/25 (192.0.2.128 - 192.0.2.255)

  • wan: 192.0.2.1/30 (192.0.2.0 - 192.0.2.3)

支持标记的配置

大多数 DSA 交换机都期望并支持基于标记的配置。这些交换机能够标记传入和传出的流量,而无需使用基于 VLAN 的配置。

单端口
# configure each interface
ip addr add 192.0.2.1/30 dev lan1
ip addr add 192.0.2.5/30 dev lan2
ip addr add 192.0.2.9/30 dev lan3

# For kernels earlier than v5.12, the conduit interface needs to be
# brought up manually before the user ports.
ip link set eth0 up

# bring up the user interfaces
ip link set lan1 up
ip link set lan2 up
ip link set lan3 up
桥接
# For kernels earlier than v5.12, the conduit interface needs to be
# brought up manually before the user ports.
ip link set eth0 up

# bring up the user interfaces
ip link set lan1 up
ip link set lan2 up
ip link set lan3 up

# create bridge
ip link add name br0 type bridge

# add ports to bridge
ip link set dev lan1 master br0
ip link set dev lan2 master br0
ip link set dev lan3 master br0

# configure the bridge
ip addr add 192.0.2.129/25 dev br0

# bring up the bridge
ip link set dev br0 up
网关
# For kernels earlier than v5.12, the conduit interface needs to be
# brought up manually before the user ports.
ip link set eth0 up

# bring up the user interfaces
ip link set wan up
ip link set lan1 up
ip link set lan2 up

# configure the upstream port
ip addr add 192.0.2.1/30 dev wan

# create bridge
ip link add name br0 type bridge

# add ports to bridge
ip link set dev lan1 master br0
ip link set dev lan2 master br0

# configure the bridge
ip addr add 192.0.2.129/25 dev br0

# bring up the bridge
ip link set dev br0 up

不支持标记的配置

少数交换机无法使用标记协议 (DSA_TAG_PROTO_NONE)。这些交换机可以通过基于 VLAN 的配置进行配置。

单端口

配置只能通过 VLAN 标记和网桥设置进行。

# tag traffic on CPU port
ip link add link eth0 name eth0.1 type vlan id 1
ip link add link eth0 name eth0.2 type vlan id 2
ip link add link eth0 name eth0.3 type vlan id 3

# For kernels earlier than v5.12, the conduit interface needs to be
# brought up manually before the user ports.
ip link set eth0 up
ip link set eth0.1 up
ip link set eth0.2 up
ip link set eth0.3 up

# bring up the user interfaces
ip link set lan1 up
ip link set lan2 up
ip link set lan3 up

# create bridge
ip link add name br0 type bridge

# activate VLAN filtering
ip link set dev br0 type bridge vlan_filtering 1

# add ports to bridges
ip link set dev lan1 master br0
ip link set dev lan2 master br0
ip link set dev lan3 master br0

# tag traffic on ports
bridge vlan add dev lan1 vid 1 pvid untagged
bridge vlan add dev lan2 vid 2 pvid untagged
bridge vlan add dev lan3 vid 3 pvid untagged

# configure the VLANs
ip addr add 192.0.2.1/30 dev eth0.1
ip addr add 192.0.2.5/30 dev eth0.2
ip addr add 192.0.2.9/30 dev eth0.3

# bring up the bridge devices
ip link set br0 up
桥接
# tag traffic on CPU port
ip link add link eth0 name eth0.1 type vlan id 1

# For kernels earlier than v5.12, the conduit interface needs to be
# brought up manually before the user ports.
ip link set eth0 up
ip link set eth0.1 up

# bring up the user interfaces
ip link set lan1 up
ip link set lan2 up
ip link set lan3 up

# create bridge
ip link add name br0 type bridge

# activate VLAN filtering
ip link set dev br0 type bridge vlan_filtering 1

# add ports to bridge
ip link set dev lan1 master br0
ip link set dev lan2 master br0
ip link set dev lan3 master br0
ip link set eth0.1 master br0

# tag traffic on ports
bridge vlan add dev lan1 vid 1 pvid untagged
bridge vlan add dev lan2 vid 1 pvid untagged
bridge vlan add dev lan3 vid 1 pvid untagged

# configure the bridge
ip addr add 192.0.2.129/25 dev br0

# bring up the bridge
ip link set dev br0 up
网关
# tag traffic on CPU port
ip link add link eth0 name eth0.1 type vlan id 1
ip link add link eth0 name eth0.2 type vlan id 2

# For kernels earlier than v5.12, the conduit interface needs to be
# brought up manually before the user ports.
ip link set eth0 up
ip link set eth0.1 up
ip link set eth0.2 up

# bring up the user interfaces
ip link set wan up
ip link set lan1 up
ip link set lan2 up

# create bridge
ip link add name br0 type bridge

# activate VLAN filtering
ip link set dev br0 type bridge vlan_filtering 1

# add ports to bridges
ip link set dev wan master br0
ip link set eth0.1 master br0
ip link set dev lan1 master br0
ip link set dev lan2 master br0

# tag traffic on ports
bridge vlan add dev lan1 vid 1 pvid untagged
bridge vlan add dev lan2 vid 1 pvid untagged
bridge vlan add dev wan vid 2 pvid untagged

# configure the VLANs
ip addr add 192.0.2.1/30 dev eth0.2
ip addr add 192.0.2.129/25 dev br0

# bring up the bridge devices
ip link set br0 up

转发数据库 (FDB) 管理

现有的 DSA 交换机没有必要的硬件支持来使网桥的软件 FDB 与硬件表保持同步,因此这两个表是分开管理的(bridge fdb show 查询两者,并且取决于是否使用 selfmaster 标志,bridge fdb addbridge fdb del 命令对来自一个或两个表的条目起作用)。

在内核 v4.14 之前,DSA 仅支持使用网桥旁路操作(不更新软件 FDB,仅更新硬件 FDB)使用 self 标志(可选,可以省略)来管理桥 FDB 条目的用户空间。

bridge fdb add dev swp0 00:01:02:03:04:05 self static
# or shorthand
bridge fdb add dev swp0 00:01:02:03:04:05 static

由于一个错误,DSA 提供的网桥旁路 FDB 实现没有区分 staticlocal FDB 条目(static 用于转发,而 local 用于本地终止,即发送到主机端口)。相反,所有带有 self 标志(隐式或显式)的 FDB 条目都被 DSA 视为 static,即使它们是 local

# This command:
bridge fdb add dev swp0 00:01:02:03:04:05 static
# behaves the same for DSA as this command:
bridge fdb add dev swp0 00:01:02:03:04:05 local
# or shorthand, because the 'local' flag is implicit if 'static' is not
# specified, it also behaves the same as:
bridge fdb add dev swp0 00:01:02:03:04:05

最后一条命令是使用网桥旁路操作向 DSA 交换机添加静态网桥 FDB 条目的不正确方法,并且由于错误而起作用。其他驱动程序会将通过相同命令添加的 FDB 条目视为 local,因此不会转发它,这与 DSA 相反。

在内核 v4.14 和 v5.14 之间,DSA 同时支持两种向交换机添加桥 FDB 条目的模式:上述的网桥旁路以及使用 master 标志的新模式,该模式也会在软件网桥中安装 FDB 条目。

bridge fdb add dev swp0 00:01:02:03:04:05 master static

自内核 v5.14 起,DSA 已经与网桥的软件 FDB 进行了更强的集成,并且已经删除了对其网桥旁路 FDB 实现(使用 self 标志)的支持。这导致以下更改:

# This is the only valid way of adding an FDB entry that is supported,
# compatible with v4.14 kernels and later:
bridge fdb add dev swp0 00:01:02:03:04:05 master static
# This command is no longer buggy and the entry is properly treated as
# 'local' instead of being forwarded:
bridge fdb add dev swp0 00:01:02:03:04:05
# This command no longer installs a static FDB entry to hardware:
bridge fdb add dev swp0 00:01:02:03:04:05 static

因此,建议脚本编写者在处理 DSA 交换机接口上的桥 FDB 条目时使用 master static 标志集。

用户端口与 CPU 端口的亲和性

通常,DSA 交换机通过单个以太网接口连接到主机,但在交换机芯片是离散的情况下,硬件设计可能允许使用 2 个或更多连接到主机的端口,以提高终止吞吐量。

DSA 可以通过两种方式使用多个 CPU 端口。首先,可以将与某个用户端口关联的终止流量静态分配给某个 CPU 端口进行处理。这样,用户空间可以通过根据可用的 CPU 端口分散亲和性来实施用户端口之间的静态负载平衡的自定义策略。

其次,可以按每个数据包在 CPU 端口之间执行负载平衡,而不是静态地将用户端口分配给 CPU 端口。这可以通过将 DSA 导管置于 LAG 接口(绑定或团队)下实现。DSA 监视此操作,并在面对构成 LAG 从设备物理 DSA 导管的 CPU 端口上创建此软件 LAG 的镜像。

要使用多个 CPU 端口,交换机的固件(设备树)描述必须使用 ethernet 引用/phandle 标记 CPU 端口及其 DSA 导管之间的所有链路。在启动时,只会使用单个 CPU 端口和 DSA 导管 - 来自固件描述中具有 ethernet 属性的数值上第一个端口。用户需要配置系统以使交换机使用其他导管。

DSA 使用 rtnl_link_ops 机制(具有 “dsa” kind)来允许更改用户端口的 DSA 导管。 IFLA_DSA_CONDUIT u32 netlink 属性包含处理每个用户设备的导管设备的 ifindex。DSA 导管必须是基于固件节点信息的有效候选对象,或者是仅包含作为有效候选对象的从设备的 LAG 接口。

使用 iproute2,可以进行以下操作:

# See the DSA conduit in current use
ip -d link show dev swp0
    (...)
    dsa master eth0

# Static CPU port distribution
ip link set swp0 type dsa master eth1
ip link set swp1 type dsa master eth0
ip link set swp2 type dsa master eth1
ip link set swp3 type dsa master eth0

# CPU ports in LAG, using explicit assignment of the DSA conduit
ip link add bond0 type bond mode balance-xor && ip link set bond0 up
ip link set eth1 down && ip link set eth1 master bond0
ip link set swp0 type dsa master bond0
ip link set swp1 type dsa master bond0
ip link set swp2 type dsa master bond0
ip link set swp3 type dsa master bond0
ip link set eth0 down && ip link set eth0 master bond0
ip -d link show dev swp0
    (...)
    dsa master bond0

# CPU ports in LAG, relying on implicit migration of the DSA conduit
ip link add bond0 type bond mode balance-xor && ip link set bond0 up
ip link set eth0 down && ip link set eth0 master bond0
ip link set eth1 down && ip link set eth1 master bond0
ip -d link show dev swp0
    (...)
    dsa master bond0

请注意,在 LAG 下的 CPU 端口情况下,严格来说不需要使用 IFLA_DSA_CONDUIT netlink 属性。相反,DSA 对其当前导管(eth0)的 IFLA_MASTER 属性更改做出反应,并将所有用户端口迁移到 eth0 的新上层,即 bond0。 类似地,当使用 RTM_DELLINK 销毁 bond0 时,DSA 会将分配给此接口的用户端口迁移到第一个符合条件的物理 DSA 导管,这基于固件描述(它实际上会恢复到启动配置)。

在具有两个以上物理 CPU 端口的设置中,因此可以将静态用户到 CPU 端口的分配与 DSA 导管之间的 LAG 混合使用。 不可能将用户端口静态分配给任何具有上层接口的 DSA 导管(这包括 LAG 设备 - 在这种情况下,导管必须始终是 LAG)。

允许实时更改用户端口的 DSA 导管(以及 CPU 端口)亲和性,以便允许根据流量进行动态重新分配。

物理 DSA 导管可以随时加入和离开用作 DSA 导管的 LAG 接口;但是,除非 LAG 接口至少有一个物理 DSA 导管作为从设备,否则 DSA 会拒绝 LAG 接口作为有效的 DSA 导管候选者。