网卡

网卡工作在物理层和数据链路层,主要由PHY/MAC芯片、Tx/Rx FIFO、DMA等组成,其中网线通过变压器接PHY芯片、PHY芯片通过MII接MAC芯片、MAC芯片接PCI总线

PHY芯片主要负责:CSMA/CD、模数转换、编解码、串并转换

MAC芯片主要负责:

1. 比特流和帧的转换:7字节的前导码Preamble和1字节的帧首定界符SFD

2. CRC校验

3. Packet Filtering:L2 Filtering、VLAN Filtering、Manageability / Host Filtering

Intel的千兆网卡以82575/82576为代表、万兆网卡以82598/82599为代表

收发包过程图

ixgbe_adapter包含ixgbe_q_vector数组(一个ixgbe_q_vector对应一个中断),ixgbe_q_vector包含napi_struct

硬中断函数把napi_struct加入CPU的poll_list,软中断函数net_rx_action()遍历poll_list,执行poll函数

发包过程

1、网卡驱动创建tx descriptor ring(一致性DMA内存),将tx descriptor ring的总线地址写入网卡寄存器TDBA

2、协议栈通过dev_queue_xmit()将sk_buff下送网卡驱动

3、网卡驱动将sk_buff放入tx descriptor ring,更新TDT

4、DMA感知到TDT的改变后,找到tx descriptor ring中下一个将要使用的descriptor

5、DMA通过PCI总线将descriptor的数据缓存区复制到Tx FIFO

6、复制完后,通过MAC芯片将数据包发送出去

7、发送完后,网卡更新TDH,启动硬中断通知CPU释放数据缓存区中的数据包

Tx Ring Buffer

收包过程

1、网卡驱动创建rx descriptor ring(一致性DMA内存),将rx descriptor ring的总线地址写入网卡寄存器RDBA

2、网卡驱动为每个descriptor分配sk_buff和数据缓存区,流式DMA映射数据缓存区,将数据缓存区的总线地址保存到descriptor

3、网卡接收数据包,将数据包写入Rx FIFO

4、DMA找到rx descriptor ring中下一个将要使用的descriptor

5、整个数据包写入Rx FIFO后,DMA通过PCI总线将Rx FIFO中的数据包复制到descriptor的数据缓存区

6、复制完后,网卡启动硬中断通知CPU数据缓存区中已经有新的数据包了,CPU执行硬中断函数:

  • NAPI(以e1000网卡为例):e1000_intr() -> __napi_schedule() -> __raise_softirq_irqoff(NET_RX_SOFTIRQ)
  • 非NAPI(以dm9000网卡为例):dm9000_interrupt() -> dm9000_rx() -> netif_rx() -> napi_schedule() -> __napi_schedule() -> __raise_softirq_irqoff(NET_RX_SOFTIRQ)

7、ksoftirqd执行软中断函数net_rx_action():

  • NAPI(以e1000网卡为例):net_rx_action() -> e1000_clean() -> e1000_clean_rx_irq() -> e1000_receive_skb() -> netif_receive_skb()
  • 非NAPI(以dm9000网卡为例):net_rx_action() -> process_backlog() -> netif_receive_skb()

8、网卡驱动通过netif_receive_skb()将sk_buff上送协议栈

Rx Ring Buffer

软件(SW)向从next_to_use开始的N个descriptor补充sk_buff,next_to_use += N,tail = next_to_use - 1(设置网卡寄存器RDT)

硬件(HW)向从head开始的M个descriptor的sk_buff复制数据包并设置DD,head += M

SW将从next_to_clean的开始的L个sk_buff移出Rx Ring Buffer交给协议栈,next_to_clean += L,向从next_to_use开始的L个descriptor补充sk_buff,next_to_use += L,tail = next_to_use - 1

注意:每次补充完sk_buff以后,tail、next_to_use、next_to_clean三者都是紧挨着的

中断上下部

do_IRQ()是CPU处理硬中断的总入口,在do_IRQ()中调用硬中断函数

netif_rx()

在netif_rx()中把skb加入CPU的softnet_data

RSS + FDIR

FDIR(Flow Director)的优先级高于RSS(Receive Side Scaling)

RSS通过计算包的五元组(sip、sport、dip、dport、protocol)的hash并取余,得到队列的index,然后将包放入这个队列,实现了数据包在各个队列之间的负载均衡,不过RSS不能保证回包也落在同一个队列上

对称hash(sip/sport和dip/dport交换后hash不变)可以部分解决该问题,但是对于一些需要做NAT的设备(比如负载均衡)就失效了,FDIR可以完全解决该问题,参见https://tech.meituan.com/MGW.html

