Skip to content

Commit 34cacf2

Browse files
committed
docs(rib-fix): add Phase 2 rib/rtentry IP configuration fix log
Capture the Phase 2 of the FreeBSD 13->15 runtime-fix work: - rib-fix-plan.md: full plan with decision points (DP-RT-FIX-1=A root-cause fix, DP-RT-FIX-2=B strict 3-criteria acceptance plus helloworld non-regression, DP-RT-FIX-3=A one-root-cause-per-commit), 4-source cross-validation table for rt_alloc signature, 6-phase pipeline, risk assessment. - runtime-fix-execution-log.md §10.3 corrected (errno 55 is ENOBUFS, not EOPNOTSUPP — Linux/FreeBSD errno values differ). - runtime-fix-execution-log.md §11 (new chapter, Phase 2): root cause call chain, 4-source evidence table, two-file fix summary, strict 3-criteria acceptance results (3/3 PASS), backup paths, and a consolidated Phase 1+2 summary table showing all four fixed issues (UMA loop, smr_create %gs SEGV, rt_ifmsg NULL deref, IP setaddr ENOBUFS) plus the panic-stub defensive hardening from Phase 1. The runtime-fix project as a whole now reaches 3/3 strict acceptance: helloworld init success, ff_ifconfig shows inet 9.134.214.176 on f-stack-0, ff_netstat -a shows tcp4/tcp6 *.80 LISTEN.
1 parent 2e1612a commit 34cacf2

2 files changed

Lines changed: 178 additions & 4 deletions

