init: DPDK → DPU learning blog (VitePress)

- VitePress static site for rendering all markdown documents
- Auto-discovers .md files from dpdk-roadmap-v3 and dpdk-study-kb
- Features: full-text search, dark mode, responsive design
- Pages: roadmap, notes (Phase 0-3), product docs, knowledge base
This commit is contained in:
newbie
2026-08-09 15:42:47 +00:00
commit 41531c19c2
20 changed files with 9262 additions and 0 deletions
+349
View File
@@ -0,0 +1,349 @@
# 家用 DPDK 网络加速器 — 产品规划文档
> **创建日期**: 2026-07-13
> **关联学习路线**: `2026-06-29-dpdk-roadmap-v3-design.md`
> **目标**: 基于 DPDK 做一个低成本家用网络加速器,可以量产销售
---
## 一、产品定义
| 项目 | 内容 |
|------|------|
| 产品名 | 家用网络加速器(暂定) |
| 定位 | 插在光猫和路由器之间,即插即用 |
| 一句话卖点 | "让千兆宽带真正跑满,全家不卡,不用设置" |
| 目标用户 | 家庭用户,不折腾 |
| 参考售价 | ¥299(100 台试水,单台毛利 ~¥118) |
### 使用方式
```
原来: 光猫 ─── 路由器 ─── 全家设备
↑ 光猫 NAT 性能差,有人下载全家卡
加盒子: 光猫 ─── [你的盒子] ─── 路由器 ─── 全家设备
↑ ↑
桥模式/无感透传 DPDK 线速 + 智能 QoS
```
---
## 二、三大核心功能
| # | 功能 | 痛点 | 实现原理 |
|---|------|------|---------|
| 1 | **提速** | 运营商光猫 NAT 差,千兆宽带只能跑 600M | 光猫改桥接,盒子 DPDK 线速 NAT/转发,跑满 940M |
| 2 | **不卡** | 有人下载/BT/看视频,其他人游戏延迟爆炸 | DPDK rte_flow 按流特征分类:小包优先、大包限速、视频保底 |
| 3 | **零配置** | 用户不想进后台、不想学网络知识 | 开机自动 DHCP 探测 WAN/LAN 方向,默认桥模式透传 |
### 功能 2 详细:智能流控
```
收包 → rte_flow 五元组分类
│
├── 小包持续流 (<256B, >100pps)
│ → 标记 "游戏/通话/视频会议"
│ → 高优先级队列,绝对优先
│
├── 大包持续流 (>1024B, >50Mbps)
│ → 标记 "下载/BT/视频缓冲"
│ → 低优先级队列,带宽上限
│
└── 其他
→ 普通优先级,尽力转发
```
> 关键设计:不识别具体应用(不需要 DPI),只靠流特征判断。简单、可靠、私密。
---
## 三、硬件 BOM(最低成本,支持 VFIO)
### 选型理由
- **J3355B-ITX**: Apollo Lake 起全系支持 VT-d,这是 Intel 平台最便宜的 VT-d 方案
- **Intel 82576**: DPDK igb PMD 原生驱动,最老最稳定的网卡之一,二手极便宜
- **VFIO > UIO**: VFIO 是 DPDK 官方推荐驱动方式,内核主线永久支持,DMA 安全隔离
### 逐项 BOM
| # | 零件 | 规格 | 来源 | 单价 |
|---|------|------|------|------|
| 1 | 主板 | ASRock J3355B-ITX (双核 2.0GHz, 10W, VT-d) | 闲鱼 | ¥100 |
| 2 | 内存 | DDR3L 2GB SODIMM | 闲鱼拆机 | ¥12 |
| 3 | 存储 | 8GB mSATA SSD | 闲鱼拆机 | ¥10 |
| 4 | 网卡 | Intel 82576 双口千兆 (PCIe 2.0 x4) | 闲鱼拆机 | ¥30 |
| 5 | 电源 | 12V 3A 适配器 + DC 5.5×2.5mm 线 | 1688 批发 | ¥8 |
| 6 | 外壳 | 3mm 亚克力激光切割 (17×17cm ITX) | 淘宝定制 | ¥10 |
| 7 | 铜柱+螺丝 | M3×6 一套 4 颗 | 1688 | ¥2 |
| 8 | 导热垫 | 40×40×1mm 硅胶 | — | ¥1 |
| | | | **合计** | **¥173** |
### 备选主板
| 型号 | CPU | 核数 | VT-d | 价格 | 备注 |
|------|-----|------|------|------|------|
| ASRock J3355B-ITX | J3355 | 双核 | ✅ | ¥100 | **首选,最便宜 VT-d** |
| ASRock J3455-ITX | J3455 | 四核 | ✅ | ¥140 | J3355 缺货时备选 |
| ASRock J4205-ITX | J4205 | 四核 | ✅ | ¥160 | 第二备选 |
### 内存使用分析
```
DPDK hugepage: 64MB
Alpine Linux: ~128MB
DPDK app: ~50MB
空闲缓冲: ~1.7GB
总计 (2GB): ~300MB 使用 / ~1.7GB 空闲
结论: 2GB 绰绰有余,不需要 4GB
```
### 存储使用分析
```
Alpine Linux: ~130MB ISO → 安装后 ~50MB
DPDK 库: ~20MB
应用二进制: ~5MB
配置/日志: ~10MB
总计: <100MB
结论: 8GB mSATA 完全够用
```
---
## 四、软件技术栈
| 层 | 组件 | 说明 |
|----|------|------|
| 操作系统 | Alpine Linux 3.20 | 最小 Linux 发行版,~50MB |
| 内核 | linux-lts 6.6 | VFIO、hugepage、AF_PACKET 主线支持 |
| 数据面框架 | DPDK 24.11 LTS | 用户态高性能包处理 |
| PMD 驱动 | `drivers/net/igb` | Intel 82576 原生 DPDK Poll Mode Driver |
| 设备绑定 | `vfio-pci` | VT-d + IOMMU,DPDK 官方推荐方式 |
| 转发 | 自研 DPDK 应用 | L3 转发 + NAT + rte_flow QoS |
| 控制面 | Unix socket + HTTP API | 配置下发、状态查询 |
| 初始化 | 自定义 init 脚本 | DHCP 探测、自动识别 WAN/LAN |
### DPDK 技术点与学习路线对应
| DPDK 技术 | 用途 | 学习路线阶段 |
|-----------|------|------------|
| `rte_mempool` | 包内存池管理 | P1 |
| `rte_mbuf` | 包数据结构 | P1 |
| `rte_ring` | lcore 间无锁通信 | P1 |
| `rte_eal_init` | EAL 初始化 (hugepage/lcore) | P1 |
| `rte_ethdev` (igb PMD) | 82576 网卡收发 | P1 |
| `rte_eth_tx_burst` / `rte_eth_rx_burst` | 批量收发包 | P1 |
| `rte_flow` | 流分类 (小包/大包分流) | P3 |
| `rte_hash` | NAT 连接跟踪表 | P1 |
| `rte_lcore` | 核绑定 (控制面/数据面分离) | P1 |
| `rte_kni` | DPDK↔内核通道 (可选) | P2 |
---
## 五、数据面架构
### 整体架构:快慢路径分离
```
┌────────────────────┐
│ 控制面 (lcore 0) │
│ │
│ DHCP Client │ ← 自动探测 WAN 口
│ 配置管理 │
│ HTTP API (可选) │ ← 手机配置用
│ 日志/统计 │
└────────┬───────────┘
│
Unix socket
│
┌────────────────────────┼────────────────────────┐
│ │ │
▼ ▼ ▼
WAN 口 (port 0) 转发核 (lcore 1) LAN 口 (port 1)
│ │ │
▼ ▼ ▼
┌─────────┐ ┌───────────────┐ ┌─────────┐
│ RX 队列 │──mbuf──►│ rte_flow 分流 │──mbuf──►│ TX 队列 │
│ │ │ │ │ │
│ 82576 │ │ 小包→高优先 │ │ 82576 │
│ igb PMD │ │ 大包→低优先 │ │ igb PMD │
│ │ │ NAT 连接跟踪 │ │ │
└─────────┘ └───────────────┘ └─────────┘
```
### 收发包路径
```
收包:
rte_eth_rx_burst(port, queue, mbufs, BURST_SIZE)
→ 逐包处理:
1. rte_flow 匹配(五元组 hash)
2. 如果不是已知流 → 新建流表项
3. 按流优先级入队
4. NAT 转换 (SNAT/DNAT)
5. 查路由表决定出端口
发包:
高优先队列 → rte_eth_tx_burst (先发)
低优先队列 → rte_eth_tx_burst (后发,有剩余带宽才发)
```
### Lcore 分配
```
lcore 0 (主核):
- EAL 初始化
- 控制面逻辑
- 定时器 (统计收集)
- Unix socket 服务
lcore 1 (转发核):
- 数据面死循环
- 收包 → 分流 → NAT → 发包
- 独占 100% CPU,无中断干扰
```
---
## 六、软件模块划分
```
dpdk-gateway/
├── src/
│ ├── main.c # EAL 初始化,启动 lcore
│ ├── forward.c # 转发核主循环
│ ├── forward.h
│ ├── nat.c # NAT 连接跟踪 (SNAT/DNAT)
│ ├── nat.h
│ ├── classifier.c # rte_flow 流分类 + 优先级队列
│ ├── classifier.h
│ ├── control.c # 控制面 (DHCP 探测 + 配置)
│ ├── control.h
│ ├── stats.c # 统计收集
│ └── stats.h
├── scripts/
│ ├── init.sh # 启动脚本 (配 hugepage/绑定网卡)
│ └── probe.sh # WAN/LAN 自动探测脚本
├── config/
│ └── gateway.conf # 默认配置文件
├── Makefile # 或 meson.build
└── README.md
```
---
## 七、量产降本路径
| 阶段 | 数量 | 主板来源 | 网卡来源 | 单台 BOM |
|------|------|---------|---------|---------|
| 样机验证 | 1 台 | 闲鱼 J3355B ¥100 | 闲鱼 82576 ¥30 | ¥173 |
| 小批试水 | 100 台 | 闲鱼打包 ¥90 | 闲鱼打包 ¥25 | ¥146 |
| 中批 | 500 台 | 批发商 ¥85 | 批发 ¥22 | ¥130 |
| 大批定制 | 1000 台 | 自研板 (I226 焊板) | 芯片直焊 | ~¥120 |
> 1000 台定制板后,Intel I226-V 网卡芯片直接焊主板上,省去独立网卡和 PCIe 槽。
---
## 八、成本与利润测算
### 100 台试水
| 项目 | 金额 |
|------|------|
| 单台 BOM | ¥146 |
| 单台组装(自己干) | ¥0 |
| 包装盒(定制牛皮纸,100 个) | ¥3/台 |
| 快递费(均摊) | ¥5/台 |
| 单台全成本 | ¥154 |
| **售价** | **¥299** |
| **单台毛利** | **¥145** |
| **100 台总毛利** | **¥14,500** |
### 1000 台(定制板)
| 项目 | 金额 |
|------|------|
| 单台 BOM | ¥120 |
| 组装(深圳厂 ¥15/台) | ¥15 |
| 包装盒 | ¥3 |
| 快递 | ¥5 |
| 单台全成本 | ¥143 |
| **售价** | **¥299** |
| **单台毛利** | **¥156** |
| **1000 台总毛利** | **¥156,000** |
---
## 九、下一步行动计划
```
Phase 1: 样机验证 (1-2 周)
□ 1. 采购 J3355B-ITX + Intel 82576 + DDR3L 2GB + mSATA 8GB
□ 2. 安装 Alpine Linux,配置 VFIO + hugepage
□ 3. 编译 DPDK,跑通 testpmd L2 转发
□ 4. 编写最简单的 DPDK L3 转发程序 (main.c + forward.c)
Phase 2: 核心功能 (2-4 周)
□ 5. 实现 NAT (SNAT/DNAT + 连接跟踪)
□ 6. 实现 rte_flow 流分类 (小包/大包分流)
□ 7. 实现优先级队列调度
□ 8. 实现 WAN/LAN 自动探测 (DHCP)
Phase 3: 产品化 (2-4 周)
□ 9. 添加启动脚本 (init.sh + probe.sh)
□ 10. 添加 LED 状态指示 (通过 GPIO 或内核接口)
□ 11. 制作 Alpine 固件镜像 (dd 可刷)
□ 12. 设计外壳图纸 (DXF for 亚克力切割)
Phase 4: 自用验证 (4 周)
□ 13. 替换家中路由器,自己用 1 个月
□ 14. 记录所有问题和改进点
□ 15. 性能压测 (iperf3 小包/大包)
Phase 5: 开源 + 销售
□ 16. GitHub 开源基础版
□ 17. 恩山论坛 / chiphell 发帖
□ 18. 淘宝/闲鱼上架
```
---
## 十、风险评估
| 风险 | 严重度 | 概率 | 应对措施 |
|------|--------|------|---------|
| 二手主板货源不稳定 | 🟡 中 | 中 | 初期囤 100 片;J3455-ITX 备选;1000 台后走定制 |
| 用户不会改光猫桥接 | 🔴 高 | 高 | 默认纯桥模式透传,不改任何配置也能工作(仅提速效果打折) |
| 2 口不够替代路由器 | 🟡 中 | 高 | 就定位加速器,不定位路由器;明确告诉用户"插在光猫和路由器之间" |
| GPL 合规问题 | 🟢 低 | 低 | DPDK 用户态程序 BSD 协议,Alpine Linux 用 GPL 但无需修改内核 |
| 售后工作量大 | 🔴 高 | 中 | 初期配详细 LED 故障灯说明、FAQ 文档;逐步建立知识库 |
| 被友商抄袭 | 🟡 中 | 中 | 开源 + 社区粘性 + 持续更新;品牌信任是壁垒 |
| 3C 认证 (做硬件后) | 🔴 高 | 中 | 初期只卖固件/散件/DIY 套件;量大了再走认证 |
---
## 十一、竞品对比
| 对比维度 | 运营商光猫 | 小米路由器 | 软路由 (iStoreOS) | **你的盒子** |
|---------|-----------|-----------|-----------------|------------|
| NAT 性能 (千兆) | ~600M | ~940M | ~940M | **~940M (线速)** |
| 满载延迟 (小包) | 200ms+ | 80ms+ | 50ms+ | **<20ms** |
| 智能流控 | ❌ | 基础 QoS | 需手动配置 | **自动,零配置** |
| 配置难度 | 不用 (默认烂) | 中等 | 高 | **不用配** |
| 售价 | ¥0 (送的) | ¥300 | ¥400+ | **¥299** |
| 开源 | ❌ | ❌ | 部分 | **✅ 核心开源** |
---
## 十二、相关资源
- **学习路线文档**: `2026-06-29-dpdk-roadmap-v3-design.md`
- **加速路径文档**: `DPDK_ACCELERATED_PATH.md`
- **DPDK 源码**: `~/myshare/dpdk-stable-24.11.6`
- **内核对照**: `~/myshare/linux-stable` (v6.6)
- **性能压测工具**: `~/myshare/dperf-main`
+23
View File
@@ -0,0 +1,23 @@
# 产品设计文档
## DPDK Home Gateway 网络加速器
→ [完整产品方案](/products/home-gateway)
基于 DPDK 的家庭网关网络加速方案,包括:
- 硬件选型与 BOM 清单
- 定价策略与市场分析
- 分阶段研发计划
- 竞品对比分析
## uNOS — 用户态网络操作系统
→ [设计规格书](/products/unos-design) | [学习方法论](/products/unos-method)
uNOS (user-space Network Operating System) 是一个生产级的用户态网络操作系统设计:
- **三层剥洋葱法**: 从 Linux 内核到 DPDK,再到 DPU
- **架构设计**: 控制平面 / 数据平面分离
- **核心模块**: 协议栈、转发引擎、硬件抽象层
- **对标**: Cisco IOS-XR / Juniper JunOS 架构
+1735
View File
File diff suppressed because it is too large Load Diff
+359
View File
@@ -0,0 +1,359 @@
# uNOS 学习方法论 — 三层剥皮法
> **创建日期**: 2026-08-01
> **适用**: 系统编程学习(DPDK / 内核 / TCP 协议栈 / PMD 驱动)
> **关联**: `uNOS_REQUIREMENTS.md`、`uNOS_DESIGN_SPEC.md`、`lazy-puzzling-rocket.md`
---
## 一、核心公式
```
掌握 = 内核为什么慢 → DPDK 怎么解决的 → 我亲手写一遍 → 性能数据证明
────────── ────────────── ────────── ─────────────
Layer 1 Layer 2 Layer 3 Layer 4
(理解问题) (理解方案) (内化知识) (验证理解)
```
每一层不可跳过:
| 跳过 | 后果 |
|------|------|
| Layer 1 | 不知道为什么需要 DPDK,面试回答停留在"因为快" |
| Layer 2 | 只会调 API,不理解设计决策 |
| Layer 3 | "看懂了但不会写",面试一问细节就崩 |
| Layer 4 | "写出来了但不知道自己写对了没" |
---
## 二、四层详解
### Layer 1: 内核为什么慢(20 分钟,理解问题)
**做什么**:读内核源码,找到瓶颈的**精确位置**。
**方法**:
1. 先确定要研究的子系统(如:包分配、路由查找、TCP 状态机)
2. 在 Linux 内核源码中找到对应的 C 文件
3. 跟踪一个完整的数据路径(如:收包 → 分配 skb → 协议栈 → 应用)
4. 标注每一步的延迟来源:中断、锁、内存分配、cache miss、上下文切换
**产出标准**:能用一句话解释"内核做 X 要走多少步、每一步慢在哪"。
**示例**(mempool):
```
问题: 内核是怎么分配网络包的?
精确到源码:
收包: net/core/dev.c → netif_rx() → enqueue_to_backlog()
→ 每个包触发一次 ksoftirqd 调度
分配: include/linux/skbuff.h → alloc_skb()
→ kmem_cache_alloc() → slab allocator
→ 每次分配都要获取 per-cpu 锁
为什么慢:
1. 每包一次中断 → 每包一次上下文切换
2. slab allocator 有锁 → 多核竞争
3. kmem_cache 有冷热分离 → 热路径 miss 时有 cache miss
4. sk_buff 结构体 200+ 字节,跨多个 cacheline
```
---
### Layer 2: DPDK 怎么解决的(20 分钟,理解方案)
**做什么**:读 DPDK 源码,找到优化的**精确手段**。
**方法**:
1. 在 DPDK 源码中找到对应的库/驱动
2. 读头文件的 struct 定义和函数注释
3. 读实现文件的几个关键函数
4. 画出"数据路径图":一个包从进入到离开,经过哪些结构体、哪些函数
**产出标准**:能用一张图画出关键路径,标注每一级的延迟量级。
**示例**(mempool):
```
方案: rte_mempool
精确到源码:
lib/mempool/rte_mempool.h line 230 → struct rte_mempool
lib/mempool/rte_mempool.h line 90 → struct rte_mempool_cache
三级路径:
L1: mbuf 从 per-lcore cache 拿 → 零锁,L1 cache 常驻 (~5ns)
L2: cache 空了 → 从 ring 批量补 256 个 → CAS 一次 (~50ns 均摊)
L3: ring 也空了 → 从 hugepage 拿 → 很少触发 (~200ns)
为什么快:
1. 预分配 → 收发过程零分配,只从池里取
2. per-lcore cache → 无锁,无竞争
3. ring 批量操作 → 分摊 CAS 开销
4. mbuf 固定 128B,2 个 cacheline → prefetch 友好
```
---
### Layer 3: 亲手写一遍(60 分钟,内化知识)
**做什么**:关掉所有参考代码,自己从头写。
**方法**:
1. 读完 Layer 1-2 后,**立即关掉 DPDK 源码**
2. 打开编辑器,自己写
3. 编译 → crash → gdb backtrace → 读报错 → 修 → 继续
4. 跑通后用 gdb 单步跟踪关键路径:打印 struct 内容、看指针偏移
5. 用 `pahole` 看结构体 cache line 布局
**产出标准**:能在 gdb 里打印出关键结构体的内部状态,能解释为什么这么快。
**示例**(mempool):
```c
// 自己写:
// 1. 创建 mempool
struct rte_mempool *pool = rte_pktmbuf_pool_create(
"my_pool", 8191, 256, 0,
RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()
);
// 2. 分配/释放循环,测性能
uint64_t start = rte_rdtsc();
for (int i = 0; i < 1000000; i++) {
struct rte_mbuf *m = rte_pktmbuf_alloc(pool);
rte_pktmbuf_free(m);
}
uint64_t cycles = (rte_rdtsc() - start) / 1000000;
printf("avg cycles per alloc+free: %lu\n", cycles);
// 3. gdb 验证
// (gdb) p *pool
// (gdb) p pool->cache[0] ← per-lcore cache 里有多少个 mbuf?
// (gdb) p pool->cache[0].len ← 当 len > 0 时 alloc 走 L1
// (gdb) p pool->cache[0].len ← 当 len = 0 时 alloc 走 L2 补货
```
**禁止事项**:
- ❌ 复制粘贴 DPDK examples 代码
- ❌ 先看答案再写
- ❌ crash 后直接问 AI 怎么修(先自己 gdb 至少 5 分钟)
---
### Layer 4: 性能数据证明(20 分钟,验证理解)
**做什么**:用数据证明你写的东西确实比内核快。
**方法**:
1. `perf stat` 对比内核路径 vs DPDK 路径
2. `perf record` + FlameGraph 生成火焰图
3. 填一张对比表
4. 写入 `docs/` 文档
**产出标准**:有一张表格,有数字,有火焰图链接。
**示例**(mempool):
```
│ 指标 │ 内核 (slab) │ DPDK (mempool) │
│ alloc+free 延迟 │ ~200ns │ ~15ns │
│ L1 cache miss │ ~8% │ ~0.5% │
│ 锁竞争 │ 有 (per-cpu) │ 无 (per-lcore) │
│ 火焰图 │ [链接] │ [链接] │
```
---
## 三、每阶段时间分配
```
总时间: 2 小时/阶段
Layer 1: 20 分钟 (读内核源码 + 理解问题)
Layer 2: 20 分钟 (读 DPDK 源码 + 理解方案)
Layer 3: 60 分钟 (手写 + gdb 跟踪)
Layer 4: 20 分钟 (perf 验证 + 写文档)
输入 (Layer 1-2): 30%
输出 (Layer 3-4): 70%
```
---
## 四、应用到 uNOS 每个 Phase
### Phase 1: L2 MAC 转发
| Layer | 内容 | 产出 |
|-------|------|------|
| 1 | 读 `net/core/dev.c` NAPI 收包路径 | 理解中断驱动的瓶颈在哪 |
| 2 | 读 DPDK PMD 轮询模式: `rte_eth_rx_burst` | 理解零中断轮询 |
| 3 | 手写 L2 转发循环,gdb 跟踪 mbuf 从口0到口1 | 能跑通,iPerf3 双向通 |
| 4 | `perf record` 火焰图 | CPU 100% 有用功,中断开销 0% |
### Phase 2: L3 路由转发
| Layer | 内容 | 产出 |
|-------|------|------|
| 1 | 读 `net/ipv4/fib_trie.c` 内核路由表 | 理解 FIB trie 的结构 |
| 2 | 读 `lib/librte_lpm/rte_lpm.c` DIR-24-8 算法 | 理解 LPM 的 2 级 Trie |
| 3 | 手写 LPM lookup + TTL 减一 + checksum | 跨网段 ping 通 |
| 4 | rdtsc 测量单次 lookup 延迟 | 内核 ~500ns vs DPDK ~200ns |
### Phase 3: ARP 协议
| Layer | 内容 | 产出 |
|-------|------|------|
| 1 | 读 `net/ipv4/arp.c` 内核 ARP 实现 | 理解 ARP 表的维护逻辑 |
| 2 | 读 `lib/ring/rte_ring.h` 无锁 CAS 原理 | 理解 ring 的 MP/MC 模式 |
| 3 | 手写 ARP 请求/应答 + pending 队列 | arping 能收到回复 |
| 4 | 连续 ARP 风暴,检查 mbuf 泄漏 | 内存无泄漏 |
### Phase 4: 控制面框架
| Layer | 内容 | 产出 |
|-------|------|------|
| 1 | 读内核 workqueue / tasklet 机制 | 理解异步任务调度 |
| 2 | 读 `rte_eal_remote_launch` + `rte_timer` | 理解 DPDK 的多核 + 定时器 |
| 3 | 手写 Pipeline 框架 + Interface Manager | 两机多 lcore 运行 |
| 4 | 控制面定时器无影响数据面延迟 | 数据面延迟不因定时器而抖动 |
### Phase 5: NAT + 连接跟踪
| Layer | 内容 | 产出 |
|-------|------|------|
| 1 | 读 `net/netfilter/nf_conntrack_core.c` | 理解内核 conntrack 的锁竞争 |
| 2 | 读 `lib/hash/rte_cuckoo_hash.c` Cuckoo hash | 理解 2-bucket 开放寻址 |
| 3 | 手写 SNAT/DNAT + rte_hash 连接表 | 内网 curl 外网能通 |
| 4 | 100K 连接查找延迟 + 哈希冲突率 | 查找 O(1),冲突率 < 5% |
### Phase 6: ACL + QoS
| Layer | 内容 | 产出 |
|-------|------|------|
| 1 | 读内核 `net/sched/` TC 调度框架 | 理解多队列调度的复杂度 |
| 2 | 读 `lib/acl/rte_acl.h` + `lib/sched/` | 理解硬件加速分类 + 调度 |
| 3 | 手写 5 元组 ACL + 8 队列 SP/WRR | 满载大包时小包延迟 < 2ms |
| 4 | iperf3 大包 + ping 小包 CDF 曲线 | 内核 p99 > 80ms vs uNOS < 2ms |
### Phase 7: IPv4/IPv6 + ICMP + Fragmentation
| Layer | 内容 | 产出 |
|-------|------|------|
| 1 | 读 `net/ipv4/ip_input.c` IP 收包路径 | 理解 IP 层在内核中的位置 |
| 2 | 读 RFC 791, RFC 792, RFC 815 | 理解协议规范本身 |
| 3 | 手写 IP 封装/解封 + ICMP Echo Reply | 能 ping 通你的栈 |
| 4 | 分包重组 2000 字节包 | 正确重组 |
### Phase 8: TCP 状态机
| Layer | 内容 | 产出 |
|-------|------|------|
| 1 | 读 `net/ipv4/tcp_input.c` tcp_rcv_state_process | 理解内核 11 状态 |
| 2 | 读 RFC 793(逐字读) | 画出自己的状态转换表 |
| 3 | 手写 11 状态 + scapy 逐状态触发 | gdb 单步跟踪每个转换 |
| 4 | scapy 100 万 TIME_WAIT → 时间轮 O(1) | 内核链表 O(n) vs 时间轮 O(1) |
### Phase 9: 重传引擎
| Layer | 内容 | 产出 |
|-------|------|------|
| 1 | 读 `net/ipv4/tcp_output.c` tcp_retransmit_skb | 理解内核重传逻辑 |
| 2 | 读 RFC 6298 (RTO), RFC 2018 (SACK) | 理解重传算法 |
| 3 | 手写 RTO + 快速重传 + SACK | tc netem 丢包 5% → 正确补偿 |
| 4 | rdtsc 测量 RTO 精度 | 误差 < 10ms |
### Phase 10: 拥塞控制
| Layer | 内容 | 产出 |
|-------|------|------|
| 1 | 读 `net/ipv4/tcp_cubic.c` 内核 CUBIC | 理解三次函数窗口增长 |
| 2 | 读 RFC 8312 + 2008 年 CUBIC 论文 | 理解设计决策 |
| 3 | 手写滑动窗口 + CUBIC | wireshark 验证窗口曲线 |
| 4 | 内核 TCP vs 自研 TCP 吞吐对比 | 1G: 940M vs 940M (持平) |
| | | CPU: 50% vs 8% (6x 优) |
### Phase 11: Socket API
| Layer | 内容 | 产出 |
|-------|------|------|
| 1 | 读 POSIX socket 语义 | 理解 API 设计哲学 |
| 2 | 读内核 `net/socket.c` socket 系统调用 | 理解 fd 到 sock 的映射 |
| 3 | 手写 tcp_socket/bind/listen/accept/send/recv | HTTP Server 跑在自研 TCP 上 |
| 4 | wrk 压测 HTTP QPS | 自研栈 ≥ 内核栈 QPS |
### Phase 12-17 (应用层/管理面/生产级增强)
每个 Phase 同样应用四层框架。Layer 1-2 以阅读对应 RFC / 工业标准实现为主。
---
## 五、方法论红黑榜
### ✅ 做这些
```
每个概念都按 1→2→3→4 顺序来,不跳层
Layer 3 时关掉所有参考,完全自己写
每次 crash 先 gdb 至少 5 分钟再搜答案
每层产出必须可验证(代码能跑 / 图表能看 / 数据能复现)
每天产出至少 50 行可运行的代码
```
### ❌ 不做这些
```
跳过 Layer 1 直接看 DPDK 文档 → 不知道为什么需要
跳过 Layer 3 只看不写 → "我看懂了"(其实没有)
Layer 3 复制粘贴 examples → 没有内化
不写文档 → 一个月后全忘了
反复讨论设计但不写代码 → 设计永远不会完美
不跑 perf 不生成数据 → 证明不了自己写的东西好
```
---
## 六、每日日志模板
```
日期: 2026-08-XX
阶段: Phase X - XXX
Layer 1 (20min):
读了: [内核文件/函数]
理解: [一句话瓶颈描述]
Layer 2 (20min):
读了: [DPDK 文件/函数]
理解: [一句话优化描述]
画了: [数据路径图]
Layer 3 (60min):
写了: [文件路径,代码行数]
Crash: [次数 + 最关键的 bug]
gdb 发现: [最关键的 insight]
Layer 4 (20min):
perf 数据: [关键对比数字]
火焰图: [链接]
文档: [docs/ 文件路径]
明天计划:
[下一阶段的 Layer 1 要读什么]
```
---
> **文档结束**
>
> 这个方法不是学知识的,是逼你写代码的。
> 系统编程不能靠"看懂",要靠"调通"。
> 每层 20/20/60/20 分钟,一天 2 小时一个模块。