网卡驱动收包

news/2024/10/30 23:22:04/
一、NAPI方式处理数据包接收(中断与轮询配合,由硬件中断触发接收处理,之后关闭网卡硬中断,当处理完成后,再将网卡硬中断开启,在高负荷工作情况下,可以减少因频繁切换中断上下文造成的CPU开销)
1、e100网卡驱动接收中断触发
e100_intr
//e100网卡驱动中,在如下流程中设置中断回调
//netdev->open   (当应用层执行ifup时,调用了设备回调netdev->open)
//e100_open
//    e100_up
//        request_irq(nic->pdev->irq, e100_intr, IRQF_SHARED,...)
//		 e100_enable_irq(nic)u8 stat_ack = readb(&nic->csr->scb.stat_ack)if(stat_ack == stat_ack_not_ours ||stat_ack == stat_ack_not_present)return IRQ_NONE;writeb(stat_ack, &nic->csr->scb.stat_ack)if(stat_ack & stat_ack_rnr)nic->ru_running = RU_SUSPENDED;if(likely(netif_rx_schedule_prep(netdev)))//如果设置为打开状态(__LINK_STATE_START)并且先前还未进行接收调度//(__LINK_STATE_RX_SCHED),则条件满足e100_disable_irq(nic);	//关闭硬件中断__netif_rx_schedule(netdev)//将当前设备加入到每CPU的轮询设备列表中//分配当前设备的接收报文配额//触发软中断NET_RX_SOFTIRQlist_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list);dev->quota = dev->weight;__raise_softirq_irqoff(NET_RX_SOFTIRQ);2、软中断NET_RX_SOFTIRQ中断函数,之前在net_dev_init中初始化
net_rx_actionqueue = &__get_cpu_var(softnet_data)//获取每CPU软中断处理队列budget = netdev_budget;//获取总的执行配额while (!list_empty(&queue->poll_list))//遍历轮询设备列表中每个需要接收的设备if (budget <= 0 || jiffies - start_time > 1)//当总的收包配额使用完,或者已经执行了1秒钟则暂时退出轮询处理goto softnet_break;dev = list_entry(queue->poll_list.next,....)//从轮询设备列表中取出第一个待处理的设备if (dev->quota <= 0 || dev->poll(dev, &budget))//如果在处理的设备自己的收包配额使用完,还有未接收的数据,则当前设备//轮询列表首部移动轮询列表尾部,同时更新此设备的接收配额。list_move_tail(&dev->poll_list, &queue->poll_list);dev->quota = dev->weight;Elsedev_put(dev)		//释放该设备......3、dev->poll,e100驱动在PCI总线探测回调中设置该函数回调为e100_poll
e100_pollwork_to_do = min(netdev->quota, *budget)//budget是调用dev->poll时传入的参数,budget是设备核心模块总的一次轮询配额,这//里用当前设备的收包配额和总的收包配额进行对比,取出最小接收包配额值。e100_rx_clean(nic, &work_done, work_to_do);//这里从网卡中获取数据包,并调用netif_receive_skb函数进行上层协议处理,这里暂//时不进行分析。if((!tx_cleaned && (work_done == 0)) || !netif_running(netdev))//如果发送和接收都处理完成,或者设备未开启,则将设备从轮询列表删除,清除正在//接收的调度标记,同时开启硬中断netif_rx_completelist_del(&dev->poll_list);clear_bit(__LINK_STATE_RX_SCHED, &dev->state);e100_enable_irqReturn 0*budget -= work_done;			//将总的接收配额及设备接收配额递减,并返回还有待netdev->quota -= work_done;		//处理的数据(retur 1)Return 1二、非NAPI方式处理数据包接收(始终靠网卡的硬中断来处理收包)
1、de600网卡驱动接收中断触发
de600_rx_intrnetif_rx(skb)//接收中断触发后执行netif_rx进行接收包处理if (netpoll_rx(skb))return NET_RX_DROP;if (!skb->tstamp.off_sec)net_timestamp(skb);//skb->tstamp,更新收包的时间戳queue = &__get_cpu_var(softnet_data);//获取每CPU软中断处理队列if (queue->input_pkt_queue.qlen <= netdev_max_backlog)//如果接收包的队列没满则继续处理,否则丢弃。if (queue->input_pkt_queue.qlen)//如果队列中已经有值,表明软中断正在处理,直接将包放入队列尾。enqueue:__skb_queue_tail(&queue->input_pkt_queue, skb);return NET_RX_SUCCESS;netif_rx_schedule(&queue->backlog_dev);if (netif_rx_schedule_prep(dev))__netif_rx_schedule(dev)//接口为开启,先没有进行接收调度,则触发接收调度,将设备//加入到轮询设备列表中,同时触发接收软中断。注意这里的向//轮询列表加入的设备是虚拟的backlog_dev,同时接收软中断在//调用设备接收回调函数也是使用的这个虚拟设备的接收函数。goto enqueue;//如果队列是空的,则激活软中断,同时将包放入队列中。kfree_skb(skb)return NET_RX_DROP;//在上面判断队列已经满了,则新来的包丢弃处理。2、接收软中断任务在上面已经描述过了,接收软中断任务主要从设备轮询列表调用对应设备的poll回调函数,非NAPI方式的驱动在上面使用的是虚拟设备backlog_dev,该设备的回调函数在net_dev_init初始化时已经设置为process_backlogprocess_backlogquota = min(backlog_dev->quota, *budget)//从总的收包配额,与设备的收包配额中选取一个较小的值for (;;)skb = __skb_dequeue(&queue->input_pkt_queue);//从接收队列中获取一个包,如果队列已空,则返回接收完成。if (!skb)goto job_done;dev = skb->dev;netif_receive_skb(skb);//调用上层接口进行包处理work++;if (work >= quota || jiffies - start_time > 1)//如果已经达到了收包限额,或者执行了1秒中,则退出循环break;backlog_dev->quota -= work;
*budget -= work;
return -1;
//将设备限额和总收包限额递减,返回-1表明还有包需要处理job_done:
backlog_dev->quota -= work;
*budget -= work;
list_del(&backlog_dev->poll_list);
//接收队列中已经没有包需要处理,则递减包限额后,从轮询列表中删除虚拟设备。netif_poll_enable(backlog_dev);
//将虚拟设备状态去除__LINK_STATE_RX_SCHED,表明已经接收调度已经没有运行。三、netif_receive_skb
if (skb->dev->poll && netpoll_rx(skb))
//如果netpoll处理,则这里直接丢弃包,不再向上层传递。return NET_RX_DROP;if (!skb->tstamp.off_sec)
//更新时间戳net_timestamp(skb);if (!skb->input_dev)skb->input_dev = skb->dev;orig_dev = skb_bond(skb);
//如果有绑定功能,则获取绑定主设备,否则不支持绑定功能,则取当前获取包的设备//初始化skb一些参数值
skb->h.raw = skb->nh.raw = skb->data;
skb->mac_len = skb->nh.raw - skb->mac.raw;pt_prev = NULL;list_for_each_entry_rcu(ptype, &ptype_all, list)
//将包传给所有嗅探器,这里ptype_all是指可以处理任何二层以上的包类型列表。通常应用
//层实现嗅探器创建的套接口类型为socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL)),
//则系统就会调用dev_add_pack向ptype_all包类型列表中添加。这里嗅探器得到接收的所有
//报文,同样也会得到所有发送的报文。在dev_add_pack函数执行时,如果包类型为
//ETH_P_ALL,则递增全局变量netdev_nit,之后dev_hard_start_xmit发包函数中判断如果
//netdev_nit大于0,则会把发出的包放到当前嗅探器的套接收接收队列中。if (!ptype->dev || ptype->dev == skb->dev)if (pt_prev)deliver_skb(skb, pt_prev, orig_dev);pt_prev->func(skb, skb->dev, pt_prev, orig_dev);pt_prev = ptype;if (handle_bridge(&skb, &pt_prev, &ret, orig_dev))
//如果二层桥已经处理,则返回goto out;type = skb->protocol;
list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type)&15], list)
//处理所有注册到基本包类型的包。(最后一个不做处理)if (ptype->type == type && (!ptype->dev || ptype->dev == skb->dev))if (pt_prev)ret = deliver_skb(skb, pt_prev, orig_dev);pt_prev->func(skb, skb->dev, pt_prev, orig_dev);pt_prev = ptype;if (pt_prev)ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);//处理注册到基本包类型的最后一个符合条件的包。
eslekfree_skb(skb)ret = NET_RX_DROP;//不识别的类型包,丢弃处理。