File tree

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Rib/rtentry IP Configuration Fix Plan(runtime-fix Phase 2)
2+
3+
> 目标:让 `ff_ifconfig` 显示 `f-stack-0``inet 9.134.214.176``ff_netstat -a` 继续显示 `tcp4/tcp6 *.80 LISTEN`
4+
5+
> 文档目的:在已有 runtime-fix 5 commit(UMA / atomic / rtbridge / docs ×2)的基础上,攻克"最后一公里"IP 配置失败问题。
6+
7+
---
8+
9+
## 1. 用户原始需求(2026-06-01 20:41)
10+
11+
继续 runtime-fix。已修 3 个根本问题(UMA 死循环 + smr_create %gs + rt_ifmsg NULL deref),helloworld init success ✅,ff_netstat -a tcp4/tcp6 *.80 LISTEN ✅。**剩 1 项严格验收**`ff_ifconfig` 显示 `inet 9.134.214.176`
12+
13+
用户原话:"验收标准为执行 ff_ifconfig 和 ff_netstat -a 可以获取到相关网卡和监听 80 端口信息,暂不需要实际 curl 测试"。
14+
15+
启动命令:`cd /data/workspace/f-stack; bash ./start.sh ./example/helloworld`
16+
17+
## 2. 调研实测发现(Phase 0 静态调研已完成)
18+
19+
### 2.1 关键纠错(!!!)
20+
21+
之前 runtime-fix-execution-log.md §10.3 记录的"errno 55 EOPNOTSUPP"是**误判**
22+
- **FreeBSD errno 55 = ENOBUFS**(No buffer space available),见 `freebsd/sys/errno.h:118`
23+
- FreeBSD EOPNOTSUPP = 45
24+
- Linux EOPNOTSUPP = 95(值不同 — 之前在 helloworld 日志看到 55 直接 mapping 到 Linux 的 EOPNOTSUPP 是错误的)
25+
26+
### 2.2 真实根因调用链(4 方交叉验证)
27+
28+
```
29+
ff_veth_setaddr → socreate(AF_INET) → ifioctl(SIOCAIFADDR)
30+
→ in_control_ioctl → in_aifaddr_ioctl → ifa_maintain_loopback_route
31+
→ rib_action(RTM_ADD) → rib_add_route → add_route_byinfo
32+
→ rt_alloc(rnh, dst, netmask) → NULL → return ENOBUFS (55)
33+
```
34+
35+
### 2.3 关键代码定位(实测取证)
36+
37+
|| 位置 | 状态 |
38+
|---|---|---|
39+
| 真实 `rt_alloc` | `f-stack/freebsd/net/route/route_rtentry.c:82`(8375 字节 / 6 个 14.0+ rib 核心函数) | ✅ 文件已存在但未编译 |
40+
| 真实签名 | `rt_alloc(rnh, dst, struct sockaddr *netmask)` ||
41+
| `lib/Makefile` SRCS | 含 route_ctl.c / route_tables.c / route_helpers.c / route_ifaddrs.c / route_temporal.c / nhop_utils.c / nhop.c / nhop_ctl.c / rtsock.c / slcompress.c —— **不含 route_rtentry.c** | ❌ 漏 |
42+
| `ff_stub_14_extra.c` 错误 stub | 6 个:rt_alloc / rt_free / rt_free_immediate / rt_get_family / rt_get_raw_nhop / rt_is_host —— 全返 NULL / 签名错(rt_alloc 第 3 参 `route_nhop_data *` vs 真实 `sockaddr *`| ❌ 截胡链接 |
43+
44+
### 2.4 4 方交叉验证一致性表
45+
46+
| 数据源 | rt_alloc 签名 |
47+
|---|---|
48+
| 15.0 baseline `/data/workspace/freebsd-src-releng-15.0/sys/net/route/route_rtentry.c:82` | `(rnh, dst, struct sockaddr *netmask)`|
49+
| fstack `f-stack/freebsd/net/route/route_rtentry.c:82` | `(rnh, dst, struct sockaddr *netmask)`|
50+
| 调用方 `f-stack/freebsd/net/route/route_ctl.c:762` | `rt_alloc(rnh, dst, netmask)`|
51+
| fstack stub `f-stack/lib/ff_stub_14_extra.c:534` | `(rnh, dst, struct route_nhop_data *rnd)`|
52+
53+
**结论**:lib stub 签名错误 + 总返 NULL → 永远走 `add_route_byinfo``return (ENOBUFS)` 兜底 → ff_veth_setaddr 失败 → ifa_maintain_loopback_route 失败 → IP 配不上。
54+
55+
## 3. 决策点(DP-RT-FIX-1~3)
56+
57+
| DP | 选项 | 推荐 |
58+
|---|---|---|
59+
| **DP-RT-FIX-1** 修复策略 | **A: 把 route_rtentry.c 加到 lib/Makefile SRCS + 删 ff_stub_14_extra.c 中 6 个错 stub**(根本修复) / B: 仅修 stub 签名 + 返伪 rtentry(不可行:rt_alloc 内部 uma_zalloc + RTF_HOST 逻辑需真实运行) | **A** |
60+
| **DP-RT-FIX-2** 验证范围 | A: 严格 - ff_ifconfig 显示 inet + ff_netstat -a 显示 :80 LISTEN(与用户原话 100% 对齐) / **B: 严格 A + helloworld init success 不退化** / C: 严格 B + 6 工具 EAL stage 不退化 | **B** |
61+
| **DP-RT-FIX-3** commit 节奏 | **A: 一根因一 commit**(同 runtime-fix #1-3 风格) / B: 单 commit 合并 | **A** |
62+
63+
未答按 **A/B/A** 默认。
64+
65+
## 4. 6 阶段流水线
66+
67+
| Phase | 任务 | 关键产物 |
68+
|---|---|---|
69+
| Phase 0 | Kickoff:cp -a rib-fix-start 备份 + 更新 execution log §6 嫌疑点 8/9 | rib-fix-start 33,122 文件 |
70+
| Phase 1 | 静态调研(已完成 - 上面 §2 调研) | 见上 |
71+
| Phase 2 | 修复实施:lib/Makefile +1 SRCS(route_rtentry.c)+ ff_stub_14_extra.c 删 6 个错 stub | 2 文件修改 |
72+
| Phase 3 | 强制重编(make clean → make)+ example 重 link | libfstack.a 5.2M+ / 251 .o(+1) / helloworld 27M+ |
73+
| Phase 4 | 重启 helloworld + 实测 ff_ifconfig / ff_netstat 严格 2 项验收 | runtime 输出验证 |
74+
| Phase 5 | 项目结案:cp -a rib-fix-done + 更新 99 §12.20 + runtime-fix-execution-log §11 + 2 commits | git log + 备份 |
75+
76+
## 5. 强制规约(继承全部 3 项 + commit message 英文)
77+
78+
| 规约 | AI memory ID | 内容 |
79+
|---|---|---|
80+
| rm_tmp_file.sh | 81725399 | 所有删除走 `/data/workspace/rm_tmp_file.sh` |
81+
| kill_process.sh | 90098233 | 所有进程终止走 `/data/workspace/kill_process.sh` |
82+
| chmod_modify.sh | 21626578 | 所有权限修改走 `/data/workspace/chmod_modify.sh` |
83+
| commit message 英文 | 73362122 | 所有 git commit message 英文 |
84+
| 实测优先 | - | 4 方交叉验证;不一致以代码为准 |
85+
| 强制重编 | - | 修头文件后必 `make clean`(M3 末 .o 缓存教训) |
86+
87+
## 6. 风险评估
88+
89+
| 风险 | 缓解 |
90+
|---|---|
91+
| route_rtentry.c 编译可能引入额外 link 错误 | 真实文件已存在 15.0 vendor;只 8375 字节;相邻 route_*.c 都已编译 OK → 风险低 |
92+
| 删 6 个 stub 后是否触发其他 undef 引用 | rt_alloc 真实在 route_rtentry.o 提供;其他 5 个也是;删 stub 后由真实 .o 解析 → 无 undef |
93+
| 是否影响其他 5 个 commit 已修问题 | 修改范围仅 2 文件(Makefile + ff_stub_14_extra.c),不动 amd64/atomic.h、amd64/vmparam.h、arm64/vmparam.h |
94+
| 验收时 helloworld 是否需要 restart | 是 — 旧 helloworld 113746 跑了 18+ 分钟,新 binary link 后必须新进程才能生效 |
95+
96+
## 7. 待用户确认
97+
98+
请回复 **"接受计划并立即开始"****"调整 DP-RT-FIX-X"**。如直接说 **"继续执行"**,按 A/B/A 默认开干。

docs/freebsd_13_to_15_upgrade_spec/zh_cn/runtime-fix-execution-log.md

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,87 @@
116116
3. ✅ rt_ifmsg SEGV(NULL deref) — rtbridge no-op stub
117117
4. ✅ helloworld init success 输出 — 编译 + 启动闭环
118118

119-
### 10.3 待解决的非致命问题
119+
### 10.3 待解决的非致命问题(runtime-fix Phase 1 阶段记录;Phase 2 已修 1+2)
120120

121-
1. 🟡 `ff_veth_setaddr failed` — rib_action(RTM_ADD) 返 errno 55 EOPNOTSUPP(14.0+ rib/nexthop 重写后 fstack lib stub 未对齐)
122-
2. 🟡 `ifa_maintain_loopback_route: insertion failed: 55` — 同根因
123-
3. 🟡 `kernel_sysctlbyname failed: net.inet.tcp.hpts.skip_swi=1, error:2` — sysctl 节点未注册(非致命)
121+
1. ~~🟡 `ff_veth_setaddr failed` — rib_action(RTM_ADD) 返 errno 55 EOPNOTSUPP(14.0+ rib/nexthop 重写后 fstack lib stub 未对齐)~~**✅ Phase 2 已修复**(详见 §11;errno 55 实为 ENOBUFS 非 EOPNOTSUPP — 此处原记录有误读,Phase 2 已纠正)
122+
2. ~~🟡 `ifa_maintain_loopback_route: insertion failed: 55` — 同根因~~**✅ Phase 2 已修复**
123+
3. 🟡 `kernel_sysctlbyname failed: net.inet.tcp.hpts.skip_swi=1, error:2` — sysctl 节点未注册(非致命;不影响 ff_ifconfig/ff_netstat 验收)
124+
125+
## 11. Phase 2 (rib/rtentry IP 配置修复) — 2026-06-01 20:52
126+
127+
### 11.1 关键纠错:errno 55 ≠ EOPNOTSUPP
128+
129+
Phase 1 记录中误把 errno 55 标为 EOPNOTSUPP,实际:
130+
- **FreeBSD errno 55 = ENOBUFS**(No buffer space available),见 `freebsd/sys/errno.h:118`
131+
- FreeBSD EOPNOTSUPP = 45
132+
- Linux EOPNOTSUPP = 95(值不同 — Phase 1 时直接套用 Linux mapping 是错误的)
133+
134+
### 11.2 真实根因调用链(4 方交叉验证)
135+
136+
```
137+
ff_veth_setaddr → socreate(AF_INET) → ifioctl(SIOCAIFADDR)
138+
→ in_control_ioctl → in_aifaddr_ioctl → ifa_maintain_loopback_route
139+
→ rib_action(RTM_ADD) → rib_add_route → add_route_byinfo
140+
→ rt_alloc(rnh, dst, netmask) → NULL → return ENOBUFS (55)
141+
```
142+
143+
### 11.3 4 方实测取证
144+
145+
| 数据源 | rt_alloc 签名 |
146+
|---|---|
147+
| 15.0 baseline `/data/workspace/freebsd-src-releng-15.0/sys/net/route/route_rtentry.c:82` | `(rnh, dst, struct sockaddr *netmask)`|
148+
| fstack `f-stack/freebsd/net/route/route_rtentry.c:82`(8375 字节 / 6 个 14.0+ rib 重写后的核心函数)| `(rnh, dst, struct sockaddr *netmask)`|
149+
| 调用方 `f-stack/freebsd/net/route/route_ctl.c:762` | `rt_alloc(rnh, dst, netmask)`|
150+
| fstack stub `f-stack/lib/ff_stub_14_extra.c:534`(旧)| `(rnh, dst, struct route_nhop_data *rnd)`|
151+
152+
**双重错误**
153+
1. `lib/Makefile` SRCS 漏添 `route_rtentry.c` — 真实 rt_alloc/rt_free/rt_is_host/rt_get_family/rt_get_raw_nhop/rt_get_rnd/rt_is_exportable/rt_get_inet*_prefix_p{len,mask}/vnet_rtzone_{init,destroy} 这 11 个函数全部未编译
154+
2. `ff_stub_14_extra.c` M5 期间根据 link error 自动生成 11 个 stub 截胡链接,其中 rt_alloc 签名还错了(第 3 参 `route_nhop_data *` ≠ 真实 `sockaddr *`),所有 stub 返 NULL/empty
155+
156+
### 11.4 修复(2 文件,最小 diff)
157+
158+
| 文件 | 改动 |
159+
|---|---|
160+
| `lib/Makefile` | NET_SRCS 加 `route_rtentry.c`(+1 行)|
161+
| `lib/ff_stub_14_extra.c` | 删除 11 个错 stub(rt_alloc + rt_free + rt_free_immediate + rt_is_host + rt_get_family + rt_get_raw_nhop + rt_is_exportable + rt_get_inet_prefix_plen + rt_get_inet_prefix_pmask + rt_get_inet6_prefix_plen + rt_get_inet6_prefix_pmask + vnet_rtzone_init),用 DP-RT-FIX-1 注释块说明背景 |
162+
163+
修复后:libfstack.a 5.2M / 251 .o(+1 = route_rtentry.o),nm 显示 rt_alloc 为真实函数(地址 `0x100180`,非空 stub)。
164+
165+
### 11.5 严格 3 项验收实测(DP-RT-FIX-2=B)
166+
167+
| 验收点 | 期望 | 实测 | 状态 |
168+
|---|---|---|---|
169+
| 1. helloworld init success(不退化) | `helloworld init success.` + ff_run loop | helloworld.log 含 `helloworld init success.`;进程 PID 141652 持续运行,主线程 S sleeping(健康状态);ifa_maintain_loopback_route / ff_veth_setaddr 错误信息**消失** |**PASS** |
170+
| 2. ff_ifconfig 显示 inet | `f-stack-0``inet 9.134.214.176` | `f-stack-0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> ... inet 9.134.214.176 netmask 0xfffff800 broadcast 9.134.215.255`;bonus:`lo0: inet 127.0.0.1` 也正常出来 |**PASS** |
171+
| 3. ff_netstat -a 显示 :80 LISTEN | `tcp4 *.80 LISTEN` | `tcp4 0 0 *.80 *.* LISTEN` + `tcp6 0 0 *.80 *.* LISTEN` 两条都出现 |**PASS** |
172+
173+
**runtime-fix 项目总评**:3/3 严格验收 PASS — **完整闭环 ✅**
174+
175+
### 11.6 备份
176+
177+
- 启动备份:`/data/workspace/f-stack-rib-fix-start/` 33,128 文件
178+
- 完成备份:`/data/workspace/f-stack-rib-fix-done/` 33,130 文件
179+
180+
### 11.7 Phase 1+2 总成果汇总
181+
182+
| # | 现象 | 根因 | 修复 |
183+
|---|---|---|---|
184+
| 1 | UMA 死循环 (CPU 100% busy-loop) | 14.0+ 把 UMA_MD_SMALL_ALLOC 重命名为 UMA_USE_DMAP,amd64/arm64 vmparam.h 缺 `#ifndef FSTACK` 包裹 | vmparam.h × 2 加 `#ifndef FSTACK` 包裹 |
185+
| 2 | smr_create SIGSEGV (`%gs:0x100`) | atomic.h `__storeload_barrier` `_KERNEL` 路径用 %gs PCPU 段,用户态无该段 | atomic.h `#if defined(_KERNEL) && !defined(FSTACK)` |
186+
| 3 | rt_ifmsg SIGSEGV (NULL deref) | 14.0+ 改用 rtsock_callback_p/netlink_callback_p 函数指针表,M5 stub 设 NULL | ff_stub_14_extra.c 提供 ff_stub_rtbridge_noop |
187+
| 防御 #1 | vm_page_alloc_noobj* 静默 NULL 难调试 | panic stub | ff_stub_14_extra.c panic |
188+
| **4 (Phase 2)** | **ff_veth_setaddr / loopback route 失败 errno 55** | **lib/Makefile 漏添 route_rtentry.c + ff_stub_14_extra.c 中 11 个错 stub 截胡链接** | **lib/Makefile +1 SRCS + 删 11 个错 stub** |
189+
190+
完整 git 历史(runtime-fix 全阶段):
191+
```
192+
(Phase 2) <new> rib-fix #1: link route_rtentry.c into libfstack + drop 11 wrong rt_* stubs
193+
(Phase 2) <new> docs(rib-fix): add Phase 2 rib/rtentry IP configuration fix log
194+
(Phase 1) d173a88b8 docs(runtime-fix): record chmod_modify.sh enforcement convention
195+
(Phase 1) 747da452c docs(runtime-fix): add execution log for FreeBSD 13->15 runtime hang fix
196+
(Phase 1) f4b77d3bd runtime-fix #3: provide no-op rtbridge stubs + panic on stray vm_page_alloc
197+
(Phase 1) ee424b8e8 runtime-fix #2: route __storeload_barrier to userland path under FSTACK
198+
(Phase 1) 424f8a9f6 runtime-fix #1: guard UMA_USE_DMAP with #ifndef FSTACK in amd64/arm64 vmparam.h
199+
```
124200

125201
### 10.4 关键诊断手段总结
126202

0 commit comments

Comments
 (0)