Linux内核-网络代码-关键的数据结构(struct sk_buff、struct net_device)

1、struct sk_buff结构体解析

struct sk_buff:一个封包就存储在这里。所有网络分层都会使用这个结构来储存其报头、有关用户数据的信息(有效载荷),以及用来协调其工作的其他内部信息。

struct net_device:在Linux内核中每种网络设备都用这个数据结构表示,包括软硬件的配置信息。

struct sk_buff定义在#include <linux/skbuff.h>

struct sk_buff {
        union {
                struct {
                        /* These two members must be first. */
                        struct sk_buff          *next;        /* 下一个struct sk_buff结构 */
                        struct sk_buff          *prev;        /* 前一个struct sk_buff结构 */

                        union { 

/*报文到达或者离开的时间戳; Time we arrived 表示这个skb的接收到的时间, 一般是在包从驱动中往二层发送的接口函数中设置 */

                                ktime_t         tstamp;        /* 通常只对一个已接收的封包才有意义。时间戳标记,用于表示封包何时被接收,或者有时用于表示封包预定传输的时间。此字段由netif_rx函数用net_timestamp设置,该函数在接收每个封包之后由设备驱动程序调用 */
                                struct skb_mstamp skb_mstamp;
                        };
                };
                struct rb_node  rbnode; /* used in netem & tcp stack */
        };
        struct sock             *sk;                /* 用户存储套接字的网络信息,该包属于哪个socket */
        struct net_device       *dev;          /* 收到这个包的网络设备的信息 */

        /*
         * This is the control buffer. It is free to use for every
         * layer. Please put your private variables there. If you
         * want to keep them across layers you have to do a skb_clone()
         * first. This is owned by whoever has the skb queued ATM.
         */
        char                    cb[48] __aligned(8);

        unsigned long           _skb_refdst;

/* 当此缓冲区被删除时,可以完成某些工作。当此缓冲区不属于一个套接字时,destructor通常不会被初始化。当此缓冲区属于一个套接字时,一般都是设置为sock_rfree或者sock_wfree。 */
        void                    (*destructor)(struct sk_buff *skb);
#ifdef CONFIG_XFRM
        struct  sec_path        *sp;
#endif
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
        struct nf_conntrack     *nfct;
#endif
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
        struct nf_bridge_info   *nf_bridge;
#endif
        unsigned int            len,        /* 分片数据区和连续数据区的总长度 */
                                data_len;      /* 分片结构体数据区的总长度 */
        __u16                   mac_len,        /* MAC报头的长度 */
                                hdr_len;            /* 用于clone的时候,它表示clone的skb的头的长度 */

        /* Following fields are _not_ copied in __copy_skb_header()
         * Note that queue_mapping is here mostly to fill a hole.
         */
        kmemcheck_bitfield_begin(flags1);
        __u16                   queue_mapping;        /* 多队列的设备应用,也就是说映射到哪个队列 */
        __u8                    cloned:1,
                                nohdr:1,
                                fclone:2,
                                peeked:1,
                                head_frag:1,
                                xmit_more:1;
        /* one bit hole */
        kmemcheck_bitfield_end(flags1);

        /* fields enclosed in headers_start/headers_end are copied
         * using a single memcpy() in __copy_skb_header()
         */
        /* private: */
        __u32                   headers_start[0];
        /* public: */

/* if you move pkt_type around you also must adapt those constants */
#ifdef __BIG_ENDIAN_BITFIELD
#define PKT_TYPE_MAX    (7 << 5)
#else
#define PKT_TYPE_MAX    7
#endif
#define PKT_TYPE_OFFSET()       offsetof(struct sk_buff, __pkt_type_offset)

        __u8                    __pkt_type_offset[0];
        __u8                    pkt_type:3;
        __u8                    pfmemalloc:1;
        __u8                    ignore_df:1;
        __u8                    nfctinfo:3;

        __u8                    nf_trace:1;
        __u8                    ip_summed:2;
        __u8                    ooo_okay:1;
        __u8                    l4_hash:1;
        __u8                    sw_hash:1;
        __u8                    wifi_acked_valid:1;
        __u8                    wifi_acked:1;

        __u8                    no_fcs:1;
        /* Indicates the inner headers are valid in the skbuff. */
        __u8                    encapsulation:1;
        __u8                    encap_hdr_csum:1;
        __u8                    csum_valid:1;
        __u8                    csum_complete_sw:1;
        __u8                    csum_level:2;
        __u8                    csum_bad:1;

#ifdef CONFIG_IPV6_NDISC_NODETYPE
        __u8                    ndisc_nodetype:2;
#endif
        __u8                    ipvs_property:1;
        __u8                    inner_protocol_type:1;
        __u8                    remcsum_offload:1;
        /* 3 or 5 bit hole */

#ifdef CONFIG_NET_SCHED
        __u16                   tc_index;       /* traffic control index */
#ifdef CONFIG_NET_CLS_ACT
        __u16                   tc_verd;        /* traffic control verdict */
#endif
#endif

