概述
wfb_tun 是 WFB-ng 的 TUN(网络隧道)设备桥接程序,负责在 Linux TUN 虚拟网卡和 UDP socket 之间双向转发 IPv4 数据包。它使得可以通过 WFB-ng 无线链路传输任意的 IP 流量,实现通用的 IPv4 over WiFi 隧道功能。
该程序使用 libevent 事件库实现非阻塞 I/O,支持数据包聚合以减少小包的无线开销,并内置心跳机制维持链路活跃。
工作原理
1 2
| TUN 虚拟网卡 <===> wfb_tun <===> UDP socket <===> wfb_tx/wfb_rx <===> 无线链路 (IP包) (桥接+聚合) (UDP封装) (FEC+加密) (空中传输)
|
数据流向
- TUN -> Socket(发送方向):从 TUN 设备读取 IP 数据包,添加长度头部进行聚合,通过 UDP 发送到对端
- Socket -> TUN(接收方向):从 UDP socket 接收聚合的数据包,解析长度头部提取原始 IP 包,写入 TUN 设备
数据包格式
1 2 3 4 5
| +------------------+------------------+------------------+ | tun_packet_hdr_t | IP Packet | tun_packet_hdr_t | ... | (2 bytes: len) | (variable) | (2 bytes: len) | +------------------+------------------+------------------+ ^ Entire batch sent as single UDP packet (max MTU=1445 bytes)
|
使用方式
1 2
| wfb_tun [-t tun_name] [-a tun_addr] [-c peer_addr] [-u peer_port] \ [-l listen_port] [-T agg_timeout_ms]
|
参数详解
| 参数 |
说明 |
默认值 |
-t tun_name |
TUN 设备名称。创建/使用的虚拟网卡接口名。程序会自动创建设备并配置。 |
wfb-tun |
-a tun_addr |
TUN 设备的 IP 地址(CIDR 格式)。设置虚拟网卡的 IP 地址和子网掩码,同时自动将接口设为 UP 状态并配置 MTU。 |
10.5.0.2/24 |
-c peer_addr |
对端 UDP 地址。发送方向的目标 IP 地址。接收方向的 socket 绑定到所有接口(INADDR_ANY),不限制来源。 |
127.0.0.1 |
-u peer_port |
对端 UDP 端口号。发送方向的目标端口。通常指向本地 wfb_tx/wfb_rx 的监听端口。 |
5801 |
-l listen_port |
本地 UDP 监听端口号。接收方向的绑定端口。wfb_rx 输出的数据会发送到这个端口。 |
5800 |
-T agg_timeout_ms |
聚合超时时间(毫秒)。小数据包在发送前等待此时间以聚合更多数据到一个 UDP 包中,减少无线开销。设为 0 表示不聚合、立即发送每个包。 |
5 |
内部机制
MTU 配置
- 无线侧 MTU:1445 字节(定义为
MTU)
- TUN 设备 MTU:自动设置为
MTU - sizeof(tun_packet_hdr_t) = 1443 字节
- 每个 IP 包前面添加 2 字节的长度头部
数据包聚合
1 2 3 4 5 6 7 8 9 10
| 聚合流程(TUN -> Socket): 1. 从 TUN 读取 IP 包,添加 tun_packet_hdr_t 头部 2. 如果缓冲区 <= MTU,继续累积更多包 3. 当缓冲区 >= MTU 或达到 agg_timeout_ms 超时,发送整个批次 4. 如果 agg_timeout_ms = 0,每个包立即单独发送
聚合好处: - 减少小包数量,降低 FEC 编码开销 - 提高无线链路的有效利用率 - 适合 mavlink 等小数据包场景
|
心跳机制
- 间隔:每 500 毫秒(
PING_INTERVAL_MS)
- 条件:仅当过去 500ms 内没有发送任何数据时,才发送空包作为心跳
- 目的:保持链路活跃,防止 NAT/防火墙超时断开连接
- 接收端处理:收到长度为 0 的包直接丢弃(识别为心跳)
事件驱动架构
使用 libevent 实现五个核心事件:
| 事件 |
触发条件 |
回调函数 |
作用 |
ev_ping |
定时器(500ms) |
ev_ping_cb() |
心跳发送 |
ev_tun_read |
TUN fd 可读 |
ev_tun_read_cb() |
从 TUN 读取 IP 包并聚合 |
ev_tun_read_timeout |
聚合超时 |
ev_socket_write_cb() |
超时后刷新聚合缓冲区 |
ev_socket_write |
socket 可写 |
ev_socket_write_cb() |
发送聚合批次到 UDP |
ev_socket_read |
socket 可读 |
ev_socket_read_cb() |
从 UDP 接收数据并写入 TUN |
信号处理
- SIGINT(Ctrl+C):优雅退出,关闭所有 fd
- SIGTERM:优雅退出,关闭所有 fd
典型使用场景
1. 本地 mavlink 隧道(最常见)
1 2 3 4 5
| wfb_tun -t wfb-tun -a 10.5.0.2/24 -c 127.0.0.1 -u 5801 -l 5800
wfb_tun -t wfb-tun -a 10.5.0.1/24 -c 127.0.0.1 -u 5801 -l 5800
|
2. 远程 IP 隧道
1 2 3 4 5
| wfb_tun -t drone-tun -a 10.0.0.2/24 -c 127.0.0.1 -u 5603 -l 5604
wfb_tun -t gs-tun -a 10.0.0.1/24 -c 127.0.0.1 -u 5604 -l 5603
|
3. 零聚合延迟模式
1 2
| wfb_tun -t wfb-tun -a 10.5.0.2/24 -T 0
|
4. 自定义 TUN 名称和地址
1 2
| wfb_tun -t mytun0 -a 192.168.100.1/16 -c 10.0.0.5 -u 9001 -l 9000
|
与 wfb_tx/wfb_rx 的配合
完整的 mavlink/IP 隧道链路配置:
无人机端(发送方)
1 2 3 4 5 6 7 8 9
| wfb_tun -t wfb-tun -a 10.65.0.2/24 -c 127.0.0.1 -u 5603
wfb_tun -t wfb-tun-rx -a 10.66.0.2/24 -c 127.0.0.1 -u 5605 -l 5604
wfb_tx -K /etc/drone.key -u 5603 -i 1 wlan0
|
地面站端(接收方)
1 2 3 4 5
| wfb_tun -t wfb-tun -a 10.65.0.1/24 -c 127.0.0.1 -u 5604 -l 5603
wfb_rx -K /etc/gs.key -c 127.0.0.1 -u 5603 -i 1 wlan0
|
注意事项
- 需要 root 权限:创建 TUN 设备和配置网络接口需要 CAP_NET_ADMIN 能力,通常以 root 运行或使用 sudo
- MTU 限制:通过隧道的 IP 包大小不能超过 1443 字节(减去 tun_packet_hdr_t 头部后)
- 仅支持 IPv4:当前实现只处理 IPv4 数据包
- 防火墙配置:确保 UDP 端口(listen_port 和 peer_port)在防火墙上开放
依赖库
- libevent(事件驱动 I/O)
- Linux TUN/TAP 设备(/dev/net/tun)