以太网桥接

简介

IEEE 802.1Q-2022(桥接和桥接网络)标准定义了计算机网络中桥接器的操作。在此标准上下文中,桥接器是一种连接两个或多个网段的设备,并在 OSI(开放系统互连)模型的 数据链路层(第 2 层)上运行。桥接器的目的是根据目标 MAC(媒体访问控制)地址在不同网段之间过滤和转发帧。

桥接 kAPI

以下是桥接代码的一些核心结构。请注意,kAPI 是不稳定的,并且可以随时更改。

struct net_bridge_vlan

每个 VLAN 条目

定义:

struct net_bridge_vlan {
    struct rhash_head               vnode;
    struct rhash_head               tnode;
    u16 vid;
    u16 flags;
    u16 priv_flags;
    u8 state;
    struct pcpu_sw_netstats __percpu *stats;
    union {
        struct net_bridge       *br;
        struct net_bridge_port  *port;
    };
    union {
        refcount_t refcnt;
        struct net_bridge_vlan  *brvlan;
    };
    struct br_tunnel_info           tinfo;
    union {
        struct net_bridge_mcast         br_mcast_ctx;
        struct net_bridge_mcast_port    port_mcast_ctx;
    };
    u16 msti;
    struct list_head                vlist;
    struct rcu_head                 rcu;
};

成员

vnode

rhashtable 成员

tnode

rhashtable 成员

vid

VLAN ID

flags

桥接 VLAN 标志

priv_flags

私有(内核)桥接 VLAN 标志

state

STP 状态(例如,阻塞、学习、转发)

stats

每个 CPU 的 VLAN 统计信息

{unnamed_union}

匿名

br

如果设置了 MASTER 标志,则此指针指向一个桥接结构

port

如果未设置 MASTER 标志,则此指针指向一个端口结构

{unnamed_union}

匿名

refcnt

如果设置了 MASTER 标志,则每个引用它的端口都会增加此值

brvlan

如果未设置 MASTER 标志,则此指针指向此 VLAN 条目的全局每个 VLAN 上下文

tinfo

桥接隧道信息

{unnamed_union}

匿名

br_mcast_ctx

如果设置了 MASTER 标志,则这是全局 VLAN 多播上下文

port_mcast_ctx

如果未设置 MASTER 标志,则这是每个端口/VLAN 多播上下文

msti

如果设置了 MASTER 标志,则此值保存 VLAN 的 MST 实例

vlist

VLAN 条目的排序列表

rcu

用于条目销毁

描述

此结构在桥接 rhashtable 中包含的全局每个 VLAN 条目和端口 rhashtable 中包含的本地每个端口每个 VLAN 条目之间共享。应根据设置的条目标志解释联合条目。

桥接 uAPI

现代 Linux 桥接 uAPI 通过 Netlink 接口访问。您可以在以下文件中找到定义桥接和桥接端口 Netlink 属性的文件。

网桥 sysfs

sysfs 接口已弃用,如果添加新选项,则不应扩展。

STP

Linux 网桥驱动程序中的 STP(生成树协议)实现是一项关键功能,可通过识别和禁用冗余链路来帮助防止以太网中的环路和广播风暴。在 Linux 网桥环境中,STP 对于网络稳定性和可用性至关重要。

STP 是在 OSI 模型的“数据链路层”中运行的二层协议。它最初开发为 IEEE 802.1D,后来演变为多个版本,包括快速生成树协议 (RSTP) 和多生成树协议 (MSTP)

802.1D-2004 删除了原始的生成树协议,而是加入了快速生成树协议 (RSTP)。到 2014 年,IEEE 802.1D 定义的所有功能都已并入 IEEE 802.1Q(网桥和网桥网络)或 IEEE 802.1AC(MAC 服务定义)。802.1D 已于 2022 年正式撤回。

网桥端口和 STP 状态

在 STP 的上下文中,网桥端口可以处于以下状态之一
  • 阻塞:端口禁用数据流量,仅侦听来自其他设备的 BPDU(网桥协议数据单元),以确定网络拓扑。

  • 侦听:端口开始参与 STP 进程,并侦听 BPDU。

  • 学习:端口继续侦听 BPDU,并开始从传入帧中学习 MAC 地址,但不转发数据帧。

  • 转发:端口完全运行,并转发 BPDU 和数据帧。

  • 禁用:端口已通过管理方式禁用,不参与 STP 进程。数据帧转发也被禁用。

根网桥和收敛

在 Linux 中网络和以太网桥接的上下文中,根网桥是桥接网络中指定的交换机,它作为生成树算法创建无环拓扑的参考点。