        union {
                __wsum          csum;
                struct {
                        __u16   csum_start;
                        __u16   csum_offset;
                };
        };
        __u32                   priority;       /* 优先级,主要用于QOS */ 
        int                     skb_iif;
        __u32                   hash;
        __be16                  vlan_proto;
        __u16                   vlan_tci;
#if defined(CONFIG_NET_RX_BUSY_POLL) || defined(CONFIG_XPS)
        union {
                unsigned int    napi_id;
                unsigned int    sender_cpu;
        };
#endif
#ifdef CONFIG_NETWORK_SECMARK
        __u32                   secmark;
#endif
        union {
                __u32           mark;
                __u32           reserved_tailroom;
        };

        union {
                __be16          inner_protocol;
                __u8            inner_ipproto;
        };

        __u16                   inner_transport_header;        /*  */
        __u16                   inner_network_header;
        __u16                   inner_mac_header;

        __be16                  protocol;        /* 协议类型 */
        __u16                   transport_header;        /* 传输层头部 */
        __u16                   network_header;        /* 网络层头部 */
        __u16                   mac_header;        /* 链路层头部 */

        /* private: */
        __u32                   headers_end[0];
        /* public: */

        /* These elements must be at the end, see alloc_skb() for details.  */
        sk_buff_data_t          tail;        /* 实际数据区的尾端 */
        sk_buff_data_t          end;        /* 数据区的尾端 */
        unsigned char           *head,        /* 数据区的起始位置 */
                                *data;                /* 实际数据区的起始位置 */

/* 这些字段代表缓冲区的边界以及其中的数据。当每一分层为其工作而准备缓冲区时,可能会为一个报头或更多的数据分配更多的空间。head和end指向已分配缓冲区空间的开端和尾端,而data和tail则指向实际数据的开端和尾端。可以在head和data之间的空隙中填上一个协议报文头 */

/*  */
        unsigned int            truesize;

/* 这个是在缓冲区中实例化的计数。其作用就是在销毁skb结构体时,先查看users是否为0,若不为0,则调用函数递减下引用计数users即可;当销毁时,users为0才真正释放内存空间。有两个操作函数:atomic_inc()计数增加1;atomic_dec()计数jian'qu */
        atomic_t                users;
};

2、struct sk_buff结构体的管理函数

        skb_put之前和之后

       

         skb_push之前和之后

        

         skb_pull

        skb_reserver

         分配内存:alloc_skb和dev_alloc_skb

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/483494.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

力扣-python-合并两个有序链表

题解&#xff1a; 这段代码是用于合并两个有序列表的递归函数&#xff0c;函数的输入是两个链表l1和l2&#xff0c;返回合并后的有序列表。具体操作是比较两个链表的头结点&#xff0c;将较小的头结点作为合并后的链表的头结点&#xff0c;并递归的将剩余的部分与另一个链表进…

unity编辑器扩展高级用法

在PropertyDrawer中&#xff0c;您不能使用来自GUILayout或EditorGUILayout的自动布局API&#xff0c;而只能使用来自GUI和EditorGUI的绝对Rect API始终传递相应的起始位置和维度。 你需要 计算显示嵌套内容所需的总高度将此高度添加到public override float GetPropertyHeig…

深入解析实时数仓Doris:介绍、架构剖析、应用场景与数据划分细节

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! Doris是一款高性能、开源的实时分析数据仓库&#xff0c;旨在为用户提供毫秒级查询响应、高并发、高可用以及易于扩展的OLAP解决方…

P1563 [NOIP2016 提高组] 玩具谜题

题目传送门 这道题实在是一道水题 话不多说&#xff0c;上代码 #include<iostream> #include<cstring> using namespace std; struct a{int io;//in朝里 out朝外 小人的朝向 string name;//小人的名字 int number;//角色编号 }a[100000]; int main(){int n, m…

连续子数组的最大和

问题描述&#xff1a; 输入一个整型数组&#xff0c;数组里有正数也有负数。求连续子数组中的最大和为多少。 举例&#xff1a; 数组&#xff1a;arry{1 , 2 &#xff0c;-5 , 4 , 1 &#xff0c;-2} 输出&#xff1a;5&#xff0c;数组中连续的位置相加最大值为5, 41 方法…

yolov8目标检测数据集制作——make sense

背景 在前几天我进行了录制视频以准备足够多的数据集&#xff0c;同时使用利用python自定义间隔帧数获取视频转存为图片&#xff0c;所以今天我准备对我要训练的数据集进行标注。我要做的是一个基于yolo的检测项目&#xff0c;在搜索资料后得知大家多是用labelme或者make sens…

文心一言 VS 讯飞星火 VS chatgpt (221)-- 算法导论16.3 3题

三、如下所示&#xff0c;8个字符对应的出现频率是斐波那契数列的前8个数&#xff0c;此频率集合的赫夫曼编码是怎样的? a:1 b:1 c:2 d:3 e:5 f:8 g:13 h:21 你能否推广你的结论&#xff0c;求频率集为前 n 个斐波那契数的最优前缀码? 文心一言&#xff1a; 首先&#xff0…

