linux操作系统网络数据流程(1)

前言

这部分准备总结主机如何从 网卡抓取数据然后再将数据通过TCP/IP协议栈逐个向上传递的。不过在总结这部分的时候不再像教科书一样对各个数据结构进行补充,而是跳过数据结构部分直接动态的描述数据的流程和流向,部分地方可能会参考源代码。

数据接收

传统对数据的接收有两种方式一种采用轮询的方式,一种采用中断的方式。而为了提升数据传输的效率目前也提出了结合轮询和中断两种方式的结合体NAPI方式。

NAPI的实现:如果一批数据的第一个数据包到达网络设备,采用中断的方式(硬中断)通知系统,硬中断处理中,系统将设备添加到cpu的设备轮询队列中,并关闭中断,同时激活数据包处理软中断;软中断遍历轮询队列中的网络设备,并从中读取数据包。具体实现流程如下:


写到这里将不得不开始将源代码纳入分析了。net_rx_action 该函数为网络输入软中断处理例程。如果网络设备有数据包输入的时候,非NAPI和NAPI的网络设备驱动程序,一般都会激活网络输入软中断处理例程。既然中断(软中断或者硬中断)涉及设备,那么设备就不得不提及驱动程序。net_rx_action的调用自然也就是在驱动程序中调用的。

(软中断处理历程在系统初始化的时候在net_dev_init函数中注册的网络报文输入/输出处理例程的。代码如下)

拿e100驱动程序来说,数据包到达网络设备的时候设备触发中断,然后由e100_intr函数处理。该函数调用__netif_rx_schedule函数最终激活net_rx_action网络输入软中断处理例程。net_rx_action执行过程中会调用e100_poll函数,该函数为e100的轮询处理函数该函数通过调用e100_rx_clean函数进一步调用netif_receive_skb函数将数据包向上传递。

不论是NAPI或者非NAPI的方式最后都将调用netif_receive_skb函数将数据向上传递。该函数遍历ptype_all链表,输入报文到ptype_all链表输入接口,然后桥接转发,如果转发成功则不需要输入到本地,否则遍历ptype_base散列表,根据接收报文的传输层协议,调用相应的报文接收例程。如果是ip数据报则采用ip_rcv函数向上传递。

这里有一点就是主机能对自己输出的数据包进行捕获,当使用socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL))创建原始套接口的时候就可以捕获本地主机输出的满足条件的数据包。(这里有一篇我本人关于使用该方式捕获数据包的代码样例博文)而dev_queue_xmit_nit则用于接收本地输出的数据包。并将数据包输入到RAW套接口。


  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值