SKB包的接收-----从网卡驱动到TCP层的处理流程
在开发模块过程中,遇到一个问题:在NF_INET_LOCAL_IN钩子处截获数据包后,如果操作失败,还要把这些截获的数据包重新传递到TCP层处理。但是这个操作是在内核线程中完成,不知道会不会对正常的数据包接收过程产生影响?因此,需要知道数据包在从网络层传递到传输层时的上下文环境(指的是是否禁止内核抢占、是否需要获取锁等)。为了解决这个问题,决定将数据包的接收过程从驱动程序到TCP层的处理流程梳理了一遍。
在文中的叙述过程中,将网卡驱动和网络层之间的部分,称之为网络核心层,如下图所示:
一、驱动程序
为了找到skb包传递到传输层的上下文,肯定要从数据包接收的下半部,也就是数据接收的软中断中去找,但是既然要梳理,就要梳理的彻底一点,确保没有遗漏,因此从网卡的驱动程序开始。每个网卡都会有一个中断号,驱动程序中会有一个对应的中断处理函数。当数据包到达时,网卡会向CPU发送一个中断,然后会调用特定于网络的驱动程序,来接收数据包。选择的驱动程序是3c501网卡的驱动,该驱动比较简单,便于看出从驱动程序传递到网络核心层传输的过程。3c501网卡对应的中断处理函数el_interrupt(),源码如下(只列出关键的部分):
三、网络层
网络层中主要关注IPv4协议,其接收函数时ip_rcv()。ip_rcv()中首先判断skb包是否是发送给本机,如果是发送给其他机器,则直接丢弃,然后检查IP数据包是否是正常的IP包,如果是正常的数据包,则调用ip_rcv_finish()继续处理(忽略钩子的处理),如下所示: