sk_buff ,当网络包被内核处理时,底层协议的数据被传送更高层,当数据传送时过程反过来。由不同协议产生的数据(包括头和负载)不断往下层传递直到它们最终被发送。因为这些操作的速度对于网络层的表现至关重要,内核使用一个特定的结构叫 sk_buff, 其定义文件在 skbuffer.h。Socket buffer被用来在网络实现层交换数据而不用拷贝来或去数据包 –这显著获得速度收益。
sk_buff 是 Linux 网络的一个核心数据结构,其定义文件在 skbuffer.h。
socket kernel buffer (skb) 是 Linux 内核网络栈(L2 到 L4)处理网络包(packets)所使用的 buffer,它的类型是 sk_buffer。简单来说,一个 skb 表示 Linux 网络栈中的一个 packet;TCP 分段和 IP 分组生产的多个 skb 被一个 skb list 形式来保存。
struct sock 有三个 skb 队列(sk_buffer queue),分别是 rx , tx 和 err。
15
它的主要结构成员:
复制代码
struct sk_buff {
/* These two members must be first. */ # packet 可以存在于 list 或者 queue 中,这两个成员用于链表处理
struct sk_buff *next;
struct sk_buff *prev;
struct sk_buff_head *list; #该 packet 所在的 list
...
struct sock *sk; #跟该 skb 相关联的 socket
struct timeval stamp; # packet 发送或者接收的时间,主要用于 packet sniffers
struct net_device *dev; #这三个成员跟踪该 packet 相关的 devices,比如接收它的设备等
struct net_device *input_dev;
struct net_device *real_dev;
union { #指向各协议层 header 结构
struct tcphdr *th;
struct udphdr *uh;
struct icmphdr *icmph;
struct igmphdr *igmph;
struct iphdr *ipiph;
struct ipv6hdr *ipv6h;
unsigned char *raw;
} h;
union {
struct iphdr *iph;
struct ipv6hdr *ipv6h;
struct arphdr *arph;
unsigned char *raw;
} nh;
union {
unsigned char *raw;
} mac;
struct dst_entry *dst; #指向该 packet 的路由目的结构,告诉我们它会被如何路由到目的地
char cb[40]; # SKB control block,用于各协议层保存私有信息,比如 TCP 的顺序号和帧的重发状态
unsigned int len, #packet 的长度
data_len,
mac_len, # MAC header 长度
csum; # packet 的 checksum,用于计算保存在 protocol header 中的校验和。发送时,当 checksum offloading 时,不设置;接收时,可以由device计算
unsigned char local_df, #用于 IPV4 在已经做了分片的情况下的再分片,比如 IPSEC 情况下。
cloned:1, #在 skb 被 cloned 时设置,此时,skb 各成员是自己的,但是数据是shared的
nohdr:1, #用于支持 TSO
pkt_type, #packet 类型
ip_summed; # 网卡能支持的校验和计算的类型,NONE 表示不支持,HW 表示支持,
__u32 priority; #用于 QoS
unsigned short protocol, # 接收 packet 的协议
security;
skb 的主要操作
(1)分配 skb = alloc_skb(len, GFP_KERNEL)
16
(2)添加 payload (skb_put(skb, user_data_len))
17
(3)使用 skb->push 添加 protocol header,或者 skb->pull 删除 header
18
sk_buff 是 Linux 网络的一个核心数据结构,其定义文件在 skbuffer.h。
socket kernel buffer (skb) 是 Linux 内核网络栈(L2 到 L4)处理网络包(packets)所使用的 buffer,它的类型是 sk_buffer。简单来说,一个 skb 表示 Linux 网络栈中的一个 packet;TCP 分段和 IP 分组生产的多个 skb 被一个 skb list 形式来保存。
struct sock 有三个 skb 队列(sk_buffer queue),分别是 rx , tx 和 err。
15
它的主要结构成员:
复制代码
struct sk_buff {
/* These two members must be first. */ # packet 可以存在于 list 或者 queue 中,这两个成员用于链表处理
struct sk_buff *next;
struct sk_buff *prev;
struct sk_buff_head *list; #该 packet 所在的 list
...
struct sock *sk; #跟该 skb 相关联的 socket
struct timeval stamp; # packet 发送或者接收的时间,主要用于 packet sniffers
struct net_device *dev; #这三个成员跟踪该 packet 相关的 devices,比如接收它的设备等
struct net_device *input_dev;
struct net_device *real_dev;
union { #指向各协议层 header 结构
struct tcphdr *th;
struct udphdr *uh;
struct icmphdr *icmph;
struct igmphdr *igmph;
struct iphdr *ipiph;
struct ipv6hdr *ipv6h;
unsigned char *raw;
} h;
union {
struct iphdr *iph;
struct ipv6hdr *ipv6h;
struct arphdr *arph;
unsigned char *raw;
} nh;
union {
unsigned char *raw;
} mac;
struct dst_entry *dst; #指向该 packet 的路由目的结构,告诉我们它会被如何路由到目的地
char cb[40]; # SKB control block,用于各协议层保存私有信息,比如 TCP 的顺序号和帧的重发状态
unsigned int len, #packet 的长度
data_len,
mac_len, # MAC header 长度
csum; # packet 的 checksum,用于计算保存在 protocol header 中的校验和。发送时,当 checksum offloading 时,不设置;接收时,可以由device计算
unsigned char local_df, #用于 IPV4 在已经做了分片的情况下的再分片,比如 IPSEC 情况下。
cloned:1, #在 skb 被 cloned 时设置,此时,skb 各成员是自己的,但是数据是shared的
nohdr:1, #用于支持 TSO
pkt_type, #packet 类型
ip_summed; # 网卡能支持的校验和计算的类型,NONE 表示不支持,HW 表示支持,
__u32 priority; #用于 QoS
unsigned short protocol, # 接收 packet 的协议
security;
skb 的主要操作
(1)分配 skb = alloc_skb(len, GFP_KERNEL)
16
(2)添加 payload (skb_put(skb, user_data_len))
17
(3)使用 skb->push 添加 protocol header,或者 skb->pull 删除 header
18