Linux内核接收报文流程学习

1、关键数据结构

struct sk_buff{

....

}

1.1 嵌套字缓冲区

一个数据封包就存储在这里,所有网络分层都会使用这个结构来存储其报头、有关的用户数据信息(有效载荷),以及用来协调其工作的其他内部信息。

当该结构从一个分层由上至下传到另一个分层时,其不同的字段会随之发生变化,在首部附加上该层自己的报头。

附加报头比起在分层之间拷贝更有效率

附加报头就要在缓冲区开端新增空间,也就是要改变指向该缓冲区的变量,内核提供了skb_reserve()函数,为该协议的报头预留空间。

当缓冲区由下至上传经各个网络分层时,每个源自旧分层的报头就不再有用处,把指向有效载荷的指针向前移动到上层报头的开端。

1.2 布局字段

内核在一个双向链表中维护所有的sk_buff结构,但是该表的组织逼传统的双向链表更为复杂

每个sk_buff结构必须能够迅速找出这个表的头,在表的开端额外增加一个sk_buff_head结构作为一种哑元元素

struct sk_buff_head{
        /* 这两个成员必须在最前 */
        struct sk_buff    *next;
        struct sk_buff    *prev;

        __u32              qlen;  //代表表中元素的数目
        spinlock_t         lock;  //用于防止对表的并发访问
}

1.3 缓冲区的克隆和拷贝

当同一个缓冲区需要由不同消费者个别处理时,那些消费者可能需要修改sk_buff扫描符的内容(指向协议报头的h和nh指针),但内核不需要完全拷贝sk_buff结构和相关联的数据缓冲区。

为了提高效率,内核可以克隆(clone)原始值,也就是只拷贝sk_buff结构,然后使用引用计数,以避免过早释放共享的数据块。缓冲区的克隆由skb_clone函数实现。

2、网络接口

2.1 网络接口的命名

  • eth0: ethernet的简写,一般用于以太网接口
  • wifi0: wifi是无线局域网,因此wifi0一般指无线网络接口
  • ath0: Atheros的简写,一般指Atheros芯片所包含的无线网络接口
  • lo: local的简写,一般指本地环回接口

2.2 网络接口如何工作

网络接口是用来发送和接收数据包的基本设备。系统中所有网络接口组成一盒连撞节后,应用层程序使用时按名称调用。每个网络接口在linux系统中对应一个struct net_device结构体,包含name,mac,mask,mtu...信息。每个硬件网卡(一个MAC)对应一个网络接口,其工作完全由相应的驱动程序控制。

2.3 虚拟网络接口

虚拟网络接口的应用范围非常广泛,最著名的是“lo”,基本上每个linux系统都有这个接口

虚拟网络接口并不真实地从外界接收和发送数据包,而是在系统内部接受和发送数据包,因此虚拟网络接口不需要驱动程序。虚拟网络接口和真实存在的网络接口在使用上是一致的

硬件网卡的网络接口由驱动程序创建,而虚拟的网络接口由系统创建货通过应用层程序创建

2.4 linux中的lo(回环接口)

用于本地进程间数据包通信的虚拟网络接口

在linux系统中,除了网络接口eth0,还可以有别的接口,比如lo(本地环路接口)

假如包是由一个本地进程为另一个进程产生的,他们将通过外出链的“lo”接口,具体参考包过滤器的相关内容

负责接收帧的代码分成两部分:首先,驱动程序把该帧拷贝到内核可访问的输入队列,然后内核在予以处理,通常是把把那个帧传给一个相关协议(如IP)专用的处理函数。第一部分会在中断环境中执行,而且可以抢占第二部分的执行。接收输入帧并将其拷贝到队列的代码比实际处理帧的代码的优先级要高。

接收-活锁(receive-livelock)

在高流量负载下,中断代码会持续抢占正在处理的代码。输入队列已满,但是由于应该让帧退出队列并予以处理的代码的优先级过低而没有机会执行,结果系统就崩溃了。新的帧无法排入队列,而旧的帧无法被处理

通常的Linux报文处理方式中,报文分组到达内核,触发设备中断,中断处理程序为新报文创建套接字缓冲区,分组内容以DMA的方式从网卡传输到缓冲区中指向的物理内存。然后内核分析新报文的首部,此时报文处理已由网卡驱动代码转到网络层的通用接口,同时该函数将接收的报文送入特定的CPU等待队列中,触发该CPU的NET_RX_SOFTIRQ软中断,并且退出中断上下文。特定CPU的NET_RX_SOFTIRQ软中断处理对应等待队列中的报文的嵌套字缓冲区。

正式由此开始协议栈之旅:由netif_receive_skb分析报文类型,skb_buff结构经过网络层报文分类和分别处理(解析、分片重组等)进入传输层,由传输层进一步处理,最后用户空间应用程序通过socket API调用获取报文内容,亦或是由自定义的内核模块获取报文进行处理转发或统计。自定义内核模块可在协议栈多个点通过不同方式获取报文,如netfilter方式。

屏幕快照 2016-11-28 上午10.06.49.png

DPDK支持Run to Completion和Pipeline两种报文处理模式,用户可以依据需求灵活选择,或者混合使用。Run to Completion是一种水平调度方式,利用网卡的多队列,将报文分发给多个CPU核处理,每个核均独立处理到达该队列的报文,资源分配相对固定,减少了报文在核间的传递开销,可以随着核的数目灵活扩展处理能力; Pipeline模式则通过共享环在核间传递数据报文或消息,将系统处理任务分解到不同的CPU核上处理, 通过任务分发来减少处理等待时延。