http://www.ppmy.cn/news/271270.html

相关文章

网卡驱动程序框架

我们这里说的是网卡驱动程序&#xff0c;不是网络驱动程序&#xff0c;网络有七层&#xff0c;我们写的只是最底层的东西&#xff0c;网络这么多层&#xff0c;但是最终你还是要操作硬件啊 所以上面肯定有个硬件相关层&#xff0c;我们要写的就是硬件相关的驱动程序这一小块。…

驱动精灵-万能网卡版

驱动管理&#xff0c;网络修复工具&#xff0c;修复网络配置&#xff0c;重启。

万能驱动VIP版(EasyDrv) v7.23.317.2 正式版

万能驱动VIP版(简称EasyDrv)是IT天空出品的一款智能识别电脑硬件并自动安装驱动的驱动安装工具.它拥有简约友好的用户界面,驱动覆盖面广泛,智能精确识别硬件设备,万能驱动搭载了IT天空团队精心整理制作的离线驱动包.这是到目前为止,针对当前主流硬件设备收集和整理得最为全面的…

驱动精灵万能网卡版单文件版 v9.61

电脑因为缺少各种.Net、VC运行库致使程序无法运行怎么办&#xff1f;电脑卡顿无法运行怎么办&#xff1f;无须担心&#xff0c;今天为大家带来的是驱动精灵万能网卡版&#xff0c;这是一款集驱动管理和硬件检测于一体的驱动管理和维护工具&#xff0c;通过它可以快速找到相关运…

