分享到plurk 分享到twitter 分享到facebook

版本 8a411c9d975313d11525f4dd27f7a7f7c466b8dc

User/JOJOTOOL

Changes from 8a411c9d975313d11525f4dd27f7a7f7c466b8dc to 6805ac1c6ba5ec7f2600092e2f89107e3f694863

# 2026 年 Linux 核心設計課程自我評量

姓名:張力升 GitHub:JOJOTOOL (https://github.com/JOJOTOOL)
姓名:張力升 GitHub:[JOJOTOOL](https://github.com/JOJOTOOL)

本自我評量遵循本課程評量準則:以客觀事實為主,強調過去與現在、不寫「期許自己」這類對未來的空泛承諾;所有產出均附公開紀錄(commit、PR、HackMD、pcap 佐證),可逐項查證。

[TOC]

---

## 成果發表與貢獻

> 自評:8分

### 課程教材與 sysprog21 專案

本學期對 sysprog21 的 [kbox](https://github.com/sysprog21/kbox)(把真實 Linux 核心以 [LKL](https://github.com/lkl/linux) 形式連進行程、就地攔截 syscall 的 rootless 執行環境)貢獻了一套**具第二層(L2)隔離的網路子系統**,取代原本只能 outbound 的 SLIRP 使用者態網路。技術細節見下方〈期末專題〉,規模與佐證:

- 變更規模(`git diff --stat HEAD` 可重現):**34 個檔案、+2155 / −1112 行**,主體為 `src/net-slirp.c`、`src/dispatch-net.c`。
- 對應 PR / commit:【填入你的 PR 連結】;基準點 commit [`ba08934`](https://github.com/sysprog21/kbox)(SLIRP 起點)、[`0000c75`](https://github.com/sysprog21/kbox)(buffer overflow 修正)。

---

## 作業與隨堂測驗

> 自評:7分


## 期末專題:擴展 kbox 的完整網路能力

> 自評:8分

> 專題文件:<https://hackmd.io/@sysprog/HkncHMvAbe> 關鍵程式:`src/dispatch-net.c`、`src/net-slirp.c`、`src/net.h`

### 專題背景與問題定義(起點)

kbox 最初的網路以 SLIRP 實作,只支援 outbound TCP/UDP(commit [`ba08934`](https://github.com/sysprog21/kbox) `Add SLIRP user-mode networking`)。其客觀限制(可從當時行為驗證):

1. **沒有隔離**:guest 的 socket 呼叫經位址轉譯後,實際使用 host 的網路堆疊。
2. **L2 不可見**:流量在 SLIRP 層被重新封裝,乙太網路訊框(Ethernet frame)這一層看不到,無法用 `tcpdump` 觀察或在訊框邊界分析。
3. **設定寫死**:IP 位址靜態硬編碼,沒有動態協定行為。
4. **無法注入故障**:不能模擬封包遺失、延遲或網路異常。



### 系統設計

以三層架構把網路堆疊搬進 LKL,並在 host 端串接外部網路。

**第一層 — syscall 層隔離(`src/dispatch-net.c`)**:把 guest 的網路 syscall 從「落到 host」改為「轉送進 LKL」。實作的轉送函式皆呼叫對應 `kbox_lkl_*` 包裝,最終進入 `lkl_syscall()`:`forward_socket`、`forward_bind`、`forward_connect`、`forward_listen`、`forward_accept4`、`forward_sendto`、`forward_recvfrom`、`forward_sendmsg`、`forward_recvmsg`、`forward_getsockopt`、`forward_setsockopt`、`forward_getsockname`、`forward_getpeername`、`forward_shutdown`、`forward_poll`(涵蓋 `poll()` / `ppoll()`)。

**第二層 — LKL 網路裝置(`src/net-slirp.c`)**:以 `lkl_netdev_tap_create()` 建立 TAP 介面 `kbox0`,再用 `lkl_netdev_add()` 掛進 LKL 的 virtio-net 後端;guest 端設定靜態 `10.0.2.15/24` 或 DHCP,預設閘道 `10.0.2.2` 並設定 DNS。對應 `kbox_net_add_device()`、`kbox_net_configure()`,並保留 LKL/網路關閉時的 stub 實作以維持建置不失敗。

**第三層 — host 端串接**:對 TAP 指派 `10.0.2.2/24`、開啟 IP forwarding、加上 MASQUERADE NAT、放行 FORWARD 鏈,作為 LKL 隔離堆疊與外部網路之間的橋。

**DHCP 狀態機(RFC 2131)**:client 端 `dhcp_build_discover()` / `dhcp_build_request()` / `dhcp_opt_find()`,server 端 `dhcp_server_start()` / `dhcp_server_build_reply()`(監聽 port 67),完成 DISCOVER → OFFER → REQUEST → ACK 四步交握。

**可觀測性與故障注入**:`pcap_open()` / `pcap_write_packet()` / `pcap_close()` 把 L2 訊框連同時戳寫成 pcap;另有獨立 AF_PACKET 監看執行緒。故障注入以 `tc flower` DROP(IPv6、mDNS)、`tc netem` 經 IFB 裝置注入延遲、`kbox_net_inject_frame()` 直接在 L2 注入自訂訊框。對外介面見 `src/net.h`(新增 `kbox_net_set_pcap` / `set_dhcp` / `set_inject_frame` 等)。

### 量測方法

> 範例特別強調「謹慎用詞」與統計嚴謹:效能宣稱要有**前後對照 + 信賴區間 + 檢定**,不寫「快很多」。請以此標準補上實測資料。

- **延遲注入驗證**:設定 `tc netem` 500 ms 延遲,量測 ICMP RTT 由 【base RTT】 增為 【延遲後 RTT】(建議 N ≥ 30 次、附 95% 信賴區間)。
- **過濾規則驗證**:以 `tc` DROP 規則的計數器遞增,佐證 IPv6 / mDNS 被擋(附計數器前後值)。
- **協定正確性**:以 pcap 追蹤確認 ARP who-has、DHCP 四步交握的封包序列(附 `tcpdump` 判讀)。
- 【若有吞吐量 / 建立連線延遲的前後對照(SLIRP vs LKL+TAP),以表格呈現並註明量測環境。】

### 期末展示

可重現的驗證結果(建議附你自己的截圖 / pcap 檔):

| 驗證項目 | 觀察到的客觀結果 |
| --- | --- |
| 網路介面建立 | `kbox0` 出現在 host 網路堆疊 |
| DNS 解析 | 沙箱內 `nslookup google.com` 成功 |
| 對外連線 | `ping 8.8.8.8`、`wget http://example.com` 可通 |
| ARP 協定 | pcap 中擷取到 ARP who-has 封包 |
| 封包過濾 | `tc` DROP 計數器遞增(IPv6、mDNS 被擋) |
| 延遲注入 | ICMP 被 `tc netem` 延遲 500 ms |
| DHCP 交握 | 完整四步交換,經 `tcpdump` 確認 |

**目前尚未完成 / 待收斂**(誠實列出,不找藉口):

1. inbound server socket 路徑(`forward_listen` / `forward_accept4`)已實作,但仍保留 `fprintf(stderr, ">>> ...")` 除錯輸出待清除。
2. per-socket 的 pcap 註冊尚未接上:`kbox_net_register_socket()` 在 `forward_socket()` 中仍為註解狀態。




---

## 與授課教師的互動

> 自評:6分



### 課堂問答軌跡

2026/3/17 
2026/6/9

---

## 所見所聞所感

> 自評:8分

### 關於實驗設計與可重現性

從這次專題我具體學到:效能與行為宣稱必須可重現。SLIRP 之所以看不到 L2,是因為它在使用者態重新封裝流量——這讓我把觀測點改放在 TAP 與 virtio-net 之間,才拿得到完整的 ARP、TCP 重傳等協定行為。這也促使我在〈量測方法〉採前後對照與統計信賴區間,而非只給單次數字。

### 關於謹慎用詞

一開始自行拼湊封包 / 位址結構、對長度與對齊做不安全假設,導致緩衝區溢位(commit [`0000c75`](https://github.com/sysprog21/kbox));改用標準網路結構後才體認到跨 ABI 邊界傳遞結構時,自訂 layout 的長度假設不可靠。【延伸:術語要精確,例如 socket / connection / endpoint 不可混用。】


### 關於自身投入的回顧

誠實回顧投入(範例甚至以每週時數與同儕基準對照),以及起點 → 終點的能力變化:從只熟悉使用者態 socket API,到能在 LKL 內設定 virtio-net/TAP、實作 DHCP 交握、用 `tc`/`netem`/IFB 做 L2 故障注入、用 pcap+AF_PACKET 擷取分析訊框。

---

## 分數計算

各項自評如下,總分採**幾何平均**(任一項偏低都會顯著拉低總分):

| 評量項目 | 自評分數 |
| --- | --- |
| 成果發表與貢獻 | 8 |
| 作業與隨堂測驗 | 7 |
| 期末專題 | 8 |
| 與授課教師的互動 | 6 |
| 所見所聞所感 | 8 |

$$
\text{總分} = \sqrt[5]{8 \times 7 \times 8 \times 6 \times 8}
$$

**方案 A**:若〈成果發表與貢獻〉的非顯著(non-trivial)貢獻達門檻,依方案 A 計分並在該節附檢核表;否則走一般方案。

自我評量總分:**7.3 / 10**

---

## 附錄:佐證連結與證據

- 期末專題技術文件:<https://hackmd.io/@sysprog/HkncHMvAbe>
- 自我評量範例(結構參考):<https://hackmd.io/@sysprog/HkRmtTGlze>
- 自我評量原則:<https://hackmd.io/@sysprog/linux2024-assessment>
- 關鍵程式檔:`src/dispatch-net.c`、`src/net-slirp.c`、`src/net.h`、`src/lkl-wrap.c` / `src/lkl-wrap.h`