Skip to content

Commit c618c26

Browse files
committed
docs: rework kernel_event_support spec (zh_cn) to connection-level stack selection (drop KNI)
1 parent f613125 commit c618c26

9 files changed

Lines changed: 596 additions & 563 deletions
Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,52 @@
1-
# F-Stack 本地 socket/fd/event 访问能力 —— 项目总览与文档导航(00-overview.md
1+
# 00 总览:F-Stack 连接级选栈增强(本机直访 F-Stack 服务
22

33
> **文档编号**:SPEC-KE-00
4-
> **版本**v0.1 草稿
4+
> **版本**v2(全量重做)
55
> **日期**:2026-06-15
66
> **状态**:编写中
7-
> **作用域**`/data/workspace/f-stack/`(本阶段仅产出中文 spec 文档)
7+
> **作用域**本目录中文 spec 的导航、术语与范围声明
88
99
---
1010

1111
## 1. 一句话目标
1212

13-
让 DPDK 接管网卡后的 F-Stack 主机,**业务流量走用户态 FreeBSD 协议栈、本机/管理面流量(ping、本地 curl 等)仍可走内核协议栈**,并将该能力以 lib 库形式沉淀
13+
为 F-Stack 提供一个 lib,使应用进程能在 **F-Stack 用户态栈****宿主机 Linux 内核栈****同时**创建/监听 socket,并以**统一的 fd / event 抽象**在单事件循环中服务两栈;从而即使 DPDK 接管了网卡,本机的 `ping` / `curl` 等工具也能**直接访问该应用在内核栈侧暴露的服务**
1414

15-
## 2. 阅读路径
15+
## 2. 范围声明(重要)
1616

17-
```
18-
plan.md ← 总体规划 / 团队拓扑 / 门禁规约(先读)
19-
00-overview.md ← 本文:导航
20-
01-requirements-spec.md ← 为什么做、做到什么程度(需求/边界)
21-
02-current-state-analysis.md ← 现状:F-Stack 已有的两个参考机制(代码级、文件:行号)
22-
03-external-research.md ← 业界怎么做:KNI/TAP/exception path/virtio-user(附 URL)
23-
04-architecture-design.md ← 我们怎么做:目标 lib 架构与分流模型
24-
05-interface-design.md ← 对外 API / 编译宏 / 数据结构
25-
06-milestones.md ← 分几步落地 + 编码工作清单
26-
07-test-spec.md ← 怎么验证:单测/集成/性能基线
27-
08-review-gate.md ← 审核门禁结论 + bounce 记录
28-
```
17+
- **本特性 = 连接级选栈增强(Connection-level Stack Selection)**
18+
- **首要参考**:nginx 的 `kernel_network_stack` 开关(`belong_to_host` 1-bit 选栈 + 双事件后端)。
19+
- **次要参考**`adapter/syscall``FF_KERNEL_EVENT` 编译宏(`fstack_kernel_fd_map` + 双栈 epoll 合并)。
20+
- **明确排除(非目标)**:KNI / `rte_kni` / virtio-user / TAP / AF_XDP 等"报文回灌内核"方案——它们解决的是"未被应用接管的报文回到内核",与本特性"应用主动在内核栈侧暴露服务"是不同问题,仅在方案对比中用于澄清边界。
2921

30-
## 3. 关键术语
22+
## 3. 阅读路径
3123

