转:http://blog.csdn.net/adamska0104/article/details/45397177

Linux内核网络报文简单流程2014-08-12 10:05:09

分类: Linux

linux下的网卡驱动中通常会提供类似XXX_rx的接收函数

该函数处理与具体硬件相关的寄存器操作

包括中断检查,数据状态检查,错误检查等

在确认有数据抵达后读取数据或从DMA的接收环中获取数据地址

XXX_rx函数以skb为元数据结构组织报文数据

随后调用内核接口函数netif_rx或netif_receive_skb

这里会涉及到软中断的处理,NAPI的接收方式

但是最后都会走netif_receive_skb函数

现在内核中使用了RPS机制

将报文分散到各个cpu的接收队列中进行负载均衡处理

在netif_receive_skb函数中进行了封装

真正的数据处理从__netif_receive_skb_core函数开始

现在可以将该函数视为协议栈的入口函数

首先进行skb中报文头元数据的调整

如果是vlan报文则先从数据中提取至vlan_tci字段

将vlan标签的4个字节从数据移除

即在调用deliver_skb向上层传递报文数据时不含vlan标签

ptype_all链表的处理主要用于抓包

在应用程序中注册PF_PACKET族ETH_P_ALL的socket便可以得到所有的输入报文

也可以用于实现自定义的协议类型报文收发

随后内核会丢弃无法识别的报文

也可以在内核模块中使用dev_add_pack向ptype_all注册自定义的处理函数

如果接口上配置了输入流控

则根据具体的队列和分类规则决定继续处理或丢弃报文

对于vlan数据报文

将skb记录的输入接口修改为vlan虚接口

比如使用vconfig配置的eth0.100虚接口

再重复上述处理

内核提供了netdev_rx_handler_register接口函数向接口注册rx_handler

比如为网桥下的接口注册br_handle_frame函数

为bonding接口注册bond_handle_frame函数

这相对于老式的网桥处理更灵活

有了这个机制也可以在模块中自行注册处理函数

网桥的处理包括向上层提交和转发

发往本地的报文会修改入接口为网桥虚接口如br0

调用netif_receive_skb重新进入协议栈处理

对于上层协议栈见到的只有桥虚接口

需要转发的报文根据转发表进行单播或广播发送

netfilter在网桥的处理路径中从br_handle_frame到br_dev_queue_push_xmit设置了5个hook点

根据nf_call_iptables的配置还会经过NFPROTO_IPV4的hook点等

内核注册的由br_nf_ops数组中定义

可在模块中自行向NFPROTO_BRIDGE族的几个hook点注册函数

ebtables在netfilter框架NFPROTO_BRIDGE中实现了桥二层过滤机制

配合应用程序ebtables可在桥下自定义相关规则

处理完接口上的rx_handler后便根据具体的3层协议类型在ptype_base中寻找处理函数

比如ETH_P_IP则调用ip_rcv,ETH_P_IPV6则调用ipv6_rcv

这些函数都由dev_add_pack注册

可在模块中自定义协议类型处理函数

如果重复定义相同协议的处理函数则要注意报文的修改对后续流程的影响

IP报文进入ip_rcv后进行简单的检查便进入路由选择

根据路由查找结果调用ip_local_deliver向上层提交或调用ip_forward进行转发

向上层提交前会进行IP分片的重组

在ip_local_deliver_finish中会根据报文中4层协议类型调用对应的处理函数

处理函数由接口函数inet_add_protocol注册

针对TCP或UDP进行不同处理,最后唤醒应用程序接收数据

向外发送和转发数据经由ip_output函数

包括IP的分片,ARP学习,MAC地址的修改或填充等

netfilter在从ip_rcv到ip_output间设置了5个hook点

向各个点的链表中注册处理函数或使用iptables工具自定义规则

实现报文处理的行为控制

报文的发送最后汇聚到队列发送函数dev_queue_xmit

在接口up的时候dev_activate会创建默认的队列规则

这里也涉及到接口驱动初始化的时候软件多队列与硬件多队列

配合tc工具可以在报文发送前进行流量控制等

最终报文发送到dev_hard_start_xmit调用接口注册的动作函数ndo_start_xmit

发送前会检查ptype_all链表,支持抓包处理等

如果是虚拟接口则通常调用其对应物理接口的发送函数

到这里内核对报文的控制便结束了

根据不同网卡驱动的实现,操作寄存器等由物理层将数据发送出去

整个调用链相对较长

每个点都包含大量的细节

主线都是围绕元数据结构skb的处理

