【转】sk_buff详解

sk_buff数据结构详解 sk_buff 简介 封包存储于struct sk_buff中,所有网络分层都会使用这个结构来储存其报头、有关用户数据的信息,以及协调其工作的其他内部信息。从第二层到第四层都会使用这个数据结构。L4附加一个报头传给L3,L3附加自己的报头传给L2,L2附加自己的报头传给L1转发出去。设备收到sk_buff之后,每层都只处理自己的报头,并将其呈交给上层。 sk_buff数据结构 内核使用一个双向链表来维护sk_buff,链表的开端使用了一个哑元元素sk_buff_head,如下图所示为sk_buff链表 阅读详情


One of the problems of having many layers of network protocols, each one using the services of another, is that each protocol needs to add protocol headers and tails to data as it is transmitted and to remove them as it processes received data [Cox96] [Rus96]. This make passing data buffers between the protocols difficult as each layer needs to find where its particular protocol headers and tails are. One solution is to copy buffers at each layer but that would be inefficient. Instead, Linux uses socket buffers or sk_buffs to pass data between the protocol layers and the network device drivers. sk_buffs contain pointer and length fields that allow each protocol layer to manipulate the application data via standard functions or "methods".


Figure: Network Socket Buffers

Figure (fig [*]) shows the sk_buff data structure, each sk_buff has a block of data associated with it. The sk_buff has four data pointers, which are used to manipulate and manage the socket buffer's data. (The reader is referred to include/linux/skbuff.h of the linux source for details).

head points to the start of the data area in memory. This is fixed when the sk_buff and its associated data block is allocated.

data points at the current start of the protocol data. This pointer varies depending on the protocol layer that currently owns the sk_buff.

tail points at the current end of the protocol data. Again, this pointer varies depending on the owning protocol layer.

end points at the end of the data area in memory. This is fixed when the sk_buff is allocated.

There are two length fields len and truesize, which describe the length of the current protocol packet and the total size of the data buffer respectively. The sk_buff handling code provides standard mechanisms for adding and removing protocol headers and tails to the application data. These safely manipulate the data, tail and len fields in the sk_buff. (The reader is advised to refer to net/core/skbuff.c for more details).

push This moves the data pointer towards the start of the data area and increments the len field. This is used when adding data or protocol headers to the start of the data to be transmitted.

pull This moves the data pointer away from the start, towards the end of the data area and decrements the len field. This is used when removing data or protocol headers from the start of the data that has been received.

put This moves the tail pointer towards the end of the data area and increments the len field. This is used when adding data or protocol information to the end of the data to be transmitted.

trim This moves the tail pointer towards the start of the data area and decrements the len field. This is used when removing data or protocol tails from the received packet.

The sk_buff data structure also contains pointers that are used as it is stored in doubly linked circular lists of sk_buff's during processing. There are generic sk_buff routines for adding sk_buffs to the front and back of these lists and for removing them.

The primary goal of the sk_buff routines is to provide a consistent and efficient buffer handling method for all of the network layers, and by being consistent to make it possible to provide higher level sk_buff and socket handling facilities to all the protocols.



包缓冲区操作的几个内嵌函数
==========================

包缓冲由sk_buff结构描述, 包缓冲数据区由其head和end成员界定,
而包数据体则由包数据区内data和tail界定的子区域来描述,
采用这种结构可以使添加或去除包头的操作变得非常方便.

skb_put(skb,len) 在包体尾部扩展长度为len的数据块, 返回扩展块的地址

__skb_put()为未校验版本

skb_push(skb,len) 在包体前部扩展长度为len的数据块, 返回扩展块的地址

__skb_push()为未校验版本

skb_pull(skb,len) 去除包体前部长度为len的数据块, 返回新包体的起始地址

__skb_pull()为未校验版本

skb_headroom(skb) 返回包体前部距离包区开始的长度

skb_tailroom(skb) 返回包体尾部距离包区结束的长度

skb_reserve(skb,len) 设置包体起始位置为包区开始的len字节

