-10 +

network stack

Network stack

网络子系统是 kernel 最大的子系统,被叫做 stack 是因为由多种协议组成, 每一个协议构建在上一个协议之上。

layer of network stack

网络协议的层级定义可以通过 OSI model 或者 TCP/IP stack。 当用户数据传输到网络层后,这些数据将被封装成协议:数据传递到协议层后,会在数据的头和尾带上额外的描述数据。 这样即使某些数据丢失或者传输过程中包的顺序打乱了,接收者能够根据这些额外的数据重建原始信息。

网络的每一层都有自己的职责,所有它们不关心更高层协议。 例如:IP 允许发送数据通过多个网络和路由器,它可以重组数据包,但是不保证数据的可靠性, 可靠性由 TCP 协议来保证。它们都可以传输原始数据,编码和压缩依靠更上次的协议实现,如 HTTP。

网络子系统和块存储系统最大的不同是:网络是延迟敏感的,所有 写/读 数据不能被延迟。 这也就是说,发送和读取数据通常在同一个线程上下文中。

网络栈在 unix 系统中大体上被划分为三个主要的层:

Ring buffer

网络被设计为发送巨量数据,所以如果是显示的发送每一次写的数据这种方式是低效的。 NIC 和 驱动程序通过维护一个 shared ring buffer 来代替单独的包处理。 驱动程序写数据到 ring buffer,NIC 网卡通过 DMA(direct memory access)来读取数据。 ring buffer 存在两个指针,head 和 tail:

当驱动程序想通过队列方式传输数据时,它会将数据写入 ring buffer,然后更新 tail 指针。 当 NIC 发送数据时,会更新 head 指针。

sk_buff structure

linux 中一般通过 sk_buff 数据结构在各层中共享数据:

sk_buff 中存在两个指针:head 和 data 指针指向协议的头。 数据长度保存在 len 属性中,包的传输时间戳保存在 tstamp 属性中。 sk_buff 通过 next 和 prev 构建一个双向列表。 网络驱动设备通过 net_device 属性保存。 一个 socket 通过下述结构对来表示:

参考

关于我

85 后程序员, 比较熟悉 Java,JVM,Golang 相关技术栈, 关注 Liunx kernel,目前痴迷于分布式系统的设计和实践。 研究包括但不限于 Docker Kubernetes eBPF 等相关技术。

Blog

Code

Life

Archive