内核版本:linux-2.6.11


本文对Linux网络子系统的收发包的流程进行一个大致梳理,以流水账的形式记录从应用层write一个socket开始到这些数据被应用层read出来的这个过程中linux的网络子系统怎么运作的。
PS:不能保证所有内容都是正确的,同时欢迎指出问题。

发包流程

1)用户进程对一个网络套接字执行write或者send后,该进程通过系统调用进入内核态。

2)在socket这层最终会通过调用sendmsg这个函数将数据传给传输层(这里涉及到使用一个多态的手法来实现不同协议的调用)。

3)接着自顶向下走协议栈的处理流程,以TCP协议为例,tcp_sendmsg作为这个函数接受到发送数据以后将其包装成sk_buff并进行协议处理,包括分组、添加头部、启动定时器等等。

4)传输层处理完以后的包会进入netfilter的NF_IP_LOCAL_OUT hook点。

5)然后将一个个sk_buff传给网络层,如果是IP协议,会进行分片、添加头部、路由判决等操作。同时会进入netfilter的NF_IP_POST_ROUTING点

6)最后,网络层通过调用dev_queue_xmit将处理完并包装好的sk_buff发给驱动程序。
此时,无论是阻塞还是非阻塞模式,write系统调用都会返回,该进程的任务结束。

7)驱动程序在接受到一个待发送的skb后,会选择将其直接从网卡发出或者加入发送队列。

8)最终,软中断NET_TX_SOFTIRQ的处理程序会将发送队列里的包由网卡发出。

收包流程

1)网卡接收到一个数据包后,会向CPU发起一个硬件中断,该中断处理程序由网卡驱动实现。

2)中断上半部会为这个新来的数据包分配合适大小的skb,并将这个数据包从网卡的缓存中拷贝到内存。最后触发中断下半部继续处理。

3)网卡中断的下半部由软中断softirq实现,NET_RX_SOFTIRQ的处理程序将会被触发,这个处理程序会开始自底向上的协议栈处理。

4)网络层收到包后会先判断是否有原始套接字的监听,然后进入netfilter的NF_IP_PRE_ROUTEING hook点。
(libpcap等抓包程序一般都是使用SOCK_PACKET套接字实现,在NF_IP_PREROUTEING点之前就被获取了的。然而libpcap对收到的包只能监测不能修改,netfilter可以对其做生死判决)

5)进行路由判决,如果是目的是本机,进入netfilter的NF_IP_LOCAL_IN hook点,如果目的不是本地且需要对其进行转发,并进入netfilter的NF_IP_FORWARDING hook点。

6)目的为本机的包将继续向上传给传输层,如果是TCP包,将进行重组,并将数据存入socket的缓冲区。

7)此时如果有一个应用进程正在read这个socket或者阻塞在read这个socket上,将会将其唤醒并把缓冲区的数据从内核拷贝到用户态的buff里。read系统调用由此返回。

补充一点细节:
当进行大流量的网络通信的时候,发包软中断和收包软中断本身还可以重新触发自己以得到再次执行。
但是由于这样会导致用户态进程饥饿,于是作为改进,当大量软中断出现的时候,内核会唤醒内核线程ksoftirqd来处理这些负载。
发包中断和收包中断的处理程序有可能在在软中断触发执行的任何地方执行。包括中断返回时、网络子系统主动触发或者被ksoftirqd强制线程化。

