网卡工作原理

十月飞翔
• 阅读 620

网卡收包

网线上的 packet 首先被网卡获取,网卡会检查 packet 的 CRC 校验,保证完整性,然后将 packet 头去掉,得到 frame。网卡会检查 MAC 包内的目的 MAC 地址,如果和本网卡的 MAC 地址不一样则丢弃 (混杂模式除外)。

网卡将 frame 拷贝到网卡内部的 FIFO 缓冲区,触发硬件中断。(如有 ring buffer 的网卡,好像 frame 可以先存在 ring buffer 里再触发软件中断(下篇文章将详细解释 Linux 中 frame 的走向),ring buffer 是网卡和驱动程序共享,是设备里的内存,但是对操作系统是可见的,因为看到 linux 内核源码里网卡驱动程序是使用 kcalloc 来分配的空间,所以 ring buffer 一般都有上限,另外这个 ring buffer size,表示的应该是能存储的 frame 的个数,而不是字节大小。另外有些系统的 ethtool 命令 并不能改变 ring parameters 来设置 ring buffer 的大小,暂时不知道为什么,可能是驱动不支持。)

网卡驱动程序通过硬中断处理函数,构建 sk_buff,把 frame 从网卡 FIFO 拷贝到内存 skb 中,接下来交给内核处理。(支持 napi 的网卡应该是直接放在 ring buffer,不触发硬中断,直接使用软中断,拷贝 ring buffer 里的数据,直接输送给上层处理,每个网卡在一次软中断处理过程能处理 weight 个 frame)

过程中,网卡芯片对 frame 进行了 MAC 过滤,以减小系统负荷。(除了混杂模式)

网卡发包

网卡驱动程序将 IP 包添加 14 字节的 MAC 头,构成 frame(暂无 CRC)。Frame(暂无 CRC)中含有发送端和接收端的 MAC 地址,由于是驱动程序创建 MAC 头,所以可以随便输入地址,也可以进行主机伪装。

驱动程序将 frame(暂无 CRC)拷贝到网卡芯片内部的缓冲区,由网卡处理。

网卡芯片将未完全完成的 frame(缺 CRC)再次封装为可以发送的 packet,也就是添加头部同步信息和 CRC 校验,然后丢到网线上,就完成一个 IP 报的发送了,所有接到网线上的网卡都可以看到该 packet。

网卡中断处理函数

产生中断的每个设备都有一个相应的中断处理程序,是设备驱动程序的一部分。每个网卡都有一个中断处理程序,用于通知网卡该中断已经被接收了,以及把网卡缓冲区的数据包拷贝到内存中。

当网卡接收来自网络的数据包时,需要通知内核数据包到了。网卡立即发出中断。内核通过执行网卡已注册的中断处理函数来做出应答。中断处理程序开始执行,通知硬件,拷贝最新的网络数据包到内存,然后读取网卡更多的数据包。

这些都是重要、紧迫而又与硬件相关的工作。内核通常需要快速的拷贝网络数据包到系统内存,因为网卡上接收网络数据包的缓存大小固定,而且相比系统内存也要小得多。所以上述拷贝动作一旦被延迟,必然造成网卡 FIFO 缓存溢出 - 进入的数据包占满了网卡的缓存,后续的包只能被丢弃,这也应该就是 ifconfig 里的 overrun 的来源。

当网络数据包被拷贝到系统内存后,中断的任务算是完成了,这时它把控制权交还给被系统中断前运行的程序。

缓冲区访问

网卡的内核缓冲区,是在 PC 内存中,由内核控制,而网卡会有 FIFO 缓冲区,或者 ring buffer,这应该将两者区分开。FIFO 比较小,里面有数据便会尽量将数据存在内核缓冲中。

网卡中的缓冲区既不属于内核空间,也不属于用户空间。它属于硬件缓冲,允许网卡与操作系统之间有个缓冲;

内核缓冲区在内核空间,在内存中,用于内核程序,做为读自或写往硬件的数据缓冲区;

用户缓冲区在用户空间,在内存中,用于用户程序,做为读自或写往硬件的数据缓冲区;

另外,为了加快数据的交互,可以将内核缓冲区映射到用户空间,这样,内核程序和用户程序就可以同时访问这一区间了。

对于有 ring buffer 的网卡,ring buffer 是由驱动与网卡共享的,所以内核可以直接访问 ring buffer,一般拷贝 frames 的副本到自己的内核空间进行处理(deliver 到上层协议,之后的一个个 skb 就是按 skb 的指针传递方式传递,直到用户获得数据,所以,对于 ring buffer 网卡,大量拷贝发生在 frame 从 ring buffer 传递到内核控制的计算机内存里)。

  1. 丢包排查思路

网卡工作在数据链路层,数据量链路层,会做一些校验,封装成帧。我们可以查看校验是否出错,确定传输是否存在问题。然后从软件层面,是否因为缓冲区太小丢包。

先查看硬件情况

一台机器经常收到丢包的报警,先看看最底层的有没有问题:

(1) 查看工作模式是否正常

[root@localhost ~]# ethtool eth0 | egrep 'Speed|Duplex'Speed: 1000Mb/sDuplex: Full

