第2章:网络协议基础回顾
做硬件加速器开发,说白了就是跟网络协议打交道。你设计的芯片要能看懂以太网帧,要能解析IP头,还要能区分TCP和UDP。这些协议栈的知识,是咱们吃饭的本钱。
我个人习惯,在开始动手写RTL代码之前,先把协议栈的脉络理清楚。这就像盖房子先看图纸,省得后面返工。今天咱们就把OSI七层模型、TCP/IP四层模型,还有以太网、IP、TCP/UDP这几个核心协议,从头到尾捋一遍。
2.1 OSI七层模型与TCP/IP四层模型
先说说这两个模型。OSI七层模型是国际标准,理论上很完美。但实际互联网用的是TCP/IP四层模型,更务实一些。我在项目中遇到过不少刚入行的工程师,把OSI模型背得滚瓜烂熟,结果一抓包分析就懵了——因为实际抓到的报文里,根本找不到会话层和表示层的影子。
核心观点:做硬件加速,重点关注TCP/IP四层模型。OSI模型可以作为理解框架,但别钻牛角尖。
TCP/IP四层模型从上到下分别是:
- 应用层:HTTP、FTP、SMTP等。硬件加速器一般不碰这层,太复杂。
- 传输层:TCP和UDP。这是硬件加速的重点区域,尤其是TCP的卸载引擎(TOE)。
- 网络层:IP协议。路由查找、IP校验和计算,都是硬件擅长的活。
- 网络接口层:以太网协议。MAC层、PHY层,这是FPGA的看家本领。
你想想看,数据从应用层一路往下,每经过一层就加一个头部。到了网络接口层,就是一个完整的以太网帧。硬件加速器要做的,就是在这些层之间快速搬运和处理数据。
我的经验:在FPGA里实现协议栈,我建议从下往上做。先搞定以太网MAC,再做IP层,最后碰TCP。这样每层的调试都有抓手,不会一上来就陷入困境。
2.2 以太网帧结构
以太网帧是网络通信的基本单位。咱们做硬件加速,天天跟它打交道。先看结构:
+----------------+----------------+----------------+----------------+----------------+
| 前导码 (7B) | 帧起始定界符(1B)| 目的MAC (6B) | 源MAC (6B) | 类型/长度 (2B) |
+----------------+----------------+----------------+----------------+----------------+
| 数据载荷 (46-1500B) | 填充 (可选) | 帧校验序列 (4B)|
+----------------------------------+----------------+----------------+
这里有几个关键点:
- MAC地址:6字节,全球唯一。硬件里做MAC地址过滤,其实就是比较几个寄存器。
- 类型/长度字段:大于1536表示类型(如0x0800是IP),小于等于1500表示长度。
- 最小帧长:64字节(不含前导码)。数据不够要填充,这个在硬件里要自动处理。
- FCS:CRC32校验。硬件算这个很快,一个时钟周期就能搞定。
我曾经踩过一个坑:在设计千兆以太网MAC时,忘了处理帧间距(IFG)。结果交换机那边一直丢包,查了两天才发现是IFG没给够。嗯,硬件设计就是这样,细节决定成败。
2.3 IP协议
IP协议是网络层的核心。咱们做硬件加速,主要关注IPv4头部的解析和校验。IPv4头部通常是20字节,结构如下:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|版本| 头部长度 | 服务类型 | 总长度(字节) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 标识符 |标志| 片偏移 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 生存时间(TTL) | 协议号 | 头部校验和 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 源IP地址 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 目的IP地址 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
硬件加速器在IP层要干几件事:
- 校验和计算:IP头部校验和是16位反码和。硬件实现就是加法树,一个周期算完。
- 路由查找:根据目的IP查路由表。这个用TCAM或者哈希表实现,是硬件加速的经典场景。
- 分片重组:IP分片在硬件里实现比较麻烦,需要缓存和定时器。我建议尽量在软件层处理。
注意:IP头部校验和只覆盖头部,不覆盖数据载荷。TCP/UDP的校验和覆盖整个报文段,这个区别在硬件设计时一定要搞清楚。
2.4 TCP协议
TCP是传输层的重头戏,也是硬件加速的难点。为什么?因为TCP有状态,有连接管理,还有拥塞控制。先看TCP头部:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 源端口 | 目的端口 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 序列号 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 确认号 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 数据偏移 | 保留 |标志位| 窗口大小 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 校验和 | 紧急指针 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
硬件加速TCP,核心要处理:
- 序列号管理:发送和接收的序列号要精确跟踪,不能出错。
- 窗口管理:接收窗口大小决定了发送速率,硬件要能动态调整。
- 重传机制:超时重传和快速重传,硬件里要用定时器实现。
我记得有一次做TCP卸载引擎(TOE),在状态机设计上栽了跟头。TCP有11种状态,状态转换图看着就头疼。后来我换了个思路:把状态机拆成发送和接收两个独立的状态机,中间用FIFO通信。这样设计清晰多了,调试也方便。
2.5 UDP协议
UDP就简单多了,无连接、无状态。头部只有8字节:
+----------------+----------------+----------------+----------------+
| 源端口 (2B) | 目的端口 (2B) | 长度 (2B) | 校验和 (2B) |
+----------------+----------------+----------------+----------------+
UDP在硬件里实现起来很轻松:
- 解析头部,提取端口号和长度
- 计算校验和(可选,UDP允许校验和为0)
- 把数据载荷直接送给上层应用
说白了,UDP就是IP协议加了个端口号。硬件实现时,我通常把UDP处理逻辑和IP层放在一起,省资源。
2.6 知识体系总览
为了让你对整个协议栈有个直观的认识,我画了张图:
这张图把TCP/IP四层模型和每层的核心协议都标出来了。右侧的星级表示硬件加速的优先级。以太网和传输层是五星重点,IP层是四星。应用层嘛,咱们暂时不碰。
2.7 小结
这一章咱们把网络协议的基础过了一遍。OSI七层模型和TCP/IP四层模型的关系,以太网帧的结构,IP头部的关键字段,TCP的复杂状态机,还有UDP的简洁设计。这些都是后面做硬件加速的基础。
我个人建议,你可以在FPGA开发板上先实现一个简单的以太网帧接收器,把MAC地址过滤和CRC校验跑通。然后再逐步加上IP解析、UDP处理。一步一步来,别着急。硬件开发最忌讳的就是想一口吃成胖子。
避坑指南:我曾经在IP校验和的计算上犯过错误。反码和的计算规则是:先求和,再把高16位加到低16位,最后取反。硬件实现时要注意进位处理,否则算出来的校验和总是不对。
好了,这一章就到这里。下一章咱们开始动手,从最简单的以太网MAC层设计讲起。