skb_trim(skb,len) 将包体截断为len字节, __skb_trim()为未校验版本

; include/linux/skbuff.h:

struct sk_buff {
  ...
  unsigned int len; /* Length of actual data */
  unsigned char *head; /* Head of buffer */
  unsigned char *data; /* Data head pointer */
  unsigned char *tail; /* Tail pointer */
  unsigned char *end; /* End pointer */
  ...
}

/*
* Add data to an sk_buff
*/

static inline unsigned char *__skb_put(struct sk_buff *skb, unsigned int len)
{
  unsigned char *tmp=skb->tail;
  skb->tail+=len;
  skb->len+=len;
  return tmp;
}

/**
* skb_put - add data to a buffer
* @skb: buffer to use 
* @len: amount of data to add
*
* This function extends the used data area of the buffer. If this would
* exceed the total buffer size the kernel will panic. A pointer to the
* first byte of the extra data is returned.
*/

static inline unsigned char *skb_put(struct sk_buff *skb, unsigned int len)
{
  unsigned char *tmp=skb->tail;
  skb->tail+=len;
  skb->len+=len;
  if(skb->tail>skb->end)
  {
    skb_over_panic(skb, len, current_text_addr());
  }
  return tmp;
}

static inline unsigned char *__skb_push(struct sk_buff *skb, unsigned int len)
{
  skb->data-=len;
  skb->len+=len;
  return skb->data;
}

/**
* skb_push - add data to the start of a buffer
* @skb: buffer to use 
* @len: amount of data to add
*
* This function extends the used data area of the buffer at the buffer
* start. If this would exceed the total buffer headroom the kernel will
* panic. A pointer to the first byte of the extra data is returned.
*/

static inline unsigned char *skb_push(struct sk_buff *skb, unsigned int len)
{
  skb->data-=len;
  skb->len+=len;
  if(skb->datahead)
  {
    skb_under_panic(skb, len, current_text_addr());
  }
  return skb->data;
}

static inline char *__skb_pull(struct sk_buff *skb, unsigned int len)
{
  skb->len-=len;
  return skb->data+=len;
}

/**
* skb_pull - remove data from the start of a buffer
* @skb: buffer to use 
* @len: amount of data to remove
*
* This function removes data from the start of a buffer, returning
* the memory to the headroom. A pointer to the next data in the buffer
* is returned. Once the data has been pulled future pushes will overwrite
* the old data.
*/

static inline unsigned char * skb_pull(struct sk_buff *skb, unsigned int len)
{ 
  if (len > skb->len)
    return NULL;
  return __skb_pull(skb,len);
}

/**
* skb_headroom - bytes at buffer head
* @skb: buffer to check
*
* Return the number of bytes of free space at the head of an &sk_buff.
*/

static inline int skb_headroom(const struct sk_buff *skb)
{
  return skb->data-skb->head;
}

/**
* skb_tailroom - bytes at buffer end
* @skb: buffer to check
*
* Return the number of bytes of free space at the tail of an sk_buff
*/

static inline int skb_tailroom(const struct sk_buff *skb)
{
  return skb->end-skb->tail;
}

/**
* skb_reserve - adjust headroom
* @skb: buffer to alter
* @len: bytes to move
*
* Increase the headroom of an empty &sk_buff by reducing the tail
* room. This is only allowed for an empty buffer.
*/

static inline void skb_reserve(struct sk_buff *skb, unsigned int len)
{
  skb->data+=len;
  skb->tail+=len;
}


static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
{
  skb->len = len;
  skb->tail = skb->data+len;
}

/**
* skb_trim - remove end from a buffer
* @skb: buffer to alter
* @len: new length
*
* Cut the length of a buffer down by removing data from the tail. If
* the buffer is already under the length specified it is not modified.
*/

static inline void skb_trim(struct sk_buff *skb, unsigned int len)
{
  if (skb->len > len)

  {
    __skb_trim(skb, len);
  }
}

