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
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
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 调试流程
- 检查端口状态:
bridge link show确认所有 veth 桥接端处于state UP。 - 检查命名空间内接口:
ip netns exec ns1 ip link确认 veth_ns 端已启用且配置了 IP。 - 检查 MAC 学习: 在 ns1 中 ping ns2 后,执行
bridge fdb show br br0应看到 ns2 的 MAC 地址已学习到对应端口。 - 抓包验证:
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 是三大核心调试手段 |