以下是 STP 的工作方式和根网桥的选取方式
  1. 网桥优先级:每个运行生成树协议的网桥都有一个可配置的“网桥优先级”值。值越低,优先级越高。默认情况下,“网桥优先级”设置为标准值(例如,32768)。

  2. 网桥 ID:“网桥 ID”由两个组件组成:“网桥优先级”和网桥的 MAC 地址。它可以唯一标识网络中的每个网桥。“网桥 ID”用于比较不同网桥的优先级。

  3. 网桥选举:当网络启动时,所有网桥最初都假设自己是根网桥。它们开始向邻居广播“网桥协议数据单元 (BPDU)”,其中包含其“网桥 ID”和其他信息。

  4. BPDU 比较:网桥交换 BPDU 以确定根网桥。每个网桥检查收到的 BPDU,包括网桥优先级和网桥 ID,以确定是否应调整自身的优先级。网桥 ID 最低的网桥将成为根网桥。

  5. 根网桥通告:一旦确定根网桥,它会将包含根网桥信息的 BPDU 发送到网络中的所有其他网桥。其他网桥使用此信息计算到根网桥的最短路径,从而创建无环拓扑。

  6. 转发端口:选择根网桥并建立生成树拓扑后,每个网桥确定其哪些端口应处于转发状态(用于数据流量),哪些端口应处于阻塞状态(用于防止环路)。根网桥的所有端口都处于转发状态。而其他网桥的一些端口则处于阻塞状态,以避免环路。

  7. 根端口:选择根网桥并建立生成树拓扑后,每个非根网桥都会处理传入的 BPDU,并根据收到的 BPDU 中的信息确定其哪个端口提供了到根网桥的最短路径。此端口被指定为根端口。它处于转发状态,允许其主动转发网络流量。

  8. 指定端口:指定端口是指非根网桥将流量转发到指定网段所通过的端口。指定端口处于转发状态。非根网桥上未指定用于特定网段的所有其他端口都处于阻塞状态,以防止网络环路。

STP 通过计算最短路径并禁用冗余链路来确保网络收敛。当发生网络拓扑更改时(例如,链路故障),STP 会重新计算网络拓扑以恢复连接,同时避免环路。

正确配置 STP 参数(如网桥优先级)会影响网络性能、路径选择以及哪个网桥成为根网桥。

用户空间 STP 助手

用户空间 STP 助手 bridge-stp 是一个程序,用于控制是否使用用户模式生成树。当在网桥上启用/禁用 STP 时(通过 brctl stp <bridge> <on|off>ip link set <bridge> type bridge stp_state <0|1>),内核会调用 /sbin/bridge-stp <bridge> <start|stop>。如果该命令返回 0,则内核启用 user_stp 模式;如果该命令返回任何其他值,则内核启用 kernel_stp 模式。

VLAN

LAN(局域网)是覆盖小地理区域的网络,通常在单个建筑物或园区内。LAN 用于连接本地区域内的计算机、服务器、打印机和其他联网设备。LAN 可以是有线的(使用以太网电缆)或无线的(使用 Wi-Fi)。

VLAN(虚拟局域网)是将物理网络逻辑分割为多个隔离的广播域。VLAN 用于将单个物理 LAN 分割为多个虚拟 LAN,允许不同的设备组像在单独的物理网络上一样进行通信。

通常有两种 VLAN 实现:IEEE 802.1Q 和 IEEE 802.1ad(也称为 QinQ)。IEEE 802.1Q 是以太网中 VLAN 标记的标准。它允许网络管理员在物理网络上创建逻辑 VLAN,并使用 VLAN 信息标记以太网帧,这称为VLAN 标记帧。IEEE 802.1ad,通常称为 QinQ 或双 VLAN,是 IEEE 802.1Q 标准的扩展。QinQ 允许在单个以太网帧内堆叠多个 VLAN 标记。Linux 网桥支持 IEEE 802.1Q 和 802.1AD 协议进行 VLAN 标记。

网桥上的 VLAN 过滤 默认情况下处于禁用状态。在网桥上启用 VLAN 过滤后,它将开始根据其目标 MAC 地址和 VLAN 标记(两者必须匹配)将帧转发到适当的目的地。

多播

Linux 网桥驱动程序具有多播支持,允许其处理 Internet 组管理协议 (IGMP) 或多播侦听器发现 (MLD) 消息,并有效地转发多播数据包。网桥驱动程序支持 IGMPv2/IGMPv3 和 MLDv1/MLDv2。

多播侦听

多播侦听是一种网络技术,允许网络交换机智能地管理局域网 (LAN) 内的多播流量。

交换机维护一个多播组表,该表记录多播组地址和主机加入这些组的端口之间的关联。组表会根据收到的 IGMP/MLD 消息动态更新。通过侦听收集的多播组信息,交换机优化了多播流量的转发。它不会盲目地将多播流量广播到所有端口,而是仅根据目标 MAC 地址将多播流量发送到已订阅相应目标多播组的端口。

