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.



posted @   张同光  阅读(45)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示