Linux内核笔记--网络子系统初探的更多相关文章

  1. Linux内核笔记--内存管理之用户态进程内存分配

    内核版本:linux-2.6.11 Linux在加载一个可执行程序的时候做了种种复杂的工作,内存分配是其中非常重要的一环,作为一个linux程序员必然会想要知道这个过程到底是怎么样的,内核源码会告诉你 ...

  2. 【转载】linux内核笔记之进程地址空间

    原文:linux内核笔记之进程地址空间 进程的地址空间由允许进程使用的全部线性地址组成,在32位系统中为0~3GB,每个进程看到的线性地址集合是不同的. 内核通过线性区的资源(数据结构)来表示线性地址 ...

  3. 【转载】linux内核笔记之高端内存映射

    原文:linux内核笔记之高端内存映射 在32位的系统上,内核使用第3GB~第4GB的线性地址空间,共1GB大小.内核将其中的前896MB与物理内存的0~896MB进行直接映射,即线性映射,将剩余的1 ...

  4. Linux内核分析 - 网络[十四]:IP选项

    Linux内核分析 - 网络[十四]:IP选项 标签: linux内核网络structsocketdst 2012-04-25 17:14 5639人阅读 评论(1) 收藏 举报  分类: 内核协议栈 ...

  5. Linux内核中网络数据包的接收-第一部分 概念和框架

    与网络数据包的发送不同,网络收包是异步的的.由于你不确定谁会在什么时候突然发一个网络包给你.因此这个网络收包逻辑事实上包括两件事:1.数据包到来后的通知2.收到通知并从数据包中获取数据这两件事发生在协 ...

  6. Linux内核之网络

    应用层: 套接字将Unix一切都是内核的概念应用到网络连接中,内核跟用户空间套接字之间的接口实现在c的标准库中,使用了socketcall系统调用. socketcall充当了一个多路分解器,将各种任 ...

  7. Linux内核简介、子系统及分类

    一.内核简介 内核:在计算机科学中是一个用来管理软件发出的数据I/O(输入与输出)要求的计算机程序,将这些要求转译为数据处理的指令并交由中央处理器(CPU)及计算机中其他电子组件进行处理,是现代操作系 ...

  8. Linux内核内存管理子系统分析【转】

    本文转载自:http://blog.csdn.net/coding__madman/article/details/51298718 版权声明:本文为博主原创文章,未经博主允许不得转载. 还是那张熟悉 ...

  9. Linux内核之mmc子系统-sdio

    现在的Linux内核中,mmc不仅是一个驱动,而是一个子系统.这里通过分析Linux3.2.0内核,结合TI的arm335x平台及omap_hsmmcd host分析下mmc子系统,重点关注sdio及 ...

随机推荐

  1. 百度地图API 批量添加 带检索功能的信息窗口

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. robotframework,selenium启动不了打不开浏览器的问题访问不了网页

    由于最近发现咨询火狐浏览器打不开的问题比较多,现罗列几点解决办法. 1,由于selenium更新3.0的原因导致不在默认支持火狐浏览器,且支持的火狐浏览器大概在45以上的版本,所以很多都由于这个原因导 ...

  3. 【Python图像】给你的头像+1

    早些年,微信朋友圈有段时间非常流行这个头像+1的套路,简直逼死强迫症. 将你的 QQ 头像(或者微博头像)右上角加上红色的数字,类似于微信未读信息数量那种提示效果. 类似于图中效果 涉及知识: Pyt ...

  4. PHP 数据库连接工具类(MySQLI函数包装)

    ====================mysql===================== <?php class mysql { private $mysqli; private $resu ...

  5. Oracle的动态性能视图[持续更新]

    前言 .... v$version:查看数据库版本 其中 Oracle Database:指代数据库版本 PL/SQL:ORACLE对于标准SQL的超集,全称Procedural Language/S ...

  6. PHP 查看安装信息

    1.运行PHP脚本,查看phpinfo函数的输出. 2.在系统环境变量Path中配好php.exe可执行文件的路径,命令管理器CMD中,执行`php.exe -i`查看. 3.在phpinfo()的输 ...

  7. java 保留字符串数字的位数,不够前面补0

    @Test public void test() { this.printToConsole(autoGenericCode("10011")); this.printToCons ...

  8. Firefox Portable Developer 52.0.0.6176-6178

    FirefoxPortableDeveloper-52.0.0.6176.7z 47.9 MB FirefoxPortableDeveloper-52.0.0.6178.7z 55.8 MB

  9. java 简单使用redis

    1.配置文件 <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig" ...

  10. heightcharts

    title:标题 subtitle:子标题 data:eval(dataList)//数据格式转换