---
title: Netfilter 与 BPF/XDP
url: https://doc.liz6.com/linux-kernel/06-network-subsystem/03-netfilter-and-bpf-xdp
locale: zh
area: linux-kernel
tags:
- linux-kernel
- 网络子系统
date: 2026-06-30
modified: 2026-06-30
description: '覆盖: Netfilter hooks → iptables/nftables → conntrack → NAT/masquerade → XDP → BPF/cBPF/eBPF → TC BPF 内核版本: 2.6 ~ 6.x'
---

# Netfilter 与 BPF/XDP

> 覆盖: Netfilter hooks → iptables/nftables → conntrack → NAT/masquerade → XDP → BPF/cBPF/eBPF → TC BPF
> 内核版本: 2.6 ~ 6.x

## 概述

Netfilter 是 Linux 的包过滤/修改引擎，提供了 iptables (旧) 和 nftables (新) 的底层基础。XDP/eBPF 则代表了更新的范式——在内核最早的收包点 (网卡驱动层) 执行用户提供的程序，实现高性能包处理。

## Netfilter Hooks

```c
// include/uapi/linux/netfilter.h
// 5 个 hook 点 (IPv4 为例):

enum nf_inet_hooks {
    NF_INET_PRE_ROUTING,   // 包到达, 路由前
    NF_INET_LOCAL_IN,      // 给本机的包, 路由后
    NF_INET_FORWARD,       // 转发的包
    NF_INET_LOCAL_OUT,     // 本机发出的包, 路由前
    NF_INET_POST_ROUTING,  // 所有发出的包, 路由后
};

// 每个 hook 点: 注册的 hook 函数按 priority 顺序调用
// 返回值:
//   NF_ACCEPT:  包通过 (正常)
//   NF_DROP:    丢弃 (不通知发送者)
//   NF_STOLEN:  包被 hook 接管
//   NF_QUEUE:   包排到用户空间队列 (nfnetlink_queue)
```

### iptables (旧, 基于 xtables)

```c
// net/ipv4/netfilter/ip_tables.c
// filter 表 (默认):
//   INPUT:   给本机的包
//   OUTPUT:  本机发出的
//   FORWARD: 转发的

// nat 表:
//   PREROUTING  (DNAT)
//   INPUT       (给本机的 DNAT)
//   OUTPUT      (本机发出的 DNAT)
//   POSTROUTING (SNAT/MASQUERADE)

// mangle 表: 修改 TOS/TTL/MARK
// raw 表:    NOTRACK (跳过 conntrack)
```

### nftables (新, 替代 iptables)

```c
// net/netfilter/nf_tables_api.c
// nft 用虚拟机执行规则 (不是 iptables 的线性匹配)
// 更灵活: 原生支持 set, map, concatenation
// 更快: 规则的一次遍历替代多个表的多次遍历

// nft list ruleset
// table inet filter {
//     chain input { type filter hook input priority 0; policy drop;
//         ct state established,related accept
//         iif lo accept
//         tcp dport 22 accept
//     }
// }
```

## Connection Tracking (conntrack)

```c
// net/netfilter/nf_conntrack_core.c
// conntrack 追踪每个连接 (flow) 的状态
//   → NAT 依赖它 (知道返回包属于哪条流)
//   → iptables state match 依赖它

// conntrack table:
//   每个连接一个 nf_conn → hash table
//   最大条目: /proc/sys/net/netfilter/nf_conntrack_max
//   超时: 每协议有独立的超时 (TCP: 432000s ≈ 5天 for ESTABLISHED)

// 小心! 在 NAT 网关上, conntrack table 可能满
//   → 丢包 → 新连接失败
//   → 增大 nf_conntrack_max 或降低超时
```

## NAT / MASQUERADE

```
SNAT (Source NAT):
  修改源 IP:port → 出口 IP:新 port
  conntrack 记录: orig_src:port → reply_dst:port → 回复包反向转换

MASQUERADE:
  动态 SNAT — 自动用出口接口的当前 IP
  适合: DHCP 客户端 (出口 IP 会变)

DNAT (Destination NAT):
  修改目标 IP:port → 内部服务器
  → 端口转发
```

## XDP: eXpress Data Path

```c
// net/core/filter.c + drivers/net/*_xdp.c
// XDP: 在网卡驱动的 NAPI poll 中、sk_buff 分配之前运行 BPF 程序
//   极早处理点 → 极高的 PPS (Mpps 级)
//   可以: DROP (最快), TX (转发), PASS (给协议栈), REDIRECT (到另一网卡)

// BPF 程序 return:
enum xdp_action {
    XDP_DROP,       // 丢弃 (如 DDoS 过滤)
    XDP_PASS,       // 交给协议栈 (正常流程)
    XDP_TX,         // 从此网卡发出 (hairpin)
    XDP_REDIRECT,   // 重定向到另一网卡或 CPU
};

// 加载: 通过 bpftool 或 ip link set dev eth0 xdp obj prog.o sec xdp
```

## eBPF 程序类型

| 类型 | Hook 点 | 用途 |
|------|---------|------|
| XDP | 网卡驱动 (最早期) | DDoS 过滤, 负载均衡 |
| TC (Traffic Control) | qdisc (ingress/egress) | 防火墙, 策略路由 |
| cgroup skb | cgroup socket | 容器网络策略 (Cilium) |
| socket filter | socket 创建 | SO_ATTACH_BPF |
| kprobe/tracepoint | 内核函数入口/tracepoint | 可观测性 |

## 参考

- **源码**: `net/netfilter/`, `net/core/filter.c`, `kernel/bpf/`
- **内核文档**: `Documentation/networking/filter.rst`, `Documentation/bpf/`
- **LWN**: "XDP and the packet processing revolution"

*关键词: netfilter, iptables, nftables, conntrack, NAT, XDP, BPF, eBPF, TC BPF*
