char cb[40]---"control buffer"
//-----------------------------------------------------------------------------
include/linux/skbuff.h
struct sk_buff {
//ztg
// char cb[80] __aligned(8);
char cb[80] __aligned(8);
}
//-----------------------------------------------------------------------------
./include/net/tcp.h
#define TCP_SKB_CB(__skb) ((struct tcp_skb_cb *)&((__skb)->cb[0]))
struct tcp_skb_cb { // 在该结构体中 添加两个成员,用于控制 skb 重复发送几次后销毁
//ztg add 在该结构体中 添加两个成员,用于控制 skb 重复发送几次后销毁
#ifdef CONFIG_MPTCP
__u16 sent_num; // skb 重复发送次数,当发送次数 和 算法中计算的次数(冗余路径数) 相同,则 销毁 skb
__u32 path_masks; // skb 发送的路径
#endif
__u32 ack_seq; // Sequence number ACK'd
#ifdef CONFIG_MPTCP
union { // For MPTCP outgoing frames
__u32 path_mask; // paths that tried to send this skb
__u32 dss[6]; // DSS options
};
#endif
}
//-----------------------------------------------------------------------------
http://www.embeddedlinux.org.cn/linux_net/0596002556/understandlni-CHP-2-SECT-1.html
char cb[40]
This is a "control buffer," or storage for private information, maintained by each layer for internal use. It is statically allocated within the sk_buff structure (currently with a size of 40 bytes) and is large enough to hold whatever private data is needed by each layer. In the code for each layer, access is done through macros to make the code more readable. TCP, for example, uses that space to store a tcp_skb_cb data structure, which is defined in include/net/tcp.h:
struct tcp_skb_cb { ... ... ... _ _u32 seq; /* Starting sequence number */ _ _u32 end_seq; /* SEQ + FIN + SYN + datalen*/ _ _u32 when; /* used to compute rtt's */ _ _u8 flags; /* TCP header flags. */ ... ... ... };
And this is the macro used by the TCP code to access the structure. The macro consists simply of a pointer cast:
#define TCP_SKB_CB(_ _skb) ((struct tcp_skb_cb *)&((_ _skb)->cb[0]))
Here is an example where the TCP subsystem fills in the structure upon receipt of a segment:
int tcp_v4_rcv(struct sk_buff *skb) { ... ... ... th = skb->h.th; TCP_SKB_CB(skb)->seq = ntohl(th->seq); TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + skb->len - th->doff * 4); TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); TCP_SKB_CB(skb)->when = 0; TCP_SKB_CB(skb)->flags = skb->nh.iph->tos; TCP_SKB_CB(skb)->sacked = 0; ... ... ... }
To see how the parameters in the cb buffer are retrieved, take a look at the function tcp_transmit_skb in net/ipv4/tcp_output.c. That function is used by TCP to push a data segment down to the IP layer for transmission.
In Chapter 22, you will also see how IPv4 uses cb to store information about IP fragmentation.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通