程序员可能关心的基本网卡知识

网卡相关介绍:http://www.linuxidc.com/Linux/2012-12/77132.htm

一、什么是网卡?

它是主机的网络设备,本身是LAN(局域网)的设备,通过网关、路由器等设备就可以把这个局域网挂接到Internet上。网卡工作在物理层和数据链路层的MAC子层,数据链路层还有LLC层,它在MAC层之上。

网卡按照数据链路层控制来分有以太网卡,令牌环网卡,ATM网卡等;按照物理层来分类有无线网卡,RJ-45网卡,同轴电缆网卡,光线网卡等等。它们的数据链路控制、寻址、帧结构等不同;物理上的连接方式不同、数据的编码、信号传输的介质、电平等不同。普通程序员常用的应该是以太网网卡。

以太网采用的CSMA/CD(载波侦听多路访问/冲突检测)的控制技术。他主要定义了物理层和数据链路层的工作方式。数据链路层和物理层各自实现自己的功能,相互之间不关心对方如何操作。二者之间有标准的接口(例如MII,GMII等)来传递数据和控制。

以太网卡的物理层可以包含很多种技术,常见的有RJ45,光纤,无线等,它们的区别在于传送信号的物理介质和媒质不同。(这些不太是程序员所关心的)

二、网卡的组成

1.网卡的基本结构

以太网网卡包括OSI(开方系统互联)模型的两个层。物理层和数据链路层。物理层定义了数据传送与接收所需要的电与光信号、线路状态、时钟基准、数据编码和电路等,并向数据链路层设备提供标准接口。数据链路层则提供寻址机构、数据帧的构建、数据差错检查、传送控制、向网络层提供标准的数据接口等功能。

2.什么是MAC?

以太网数据链路层其实包含MAC(介质访问控制)子层和LLC(逻辑链路控制)子层。MAC从PCI总线收到IP数据包(或者其他网络层协议的数据包)后,将之拆分并重新打包成最大1518Byte,最小64Byte的Frame。这个帧里面包括了目标MAC地址、自己的源MAC地址和数据包里面的协议类型(比如IP数据包的类型用80表示)。最后还有一个DWORD(4Byte)的CRC码。

收到数据帧的时候也是一样,做完CRC以后,如果没有CRC效验错误,就把帧头去掉,把数据包拿出来通过标准的接口传递给驱动和上层的协议栈,最终正确的达到我们的应用程序。

3.网络传输

PHY还有个重要的功能就是实现CSMA/CD的部分功能。它可以检测到网络上是否有数据在传送,如果有数据在传送中就等待,一旦检测到网络空闲,再等待一个随机时间后将送数据出去。如果两块网卡碰巧同时送出了数据,那样必将造成冲突,这时候,冲突检测机构可以检测到冲突,然后各等待一个随机的时间重新发送数据。

4.关于网络间的冲突

交换机和HUB最大的区别就是:一个是构建点到点网络的局域网交换设备,一个是构建冲突域网络的局域网互连设备。

当我们给网卡接入网线的时候,PHY不断发出的脉冲信号检测到对端有设备,它们通过标准的”语言”交流,互相协商并确定连接速度、双工模式、是否采用流控等。

通常情况下,协商的结果是两个设备中能同时支持的最大速度和最好的双工模式。这个技术被称为Auto Negotiation。

Linux的网卡级丢包剖析

参考:http://blog.csdn.net/zhangskd/article/details/22211295

1.网卡收包

网线上的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过滤,以减小系统负荷。(除了混杂模式)

2.网卡发包

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

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

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

3.网卡中断处理函数

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

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

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

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

缓冲区访问

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

网卡中的缓冲区既不属于内核空间,也不属于用户空间。它属于硬件缓冲,允许网卡与操作系统之间有个缓冲;
内核缓冲区在内核空间,在内存中,用于内核程序,做为读自或写往硬件的数据缓冲区;
用户缓冲区在用户空间,在内存中,用于用户程序,做为读自或写往硬件的数据缓冲区;
另外,为了加快数据的交互,可以将内核缓冲区映射到用户空间,这样,内核程序和用户程序就可以同时访问这一区间了。

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

原文链接:https://blog.csdn.net/Just_Do_IT_Ye/article/details/47000383

