内核版本: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. Netty里的设计模式

    最近在撸 Netty 源码,发现了一些模式,顺手做个笔记. 分析版本是4.0 1. 构造器模式 ServerBootstrap 和 Bootstrap 的构建 2. 责任链设计模式 pipeline ...

  2. Git 如何只更新项目中某个目录里的文件

    Git由于在远端和本地都有一个代码库, 这样更新单个文件比SVN要麻烦一点.   1. 如果想拿远端git服务器上的最新版本(或某个特定版本)覆盖本地的修改,可以使用git pull命令,   但这会 ...

  3. Sicily 1048: Inverso(BFS)

    题意是给出一个3*3的黑白网格,每点击其中一格就会使某些格子的颜色发生转变,求达到目标状态网格的操作.可用BFS搜索解答,用vector储存每次的操作 #include<bits/stdc++. ...

  4. PSD文件在MAC上和在WINDOWS上的大小有本质区别

    因为偷懒在MAC上的美工,发我的PSD文件,我就直接在上面做了= =后来不知道为什么无论我怎么合并图层.PSD的大小永远都是107M....然后忍无可忍重新画就从107M变成2M.....MAC为什么 ...

  5. Java字节流和字符流区别

    1.字节流:直接操作文件本身. 2.字符流:通过缓冲区来操作文件. 所有的文件在硬盘或在传输时都是以字节的方式进行的,包括图片等都是按字节的方式存储的,而字符是只有在内存中才会形成,所以在开发中,字节 ...

  6. 循环冗余码crc

    待编码的有效信息组多项式:M(x) 生成多项式(产生校验码的多项式):G(x) 余数多项式:R(x) 商:Q(x) 生成多项式是四次的,所以某个多项式除以生成多项式的余式肯定是三次的,所以要加四位00 ...

  7. Android studio 英文——中文 翻译插件

    TranslationPlugin 1.手动下载 TranslationPlugin ,在Android studio 中 2. 3. 4.选中文件,点击OK 5.设置快捷键 代号1 : 代号2 :

  8. 安装yum

    RedHat 安装配置 YUM 删除 1 . 查询系统是否安装 yum : rpm – qa|grep yum 2删除原有 yum rpm -qa|grep yum|xargs rpm -e – no ...

  9. js三级地区联动

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head ...

  10. access基本操作(c#操作,远程连接,执行sql,加密,备份)

    前言 最近项目用到了access,是的就是access,工作在桌面型的小数据库应用还是会用到的,如果你确定永远不会遇到access的操作,请忽略此篇文章 1.vs配置access 既然是数据库,就少不 ...