文章首发于我的公众号「Linux云计算网络」,欢迎关注,第一时间掌握技术干货!
Linux 是一个非常庞大的系统结构,模块众多,各个模块分工合作,共同运作着各自的任务,为 Linux 这个大家庭贡献着自己的力量。
Linux 网络子系统
其中,网络子系统是一个较为复杂的模块,如下图是 Linux 网络子系统的体系结构,自顶向下,可以分应用层、插口层(或协议无关层)、协议层和接口层(或设备驱动层),这个层级关系也分别对应着我们所熟悉的 OSI 七层模型(物理层、数据链路层、网络层、传输层、会话层、表示层和应用层)。
Linux 所有用户态的应用程序要访问链接内核都要依赖系统调用,这是内核提供给用户态的调用接口,这通常是由标准的 C 库函数来实现的。对于网络应用程序,内核提供了一套通用的 socket 系统调用的接口。
插口层,也叫协议无关层,它屏蔽了协议相关的操作,不论是什么协议(UDP,TCP),都提供一组通用的函数接口,也就是 socket 的实现。
协议层,用于实现各种具体的网络协议族,包括 TCP/IP,OSI 和 Unix 域的实现,每个协议族都包含自己的内部结构,例如,对于 TCP/IP 协议族,IP 是最底层,TCP 和 UDP 层在 IP 层的上面。
接口层,包括了通用设备接口,和网络设备通信的设备驱动程序,其中,包串口使用的 SLIP 驱动程序以及以太网使用的以太网驱动程序,以及环回口使用的都是这一层的设备。它对上提供了协议与设备驱动通信的通用接口,对下也提供了一组通用函数供底层网络设备驱动程序使用。具体的细节后面再开文章详细讲述。
以上是从分层的体系结构来看,下面从数据传输的角度来说说,一个数据包是如何依赖这些层次关系被发送/接收的。
首先,数据的发送过程,应用层组织好待发送的数据包,执行系统调用进入内核协议栈,按照层次关系分别进行包头的封装,如到达传输层,封装 TCP/UDP 的包头,进入网络层封装 IP 包头,进入接口层封装 MAC 帧,最后借助驱动将数据包从网卡发送出去。
然后,数据的接收过程正好与发包过程相反,是一个拆包的过程。接口层借助网卡 DMA 硬件中断感知数据包的到来,拆解包头,识别数据,借助软中断机制告知上层进行相应的收包处理,最终用户态执行系统调用接收数据包。
继续细化这个过程,其内部在实现上都是通过具体的数据结构来完成每一层的过渡的,譬如说,应用层和内核之间通过 struct sock 结构实现协议无关的接口调用进行交互,传输层提供 struct proto 的结构来支持多种协议,网络层通过 struct sk_buff 来传递数据,接口层定义 struct net_device 来完成和驱动程序的交互。
Linux 网络体系结构还是比较博大精深的,尤其是这套自顶向下的分层设计方式对很多技术都有借鉴意义。更具体的函数调用和数据收发过程,后面的文章再进行讲述,敬请期待。
总结
Linux 网络子系统的分层模型,数据收发过程,以及核心数据结构。
PS:文章未经我允许,不得转载,否则后果自负。
欢迎扫👇的二维码关注我的微信公众号,后台回复「m」,可以获取往期所有技术博文推送,更多资料回复下列关键字获取。