第二章 关键数据结构
一、网络代码常见数据结构
struct sk_buff
struct net_device
struct sock(本文不涉及)
二、 套接字缓冲区:sk_buff结构
涉及文件:src/net/core/dev.c、src/include/linux/skbuff.h
任何一个网络封包都会存储在这里。各个网络分层都会使用这个结构来储存其报头、有关用户数据的信息等。这个是linux网络代码中最重要的数据结构,代表已经接收或者正在传输的数据结构。结构体数据字段大致分为:
Layout(布局字段,主要是维护链表和维护skb_buff数据)
General(通用字段)
Feature-specific(功能专用字段)
Management functions(管理函数)
sk_buff结构体具体内容(linux3.0.8)如下:
struct sk_buff {
/* These two members must be first. */
struct sk_buff *next;
struct sk_buff *prev;
ktime_t tstamp;
struct sock *sk;
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;
#ifdef CONFIG_XFRM
struct sec_path *sp;
#endif
unsigned int len,
data_len;
__u16 mac_len,
hdr_len;
union {
__wsum csum;
struct {
__u16 csum_start;
__u16 csum_offset;
};
};
__u32 priority;
kmemcheck_bitfield_begin(flags1);
__u8 local_df:1,
cloned:1,
ip_summed:2,
nohdr:1,
nfctinfo:3;
__u8 pkt_type:3,
fclone:2,
ipvs_property:1,
peeked:1,
nf_trace:1;
kmemcheck_bitfield_end(flags1);
__be16 protocol;
void (*destructor)(struct sk_buff *skb);
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
struct nf_conntrack *nfct;
#endif
#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
struct sk_buff *nfct_reasm;
#endif
#ifdef CONFIG_BRIDGE_NETFILTER
struct nf_bridge_info *nf_bridge;
#endif
int skb_iif;
#ifdef CONFIG_NET_SCHED
__u16 tc_index; /* traffic control index */
#ifdef CONFIG_NET_CLS_ACT
__u16 tc_verd; /* traffic control verdict */
#endif
#endif
__u32 rxhash;
__u16 queue_mapping;
kmemcheck_bitfield_begin(flags2);
#ifdef CONFIG_IPV6_NDISC_NODETYPE
__u8 ndisc_nodetype:2;
#endif
__u8 ooo_okay:1;
kmemcheck_bitfield_end(flags2);
/* 0/13 bit hole */
#ifdef CONFIG_NET_DMA
dma_cookie_t dma_cookie;
#endif
#ifdef CONFIG_NETWORK_SECMARK
__u32 secmark;
#endif
union {
__u32 mark;
__u32 dropcount;
};
__u16 vlan_tci;
sk_buff_data_t transport_header;
sk_buff_data_t network_header;
sk_buff_data_t mac_header;
/* 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;
unsigned int truesize;
atomic_t users;
};
2.1 layout字段
该字段主要是为了方便搜寻以及组织sk_buff数据结构本身。通过一个双向链表来维护sk_buff数据结构,为了迅速找出整个链表头,额外增加了一个sk_buff_head结构(src/include/linux/skbuff.h)。sk_buff与sk_buff_head的关系图如下(摘自深入理解linux网络技术):
1、sk_buff_head结构初始化
(1)网络设备驱动(以stmmac为例)
在stmmac_dvr_probe()函数里初始化一个回收sk_buff队列:skb_queue_head_init(&priv->rx_recycle),priv为网卡私有数据结构:struct stmmac_priv。
(2)网络设备处理(公共)
在net_dev_init函数里进行了两个初始化处理:skb_queue_head_init(&sd->input_pkt_queue)和skb_queue_head_init(&sd->process_queue),sd为每个CPU的网络数据结构softnet_data,因此每个CPU都有sk_buff处理的相应队列。
(3)其他一些字段
struct sock *sk:指向拥有此缓冲区的套接字的sock数据结构。当数据在本地产生或者正由本地进程接受时,就需要这个指针。
unsigned int len:指缓冲区中数据区块的大小,包括主要缓冲区(由head指)的数据以及一些片段的数据。
unsigned int data_len:只计算片段中的数据大小
__u16 mac_len:MAC报头的大小
__u16 hdr_len:head头的大小
2.2 general字段
(1)ktime_t tstamp
时间戳记,通常只对一个已经接收的封包才有意义,表示封包何时被接收,或者有时用于表示封包预定传输的时间。在接受函数netif_rx or netif_receive_skb对该字段进行设置。
(2)struct net_device *dev
此字段描述一个网络设备,其类型net_device。当接收到一个封包时,该字段填充接收该封包的设备;当发送一个封包时,该字段填发送该封包的设备。
(3)unsigned long _skb_refdst
由路由子系统使用,目的地入口
(4)char cb[48] __aligned(8)
这是一个控制缓冲区或者私有数据存储空间,保存每层的控制信息,各个层通过宏来进行访问。
(5)校验和及关联标志
union {
__wsum csum;
struct {
__u16 csum_start;
__u16 csum_offset;
};
};
和ip_summed:2,
(6)位段
kmemcheck_bitfield_begin(flags1);
__u8 local_df:1, //本地可切片标志
cloned:1, //表示该缓冲区为另外一个sk_buff的克隆
ip_summed:2, //驱动程序是否进行校验表示
nohdr:1, //
nfctinfo:3; //netfilter使用
__u8 pkt_type:3, //根据帧的L2目的地址进行类型划分,表示主要数据包的类型:多播,单薄,回环等
fclone:2,
ipvs_property:1,
peeked:1,
nf_trace:1;
kmemcheck_bitfield_end(flags1);
(7)__u32 priority
表示正被传输或转发的封包QOS(服务质量)优先级
(8) __be16 protocol
驱动程序通过该字段识别L3层的协议,通知上层使用哪个处理例程,典型的有IP、IPV6、ARP等。
2.3 功能专用字段
struct nf_conntrack *nfct;
#endif
#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
struct sk_buff *nfct_reasm;
#endif
#ifdef CONFIG_BRIDGE_NETFILTER
struct nf_bridge_info *nf_bridge;
#endif
__u16 tc_index; /* traffic control index */
#ifdef CONFIG_NET_CLS_ACT
__u16 tc_verd; /* traffic control verdict */
#endif
#endif
2.4 相关操作函数
data = kmalloc_node_track_caller(size + sizeof(struct skb_shared_info)
atomic_set(&skb->users, 1);
skb->head = data;
skb->data = data;
skb_reset_tail_pointer(skb);
skb->end = skb->tail + size;
{
skb->data += len;
skb->tail += len;
}
{
unsigned char *tmp = skb_tail_pointer(skb);
SKB_LINEAR_ASSERT(skb);
skb->tail += len;
skb->len += len;
if (unlikely(skb->tail > skb->end))
skb_over_panic(skb, len, __builtin_return_address(0));
return tmp;
}
{
skb->data -= len;
skb->len += len;
if (unlikely(skb->data<skb->head))
skb_under_panic(skb, len, __builtin_return_address(0));
return skb->data;
}
{
skb->len -= len;
BUG_ON(skb->len < skb->data_len);
return skb->data += len;
}
unsigned short nr_frags;
unsigned short gso_size;
/* Warning: this field is not always filled in (UFO)! */
unsigned short gso_segs;
unsigned short gso_type;
__be32 ip6_frag_id;
__u8 tx_flags;
struct sk_buff *frag_list;
struct skb_shared_hwtstamps hwtstamps;
/*
* Warning : all fields before dataref are cleared in __alloc_skb()
*/
atomic_t dataref;
/* Intermediate layers must ensure that destructor_arg
* remains valid until skb destructor */
void * destructor_arg;
/* must be last field, see pskb_expand_head() */
skb_frag_t frags[MAX_SKB_FRAGS];
};
三、 网络设kfree_skb备:net_device结构
每种网络设备都用这个数据结构表示,包括软硬件信息。
第二章 关键数据结构相关推荐
- 第二章 基本数据结构
第二章 基本数据结构 第一课 模块(库)初识 分类: 标准库: 不需要安装的库 第三方库: 需要安装的库 sys模块: import sys print(sys.path) #打印环境变量(模块在这些 ...
- 第二章 函数式数据结构
一. 定义一个函数式的List 通常使用trait关键字引入一种数据类型 sealed trait表示这个trait的所有实现都必须定义在这个文件里 MyList有2种实现,空和非空.非空借口由初始的 ...
- 第二章 关系数据结构及关系的完整性习题解析
1.某关系R的外键是指 A.(正确答案)解析:其它关系的候选键,可以是R中的主属性或非主属性 B.(错误答案)解析:外键是另一个关系的主键 C.(错误答案)解析:其它关系的候选键,可以是R中的主属性或 ...
- 第二章 关键技术介绍
本项目主要用到的技术有os.requests.lxml.pandas等,数据库使用的是SQL. 2.1 os模块介绍 Python的标准库中的os模块包含普遍的操作系统功能.即它允许一个程序在编写 ...
- 数据结构第二章-线性表(详细知识点总结)
目录 第二章 线性表 2.1 线性表的定义和操作 2.1.1 线性表的定义 2.1.2 线性表的基本操作 2.2线性表的顺序表示 2.2.1 顺序表的定义 2.2.2 顺序表上基本操作的实现 2.3 ...
- C语言数据结构-第二章线性表-电大
第二章线性表--内容简介 本章将进入线性结构的学习. 线性结构是最简单.最常用的一种数据结构. 本章将学习线性表的定义.顺序和链式两种存储方式及相应存储结构上的运算实现.通过典型示例训练,掌握线性表的 ...
- 数据结构第二章学习总结
数据结构第二章学习总结 在数据结构第二章,我们学习了线性表的两种结构顺序和链式结构,学习了他们的定义,不同,存储结构和逻辑结构,还有一些基本的操作. 在学习过程中,我发现了许多问题:①书上的大多数代码 ...
- 删除第一个_学习数据结构--第二章:线性表(顺序存储、插入、删除)
第二章:线性表(顺序表示) 1.线性表的定义和基本操作 线性表是具有相同数据类型的n(n≥0)个数据元素的有限序列 线性表中第一个元素称为表头元素;最后一个元素称为表尾元素. 除第一个元素外,每个元素 ...
- 为什么我要放弃javaScript数据结构与算法(第二章)—— 数组
第二章 数组 几乎所有的编程语言都原生支持数组类型,因为数组是最简单的内存数据结构.JavaScript里也有数组类型,虽然它的第一个版本并没有支持数组.本章将深入学习数组数据结构和它的能力. 为什么 ...
- 【数据结构总结】第二章:线性表
第二章:线性表 提示:本文主要是以思维导图的形式概括数据结构第一章的精华内容,基本不会用到文字性的内容,目的是为了给大家梳理每个重要的知识点的相关概念,方便大家在复盘的时候快速阅读和浏览,加快记忆速度 ...
最新文章
- 卷积神经网络理解及1*1卷积核的作用
- R语言ggplot2可视化分组散点图、使用scale_shape_manual函数、scale_color_manual函数、scale_size_manual函自定义设置分组散点的形状、大小、颜色
- NTU课程笔记 mas714复习:例题
- layui设置按钮不可点击_(eblog)7、博客发布收藏、用户中心的设置
- java语言中的标识符_Java语言基本语法(一)————关键字标识符(Java语言标识符命名规范Java语言的包名、类名、接口名、变量名、函数名、常量名命名规则 )...
- 线程调度优先级和关联性
- hive架构及使用场景
- 浅析NVR主流芯片方案
- 所有赚不到钱的人都是干了自己不愿意或者自己很讨厌的事
- 【数据结构】思维导图补充知识
- [转载] python3 闭包
- 数据挖掘 文本分类(二)搜集中文语料库与ICTCLAS分词
- 微信指纹支付提示java6_苹果6微信指纹支付每次提示请验证已有的指纹用于支付,怎样才能支付?...
- 40 张最全计算机网络基础思维导图
- PhpSpreadsheet读取excel
- 关于求最大公倍数的不同算法比较
- es linux下使用api进行es故障操作处理
- 2022-12-12 系统移植
- fastdfs上传文件资料(PDF,视频,图片,FileCaseUtil,FileUploadUtil)并生成缩略图
- 【企业信息化系列】如何以BPM流程平台为核心串联公司业务系统