最近研究了linux内核的网络子系统上的网络分组的接收与发送的流程,发现这个叫sk_buff的东西无处不在,内核利用了这个结构来管理分组,在各个层中传递这个结构,因此sk_buff可以说是linux内核网络子系统的基石,所以我决定在这篇文章中好好扒一扒这个sk_buff。

  下面列出我我认为比较重要的sk_buff中的成员变量:

  内核是利用一个双链表来管理sk_buff的,不过不使用内核的标准双链表而是自己实现了双链表:

struct sk_buff *next;
struct sk_buff *prev;

struct sock *sk是sk_buff关联的socket

ktime_t tstamp是分组到达的时间

struct net_device *dev是相关联的网络硬件设备

struct  dst_entry *dst这个成员很重要,分组在ip层处理时sk_buff会被传入一个ip_route_input函数中,这个函数会判断这个分组是要在本地接收呢还是要转发出去,这时函数就会填充这个dst成员让其内的成员来代表目的地,例如:

struct dst_entry

{

……

int (*input)(struct sk_buff*);
int (*output)(struct sk_buff*);

}; 在接收分组时input被填充为ip_local_deliver或ip_forward,在发送分组时被填充为ip_output

内核会分配一块内存来存储sk_buff,head和end指示了这块内存的头和尾,data和tail则指示了这块内存中具体的数据的头和尾

mac_header、network_header和transport_header分别指向了分组的mac、ip和tcp(或udp)首部

  内核在利用sk_buff管理分组时是利用了sk_buff里的指针成员来指向分组的不同部分,这样有一个好处就是在传递该分组时不用复制整个分组而是在整个分组发送与接收过程中传递sk_buff指针即可,节省了复制分组的开销。再一个就是内核在解包和组包时只需要调整sk_buff的指针就可以了,例如要在TCP首部前增加IP首部只需要在预分配的内存里拿出一小块内存在存放IP首部,再将network_header指向那个小块内存即可,注意拿出的小块内存是在TCP首部内存之前的,两者紧密相连。

  最后来看看内核管理sk_buff的双链表吧:

sk_buff_head为链表的头,链表为双向循环链表,next指向了下一个sk_buff,prev指向了最后一个sk_buff,qlen保存了链表的sk_buff个数

linux2.6.24内核源代码分析(1)——扒一扒sk_buff的更多相关文章

  1. linux2.6.24内核源代码分析(2)——扒一扒网络数据包在链路层的流向路径之一

    在2.6.24内核中链路层接收网络数据包出现了两种方法,第一种是传统方法,利用中断来接收网络数据包,适用于低速设备:第二种是New Api(简称NAPI)方法,利用了中断+轮询的方法来接收网络数据包, ...

  2. Suse环境下编译linux-2.6.24内核

    Suse环境下编译linux-2.6.24内核 1.下载linux-2.6.24内核源码: https://mirrors.edge.kernel.org/pub/linux/kernel/v2.6/ ...

  3. Linux内核源代码分析方法

    Linux内核源代码分析方法   一.内核源代码之我见 Linux内核代码的庞大令不少人"望而生畏",也正由于如此,使得人们对Linux的了解仅处于泛泛的层次.假设想透析Linux ...

  4. 《LINUX3.0内核源代码分析》第二章:中断和异常 【转】

    转自:http://blog.chinaunix.net/uid-25845340-id-2982887.html 摘要:第二章主要讲述linux如何处理ARM cortex A9多核处理器的中断.异 ...

  5. Linux-0.11内核源代码分析系列:内存管理get_free_page()函数分析

    Linux-0.11内存管理模块是源码中比較难以理解的部分,如今把笔者个人的理解发表 先发Linux-0.11内核内存管理get_free_page()函数分析 有时间再写其它函数或者文件的:) /* ...

  6. ARMv8 Linux内核源代码分析:__flush_dcache_all()

    1.1 /* *  __flush_dcache_all() *  Flush the wholeD-cache. * Corrupted registers: x0-x7, x9-x11 */ EN ...

  7. Linux 内核源代码分析 chap 2 存储管理 (5)

    物理页面分配 linux 内核 2.4 中有 2 个版本号的物理页面分配函数 alloc_pages(). 一个在 mm/numa.c 中, 还有一个在 mm/page_alloc.c 中, 依据条件 ...

  8. linux 内核源代码分析 - 获取数组的大小

    #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 測试程序: #include<stdio.h> #include<stdlib. ...

  9. Linux内核源代码情景分析系列

    http://blog.sina.com.cn/s/blog_6b94d5680101vfqv.html Linux内核源代码情景分析---第五章 文件系统  5.1 概述 构成一个操作系统最重要的就 ...

随机推荐

  1. Javascript设置广告和时间表和数组的学习

    <html> <head> <meta charset="utf-8"> <title></title> </he ...

  2. MyEclipse8.6中提交SVN报错

    上周五(11月27日)的时候,从TortoiseSVN提交项目报错,然后直接从MyEclipse中检出来,修改后提交同样报错. MyEclipse8.6中提交SVN报错,错误提示如下: commit ...

  3. iOS开发拓展篇——如何把项目托管到GitHub

    iOS开发拓展篇——如何把项目托管到GitHub 说明:本文主要介绍如何把一个OC项目托管到Github,重操作轻理论. 第一步:先注册一个Github的账号,这是必须的 注册地址:Github官网注 ...

  4. 正在开发纯BS的可在线编辑内容的电子病历编辑器

    在线电子病历编辑器功能预览,支持Firefox/Chrome/Opera/UC/IE/Safari.演示地址 http://www.dcwriter.cn:9090/ 在WINFORM.NET中的效果 ...

  5. TexturePacker压缩png的命令

    压缩png效果最好的当然是TinyPNG这种神器了,不过一般情况下TexturePacker压缩出来的也基本上能达到效果. 你需要先安装TP(TexturePacker的简称,以下TP无特殊说明均指T ...

  6. 新建一个Activity

    如果只是新建一个class,还得自己添加XML,好不麻烦: eclipse里可以直接new other Andriod activity,ADT还是很强发滴.哈哈.

  7. Windows 7 中设置VPN(PPTP连接方式)

    第一步:打开控制面板-网络和共享中心(如图) 第二步:点击-设置新的连接或网络(如图) 第三步:选择-连接到工作区-下一步(如图) 第四步:如果已经存在其他连接,则在这一步选择”否,创建新连接“:如果 ...

  8. MySQL – 导出数据成csv

    方案有很多种,我这里简单说一下: 1.  into outfile SELECT * FROM mytable INTO OUTFILE '/tmp/mytable.csv' FIELDS TERMI ...

  9. Intellij IDEA 14的注册机

    将以下代码保存成keygen.java import java.math.BigInteger; import java.util.Date; import java.util.Random; imp ...

  10. Oracle Goldengate REPLICAT启动时报正在运行解决办法

    stop replicate时报ERROR: opening port for REPLICAT MYREP (TCP/IP error: Connection refused). start rep ...