> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/di-22-zhang-gao-ji-wang-luo/di-22.1-jie-tcp-ip-xie-yi-zhan.md).

# 22.1 TCP/IP 协议栈

## TCP/IP 协议栈

传输控制协议（Transmission Control Protocol，TCP）是互联网协议族（Internet Protocol Suite）中的核心传输层协议，软件实现体系称作 TCP 栈（采用层次化结构进行组织，因此称“栈”）。Vint Cerf 和 Bob Kahn 于 1974 年在论文《A Protocol for Packet Network Intercommunication》中首次提出 TCP 的核心思想（当时为传输与网络转发合一的单一协议），后经迭代，约在 1978 至 1979 年间决定将 TCP 与 IP 拆分为两个独立协议，并于 1981 年 9 月分别发布为 RFC 791（IP）和 RFC 793（TCP）。RFC 9293 已于 2022 年 8 月取代了 RFC 793，前者为当前 TCP 协议的最新标准规范。

TCP 栈提供端到端的可靠数据传输、拥塞控制、流量控制等关键功能。不同于其他主流操作系统，FreeBSD 创新性地实现了多 TCP 栈共存架构，该架构允许系统同时加载多个 TCP 协议栈实现，并可为不同的网络连接或系统全局选用不同的 TCP 栈。

当前主要开发与维护工作集中于 RACK 栈（RACK 算法最初出自 Google，FreeBSD 的 tcp\_rack 栈实现出自 Netflix 的 Randall Stewart）和基础栈（基于 4.4BSD 经典栈实现演化而来，默认拥塞算法是 CUBIC）。

FreeBSD 多 TCP 栈共存架构示意如下：

![FreeBSD 多 TCP 栈共存架构](/files/KQwmcEzoc3F7ASvnxEzC)

## 使用 RACK 栈

如需启用 RACK 栈，先确认加载内核模块 `tcp_rack.ko` 并即时切换默认 TCP 栈：

```sh
# kldload tcp_rack
# sysctl net.inet.tcp.functions_default=rack
```

如需重启后保持配置，将以下内容分别写入 **/boot/loader.conf** 与 **/etc/sysctl.conf**：

```sh
# echo 'tcp_rack_load="YES"' >> /boot/loader.conf
# echo 'net.inet.tcp.functions_default=rack' >> /etc/sysctl.conf
```

重启系统或加载内核模块后，用以下命令显示系统中可用 TCP 栈列表：

```sh
# sysctl net.inet.tcp.functions_available
net.inet.tcp.functions_available:
Stack                           D Alias                            PCB count
freebsd                           freebsd                          3
rack                            * rack                             0
```

输出中标记 `*` 的栈为当前系统默认使用的 TCP 协议栈。

## BBR 拥塞控制算法

BBR（Bottleneck Bandwidth and Round-trip propagation time，瓶颈带宽与往返传播时间）目标包括：

* 充分利用可用网络带宽。
* 最小化网络传输延迟。

BBR 不以丢包为拥塞信号，而是根据探测到的带宽和延迟动态调整发送速率，在高带宽长延迟的网络环境中更具优势。BBR 在 Linux 中作为拥塞控制模块实现，但在 FreeBSD 中被实现为独立的 TCP 栈（`tcp_bbr`），通过 `net.inet.tcp.functions_default` 进行切换。

## BBR 在 FreeBSD 中的实现与应用

将 `tcp_bbr` 模块加载并设为默认 TCP 栈：

```sh
# kldload tcp_bbr
# sysctl net.inet.tcp.functions_default=bbr
```

持久化配置：

```sh
# echo 'tcp_bbr_load="YES"' >> /boot/loader.conf
# echo 'net.inet.tcp.functions_default=bbr' >> /etc/sysctl.conf
```

重启系统后，查看当前系统使用的默认 TCP 栈：

```sh
# sysctl net.inet.tcp.functions_default
```

如果输出结果为 `net.inet.tcp.functions_default: bbr`，则 TCP BBR 启用成功。

## 故障排除与未竟事宜

在测试环境中，RACK 和 BBR 在局域网中表现良好，但在互联网环境下带宽显著下降：RACK 约为默认栈的三分之一，BBR 约为默认栈的六分之一。该测试在特定网络条件下完成（如高延迟跨境链路），实际性能可能因网络环境而异。需注意，RACK 与 BBR 的设计目标是提升而非降低吞吐量，上述结果可能源于特定丢包/延迟环境的系统性偏差，不代表这些栈在典型部署场景中的表现。

## 参考文献

* Netflix. netflix/tcplog\_dumper\[EB/OL]. \[2026-03-26]. <https://github.com/netflix/tcplog_dumper>. Netflix 开源项目，提供 TCP 日志转储工具，为 TCP 协议分析提供实用工具。
* Cheng Y, Cardwell N, Dukkipati N, et al. The RACK-TLP Loss Detection Algorithm for TCP: RFC 8985\[S/OL]. (2021-02)\[2026-04-17]. <https://www.rfc-editor.org/rfc/rfc8985>. RACK-TLP 丢包检测算法的 IETF 标准文档，Google Yuchung Cheng、Neal Cardwell 等人撰写。
* FreeBSD Project. tcp -- Internet Transmission Control Protocol\[EB/OL]. \[2026-04-14]. <https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4>. TCP 协议栈手册页，描述传输控制协议实现与套接字选项。
* FreeBSD Project. ip -- Internet Protocol\[EB/OL]. \[2026-04-14]. <https://man.freebsd.org/cgi/man.cgi?query=ip&sektion=4>. IP 协议手册页，描述网际协议实现与套接字选项。

## 课后习题

1. 依次启用 FreeBSD 默认栈、RACK 栈和 BBR 栈，使用 `iperf3` 在局域网和互联网环境中分别测试吞吐量和延迟，记录三种栈在不同网络场景下的性能差异，并从拥塞控制算法原理角度分析差异成因。
2. 查阅 `tcp_bbr` 模块的源代码，找出控制 BBR 算法行为的关键参数，修改其中两个参数并重新加载模块，记录参数变化对传输性能的影响。
3. 分析 FreeBSD 多 TCP 栈共存架构的实现机制，设计一个测试场景，在同一系统中为不同网络连接指定不同的 TCP 栈，记录配置方法与验证结果。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/di-22-zhang-gao-ji-wang-luo/di-22.1-jie-tcp-ip-xie-yi-zhan.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
