3. veth pair 与虚拟网桥:构建基础二层网络拓扑

在自定义协议 Socket 编程与内核网络测试中,网络命名空间(Network Namespace) 是隔离网络栈的核心手段。然而,默认情况下不同命名空间之间无法直接通信。本章将系统讲解如何通过 veth pair 和 Linux Bridge 打通命名空间之间的网络通路,构建出可复用的基础二层网络拓扑。

学习目标:
  • 掌握 veth pair 的创建、连接与命名空间绑定
  • 理解 Linux Bridge 的二层转发原理
  • 能够独立搭建多命名空间互通拓扑
  • 为后续自定义协议 Socket 测试提供网络环境基础

3.1 veth pair 设备原理与创建

veth(Virtual Ethernet)设备总是成对出现,像一根虚拟网线连接两个网络栈。数据从一端进入,立即从另一端原样输出,工作在 OSI 模型第二层。

3.1.1 核心特性

特性 说明
成对性 创建时同时生成两个端点,删除一端则另一端自动销毁
二层直连 两端之间无 MAC 地址转换,直接转发以太网帧
命名空间绑定 两端可分别移入不同命名空间,实现跨命名空间通信
零封装开销 数据在内核中直接传递,不经过物理硬件

3.1.2 创建 veth pair 并连接两个命名空间

以下步骤演示如何创建 veth pair,将两端分别放入 ns1 和 ns2,并配置 IP 地址实现互通。

# 1. 创建两个网络命名空间
ip netns add ns1
ip netns add ns2

# 2. 创建 veth pair,命名为 veth0 和 veth1
ip link add veth0 type veth peer name veth1

# 3. 将两端分别移入命名空间
ip link set veth0 netns ns1
ip link set veth1 netns ns2

# 4. 在命名空间内配置 IP 并启用
ip netns exec ns1 ip addr add 10.0.1.1/24 dev veth0
ip netns exec ns1 ip link set veth0 up

ip netns exec ns2 ip addr add 10.0.1.2/24 dev veth1
ip netns exec ns2 ip link set veth1 up

# 5. 验证连通性
ip netns exec ns1 ping -c 3 10.0.1.2
验证要点: 如果 ping 不通,请检查 ip netns exec ns1 ip link 确认 veth0 状态是否为 UP,以及 ip netns exec ns1 ip route 确认路由表中存在直连路由。

3.1.3 veth pair 二层拓扑 SVG

veth pair 连接两个命名空间 网络命名空间 ns1 veth0 10.0.1.1/24 网络命名空间 ns2 veth1 10.0.1.2/24 虚拟网线(内核直通) 数据从 veth0 进入,立即从 veth1 原样输出,反之亦然

3.2 Linux Bridge:多命名空间二层互通

veth pair 只能连接两个命名空间。当需要三个或更多命名空间互通时,必须引入 Linux Bridge。Linux Bridge 是一个纯软件实现的二层交换机,工作在数据链路层,维护 MAC 地址表进行帧转发。

3.2.1 桥接原理

  • MAC 学习: 桥接器记录每个端口收到的源 MAC 地址,建立 MAC 地址表。
  • 泛洪转发: 对于未知单播帧、广播帧和组播帧,向所有端口(除接收端口外)转发。
  • 精确转发: 对于已知单播帧,仅向目标 MAC 对应的端口转发。
  • STP 支持: 可选启用生成树协议,防止二层环路。

3.2.2 创建桥接拓扑:三个命名空间互通

以下步骤创建 br0 桥接器,将 ns1、ns2、ns3 通过 veth pair 接入同一二层网络。

# 1. 创建三个命名空间
ip netns add ns1
ip netns add ns2
ip netns add ns3

# 2. 创建 Linux Bridge
ip link add br0 type bridge
ip link set br0 up

# 3. 为每个命名空间创建 veth pair,一端放入命名空间,另一端接入桥
# ns1
ip link add veth1_ns type veth peer name veth1_br
ip link set veth1_ns netns ns1
ip link set veth1_br master br0
ip link set veth1_br up
ip netns exec ns1 ip addr add 10.0.0.1/24 dev veth1_ns
ip netns exec ns1 ip link set veth1_ns up

# ns2
ip link add veth2_ns type veth peer name veth2_br
ip link set veth2_ns netns ns2
ip link set veth2_br master br0
ip link set veth2_br up
ip netns exec ns2 ip addr add 10.0.0.2/24 dev veth2_ns
ip netns exec ns2 ip link set veth2_ns up

# ns3
ip link add veth3_ns type veth peer name veth3_br
ip link set veth3_ns netns ns3
ip link set veth3_br master br0
ip link set veth3_br up
ip netns exec ns3 ip addr add 10.0.0.3/24 dev veth3_ns
ip netns exec ns3 ip link set veth3_ns up

# 4. 验证互通
ip netns exec ns1 ping -c 2 10.0.0.2
ip netns exec ns1 ping -c 2 10.0.0.3
ip netns exec ns2 ping -c 2 10.0.0.3
常见错误: 忘记将 veth 的桥接端(如 veth1_br)设置为 up 状态,会导致该端口无法转发数据。使用 bridge link show 检查端口状态是否为 state UP。

3.2.3 桥接拓扑结构 SVG

Linux Bridge 实现多命名空间二层互通 Linux Bridge br0 MAC 地址表 | 二层转发 veth1_br veth2_br veth3_br ns1 veth1_ns 10.0.0.1/24 ns2 veth2_ns 10.0.0.2/24 ns3 veth3_ns 10.0.0.3/24 veth1_br veth2_br veth3_br 所有命名空间处于同一广播域,可直接通过 MAC 地址二层通信

3.3 桥接网络的关键操作与调试

3.3.1 常用管理命令

命令 用途
bridge link show 查看桥接器上所有端口及其状态
bridge fdb show 查看桥接器的 MAC 地址表
ip link set dev <port> master <bridge> 将端口加入桥接器
ip link set dev <port> nomaster 将端口从桥接器移除
bridge vlan show 查看 VLAN 过滤配置(如果启用)

3.3.2 调试流程

  1. 检查端口状态: bridge link show 确认所有 veth 桥接端处于 state UP。
  2. 检查命名空间内接口: ip netns exec ns1 ip link 确认 veth_ns 端已启用且配置了 IP。
  3. 检查 MAC 学习: 在 ns1 中 ping ns2 后,执行 bridge fdb show br br0 应看到 ns2 的 MAC 地址已学习到对应端口。
  4. 抓包验证: ip netns exec ns1 tcpdump -i veth1_ns -e -n 观察 ARP 请求和 ICMP 报文。
性能提示: Linux Bridge 在内核中通过 br_forward 函数实现快速转发,对于测试环境而言,其吞吐量足以模拟千兆以太网场景。如果遇到丢包,优先检查 net.core.rmem_default 和 net.core.wmem_default 内核参数。

3.4 本章小结

知识点 核心要点
veth pair 成对虚拟网线,连接两个网络栈,数据直接穿透内核
Linux Bridge 软件二层交换机,支持 MAC 学习与精确转发
拓扑构建 veth pair 一端入命名空间,另一端接桥,实现多命名空间互通
调试工具 bridge link、bridge fdb、tcpdump 是三大核心调试手段