3、原始套接字SOCK_RAW

我们常用的网络编程都是在应用层的报文首发操作,大多数接触到的流式套接字SOCK_STREAM和数据包套接字SOCK_DGRAM。而哲学数据包都是由系统提供的协议栈实现,用户只需要填充应用层报文即可,由系统完成底层报文头的填充并发送。

然而在某些情况下需要执行更底层的操作,比如修改报文头,避开系统协议栈等,这个时候就需要使用其他方法来实现。

SOCK_RAW实现于系统核心,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以,其次,SOCK_RAW也可以处理特殊的IPv4报文。总体来说,SOCK_RAW可以处理普通的网络报文之外,还可以处理一些特殊协议报文以及操作IP层及其以上的数据。

原始套接字可以用来自行组装IP数据包,然后将数据包发送到其他终端。必须在管理员权限下才能使用原始套接字,这么做可以防止普通用户往网络写出他们自行构造的IP数据报。

3.1、原始套接字的输入

  • 接收到的UDP或者TCP分组绝不传递到任何原始套接字,如果一个进程想要读取含有UDP分组或TCP分组的IP数据报,它就必须在数据链路层读取这些分组
  • 如果某个数据报以片段形式到达,那么在它的所有片段均到达且重组出改数据报之前,不传递任何分组到原始套接字。

4、NAPI

为了处理驱动程序使用NAPI接口的设备,有四个新字段添加到net_device数据结构中以供软中断使用。

  • poll
    这个虚函数可用于把缓冲区从设备的输入队列中退出,此队列时使用NAPI设备的私有队列。而softnet_data->input_pkt_queue供其他设备使用。

  • poll_list
    这是设备列表,列表中的设备就是在入口队列中有等待被处理的新帧的设备。这些设备就是所谓的处于轮询状态

  • quota
    配额是一个整数,代表的是poll虚函数一次可以从队列推出缓冲区的最大数目。配额越低,表示潜在的延时越低,因此让其他设备饿死的风险就越低。另一方面,低配额会增加设备间的切换量,因此整体的耗费会增加。

  • weight
    quota值的增加以weight为单位,用于在不同设备之间施加某种公平性。

5、

5.1 netif_rx

当新的输入帧正等待处理时,设备驱动程序通常是调用定义在net/core/dev.c中的netif_rx函数。此函数的工作是为短暂执行的软IRQ(把帧退出队列然后予以处理)调度

netif_rx通常是在中断环境下被驱动程序调用,netif_rx在其启动时会关闭本地CPU的中断事件,然后当其完成工作时回再予以重新开启

5.2 softnet_data

每个CPU都有其队列,用来接收进来的帧,因为每个CPU都有其数据结构处理入口和出口流量,因此,不同CPU之间没有必要使用上锁机制。此队列的数据结构softnet_data就定义在include/linux/netdevice.h

struct softnet_data
{
    int                  throttle;
    int                  cng_level;
    struct sk_buff_head  input_pkt_queue;
    struct list_head     poll_list;
    struct net_device    *output_queue;
    struct sk_buff       *completion_queue;
    struct net_device    backlog_dev;
}

此结构的字段可用于接收和传输,换而言之,NET_RX_SOFTIRQNET_TX_SOFTIRQ软IRQ都引用此数据结构。入口帧会排入input_pkt_queue ,而出口队列会放入由流量控制(QoS层)所处理的特殊队列(而不是由软IRQ和softnet_data结构所处理)

  • throttle
    布尔变量,超负载为真,否则为假。其值依赖于input_pkt_queue中帧的数目,当其置位时,此CPU接收到的数据帧全部丢弃
  • avg_blog
    代表input_pkt_queue队列长度加权后的平均值,可用于计算cng_level
  • cng_level
    代表拥塞等级

这三个参数有拥塞管理算法使用,默认每接收一个帧这三个字段都会被更新。与CPU相关,因此可用于非NAPI设备,共享每个CPU所用的队列input_pkt_queue

  • input_pkt_queue
    这个队列(在net_dev_init中初始化)用来保存进来的帧(被驱动程序处理前)

  • backlog_dev
    是一个完整的嵌入式数据结构,不只是一个指针,类型为net_device,代表着一个设备已在相关联的CPU上为net_rx_action调度以准备执行。这个字段是由非NAPI驱动程序使用,称为积压设备。

  • poll_list
    一个双向列表,其中的设备都带有输入帧等着被处理

  • output_queue / completion_queue
    output_queue是设备列表,其中的设备有数据要传输。completion_queue是缓冲区列表,其中的缓冲区已经成功传输,因此可以释放掉

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,311评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,339评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,671评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,252评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,253评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,031评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,340评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,973评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,466评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,937评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,039评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,701评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,254评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,259评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,497评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,786评论 2 345

推荐阅读更多精彩内容

  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,869评论 6 13
  • 非原创文章,网络收集,如遇原作者,请私聊会标明出处! 1--11 tcp协议中三次握手和四次挥手建立TCP需要三次...
    Juinjonn阅读 2,155评论 0 28
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,184评论 11 349
  • 以前听多了在一线城市的姑娘大多耽搁了最好的年纪,成为剩女,因为她们挑来挑去,从而错过了最佳婚育年龄,直到自己也成为...
    小小美人阅读 252评论 0 0
  • 我本向云霄,欲抵九重天 奈何落凡尘,徒为朽木枝
    cj的蓝蓝阅读 222评论 0 1