32-
| 术语 | 含义 |
33-
|---|---|
34-
| **用户态栈 / F-Stack 栈** | F-Stack 移植的 FreeBSD TCP/IP 协议栈,运行在 DPDK polling 线程内 |
35-
| **内核栈** | Linux 内核原生 TCP/IP 协议栈 |
36-
| **分流(dispatch)** | 按某种判定(fd、地址、配置开关)决定一个 socket/事件走用户态栈还是内核栈 |
37-
| **机制 A** | nginx `kernel_network_stack` per-server 开关(应用配置粒度) |
38-
| **机制 B** | `adapter/syscall``FF_KERNEL_EVENT` 宏(fd/syscall 粒度,含 `fstack_kernel_fd_map`|
39-
| **KNI / TAP / exception path / virtio-user** | DPDK 生态中将报文送回内核的几类典型路径(详见 `03-external-research.md`|
40-
41-
## 4. 现状参考的依据来源(待 02 文档实测精确化)
24+
| 顺序 | 文档 | 用途 |
25+
|---|---|---|
26+
| 1 | `plan.md` | 计划、团队、门禁、范围修正 |
27+
| 2 | `01-requirements-spec.md` | 需求与目标/非目标 |
28+
| 3 | `02-current-state-analysis.md` | 机制 A/B 代码级现状(以代码为准) |
29+
| 4 | `03-external-research.md` | 外部方案调研(附 URL) |
30+
| 5 | `04-architecture-design.md` | 双栈选栈架构与事件模型 |
31+
| 6 | `05-interface-design.md` | lib 对外接口契约 |
32+
| 7 | `06-milestones.md` | 里程碑与编码工作清单 |
33+
| 8 | `07-test-spec.md` | 测试与性能基线方案 |
34+
| 9 | `08-review-gate.md` | 审核门禁结论 |
4235

43-
- `app/nginx-1.28.0/``kernel_network_stack` 指令链路(`NGX_HAVE_FSTACK`)。
44-
- `adapter/syscall/``FF_KERNEL_EVENT` 宏(`ff_hook_syscall.c``Makefile``README.md`),含 `helloworld_stack_epoll_kernel` demo。
45-
- `docs/`:三层架构文档(`01/02/03-LAYER*.md``F-Stack_Architecture_Layer1/2/3_*.md`)与知识图谱(`KNOWLEDGE_GRAPH_WIKI.md``F-Stack_Knowledge_Base_Summary.md`)。
36+
## 4. 术语表
4637

47-
## 5. 文档纪律
48-
49-
- 现状描述一律带 `文件:行号` 实测证据;与文档/README 冲突以**实际代码**为准。
50-
- 外部方案一律附**可访问 URL**
51-
- 本阶段不改源码、不写实现。
38+
| 术语 | 含义 |
39+
|---|---|
40+
| F-Stack 栈 | DPDK PMD + 用户态 FreeBSD 协议栈(业务高速路径) |
41+
| 内核栈 | 宿主机 Linux 内核网络协议栈(本机/管理/异常路径) |
42+
| 连接级选栈 | 在 socket/listen/connect 粒度上决定该连接走 F-Stack 还是内核栈 |
43+
| `belong_to_host` | nginx 中标记某连接/监听走内核栈的 1-bit 标志 |
44+
| `SOCK_FSTACK` | F-Stack 适配层在 `socket()` type 上附加的标志,表示走 F-Stack |
45+
| `FF_KERNEL_EVENT` | LD_PRELOAD 适配层的编译宏,使事件循环同时处理内核 fd |
46+
| `fstack_kernel_fd_map` | "F-Stack fd → 内核 fd"映射表,用于双栈事件合并 |
47+
48+
## 5. 依据来源
49+
50+
- F-Stack 实际代码(`app/nginx-1.28.0/``adapter/syscall/``lib/`)——**最高优先级,冲突以代码为准**
51+
- F-Stack 三层架构文档与知识图谱(`docs/`)。
52+
- 外网公开资料(GitHub issue/wiki、技术博客等),均在 `03` 附可访问 URL。
Lines changed: 54 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,81 @@
1-
# 需求与问题域规格(01-requirements-spec.md)
1+
# 01 需求规格:F-Stack 连接级选栈增强 lib
22

33
> **文档编号**:SPEC-KE-01
4-
> **版本**v0.1 草稿
4+
> **版本**v2(全量重做)
55
> **日期**:2026-06-15
66
> **状态**:编写中
7-
> **作用域**F-Stack 本地 socket/fd/event 访问能力的需求边界
7+
> **作用域**定义"连接级选栈增强 lib"的问题域、目标/非目标、功能与非功能需求、成功标准。
88
99
---
1010

1111
## 1. 问题域
1212

13-
### 1.1 根因
14-
F-Stack 启动后,DPDK 通过 UIO/VFIO 将物理网卡从内核驱动解绑并独占(PMD 轮询),内核协议栈**不再能看到该网卡**。因此本机基于内核栈的工具——`ping``curl``ssh``ntpdate`、监控 agent 等——**无法经该网卡收发**,运维/管理面受阻。
13+
F-Stack 通过 DPDK 接管网卡后,该网卡流量绕过 Linux 内核协议栈,导致**本机工具(`ping`/`curl`/`ssh` 等)无法访问运行在 F-Stack 用户态栈上的服务**
1514

16-
### 1.2 现状(详见 `02-current-state-analysis.md`,以代码为准)
17-
F-Stack 已存在三类"流量回内核"机制:
18-
- **机制 A** nginx `kernel_network_stack`:仅服务 nginx,per-server/upstream 选栈,强耦合 nginx 源码。
19-
- **机制 B** `FF_KERNEL_EVENT`:LD_PRELOAD 层,仅镜像 epoll 事件,不覆盖数据 socket。
20-
- **机制 C** KNI(已迁移为 **virtio-user + vhost-net** exception path):报文级分流、可运行时调控,**已能支撑本机 ping/curl**,但缺少面向通用应用的统一编程接口与易用封装。
15+
现有解法分两类:
2116

22-
### 1.3 缺口
23-
机制 C 提供了数据面通路,但:
24-
- 配置分散(`config.ini [kni]` + 运行时 `FF_KNICTL` IPC),无统一 lib API;
25-
- 缺少面向"本地 socket/fd/event"的应用编程模型(应用难以显式声明"这条连接走内核栈");
26-
- 缺少独立可复用的 lib 形态(当前能力散落在 `lib/ff_dpdk_if.c``lib/ff_dpdk_kni.c``adapter/syscall/`、nginx 补丁中)。
17+
- **报文回灌(KNI/virtio-user/TAP)**:把裸报文送回内核——**本特性不采用**(见非目标)。
18+
- **连接级选栈**:应用**主动**在内核栈侧也创建/监听 socket,按连接/监听粒度选栈,并在统一事件循环中服务两栈——**本特性采用**
2719

28-
## 2. 目标
20+
F-Stack 自身已有两处"连接级选栈"实现(`02` 机制 A/B),但分别**内嵌**在 nginx 适配与 LD_PRELOAD syscall 适配中,**无法被任意 F-Stack 应用直接复用**。本特性即将其抽象为**应用无关的通用 lib**
2921

30-
提供一个**lib 库**,使**任意本机应用**(不限 nginx)在 DPDK 接管网卡的前提下,仍可:
31-
1. 通过内核协议栈完成本机/管理面网络操作(ping、本地 curl 等);
32-
2. 以统一、显式的接口声明某个 socket/fd/事件走"内核栈"或"F-Stack 用户态栈";
33-
3. 复用 F-Stack 既有 virtio-user exception path 数据面(机制 C),不重造轮子。
22+
---
23+
24+
## 2. 目标与非目标
3425

35-
## 3. 范围
26+
### 2.1 目标(In Scope)
27+
- G1:提供一个 lib,使 F-Stack 应用能在**内核栈侧创建/监听 socket**,本机 `ping`/`curl` 等可直接访问该服务。
28+
- G2:提供**连接/监听级选栈**能力(某监听走内核栈、某监听走 F-Stack),范式借鉴机制 A 的 `belong_to_host`
29+
- G3:提供**统一 fd/event 抽象**,使一个事件循环可同时服务内核栈 fd 与 F-Stack fd(合并事件),范式借鉴机制 B 的 `fstack_kernel_fd_map` + 双栈 epoll。
30+
- G4:对应用**低侵入**(编译开关 + 少量 API),不强制改造业务逻辑;不绑定 nginx 或 LD_PRELOAD。
3631

37-
### 3.1 本阶段(spec 文档)
38-
- **仅产出中文 spec 文档**,不写实现代码、不改源码。
39-
- 交付:需求/现状/外部调研/架构/接口/里程碑/测试/门禁 共 9 篇(见 `plan.md`)。
32+
### 2.2 非目标(Out of Scope)
33+
- N1:****采用 KNI / `rte_kni` / virtio-user / TAP / AF_XDP 等报文回灌方案(`rte_kni` 已于 DPDK 23.11 移除;gazelle KNI 亦衰退)。
34+
- N2:本阶段**不写实现代码、不改 f-stack 源码**,仅产出中文 spec。
35+
- N3:本阶段**不生成英文文档**
36+
- N4:不实现内核栈与 F-Stack 之间的 socket 自动迁移/透明代理(连接归属在创建时确定)。
4037

41-
### 3.2 后续实现阶段(本 spec 规划,非本阶段交付)
42-
- 在 mechanism C 之上抽象统一 lib(暂名 `libff_local` / `ff_local_*`)。
43-
- 提供编译开关与运行时控制对齐。
44-
- 单测/集成/性能基线。
38+
---
4539

46-
### 3.3 不在范围
47-
- 不改变 F-Stack 业务快路径性能模型;
48-
- 不引入新的自研内核模块(KNI 内核模块已被 DPDK 23.11 移除,禁止回退);
49-
- 本阶段不产出英文文档。
40+
## 3. 功能需求(FR)
5041

51-
## 4. 功能性需求(FR)
42+
| 编号 | 需求 | 验收要点 | 代码依据 |
43+
|---|---|---|---|
44+
| FR-1 | 应用可在内核栈侧创建监听 socket,本机 `curl`/`ssh` 可访问 | 本机访问内核栈监听成功 | 机制 A `ngx_event_connect.c:46-50` |
45+
| FR-2 | 本机 `ping`(ICMP)对内核栈侧地址可达 | ping 通 | 内核栈原生处理 ICMP |
46+
| FR-3 | 连接/监听级选栈:可声明某监听走内核栈或 F-Stack | 两类监听并存且各自可达 | 机制 A `belong_to_host` `ngx_http.c:1890` |
47+
| FR-4 | 统一事件循环:单循环同时收 F-Stack 与内核栈事件 | 两栈事件均被正确投递 | 机制 B `ff_hook_syscall.c:2329-2338` |
48+
| FR-5 | fd 归属判定:lib 能区分 fd 属内核栈还是 F-Stack | API 行为按归属正确分流 | 机制 B `is_fstack_fd` `:309` |
49+
| FR-6 | 资源联动:关闭/异常时两栈 fd 一致释放 | 无 fd 泄漏 | 机制 B close 联动 `:1874-1883` |
50+
| FR-7 | 编译开关:本能力可编译期开/关,默认关闭零开销 | 关闭时与原 F-Stack 行为一致 | 机制 B `Makefile -DFF_KERNEL_EVENT` |
5251

53-
| 编号 | 需求 | 验收线索 |
54-
|---|---|---|
55-
| FR-1 | 本机可经内核栈 `ping` F-Stack 主机网卡 IP | 启用方案后 `ping <nic_ip>`|
56-
| FR-2 | 本机可经内核栈 `curl` 本机/外部地址 | `curl` 成功,走 veth/virtio-user |
57-
| FR-3 | 提供统一开关:全部走内核 / 全部走 F-Stack / 默认按规则 | 对齐 `FF_KNICTL_ACTION_*``lib/ff_msg.h:118-123`|
58-
| FR-4 | 支持按 tcp/udp 端口、协议(ICMP/ARP/OSPF)分流 | 对齐 `config.ini [kni] method/tcp_port/udp_port` |
59-
| FR-5 | 提供运行时动态调整分流策略的接口 | 对齐 `handle_knictl_msg``lib/ff_dpdk_if.c:1960-1977`|
60-
| FR-6 | 提供本地 socket/fd/event 编程接口(供应用显式选栈) | 借鉴机制 A 的 1-bit 选栈与机制 B 的 fd 映射 |
52+
---
6153

62-
## 5. 非功能性需求(NFR)
54+
## 4. 非功能需求(NFR)
6355

6456
| 编号 | 需求 |
6557
|---|---|
66-
| NFR-1 | 关闭本能力时对业务快路径**零额外开销**(默认 KNI 关闭,见官方提示) |
67-
| NFR-2 | 开启时分流检查开销可控、可限速(对齐 `console_packets_ratelimit`/`general_packets_ratelimit`/`kernel_packets_ratelimit`|
68-
| NFR-3 | 不依赖已移除的 `rte_kni`;仅用 upstream 能力(virtio-user/vhost-net) |
69-
| NFR-4 | 与现有 `config.ini``FF_KNICTL` 语义兼容,不破坏既有部署 |
70-
| NFR-5 | 多进程(primary/secondary)模型下行为明确 |
58+
| NFR-1 | **默认零开销**:未开启本能力时不引入任何额外分支/内存开销 |
59+
| NFR-2 | **业务快路径无回归**:F-Stack 高速路径性能不受影响(性能基线见 `07`|
60+
| NFR-3 | **可移植**:兼容本工作区 DPDK 23.11.5 / 24.11.6 与移植后的 FreeBSD 栈 |
61+
| NFR-4 | **可观测**:提供两栈 fd 数、事件数等基本统计 |
62+
| NFR-5 | **接口稳定**:lib API 语义贴合 POSIX/`ff_api.h`,降低学习成本 |
7163

72-
## 6. 边界与异常场景
64+
---
65+
66+
## 5. 边界与异常场景
7367

74-
- 内核 `vhost-net` 模块缺失 / 无权限 / hugepage 不足 → 明确报错路径。
75-
- `method=accept` vs `reject` 语义边界(见 `config.ini:250-253`)。
76-
- 单网卡场景:管理流量与业务流量共网卡时的端口规划。
77-
- secondary 进程不创建 virtio_user 口(`lib/ff_dpdk_if.c:609-611` 仅 primary 翻倍端口)。
68+
- 内核栈侧地址/端口与 F-Stack 侧冲突时的行为约定(应报错而非静默)。
69+
- `maxevents` 过小(机制 B 要求 `>=2`)时的处理。
70+
- 内核栈 fd 与 F-Stack fd 在同一 epoll/kqueue 中混用时的事件合并正确性。
71+
- 本能力关闭(编译期/运行期)时,所有 API 退化为纯 F-Stack 行为。
72+
- 系统前提缺失(参考 gazelle `rp_filter=1`)时的检测与提示。
73+
74+
---
7875

79-
## 7. 成功标准
76+
## 6. 成功标准
8077

81-
1. 文档层面:架构/接口/里程碑/测试方案完整、与代码交叉验证一致、外部方案附 URL,通过 `08-review-gate.md` 门禁。
82-
2. (后续实现阶段)功能层面:FR-1~FR-6 可演示;NFR 满足;性能基线达标(详见 `07-test-spec.md`)。
78+
1. DPDK 接管网卡后,本机 `ping <内核栈侧IP>` 通、`curl <内核栈侧服务>` 成功(FR-1/FR-2)。
79+
2. 同一应用进程内"内核栈监听"与"F-Stack 监听"并存,单事件循环均正确收发(FR-3/FR-4)。
80+
3. 本能力关闭时,F-Stack 业务性能与功能**零回归**(NFR-1/NFR-2)。
81+
4. spec 全集过 `08-review-gate.md` 门禁。

0 commit comments

Comments
 (0)