最近研究了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. bzoj 1637: [Usaco2007 Mar]Balanced Lineup

    1637: [Usaco2007 Mar]Balanced Lineup Time Limit: 5 Sec  Memory Limit: 64 MB Description Farmer John ...

  2. 10TSQL语言概述-脚本调试-命名规范-天轰穿数据库2014

    关键字:sqlserver 数据库脚本 数据库 编码规范大纲:sql概念,TSQL脚本调试,数据库编码规范 优酷超清地址 腾讯超清地址 土豆超清地址

  3. MongoDB与Mysql常用命令解释

    原文 本文旨在介绍MongoDB,Mysql的常用命令:将MongoDB 和传统的关系型数据库的常用命令对照起来学习,更加便于记忆和理解. MongoDB是由数据库(database/reposito ...

  4. Log4cpp介绍及使用

    Log4cpp是一个开源的C++类库,它提供了在C++程序中使用日志和跟踪调试的功能.使用log4cpp,可以很便利地将日志或者跟踪调试信息写入字符流.内存字符串队列.文件.回滚文件.调试器.Wind ...

  5. .net下BerkeleyDB操作封装C#版(附单元测试)

        using System; using System.Collections.Generic; using System.IO; using System.Linq; using System ...

  6. Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(一)

    一.前提: 完成Hello Game项目的创建编译. 具体参考:Cocos2dx.3x_Hello Game项目创建篇 二.本篇目标: l  说说关于塔防游戏的想法和思路 l  实现一个简单的塔防游戏 ...

  7. C++/Php/Python/Shell 程序按行读取文件或者控制台

    写程序经常需要用到从文件或者标准输入中按行读取信息,这里汇总一下.方便使用 1. C++ 读取文件 #include<stdio.h> #include<string.h> i ...

  8. checkbox的三种状态处理

    checkbox只有两种值:选中(checked)或未选中(unchecked).它可以有任何值,但是表单提交时checkbox的值只能是checked或unchecked.它的默认值是uncheck ...

  9. iOS 7.1 UITableView添加footerView 后 最后一行分割线无法显示

    今天用故事版 遇到个奇怪的问题: 我要用 tbView(tableView)展示写信息.最后一行我要显示些文案什么的.考虑用 footerView ,开心coding ..,show下 哪里有些不对吧 ...

  10. memcpy memmove区别和实现

    memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中. 但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开 ...