(2) 查看检验是否正常

[root@localhost ~]# ethtool -S eth0 | grep crcrx_crc_errors: 0

Speed,Duplex,CRC 之类的都没问题,基本可以排除物理层面的干扰。

overruns 和 buffer size

for i in seq 1 100; do ifconfig eth2 | grep RX | grep overruns; sleep 1; doneRX packets:346547657 errors:0 dropped:0 overruns:35345 frame:0-g –show-ringQueries the specified ethernet device for rx/tx ring parameter information.-G –set-ringChanges the rx/tx ring parameters of the specified ethernet device.ethtool -g eth0[root@localhost ~]Ring parameters for eth0:Pre-set maximums:RX: 4096RX Mini: 0RX Jumbo: 0TX: 4096Current hardware settings:RX: 256RX Mini: 0RX Jumbo: 0TX: 256ethtool -G eth0 rx 2048ethtool -G eth0 tx 2048[root@localhost ~][root@localhost ~][root@localhost ~]Ring parameters for eth0:Pre-set maximums:RX: 4096RX Mini: 0RX Jumbo: 0TX: 4096Current hardware settings:RX: 2048RX Mini: 0RX Jumbo: 0TX: 2048

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
TIDB集群安装部署方案————————上篇
1.   安装TIDB生成环境硬件要求组件CPU内存硬盘类型网络数量(最低要求)TiDB16核48GBSAS万兆网卡(2块最佳)2PD8核16GBSSD万兆网卡(2
Wesley13 Wesley13
3年前
SUSE12 网卡配置、SSH远程配置、解决CRT密钥交换失败,没有兼容的加密程序
安装好SUSE系统后发现网卡配置与Centos有些差异,多网卡的同学可以参考一下(我的是双网卡)SUSE系统默认第一块网卡自动获取IP,如果是多网卡,需要手动配置,由于我的第一个网卡获取正确无需更改,第二块网卡需要配置静态IP!(https://oscimg.oschina.net/oscnet/f45ba440cd5ff57ba8b568f9f
分布式id如何生成
1.UUID生成通过网卡、时间、随机数来保证生成的唯一的字符串。优点:(1)本地生成,生成简单(2)速度快(3)高可用;缺点:(1)无序,如果存入mysq,影响B的操作性能,因为B树是需要排序的;(2)占用空间较大(36个
Stella981 Stella981
3年前
Centos7.x系统_网卡启动报错的案例分析
_摘要:_ 介绍了Centos7系统,网卡启动失败的两种情况,和对应的分析解决方法。介绍了Centos7系统,网卡启动失败的两种情况,和对应的分析解决方法。情景一:ifconfig 查看不到网卡ip配置,网卡没有正常启动。处理过程: 1、启动网卡systemctlstartnetwork尝试启动网卡,不能正
Wesley13 Wesley13
3年前
50.检测网卡状态脚本
思路:sarnDEV110监测网卡进出流量,如果进出流量都为0则网卡异常!/bin/bashLANGen定义语言if$ne1||!ipaddrshow$1&/dev/null;then输入参数是否为1,!ipaddrshow判断网卡是否存在
Wesley13 Wesley13
3年前
ubuntu server 18.04 vbox,VirtualBox linux 虚拟机 网络配置
宿主机是win10虚拟机是ubuntu18.04server版按此配置以实现宿主容器内外网互通以及虚拟机上网WAN对2只网卡的设置分别是如下!网卡1(https://oscimg.oschina.net/oscnet/up6210245c4a20355c9fc27fb021b894b4367.png"网卡1")!网卡2
Stella981 Stella981
3年前
Dell服务器网卡驱动升级[CentOS 5.5 X86_64和RHEL 5.6 X86_64]
系统:CentOS5.5X86\_64、RHEL5.6X86\_64硬件:DellR610、R710、R720通过升级系统自带网卡驱动程序到最新版本,可以解决当网卡流量过大时,出现掉包、断网现象。升级步骤:1.查看当前网卡类型\/sbin/lspci|grepEthernet02:00.0Ethernet
Stella981 Stella981
3年前
IPv6通讯原理(1)
!(https://fzxiaomange.com/img/ipv6/initcover1.png)本文主题:通过抓包分析,深入观察网卡启动过程的每个步骤,从而逐步掌握通讯原理。🍀小慢哥的原创文章,欢迎转载目录▪一.为什么不能忽略网卡启动过程▪二.实验环境▪三.网卡启动前/后的样子▪
Stella981 Stella981
3年前
Docker:macvlan实现容器跨主机通信 [十四]
一、什么是macvlan1、macvlan本身是linuxkernel模块,其功能是允许在同一个物理网卡上配置多个MAC地址,2、即多个interface,每个interface可以配置自己的IP。3、macvlan本质上是一种网卡虚拟化技术二、跨主机通信1、创建m
分布式系统的主键生成方案对比 | 京东云技术团队
UUID​UUID(通用唯一识别码)是由32个十六进制数组成的无序字符串,通过一定的算法计算出来。为了保证其唯一性,UUID规范定义了包括网卡MAC地址、时间戳、名字空间(Namespace)、随机或伪随机数、时序等元素,以及从这些元素生成UUID的算法。