Overlay 网络的核心操作只有两个:封装和解封装。但不同的隧道协议在封装开销、多租户隔离、加密能力、硬件卸载支持上差异巨大。IPIP 只加 20 字节外层 IP 头,VXLAN 需要 50 字节但支持 1600 万个隔离网络,WireGuard 加 60 字节但提供了 ChaCha20-Poly1305 加密。
本文从内核源码拆解这四类隧道协议的实现,以及它们共享的
ip_tunnel 通用框架。
一、ip_tunnel 通用框架
Linux 内核为 IP
隧道提供了一套通用框架,IPIP、GRE、SIT(IPv6-in-IPv4)都基于它构建。核心数据结构是
struct ip_tunnel 和
struct ip_tunnel_key。
1.1 ip_tunnel_key:隧道元数据
// include/net/ip_tunnels.h
struct ip_tunnel_key {
__be64 tun_id; // 隧道标识符(VNI/GRE key)
union {
struct {
__be32 src; // 外层源 IP
__be32 dst; // 外层目的 IP
} ipv4;
struct {
struct in6_addr src;
struct in6_addr dst;
} ipv6;
} u;
__be16 tun_flags; // 隧道标志
u8 tos; // 外层 TOS/TC
u8 ttl; // 外层 TTL/HL
__be32 label; // IPv6 Flow Label
u32 nhid; // Nexthop ID
__be16 tp_src; // 传输层源端口(UDP 隧道)
__be16 tp_dst; // 传输层目的端口
__u8 flow_flags;
};ip_tunnel_key 抽象了所有 IP
隧道的公共参数。VXLAN 的 VNI 映射到 tun_id,GRE
的 key 也映射到 tun_id,UDP
隧道(VXLAN、Geneve)使用
tp_src/tp_dst 字段。
1.2 ip_tunnel_info:元数据隧道
// include/net/ip_tunnels.h
struct ip_tunnel_info {
struct ip_tunnel_key key;
struct ip_tunnel_encap encap;
#ifdef CONFIG_DST_CACHE
struct dst_cache dst_cache; // 路由缓存
#endif
u8 options_len; // 可选头长度
u8 mode; // TX/IPv6/Bridge 标志
};
#define IP_TUNNEL_INFO_TX 0x01 // 发送方向的隧道参数
#define IP_TUNNEL_INFO_IPV6 0x02 // key 中包含 IPv6 地址
#define IP_TUNNEL_INFO_BRIDGE 0x04 // 桥接隧道 IDip_tunnel_info 是 metadata
mode(流式隧道)的核心。当隧道设备配置为
external 模式时,OVS 或 BPF 程序通过
metadata_dst 将 ip_tunnel_info
附加到 skb
上,隧道设备直接使用这些参数进行封装,而不是查自己的静态配置。
1.3 struct ip_tunnel
// include/net/ip_tunnels.h
struct ip_tunnel {
struct ip_tunnel __rcu *next; // 哈希链表
struct hlist_node hash_node;
struct net_device *dev; // 隧道网络设备
struct net *net; // 所属命名空间
unsigned long err_time; // 最后一次 ICMP 错误时间
int err_count; // ICMP 错误计数
/* GRE 专用 */
u32 i_seqno; // 最后收到的序列号
atomic_t o_seqno; // 最后发送的序列号
int tun_hlen; // 隧道头长度
/* ERSPAN 专用 */
u32 index; // ERSPAN type II 索引
u8 erspan_ver; // ERSPAN 版本
u8 dir; // 方向(入/出)
u16 hwid; // 硬件 ID
struct dst_cache dst_cache; // 路由缓存
struct ip_tunnel_parm parms; // 用户态配置参数
int hlen; // tun_hlen + encap_hlen
struct ip_tunnel_encap encap; // FOU/GUE 封装参数
};struct ip_tunnel 是 IPIP、GRE、SIT
隧道设备的私有数据(通过 netdev_priv(dev)
获取)。dst_cache
缓存外层路由查找结果,避免每包都做 FIB 查找。
1.4 通用发送路径
所有基于 ip_tunnel 框架的隧道共享
ip_tunnel_xmit() 发送函数:
// net/ipv4/ip_tunnel.c(简化)
void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
const struct iphdr *tnl_params, u8 protocol)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
// 1. 查找外层路由(优先使用 dst_cache)
rt = ip_tunnel_get_route(tunnel, skb, ...);
// 2. 检查 MTU,必要时发送 ICMP need-frag
if (skb->len > mtu) {
icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
goto tx_error;
}
// 3. 构建外层 IP 头
skb_push(skb, tunnel->hlen);
iptunnel_xmit(skb, dev, rt, ...);
}iptunnel_xmit() 填充外层 IP
头字段(src、dst、TTL、TOS、protocol),然后调用
ip_local_out() 将封装后的包送入外层 IP 栈。
二、IPIP:最小开销的 IP 隧道
IPIP(IP-in-IP)是最简单的隧道协议——在原始 IP 包外面再套一层 IP 头,开销只有 20 字节。
2.1 封装格式
┌─────────────────────────────┐
│ 外层 IP 头(20 字节) │ protocol = 4 (IPIP)
│ src = 本端 VTEP IP │
│ dst = 对端 VTEP IP │
├─────────────────────────────┤
│ 内层 IP 头(20 字节) │
│ src = 容器 IP │
│ dst = 目的容器 IP │
├─────────────────────────────┤
│ TCP/UDP + 载荷 │
└─────────────────────────────┘
外层 IP 头的 protocol 字段设为
4(IPPROTO_IPIP),表示载荷是另一个 IPv4
包。
2.2 发送路径
// net/ipv4/ipip.c(简化)
static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb,
struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
if (unlikely(skb->protocol != htons(ETH_P_IP)))
goto tx_error; // IPIP 只能封装 IPv4
// 使用通用框架发送
ip_tunnel_xmit(skb, dev, &tunnel->parms.iph, IPPROTO_IPIP);
return NETDEV_TX_OK;
}IPIP 的发送几乎是直接调用通用框架。没有额外的隧道头部、没有序列号、没有校验和——极致简单。
2.3 接收路径
// net/ipv4/ipip.c(简化)
static int ipip_rcv(struct sk_buff *skb)
{
struct ip_tunnel *tunnel;
// 通过外层 IP 的 src/dst 查找对应的隧道设备
tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex,
TUNNEL_NO_KEY, iph->saddr, iph->daddr, 0);
if (tunnel) {
// 剥离外层 IP 头,将 skb->dev 设为隧道设备
ip_tunnel_rcv(tunnel, skb, ...);
}
}接收端通过 protocol 字段(值为 4)匹配到
IPIP 处理函数。ip_tunnel_lookup() 根据外层 IP
的源/目的地址找到对应的隧道设备。
2.4 限制
IPIP 的限制明显:
- 只支持 IPv4-in-IPv4(IPv6 需要用 ip6tnl 或 SIT)
- 没有隧道标识符——同一对 IP 之间只能有一条 IPIP 隧道
- 没有加密
- 许多中间设备(防火墙、NAT)不识别 protocol=4,可能被丢弃
Calico 默认使用
IPIP(IPIPMode: Always),因为在同一数据中心内不存在中间设备过滤的问题,而
20 字节的最小开销带来了最优的吞吐量。
三、GRE:通用路由封装
GRE(Generic Routing Encapsulation)在外层 IP 头和内层包之间插入一个 GRE 头部,提供可选的 key、序列号和校验和。
3.1 封装格式
┌─────────────────────────────┐
│ 外层 IP 头(20 字节) │ protocol = 47 (GRE)
├─────────────────────────────┤
│ GRE 头部(4-16 字节) │
│ ┌─ C K S ─── Protocol ────┐ │
│ │ 校验和(可选,4B) │ │
│ │ Key(可选,4B) │ │
│ │ 序列号(可选,4B) │ │
│ └─────────────────────────┘ │
├─────────────────────────────┤
│ 内层包(IP/Ethernet/...) │
└─────────────────────────────┘
GRE 头部最小 4 字节(只有标志位和协议字段),最大 16 字节(校验和 + key + 序列号都启用)。
3.2 Key 字段
GRE key 是 32 位标识符,允许同一对 IP 之间建立多条逻辑隧道:
// struct ip_tunnel 中 GRE 专用字段
u32 i_seqno; // 接收序列号(可选)
atomic_t o_seqno; // 发送序列号(可选)
int tun_hlen; // GRE 头部长度(根据选项变化)不同于 IPIP,GRE 的 key 字段映射到
ip_tunnel_key.tun_id,在 metadata mode 中可以由
BPF 或 OVS 动态设置。
3.3 ERSPAN
ERSPAN(Encapsulated Remote Switched Port Analyzer)是 GRE 的扩展,用于远程端口镜像:
// struct ip_tunnel 中 ERSPAN 专用字段
u32 index; // ERSPAN type II 会话索引
u8 erspan_ver; // 版本(1 或 2)
u8 dir; // 镜像方向(入/出)
u16 hwid; // 硬件 IDERSPAN 在 GRE 封装内再加一层 ERSPAN 头,携带镜像元数据。Linux 内核从 4.14 开始支持 ERSPAN type I/II,从 4.16 开始支持 type III(带时间戳)。常用于跨数据中心的流量镜像和分析。
四、VXLAN:大规模 overlay 的标准方案
VXLAN(Virtual Extensible LAN)将完整的二层以太网帧封装在 UDP 数据报中,通过 24 位 VNI 支持最多 1600 万个隔离网络。
4.1 封装格式
┌──────────────────────────────────┐
│ 外层以太网头(14B) │ 源/目的 MAC: VTEP 设备 MAC
├──────────────────────────────────┤
│ 外层 IP 头(20B) │ 源/目的 IP: VTEP 节点 IP
├──────────────────────────────────┤
│ UDP 头(8B) │ 目的端口: 4789
│ │ 源端口: 内层包哈希(用于 ECMP)
├──────────────────────────────────┤
│ VXLAN 头(8B) │ VNI (24-bit): 网络隔离标识
├──────────────────────────────────┤
│ 内层以太网帧 │ 原始 L2 帧(包含 VLAN 标签)
└──────────────────────────────────┘
总封装开销: 14 + 20 + 8 + 8 = 50 字节
4.2 VXLAN 头部
// include/net/vxlan.h
struct vxlanhdr {
__be32 vx_flags; // 标志位,I 位表示 VNI 有效
__be32 vx_vni; // VNI(高 24 位)+ Reserved(低 8 位)
};
#define VXLAN_HF_VNI cpu_to_be32(BIT(27)) // I 标志位
#define VXLAN_N_VID (1u << 24) // 最大 VNI 数量
#define VXLAN_VID_MASK (VXLAN_N_VID - 1)
#define IANA_VXLAN_UDP_PORT 4789 // 标准端口4.3 struct vxlan_dev
// include/net/vxlan.h
struct vxlan_dev {
struct vxlan_dev_node hlist4; // VNI 哈希表(IPv4)
struct vxlan_dev_node hlist6; // VNI 哈希表(IPv6)
struct list_head next; // per-netns 链表
struct vxlan_sock __rcu *vn4_sock; // IPv4 UDP socket
struct vxlan_sock __rcu *vn6_sock; // IPv6 UDP socket
struct net_device *dev; // VXLAN 网络设备
struct net *net; // 所属命名空间
struct vxlan_rdst default_dst; // 默认远端目的
struct timer_list age_timer; // FDB 老化定时器
spinlock_t hash_lock[FDB_HASH_SIZE];
unsigned int addrcnt; // FDB 条目计数
struct gro_cells gro_cells; // GRO 支持
struct vxlan_config cfg; // 用户态配置
struct hlist_head fdb_head[FDB_HASH_SIZE]; // FDB 哈希表
};vxlan_dev 的核心是 FDB
哈希表(fdb_head)——它把内层 MAC 地址映射到远端
VTEP 的 IP 地址。收到内层帧时,查 FDB 确定应该把封装后的 UDP
包发到哪个远端节点。
4.4 FDB 转发表
// drivers/net/vxlan/vxlan_core.c(简化)
struct vxlan_fdb {
struct hlist_node hlist; // 哈希链表节点
struct rcu_head rcu;
unsigned long updated; // 最后更新时间
unsigned long used; // 最后使用时间
struct list_head remotes; // 远端目的列表(可多个)
u8 eth_addr[ETH_ALEN]; // 内层 MAC 地址
u16 state; // NUD_REACHABLE 等
__be32 vni; // VNI
u16 flags; // 静态/本地等标记
};
struct vxlan_rdst {
__be32 remote_ip; // 远端 VTEP IP
__be16 remote_port; // 远端 UDP 端口
__be32 remote_vni; // 远端 VNI
u32 remote_ifindex; // 出口设备索引
struct list_head list;
struct rcu_head rcu;
};FDB 学习有三种模式:
组播学习:VTEP 加入组播组,未知单播/广播帧通过组播泛洪,收到应答后学习 MAC→VTEP 映射。
头端复制(Head-End
Replication):手动配置
bridge fdb append 00:00:00:00:00:00 dev vxlan100 dst <remote_ip>,未知帧被复制到所有已知
VTEP。
控制面注入:CNI 插件(Flannel、Calico)或 BGP EVPN 直接通过 netlink 写入 FDB 条目。这是生产环境最常用的模式——避免了组播和泛洪的开销。
4.5 VXLAN 发送路径
// drivers/net/vxlan/vxlan_core.c(简化)
static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
struct vxlan_fdb *f;
// 1. 内层目的 MAC 查 FDB
f = vxlan_find_mac(vxlan, eth_hdr(skb)->h_dest, vni);
if (f) {
// 单播:遍历该 MAC 的远端列表
list_for_each_entry_rcu(rdst, &f->remotes, list)
vxlan_xmit_one(skb, dev, vni, rdst, ...);
} else {
// 未知单播:遍历 default_dst(泛洪)
vxlan_xmit_one(skb, dev, vni, &vxlan->default_dst, ...);
}
}vxlan_xmit_one() 执行实际的封装:
- 查找外层路由(
ip_route_output()) - 构建 VXLAN 头(设置 VNI、I 标志位)
- 构建 UDP 头(目的端口 4789,源端口 = 内层帧哈希)
- 通过
udp_tunnel_xmit_skb()发送
源端口使用内层帧的哈希值是关键优化——不同的内层流量产生不同的外层 UDP 源端口,让中间交换机的 ECMP 哈希能区分不同的隧道流量。
4.6 VXLAN 接收路径
VXLAN 设备在创建时注册一个 UDP socket 监听端口 4789。收到 UDP 包后:
udp_rcv() → vxlan_rcv()
→ 解析 VXLAN 头,提取 VNI
→ 通过 VNI 哈希表查找 vxlan_dev
→ 剥离外层头部
→ skb->dev = vxlan->dev
→ 源 MAC 学习(更新 FDB)
→ netif_rx() → 进入内层协议栈
4.7 Metadata mode(流式隧道)
传统 VXLAN 设备绑定一个固定 VNI,每个 VNI 需要一个独立的
VXLAN 设备。Metadata mode(也叫 collect_md 或
external)允许单个 VXLAN 设备处理所有 VNI:
# 创建 metadata mode VXLAN 设备
ip link add vxlan0 type vxlan external dstport 4789在 metadata mode 下: - 发送时,上层(OVS/BPF)将
ip_tunnel_info 附加到 skb 的
metadata_dst 中,包含 VNI、远端 IP 等参数 -
VXLAN 设备从 metadata_dst
读取参数进行封装,而不是查自己的 FDB - 接收时,VXLAN
设备将解封装得到的元数据(VNI、远端 IP)写入
metadata_dst,供上层读取
这是 OVS 和 Cilium 使用的隧道模式。一个 VXLAN 设备服务整个节点的所有隧道流量,由 BPF 程序或 OVS 流表决定每个包的 VNI 和目的地。
4.8 GBP 扩展
VXLAN Group Based Policy(GBP)在 VXLAN 头的保留位中携带 16 位的 Group Policy ID:
// include/net/vxlan.h(GBP 头部布局)
// |G|R|R|R|I|R|R|R|R|D|R|R|A|R|R|R| Group Policy ID (16-bit) |
// | VXLAN Network Identifier (VNI) | Reserved |
#define VXLAN_GBP_USED_BITS (VXLAN_HF_GBP | VXLAN_GBP_DONT_LEARN | \
VXLAN_GBP_POLICY_APPLIED | VXLAN_GBP_ID_MASK)GBP 让 VXLAN 承载安全策略标签——Cilium 用它在 VXLAN 包中传递身份信息,接收端根据 Policy ID 执行网络策略,不需要查询目的 Pod 的标签。
五、WireGuard:加密隧道
WireGuard 是 Linux 5.6 内核引入的现代加密隧道协议。与 IPsec 的上万行代码相比,WireGuard 只有约 4000 行。
5.1 封装格式
┌──────────────────────────────────┐
│ 外层 IP 头(20B) │
├──────────────────────────────────┤
│ UDP 头(8B) │ 端口: 可配置(默认 51820)
├──────────────────────────────────┤
│ WireGuard 头(32B) │
│ ├─ Type (1B) │ 消息类型
│ ├─ Reserved (3B) │
│ ├─ Receiver Index (4B) │ 对端分配的会话索引
│ ├─ Counter (8B) │ 包序列号(防重放)
│ └─ Encrypted Payload + MAC (16B) │ ChaCha20-Poly1305 AEAD
├──────────────────────────────────┤
│ 加密的内层 IP 包 │
└──────────────────────────────────┘
总封装开销: 20 + 8 + 32 = 60 字节
5.2 加密路由(Cryptokey Routing)
WireGuard 的核心设计概念是加密路由——每个对端(peer)关联一个公钥和一组允许的 IP 段(AllowedIPs):
# WireGuard 配置示意
[Interface]
PrivateKey = <base64_private_key>
ListenPort = 51820
[Peer]
PublicKey = <base64_public_key>
AllowedIPs = 10.0.0.0/24, 192.168.1.0/24
Endpoint = 203.0.113.1:51820
发送时:
- 查找内层 IP 的目的地址匹配哪个 peer 的 AllowedIPs
- 使用该 peer 的会话密钥加密
- 发送到该 peer 的 Endpoint
接收时:
- 根据 Receiver Index 找到对应的会话
- 用会话密钥解密
- 验证解密后的内层源 IP 是否在该 peer 的 AllowedIPs 范围内
- 如果不在范围内,丢弃(防止 peer 伪造源 IP)
AllowedIPs 既是路由表又是 ACL——它同时决定”这个包发给谁加密”和”这个 peer 允许声称自己是谁”。
5.3 Noise 协议握手
WireGuard 使用 Noise_IKpsk2 协议进行密钥交换:
- Initiator → Responder:发送 Handshake Initiation(148 字节),包含加密的发起方公钥和时间戳
- Responder → Initiator:发送 Handshake Response(92 字节),包含加密的响应方公钥
- 双方各自推导出对称会话密钥
密钥每 2 分钟或传输 2^64 个包后自动轮换。握手使用 Curve25519 做 ECDH,会话使用 ChaCha20-Poly1305 做 AEAD 加密。
5.4 内核模块架构
drivers/net/wireguard/
├── main.c // 模块初始化
├── device.c // net_device_ops 实现
├── peer.c // peer 管理
├── noise.c // Noise 协议状态机
├── cookie.c // Cookie 机制(DoS 防护)
├── allowedips.c // AllowedIPs trie 查找
├── ratelimiter.c // 握手速率限制
├── send.c // 加密 + 发送
├── receive.c // 接收 + 解密
└── queueing.c // 多核并行加密队列
allowedips.c 实现了一个 radix trie,将 IP
前缀映射到 peer。发送时 O(32)(IPv4)或
O(128)(IPv6)比特匹配找到目标 peer。
queueing.c
实现了多核并行加密——加密操作分发到多个 CPU
的工作队列上,然后按序重组,充分利用现代 CPU 的 SIMD
指令集(AVX2/AVX-512 加速 ChaCha20)。
5.5 Kubernetes 集成
Calico 3.14+ 支持 WireGuard 节点间加密:
apiVersion: projectcalico.org/v3
kind: FelixConfiguration
metadata:
name: default
spec:
wireguardEnabled: true启用后,Calico 自动在每个节点创建 WireGuard 接口,生成密钥对,通过 Calico 的控制面分发公钥。Pod 间跨节点流量自动加密,延迟增加约几微秒,吞吐量在 10+ Gbps 水平(取决于 CPU 的 SIMD 能力)。
六、协议对比与选型
| 特性 | IPIP | GRE | VXLAN | Geneve | WireGuard |
|---|---|---|---|---|---|
| 层级 | L3 | L3 | L2 over L3 | L2 over L3 | L3 |
| 封装开销 | 20B | 24-28B | 50B | 50+B | 60B |
| 多租户 | 无 | 32-bit key | 24-bit VNI | 24-bit VNI | 无 |
| 加密 | 无 | 无 | 无 | 无 | ChaCha20 |
| NAT 穿透 | 差 | 差 | 好(UDP) | 好(UDP) | 好(UDP) |
| ECMP | 不支持 | 不支持 | 支持 | 支持 | 支持 |
| 硬件卸载 | 有限 | 有限 | 广泛 | 部分 | 无 |
| 可扩展性 | 无 | 无 | GBP | TLV | 无 |
| 内核版本 | 2.x+ | 2.x+ | 3.7+ | 3.18+ | 5.6+ |
选型建议:
- 同数据中心、不需加密:IPIP(Calico 默认),开销最小
- 需要 L2 overlay:VXLAN(Flannel/Cilium 默认),广泛硬件卸载支持
- 需要可扩展元数据:Geneve(OVN/Cilium),TLV 扩展能力
- 需要加密:WireGuard(Calico 加密),现代密码学 + 最小代码量
- 跨公网:WireGuard 或 VXLAN over IPsec
七、硬件卸载
现代网卡对 VXLAN 的卸载支持最为广泛:
# 检查 VXLAN 卸载能力
ethtool -k eth0 | grep -i vxlan
tx-udp_tnl-segmentation: on # 外层 TSO
tx-udp_tnl-csum-segmentation: on # 外层校验和
rx-vxlan-port-offload: on # 接收端卸载卸载的含义:
- tx-udp_tnl-segmentation:网卡直接对封装后的大包做 TSO 分段,内核不需要先分段再封装
- rx offload:网卡识别 VXLAN 包,基于内层四元组做 RSS 分流,而不是基于外层(否则同一 VTEP 的所有流量哈希到同一队列)
IPIP 和 GRE 的卸载支持取决于网卡型号。WireGuard 由于加密的特性,目前没有通用硬件卸载。
八、可观测性
8.1 bpftrace 追踪隧道封装
# 追踪 VXLAN 封装
bpftrace -e '
kprobe:vxlan_xmit_one {
$skb = (struct sk_buff *)arg0;
printf("vxlan_encap: len=%d\n", $skb->len);
}
kprobe:vxlan_rcv {
printf("vxlan_decap: pid=%d\n", pid);
}'追踪 ip_tunnel 通用路径:
bpftrace -e '
kprobe:ip_tunnel_xmit {
$dev = (struct net_device *)arg1;
printf("tunnel_xmit: dev=%s len=%d\n",
$dev->name, ((struct sk_buff *)arg0)->len);
}'8.2 MTU 问题诊断
# 监控 ICMP need-frag 消息
bpftrace -e '
kprobe:icmp_send {
$type = arg1;
$code = arg2;
if ($type == 3 && $code == 4) {
printf("ICMP need-frag: mtu=%d\n", arg3);
}
}'8.3 VXLAN FDB 检查
# 查看 VXLAN FDB 表
bridge fdb show dev vxlan100
# 查看 VXLAN 设备参数
ip -d link show vxlan100
# 抓取 VXLAN 封装包
tcpdump -i eth0 -nn 'udp port 4789' -e九、参考文献
- Linux 6.6 内核源码
include/net/ip_tunnels.h、include/net/vxlan.h - Linux 6.6 内核源码
net/ipv4/ipip.c、net/ipv4/ip_gre.c - Linux 6.6 内核源码
drivers/net/vxlan/vxlan_core.c - Linux 6.6 内核源码
drivers/net/wireguard/ - RFC 7348: Virtual eXtensible Local Area Network (VXLAN)
- RFC 2784: Generic Routing Encapsulation (GRE)
- Jason A. Donenfeld,《WireGuard: Next Generation Kernel Network Tunnel》
上一篇:虚拟网络设备内核实现:veth、bridge 与 macvlan
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【Kubernetes 网络深度系列】路由与隧道:Linux 怎么决定一个包往哪走
Linux 路由表、FIB 查找、策略路由,以及 VXLAN/Geneve/WireGuard 隧道技术深度拆解
【Linux 网络子系统深度拆解】UDP 内核实现与 socket lookup 优化
UDP 简单?在内核中它一点都不简单。双哈希表 socket 查找、SO_REUSEPORT 多核分发、Early Demux 路由缓存、UDP GRO 聚合、reader_queue 无锁读、forward allocation 内存管理、UDP 封装(ESP/L2TP/VXLAN)——本文从 Linux 6.6 内核源码拆解 UDP 的每一个优化细节。
【Linux 网络子系统深度拆解】网络丢包定位:从 drop_monitor 到 kfree_skb 追踪
从内核源码拆解 Linux 网络丢包追踪的完整体系:kfree_skb tracepoint 与 80+ 种 drop_reason 枚举、drop_monitor netlink 子系统、dropwatch 工具、perf 丢包记录、bpftrace 丢包聚合脚本,以及生产环境常见丢包点速查表。
【Linux 网络子系统深度拆解】内核网络追踪工具箱:bpftrace/perf/ftrace 实战
从内核 tracepoint 定义出发,系统讲解 bpftrace、perf、ftrace 三大工具在网络诊断中的实战用法:TCP 重传根因分析、softirq 延迟定位、收发包路径延迟剖析、conntrack 表满监控、per-function 火焰图,以及各工具的适用场景与性能开销对比。