内核版本: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. DuBrute 3.1

    PS:转载自小残博客. 今天发现时隔很久的DuBrute竟然更新了,为此我在分享给大家,软件我没测试效果,使用过的朋友或许很清楚,不会太差! 曾几何时,小残也在用DUbrute爆破工具,且玩的不亦乐乎 ...

  2. Repeater、地址栏传值、Response--2016年12月30日

    Repeater  Repeater支持以下5种模板       ● ItemTemplate : 对每一个数据项进行格式设置 [Formats each item from the data sou ...

  3. Oracle:试图访问正在使用的事务临时表

    处理步骤为 1.找到表ID select * from dba_objects where object_name like 'TPT_RPWORPA1_QRY' 2.通过表ID查找正在使用的事务 s ...

  4. 乐校园单车项目第一天——购买Apple开发者账号、创建SVN

    日常三问: 1. 我应该干什么? 2. 我能干什么? 3. 我想干什么?

  5. Activity系列讲解---返回结果的处理

    设想一下:由当前Activity跳转到其它Activity,从其它Activity再返回到当前Activity时,如何获取其它Activity存放的数据?下面用一个例子讲解, 点击selsect按钮跳 ...

  6. 读一篇Javascript问题贴的收获

    遇到这篇文章<Javascript异步调用时,回调函数内用到了函数外的变量>,是缘于我在<难道这就是JavaScript中的"闭包">文章中遇到的问题时,B ...

  7. java享元模式(flyweight)

    有个问题: Integer i1 = 12; Integer i2 = 12; System.out.println(i1 == i2);//输出true Integer i1 = 130; Inte ...

  8. 如何在Linux中搭建禅道8.4.1(httpd+php+mysql)

    1.安装httpd 命令:yum install httpd 然后一路y即可 2.安装php 命令:yum install php   3.安装php-mysql 命令:yum install php ...

  9. svn上传工程之后下载,打开下载之后的工程缺少文件

    当我们把iOS的工程上传到SVN中,当我们再从SVN中下载下来,就会出现错误,这是什么原因呢?我这里出现的错误是找不到文件,后来知道原来是被屏蔽掉了,就是上传的时候不上传某个类型的文件.例如我出错就是 ...

  10. 2. Add Two Numbers——Python

    题目: You are given two linked lists representing two non-negative numbers. The digits are stored in r ...