Linux 网络子系统底层机制分析 (1)

 网络子系统在linux中的地位非常重要。在如今这个严重依赖互联网,强调协同工作的时代,一个高效,稳定的网络处理系统是留住用户群的基本手段。前段时间花了一部分时间学习了一下linux的网络子系统的源代码以及一些处理机制。这部分是由于工作的原因,另一部分原因是想对linux的网络处理有一个更加完整,深入的认识。趁着春节假期,对前段时间的学习做一个总结,绝大部分内容参考自<Understanding Linux Network Internals>这本书,部分内容来自互联网以及自己看代码的总结。

网络子系统概貌

 Linux的网络子系统实现了TCP/IP协议栈。本来有一个图来表示socket以及各层的一个数据流向,最后才发现没有办法上传到csdn上来。

 对应用程序原来说,与网络打交道的接口就是SOCKET。从图中可以看到,linux支持多种类型的socket,当然不只图中表示的这几种。比如说SOCK_STREAM类型的socket主要用于使用TCP协议的编程,而SOCK_RAM类型的socket则可以绕过传输层,直接和IP层打交道,当然这也意味着你的工作量将会大大增加,带来的将是灵活性。

 上图L3,L4中有横向虚线,表示的是从下面一层进入的报文既可以直接往上走,也可以循着虚线方向到达一些特殊的模块。比如说由IPv4到L4,如果此报文是SOCK_RAW类型的,则直接送到SOCKET层处理,否则送到TCP,UDP等四层处理模块。

 对于出报文,最终由dev_queue_xmit函数发送到特定接口的驱动,由它发送到网络上。如果没有指定一个特定的接口,那么根据报文的目的地址,由系统路由决定的到底由哪一个网络接口发送出去。

 

网络子系统对报文的处理

 其实上面说报文并不是很恰当,因为在协议栈的不同层,其被处理的主体是不一样的。在link层,是帧;在network层是报文;在transport层则是数据包。

 在协议栈的各层,主要的处理流程基本上都是解析协议头,封装协议头等等。为了适应各种协议,以及面对将来不断增加的协议,linux的网络子系统采取的是注册处理函数的方式来实现一种松散的耦合。在注册的时候,会传入一个类似协议号的参数值,这样二层的处理函数就能根据帧的协议字段的值决定下一步处理的函数了。比如说在三层,可以注册自己的协议处理函数,比如说处理协议号为100的报文,这样,当系统收到一个适当的报文(协议号字段为100)时将把此帧递送到你注册的处理函数当中。

 
Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