网卡驱动收发包过程图解相关推荐

  1. linux内核网络协议栈--数据包的网卡驱动收发包过程(二十五)

    网卡 网卡工作在物理层和数据链路层,主要由PHY/MAC芯片.Tx/Rx FIFO.DMA等组成,其中网线通过变压器接PHY芯片.PHY芯片通过MII接MAC芯片.MAC芯片接PCI总线 PHY芯片主 ...

  2. ixgbe网卡驱动 Ⅳ----收发包流程详解

    目录 1 网卡队列收包流程概述 2 ixgbe_ring 结构 3 ixgbe 驱动收包流程 3.1 硬件中断入口 ixgbe_msix_clean_rings/ixgbe_intr 3.2 软中断入 ...

  3. linux网卡发送数据包流程,linux内核Ethernet以太网卡驱动收发数据过程

    linux内核Ethernet以太网卡驱动收发数据过程 linux内核Ethernet以太网卡驱动收发数据过程 下图简单描述了网卡驱动与Linux内核之间的联系: 关于上图的一些说明: 系统初始化: ...

  4. 2020-01-14 转载【dpdk】使用libpcap-PMD驱动收发包

    https://doc.dpdk.org/guides/nics/pcap_ring.html 中文资料 转自 https://www.cnblogs.com/zzqcn/p/4902373.html ...

  5. 一文搞懂网卡驱动的原理与移植方法

    1.网卡设备驱动原理 1.1 层次结构 Linux系统对网络设备驱动定义了4个层次, 这4个层次有到下分为: 1.网络协议接口层:实现统一的数据包收发的协议.该层主要负责调用dev_queue_xmi ...

  6. 代码学习-Linux内核网卡收包过程(NAPI)

    本文通过学习RealTek8169/8168/8101网卡的驱动代码(drivers/net/r8169.c).梳理一下Linux下网卡的收包过程. 在下水平相当有限,有不当之处,还请大家斧正^_^ ...

  7. dpdk-16.04 扩展新网卡驱动过程

    编译相关配置添加 1. 确定网卡的 vendor id 与 device id,在 rte_pci_dev_ids.h 中添加新的设备定义 示例信息如下: #ifndef RTE_PCI_DEV_ID ...

  8. Linux 网络层收发包流程及 Netfilter 框架浅析

    本文作者:sivenzhang,腾讯 IEG 测试开发工程师 1. 前言 本文主要对 Linux 系统内核协议栈中网络层接收,发送以及转发数据包的流程进行简要介绍,同时对 Netfilter 数据包过 ...

  9. Linux 网卡驱动学习(六)(应用层、tcp 层、ip 层、设备层和驱动层作用解析)

    本文将介绍网络连接建立的过程.收发包流程,以及其中应用层.tcp层.ip层.设备层和驱动层各层发挥的作用. 1.应用层 对于使用socket进行网络连接的服务器端程序,我们会先调用socket函数创建 ...

最新文章

  1. 面试:字符串拼接,什么时候用StringBuilder?
  2. android设置程序开机自启动
  3. Java数据结构和算法(一)——简介
  4. linux 无响应_系统加固之Linux安全加固
  5. ArcGIS Server常见问题集锦(转载)
  6. 小学计算机应用到英语课教案,信息技术与PEP小学英语三年级学科整合交流课例...
  7. python计算无穷级数求和常用公式_傅里叶变换(二) 从傅里叶级数到傅里叶变换...
  8. 送出15个Google Wave邀请,需要的赶快
  9. NSData与UIImage之间的转换
  10. 5款App帮你创建时间轴
  11. 音频编解码介绍(最全v1.0)
  12. 脑电分析系列[MNE-Python-17]| 使用多种滤波器对脑电数据去除伪影
  13. java if里面并列_多个if语句并列-两个if语句并列-if语句两个并列条件怎么表示
  14. 用摄像管替换电视机电路里的显现管的摄像机
  15. 面试技巧、专面、HR面、群面
  16. Window系统改装为linux系统
  17. 基于JSP动漫论坛的设计与实现(含源文件)
  18. 华为“废太子”李一男 出狱后能否东山再起?
  19. Ubuntu清理磁盘通过Stacer工具
  20. 网络安全-黑帽白帽红客与网络安全法

热门文章

  1. PropertyGrid控件 分类(Category)及属性(Property)排序
  2. RedHat Linux 5.5系统下配置yum包详细过程
  3. java poi 设置标题_poi生成Word时指定文本样式,如“正文”,“标题1”,“标题2”等...
  4. 【框架学习分享】HttpRunner
  5. 解决python中html 代码被注释掉 依旧被解释导致报错ERROR:tornado.access:500 GET /home (xxx.xxx.xxx.xxx)
  6. 静态链接与动态链接的区别
  7. 常用字符串处理函数汇总
  8. 脚本命令配置mysql_MySQL 自动化部署脚本
  9. python vector 初始化_从零开始搭建机器学习算法框架(python)--计算框架
  10. php copy array,ES6中Array.copyWithin()函数用法的详解