Linux内核网络报文简单流程的更多相关文章

  1. Linux内核网络数据包处理流程

    Linux内核网络数据包处理流程 from kernel-4.9: 0. Linux内核网络数据包处理流程 - 网络硬件 网卡工作在物理层和数据链路层,主要由PHY/MAC芯片.Tx/Rx FIFO. ...

  2. Linux内核--网络栈实现分析(一)--网络栈初始化

    本文分析基于内核Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7488828 更多请看专栏, ...

  3. Linux内核--网络栈实现分析(一)--网络栈初始化--转

    转载地址 http://blog.csdn.net/yming0221/article/details/7488828 作者:闫明 本文分析基于内核Linux Kernel 1.2.13 以后的系列博 ...

  4. Linux内核--网络栈实现分析(三)--驱动程序层+链路层(上)

    本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7497260 更多请看专栏,地址 ...

  5. Linux内核--网络栈实现分析(二)--数据包的传递过程--转

    转载地址http://blog.csdn.net/yming0221/article/details/7492423 作者:闫明 本文分析基于Linux Kernel 1.2.13 注:标题中的”(上 ...

  6. Linux内核--网络栈实现分析(十一)--驱动程序层(下)

    本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7555870 更多请查看专栏,地 ...

  7. Linux内核--网络栈实现分析(七)--数据包的传递过程(下)

    本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7545855 更多请查看专栏,地 ...

  8. Linux 内核 链表 的简单模拟(2)

    接上一篇Linux 内核 链表 的简单模拟(1) 第五章:Linux内核链表的遍历 /** * list_for_each - iterate over a list * @pos: the & ...

  9. Linux 内核 链表 的简单模拟(1)

    第零章:扯扯淡 出一个有意思的题目:用一个宏定义FIND求一个结构体struct里某个变量相对struc的编移量,如 struct student { int a; //FIND(struct stu ...

随机推荐

  1. SQL server中获取语句执行时间

    在写代码的时候,有时候实现一个功能会有好多个方法,有时候会做一下方法的耗时对比,综合下时间复杂度与空间复杂度,写出最好的代码: 同样,在写一些SQL查询,SQL代码的时候,也希望能写出一个高效一点的查 ...

  2. Spring MVC的多视图解析器配置及与Freemarker的集成

    一.从freemarker谈起 Freemarker使用模板技术进行视图的渲染.自从看了Struts标签.Freemarker.JSTL的性能对比后,我毅然决定放弃Struts标签了!效率太差…… S ...

  3. Centos7.2 MQTT的学习之Mosquitto搭建&集群搭建&使用

    下载安装包http://mosquitto.org/files/source/ 安装依赖yum install -y gcc gcc-c++ libstdc++-develyum install -y ...

  4. Linux下Apache虚拟主机配置

    Linux下Apache虚拟主机的三种配置.这样可以实现一台主机架构多个独立域名网站.其中基于域名的最为常见.性价比也最高.下面PHP程序员雷雪松详细的讲解下Linux下Apache虚拟主机配置的具体 ...

  5. 【18.065】Lecture1

    由于这一课的教材放出来了,所以直接将整个pdf放上来.   

  6. 【AMAD】django-cities -- 为Django项目提供国家,城市数据

    动机 简介 个人评分 动机 有时候看一些数据库设计,国家数据会存在一个单独的表里面.这种方式读取数据库无疑又要加上一层join,很不划算. 简介 [django-cities]1可用为你提供国家和城市 ...

  7. day34 并行并发、进程开启、僵尸及孤儿进程

    day34 并行并发.进程开启.僵尸及孤儿进程 1.并行与并发 什么是并行? 并行指的是多个进程同时被执行,是真正意义上的同时 什么是并发? 并发指的是多个程序看上去被同时执行,这是因为cpu在多个程 ...

  8. Linux特殊权限位suid、sgid深度详细及实践

    特殊权限位基本说明: Linux系统基本权限位为9位权限,但还有额外3位权限位,共12位权限: suid    s(有x)     S    4   用户对应的权限位(用户对应的3位上) sgid  ...

  9. 第六周&java实验报告四

    实验报告: 一.实验目的 (1)掌握类的继承 (2)变量的继承和覆盖,方法的继承,重载和覆盖的实现: 二.实验的内容 (1)根据下面的要求实现圆类Circle. 1.圆类Circle的成员变量:rad ...

  10. React生命周期使用

    组件的生命周期可分成三个状态: Mounting:已插入真实 DOM Updating:正在被重新渲染 Unmounting:已移出真实 DOM 生命周期的方法有: componentWillMoun ...