巧用万能驱动包安装驱动

本人从事系统维护工作的总结&#xff0c;希望对大家有用&#xff0c;不足的地方希望大家提出来&#xff0c;共同进步&#xff0c;欢迎拍砖&#xff01; 其实做维护是很枯燥的&#xff0c;但要做到高效是要动脑经的&#xff0c;否则永远都是老一套。 以前安装系统设备的驱动都是…

接口和抽象类区别

抽象类和接口都是 Java 中的重要概念&#xff0c;它们在面向对象编程中都扮演着重要角色&#xff0c;但是它们之间有许多不同点。下面在概念、用法、特性、设计等方面详细比较抽象类和接口的区别。 这里先列举接口和抽象类的区别 抽象类可以有构造方法&#xff0c;而接口不能有…

【OpenMMLab AI实战营第二期】目标检测与MMDetection

目标检测 目标检测的基本范式 划窗 使用卷积实现密集预测 锚框 多尺度检测与FPN 单阶段&无锚框检测器选讲 RPN YOLO、SSD Focal Loss与RetinaNet FCOS YOLO系列选讲 什么是目标检测 目标检测&#xff1a;给定一张图片&#xff0c;用矩形框框出所有感兴趣物体同…

【PWN · ret2libc | Canary】[2021 鹤城杯]littleof

最近比较忙&#xff0c;这道题用了好长时间来debug&#xff0c;甚至贡献了第一次在csdn上提问。。。 目录 前言 一、题目重述&思路分析 二、exp 三、Canary 四、萌新遇到的困难 总结 前言 Canary作为经典且基本的栈保护措施&#xff0c;在后期的题目中必然是基本标…