linux内核网络协议栈--数据包的网卡缓冲区(二十四)相关推荐

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

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

  2. linux内核网络协议栈--数据包的网卡转发流程(二十七)

    原文链接:https://blog.csdn.net/jackywgw/article/details/78321226

  3. linux内核网络协议栈--数据包的接收过程(二十)

    本文将介绍在Linux系统中,数据包是如何一步一步从网卡传到进程手中的. 本文只讨论以太网的物理网卡,不涉及虚拟设备,并且以一个UDP包的接收过程作为示例. 本示例里列出的函数调用关系来自于kerne ...

  4. linux内核网络协议栈--数据包的发送过程(二十一)

    继上一篇介绍了数据包的接收过程后,本文将介绍在Linux系统中,数据包是如何一步一步从应用程序到网卡并最终发送出去的. socket层 +-------------+| Application |+- ...

  5. linux内核网络协议栈--数据包的接收过程(二十二)

    与其说这篇文章分析了网卡驱动中中数据包的接收,还不如说基于Kernel:2.6.12,以e100为例,对网卡驱动编写的一个说明.当然,对数据包的接收说的很清楚. 一.从网卡说起 这并非是一个网卡驱动分 ...

  6. linux内核网络协议栈--数据包的接收流程(二十三)

    网卡在接受数据包时会产生中断,即当 有一个以太网帧到来时,网卡向内核产生一次中断: CPU收到中断信号后,执行中断处理程序,中断处理程序会设置 缓冲区地址.DMA 地址等信息: 网卡通过DMA 方式将 ...

  7. linux内核网络协议栈--数据包的skb桥转发蓝图(二十六)

    话不多说,先看一张桥转发时函数调用的一个基本蓝图. 这张图中,简单的展示了,数据的接收和发送,其中还包括netfilet的钩子点所处的位置. 需要说明的是: 1.我们先暂时忽略数据包从一开始是怎么从驱 ...

  8. linux内核网络协议栈--数据包的数据收发简略流程图(二十八)

    基于内核3.17.1版本 原文链接:https://blog.csdn.net/subfate/article/details/53107435

  9. Linux内核网络udp数据包发送(二)——UDP协议层分析

    1. 前言 本文分享了Linux内核网络数据包发送在UDP协议层的处理,主要分析了udp_sendmsg和udp_send_skb函数,并分享了UDP层的数据统计和监控以及socket发送队列大小的调 ...

最新文章

  1. kvm--virsh命令行下管理虚拟机
  2. php模块介绍,Python模块介绍
  3. 洛谷P4609 [FJOI2016]建筑师 【第一类斯特林数】
  4. 库克笑了,说要给股东多分红:换了M1后Mac销售额增长70%,iPhone也增长66%
  5. 字符设备驱动基本流程
  6. 从frame跳转到一个新的页面
  7. linux、sql 常用的一些特殊符号
  8. debug 没有错,release出错
  9. xenserver 挂载磁盘 xe sr-create_视频号挂载小商店,仅需3步!
  10. Eclipse插件安装全方式
  11. 如何遍历或枚举JavaScript对象?
  12. 计算机组成原理--白中英版 全部知识点
  13. 例外被抛出且未被接住
  14. Burp Suite CA证书下载及导入教程
  15. 选择导入过滤器endnote_EndNote 知网的 Import Filter (滤件制作实例) | 科研动力
  16. WebSocket实战之一
  17. Win10输入法移除未知区域设置(qad-Latn) 美式键盘
  18. Jsp显示应用外服务器的图片,jsp显示服务器的绝对路径图片
  19. android 市场 历史版本,安卓市场旧版本
  20. 一套完整的硬件电路设计该怎么做

热门文章

  1. 学python需要什么基础知识-学Python需要什么基础知识?零基础可以学Python吗?
  2. python介绍和用途-python python简介及其特点
  3. python哪个版本好-python应该学习哪个版本
  4. python手机版下载3.7.3-QPython3手机版下载
  5. python强大体现在哪些方面-大公司里哪些方面运用了python?
  6. python表白-教你如何用Python表白
  7. python单词意思-python 前面几个单词含义
  8. python3下载慢-PIP 下载慢,给你Python3的pip换个源 一键换源
  9. 查看安装的cuda和cudnn的版本号
  10. libevent中的基本数据结构