pytorch中tensor类型转换的几个函数

目录 IntTensor转FloatTensor FloatTensor转IntTensor Tensor类型变为python的常规类型 IntTensor转FloatTensor .float函数&#xff1a; FloatTensor转IntTensor .int函数 Tensor类型变为python的常规类型 item函数

Matlab 2024a版本在Linux系统上的安装配置

目录 前言一、​Matlab 2024a安装总结 前言 Matlab是一种高级技术计算和编程环境&#xff0c;广泛应用于科学、工程和金融等领域。它提供了丰富的工具和函数库&#xff0c;用于数据分析、可视化、模型建立、算法开发和应用部署等任务。注&#xff1a;文末附有下载链接&#xf…

一文告诉你如何用 Python 操作 ChatGPT

ChatGPT 相信大家都用过&#xff0c;你觉得它给你的工作带来了多少帮助呢&#xff1f; 对这块感兴趣的&#xff0c;可以群里聊聊 目前我们使用 ChatGPT 的方式是通过浏览器访问 chat.openai.com&#xff0c;然后输入问题&#xff0c;就像下面这样。 除了网页之外&#xff0…

Qt打开已有工程方法

在Qt中&#xff0c;对于一个已有工程如何进行打开&#xff1f; 1、首先打开Qt Creator 2、点击文件->打开文件或项目&#xff0c;找到对应文件夹下的.pro文件并打开 3、点击配置工程 这样就打开对应的Qt项目了&#xff0c;点击运行即可看到对应的效果 Qt开发涉及界面修饰…

2024-03-22 问AI: 介绍一下深度学习中的 sigmoid函数

文心一言 Sigmoid函数是深度学习中常用的一种激活函数&#xff0c;主要用于将神经元的输出值压缩到0和1之间。这种特性使得sigmoid函数在二分类问题中特别有用&#xff0c;因为输出值可以被解释为属于某个类别的概率。 sigmoid函数的数学表达式为&#xff1a; σ(x) 1 / (1…

CMake笔记之将任意官方库作为third_party完整地包含在工程项目中使用的通用模板

CMake笔记之将任意官方库作为third_party完整地包含在工程项目中使用的通用模板 —— 杭州 2024-03-20 凌晨1:06 code review! 文章目录 CMake笔记之将任意官方库作为third_party完整地包含在工程项目中使用的通用模板1.通用CMakeLists.txt模板2.GPT4给出的改进建议3.git clon…

kubernetes负载均衡-service

一、service的概念 1、什么是service 在Kubernetes中&#xff0c;pod是应用程序的载体&#xff0c;当我们需要访问这个应用时&#xff0c;可以通过Pod的IP进行访问&#xff0c;但是这里有两个问题:1、Pod的IP地址不固定&#xff0c;一旦Pod异常退出、节点故障&#xff0c;则会…

Windows11 安装confluence 7.4.0

Windows11安装confluence:7.4.0 1.打开终端管理员(管理员权限的PowerShell)2.按顺序执行以下命令,安装confluence服务3.浏览器(如Microsoft Edge) 打开 http://127.0.0.1:8100/ 配置confluence4.图示 本文是Windows11 安装confluence 7.4.0的步骤 本文参考 1.打开终端管理员(管…

使用React搭建single-spa

自己搭建的Demo GitHub - ftao123/single-spa-react-demo: single-spa-react-demo 修改子应用的webpack配置 library: "app2"和libraryTarget: "umd"配置必须添加。 可以看到filename在开发环境下的地址是static/js/bundle.js&#xff0c;所以我们主应用…

PySide6-YOLO8目标检测、追踪可视化界面

目录 项目地址实现效果DetectTrack 项目地址 https://github.com/zhengjie9510/pyside-yolo 实现效果 Detect Track

MySQL 查询性能优化

优质博文&#xff1a;IT-BLOG-CN​ 如果把查询看作是一个任务&#xff0c;那么它由一些列子任务组成&#xff0c;每个子任务都会消耗一定的时间。如果要优化查询&#xff0c;实际上要优化其子任务&#xff0c;要么消除其中一些子任务&#xff0c;要么减少子任务的执行次数。通常…

matlab批量读取目录下的文件的方法

批量处理可以提高效率&#xff0c;这里提供一个可以批量读取nc文件的代码&#xff1a; address C:\Users\Hello World!!\DESKTOP\TerraClimate_ppt\; % Get the list of files udir address; form *.nc; % Get the list of station names files GetFiles(udir,form); [n,p…

Linux 进程通信:命名管道、共享内存

目录 一、命名管道 1、概念 2、特点 3、原理 4、创建 5、匿名管道与命名管道的区别 6、命名管道的打开规则 二、命名管道—实现客户端和服务器之间的通信 1、Makefile 2、comm.hpp 3、Log.hpp 4、server.cxx 5、client.cxx 运行测试&#xff1a; 三、system V…