创建时,Linux 网桥设备默认启用多播侦听。它维护一个多播转发数据库 (MDB),该数据库跟踪端口和组关系。

IGMPv3/MLDv2 EHT 支持

Linux 网桥支持 IGMPv3/MLDv2 EHT(显式主机跟踪),该功能由 474ddb37fa3a (“net: bridge: multicast: add EHT allow/block handling”) 添加

显式主机跟踪使设备能够跟踪加入特定组或通道的每个单独主机。IGMP 中显式主机跟踪的主要好处是允许当主机离开多播组或通道时,最大程度地减少离开延迟。

主机想要离开和设备停止转发流量之间的时间长度称为 IGMP 离开延迟。如果最后请求从设备接收流量的主机表示不再想要接收流量,则配置了 IGMPv3 或 MLDv2 并具有显式跟踪的设备可以立即停止转发流量。因此,离开延迟仅受多接入网络中的数据包传输延迟和设备中的处理时间的限制。

其他多播功能

Linux 网桥还支持 每个 VLAN 的多播侦听,默认情况下禁用,但可以启用。以及 多播路由器发现,这有助于识别多播路由器的位置。

Switchdev

Linux 网桥 Switchdev 是 Linux 内核中的一项功能,它扩展了传统 Linux 网桥的功能,使其能够更有效地与支持 switchdev 的硬件交换机配合使用。通过 Linux 网桥 Switchdev,可以将某些网络功能(如以太网帧的转发、过滤和学习)卸载到硬件交换机。此卸载减轻了 Linux 内核和 CPU 的负担,从而提高了网络性能并降低了延迟。

要使用 Linux 网桥 Switchdev,您需要支持 switchdev 接口的硬件交换机。这意味着交换机硬件需要具有必要的驱动程序和功能才能与 Linux 内核协同工作。

有关更多详细信息,请参阅 以太网交换机设备驱动程序模型 (switchdev) 文档。

Netfilter

网桥 netfilter 模块是一项旧功能,允许使用 iptables 和 ip6tables 过滤桥接数据包。不建议使用。用户应考虑使用 nftables 进行数据包过滤。

较旧的 ebtables 工具与 nftables 相比功能有限,但与 nftables 一样,它也不需要此模块即可运行。

br_netfilter 模块拦截进入网桥的数据包,对 ipv4 和 ipv6 数据包执行最少的完整性检查,然后假装这些数据包正在被路由而不是桥接。然后,br_netfilter 从网桥层调用 ip 和 ipv6 netfilter 挂钩,即 ip(6)tables 规则集也将看到这些数据包。

br_netfilter 也是 iptables physdev 匹配的原因:此匹配是在 iptables 规则集中可靠地区分路由和桥接数据包的唯一方法。

请注意,ebtables 和 nftables 在没有 br_netfilter 模块的情况下也可以正常工作。iptables/ip6tables/arptables 不适用于桥接流量,因为它们插入路由堆栈。ip/ip6/inet/arp 系列中的 nftables 规则也不会看到由网桥转发的流量,但这很符合预期。

历史上,ebtables 的功能集非常有限(现在仍然如此),添加此模块是为了假装数据包被路由,并从网桥调用 ipv4/ipv6 netfilter 挂钩,以便用户可以使用功能更丰富的 iptables 匹配功能(包括 conntrack)。nftables 没有此限制,几乎所有功能都可以在任何协议系列中使用。

因此,只有当用户出于某种原因需要使用 ip(6)tables 过滤网桥转发的数据包或 NAT 桥接流量时,才需要 br_netfilter。对于纯链路层过滤,不需要此模块。

其他功能

Linux 网桥还支持 IEEE 802.11 代理 ARP介质冗余协议 (MRP)介质冗余协议 (MRP) LC 模式IEEE 802.1X 端口身份验证MAC 身份验证旁路 (MAB)

常见问题解答

桥接做什么?

桥接器透明地在多个网络接口之间转发流量。简单来说,这意味着桥接器连接两个或多个物理以太网,形成一个更大的(逻辑)以太网。

它是否与L3协议无关?

是的。桥接器可以看到所有帧,但它只使用 L2头部/信息。因此,桥接功能与协议无关,转发IPX、NetBEUI、IP、IPv6等协议应该没有问题。

联系方式

该代码目前由 Roopa Prabhu <roopa@nvidia.com> 和 Nikolay Aleksandrov <razor@blackwall.org> 维护。关于桥接器的错误和增强功能的讨论在 linux-netdev 邮件列表 netdev@vger.kernel.orgbridge@lists.linux.dev 中进行。

该列表对任何有兴趣的人开放:http://vger.kernel.org/vger-lists.html#netdev