一、结构体定义原型
首先来看 sk_buff 这个庞大的结构体。无需逐字段死记,只需了解其主要成员和用途,后文会重点介绍典型成员变量。
struct sk_buff {
union {
struct {
/* 链表中的下一个 sk_buff 指针,用于管理 skb 的链表 */
struct sk_buff *next;
/* 链表中的前一个 sk_buff 指针,形成双向链表 */
struct sk_buff *prev;
union {
/* 关联的网络设备指针,指向处理此 skb 的网络设备 */
struct net_device *dev;
/* 某些协议可能会在这里使用空间存储信息 */
unsigned long dev_scratch;
};
};
struct rb_node rbnode; // 红黑树节点
struct list_head list; // 链表头节点
struct llist_node ll_node; // 低延迟链表节点
};
union {
struct sock *sk; // 关联的 socket
int ip_defrag_offset; // IP 分片偏移
};
union {
ktime_t tstamp; // 时间戳
u64 skb_mstamp_ns; // 最早发送时间
};
/*
* 控制缓冲区(cb)。每个层可以自由使用此区域存储私有变量。
* 如果希望跨层保留数据,需使用 skb_clone() 进行克隆。
*/
char cb[48] __aligned(8); // 控制缓冲区
union {
struct {
unsigned long _skb_refdst; // 目标引用地址
void (*destructor)(struct sk_buff *skb); // 析构函数
};
struct list_head tcp_tsorted_anchor; // TCP 排序锚点
};
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
unsigned long _nfct; // 连接追踪标识
#endif
unsigned int len; // skb 的总长度
unsigned int data_len; // 非线性数据长度
__u16 mac_len; // MAC 头部长度
__u16 hdr_len; // 数据包头部长度
__u16 queue_mapping; // 队列映射
__u8 __cloned_offset[0]; // 克隆信息偏移
__u8 cloned:1, nohdr:1, fclone:2, peeked:1, head_frag:1, pfmemalloc:1, pp_recycle:1;
#ifdef CONFIG_SKB_EXTENSIONS
__u8 active_extensions; // 活动扩展数量
#endif
__u32 headers_start[0]; // 头部开始位置
__u8 __pkt_type_offset[0]; // 包类型偏移
__u8 pkt_type:3; // 包类型(如 IP、ARP)
__u8 ignore_df:1; // 忽略 DF 标志
__u8 nf_trace:1<

最低0.47元/天 解锁文章
677

被折叠的 条评论
为什么被折叠?