TCP/IP之buff分析m_buff与sk_buff 终于下决心开始看TCP/IP部分的源码了,从《TCI/IP详解,卷二》作为入口。。。 首先来分析一下存取数据的buff, 在书上,强调的是mbuf,不过好像现在新版本的内核改动比较大,更重要的还是sk_buff,不过还是先来看看mbuff吧, 文件在:Driver/net/skfp/h/mbuf.h struct s_mbuf { struct s_mbuf *sm_next ; /* 阅读详情

相关推荐

sk_buff 定义及其操作

1. sk_buff 结构体 可以看出 sk_buff 结构体很重要, sk_buff --- 套接字缓冲区,用来在linux网络子系统中各层之间数据传递,起到了“神经中枢”的作用。 当发送数据包时,linux内核的网络模块必须建立一个包含要传输的数据包的sk_buff,然后将sk_buff传递给下一层,各层在 sk_buff 中添加不同的协议头,直到交给网络设备发送。 同样,当接收数据

3599

Linux SKB结构体中各个长度字段的含义(len, data_len, headlen, pagelen)

结构体sk_buff是Linux内核网络子系统的一个基本结构体,关于它的长度有很多定义和操作,非常容易弄混,这里给出一个简单的说明。 下面这幅图是《深入理解Linux网络技术内幕》里面的图,一个skb用于存储一个报文,如果一个报文特别大的话,线性存储区放不下就需要多个skb来存储,这就是下面frag_list的作用,保存连续的skb,但是如果内核支持分散聚集技术的话,并且报文长度刚好又不大于mt...

fuyuande的博客 8489

sk_buff结构详解

sk_buff结构是Linux网络模块中最重要的数据结构之一,用以描述已接收或待发送的数据报文信息,其成员可大致分为以下几类: 与sk_buff组织相关的成员变量。通用成员变量。标志性变量。与特性相关的成员变量。   下面对sk_buff结构进行详细介绍。 struct sk_buff { /* These two members must be first. */

keepmovingnow的专栏 1708

sk_buff 函数操作(一)

1: Alloc 分配完 之后的结构 仅仅是分配了线束数据区域,但是现在还没有数据 2:skb_reserve函数 static inline void skb_reserve(struct sk_buff *skb, int len) { skb->data += len; skb->tail += len; } 这个函数很重要,是为

farmwang的专栏 2762

skb结构和相关操作函数

skb操作函数

fengcai_ke的博客 5085

嵌入式下载故障排查:ST-LINK与GD32 Programmer典型问题解决

嵌入式固件烧录是MCU开发的关键环节,其本质依赖于调试器(如ST-LINK、GD-Link)与目标芯片间的协议通信、驱动加载及硬件接口协同。原理上,SWD/JTAG协议需在正确时序、电平与供电条件下完成设备枚举、ID读取与Flash编程;技术价值在于保障量产烧录稳定性与调试可重复性;典型应用场景涵盖STM32/GD32教学开发、工业控制板量产调试及Windows 11新系统适配。本文聚焦ST-LINK-V2在Keil MDK中的下载失败和GD32 All In One Programmer的DLL加载异常两

weixin_35006125的博客 154

linux skb 结构和相关操作函数分析

sk_buff是Linux网络中最核心的结构体,它用来管理和控制接收或发送数据包的信息。各层协议都依赖于sk_buff而存在。内核中sk_buff结构体在各层协议之间传输不是用拷贝sk_buff结构体,而是通过增加协议头和移动指针来操作的。如果是从L4传输到L2,则是通过往sk_buff结构体中增加该层协议头来操作;如果是从L2到L4,则是通过移动sk_buff结构体中的data指针来实现,不会删除各层协议头。这样做是为了提高CPU的工作效率。 1.skb_buff关键结构成员 struct sk_b

魏言华的博客 8772

银河飞腾FT6678实战指南:OpenMP多核并行编程优化技巧

本文详细介绍了在银河飞腾FT6678多核处理器上使用OpenMP进行并行编程的实战技巧与优化方法。从基础语法到环境配置,再到性能优化的五大核心技巧,包括循环并行化、并行粒度控制、reduction子句使用等,帮助开发者充分发挥FT6678的8核计算能力。通过实际案例展示如何将图像处理算法从200ms优化到28ms,并深入探讨了任务调度、内存访问优化等进阶主题。

weixin_29234423的博客 287

sk_buff 整理笔记(一、数据结构)

对sk_buff结构体以及相关的sk_buff_head结构体、sk_buff结构体数据区、sk_shared_info分片结构体、分片结构体的数据区的常用成员字段进行透彻的分析。以及分析这几个结构体的关系与一个sk_buff数据包的形成和其data指针的变化。 (1)sk_buff->data_len:只计算分片中数据的长度,即是分片结构体中page指向的数据区长度。这个在分片结构体中会再详细讲解下。 (2)sk_buff->len:表示当前缓冲区中数据块的大小的总长度。它包括主缓冲中(即是sk_

YuZhiHui_No1的专栏 3万+

具身智能的建模和方法(具身智能入门一)

本文以机械臂将小红方块移动到目标位置为例对具身智能的建模和方法进行介绍,如下图所示,该例子来自https://ai-workshops.github.io/building-and-working-in-environments-for-embodied-ai-cvpr-2022/。

weixin_39699362的博客 1463

实战教程:用YOLOv11+PyQt5打造工地安全帽检测系统(附完整数据集)

本文提供了一份完整的实战指南,详细介绍了如何利用YOLOv11目标检测模型与PyQt5界面库,从零开始构建一个智能工地安全帽检测桌面应用。内容涵盖高质量数据集的准备与标注、YOLOv11模型训练与调优,以及如何使用PyQt5开发流畅、专业的图形用户界面,最终实现一个可实际部署的AI安全监控系统。

plum99的博客 738

Linux内核中sk_buff结构详解

sk_buff结构体中的都是sk_buff的控制信息,是网络数据包的一些配置,真正储存数据的是sk_buff结构体中几个指针指向的数据区中,线性数据区的大小 = (skb->end - skb->head),对于每个数据包来说这个大小都是固定不变的,在传输过程中skb->end和skb->head所指向的地址都是不变的,这里要注意这个地址不是本机的地址,如果是本机的地址那么数据包传到其他主机上这个地址就是无效的,所以这个地址是这个skb缓冲区的相对地址。各层协议头部相关信息放在线性数据区中。

smartvxworks的博客 3422

海洋科学—物理海洋学 第五章 海洋环流

本章是基于《海洋科学导论》,但里面涉及到的重要的公式推导是专门拎出来推的,主要借鉴董昌明老师的《物理海洋学导论》,其中有一些多出来的推导,会在更新完整个物理海洋学之后重新拿出来一一讲解,最后开一个番外篇

qq_58518586的博客 1万+

linux 网络 sk_buff结构

sk_buff的意思是socket buffer,这是Linux网络子系统中的核心数据结构。定义在中,它由许多变量组成,目标就是满足所有网络协议的需要。sk_buff在不同的网络层被使用(MAC 或其他在 L2 的协议,在 L3 的 IP 协议,在 L4 的 TCP 或 UDP 等),当它从一层传递到另一层时,各个字段也会发生变化。在被传递到 L3 之前,L4 会追加头信息,然后在被传递到 L2 之前,L3 会追加头信息。。

wwwlyj123321的博客 4477

YOLO11后处理优化 | 引入DIoU-NMS替代传统NMS,解决高重叠目标误删,召回率大幅提升

YOLO11模型在密集目标场景下存在NMS后处理导致的漏检问题。本文提出采用DIoU-NMS替代传统NMS,通过引入中心点距离信息,有效区分重叠但不同的目标,提升召回率。文章详细分析了传统NMS的三大局限性,对比了Soft-NMS和DIoU-NMS的优劣,并给出在YOLO11中实现DIoU-NMS的完整代码方案。该方法特别适用于安防监控、自动驾驶等目标密集场景,能够在不显著增加计算量的情况下显著改善检测效果。

2601_95807009的博客 151

ADB加密实例

主要介绍如何给adb命令增加加密访问

四儿家的小祖宗的博客 2912

sk_buff

位置:include/linux/skbuff.h

u014211079的专栏 3720

AIGC游戏测试自动化:AI如何提升游戏QA效率

随着游戏产业的蓬勃发展,游戏的复杂度和规模不断增加,传统的游戏测试方式面临着巨大的挑战。本文章的目的在于深入探讨AIGC技术在游戏测试自动化中的应用,分析AI如何提升游戏QA的效率。范围涵盖了从核心概念到实际应用的各个方面,包括算法原理、数学模型、项目实战案例以及未来发展趋势等。本文将按照以下结构进行阐述:首先介绍核心概念与联系,明确AIGC和游戏测试自动化的相关概念和关系;接着讲解核心算法原理和具体操作步骤,通过Python代码进行详细说明;然后介绍数学模型和公式,并举例说明;

AI 原生应用开发的博客 1355

sk_buff详解

sk_buff 整理笔记(一、数据结构) sk_buff整理笔记(二、操作函数) sk_buff整理笔记(三、内存申请和释放) sk_buff整理笔记(四、克隆与复制) sk_buff整理笔记(五、队列管理函数) from:https://blog.youkuaiyun.com/YuZhiHui_No1 ...

hzj_001的博客 7423

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Linux内核协议栈-sk_buff结构详解

sk_buff结构

Hbw_aini的博客 3054

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

非常详细的详谈struct sk_buff

非常详细的详谈struct sk_buff 排版太慢 难看的话可以下载WOR文档 专门详解struct_sk_buff 链接: http://pan.baidu.com/s/1gf8VNKR 密码: pquc 注:本文大部分内容来源于网络收集加上自己理解,如有不托之处,请指出,本人无任何版权! 全称socket buffers,简称skb,中文名字叫套接字缓存。它作为网络数据包

zhuhuibeishadiao 1万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

struct sk_buff详解

sk_buff是Linux网络代码中最重要的结构体之一。它是Linux在其协议栈里传送的结构体,也就是所谓的“包”,在他里面包含了各层协议的头部,比如ethernet, ip ,tcp ,udp等等。也有相关的操作等。熟悉他是进一步了解Linux网络协议栈的基础。       此结构定义在头文件中,结构体布局大致可分为以下四部分: l       布局(layout) l  

执迷不悔 6258

sk_buff详解2

转载来源:http://blog.youkuaiyun.com/lamdoc/article/details/7873120 1. sk_buff 结构体 可以看出 sk_buff 结构体很重要, sk_buff --- 套接字缓冲区,用来在linux网络子系统中各层之间数据传递,起到了“神经中枢”的作用。 当发送数据包时,linux内核的网络模块必须建立一个包

qinm的专栏 1340

sk_buff 介绍

sk_buff是Linux网络协议栈最重要的数据结构之一,该数据结构贯穿于整个数据包处理的流程。由于协议采用分层结构,上层向下层传递数据时需要增加包头,下层向上层数据时又需要去掉包头。sk_buff中保存了L2,L3,L4层的头指针,这样在层传递时只需要对数据缓冲区改变头部信息,并调整sk_buff中的指针,而不需要拷贝数据,这样大大减少了内存拷贝的需要。 struct sk_buff {//介

chn89的专栏 4627

Linux内核sk_buff结构分析

原文地址:http://blog.chinaunix.net/uid-22227409-id-2656912.html 在内核中sk_buff表示一个网络数据包,它是一个双向链表,而链表头就是sk_buff_head,在老的内核里面sk_buff会有一个list域直接指向sk_buff_head也就是链表头,现在在2.6.32里面这个域已经被删除了。 而sk_buff的内存布局可以

深海蓝的技术随笔 9084
上一篇: matlab 画图
下一篇: netlink通信机制分析
hoppboy
博客等级 码龄17年 12粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值