报文GSO分段的入口函数是skb_gso_segment函数,是在validate_xmit_skb函数中被调用。
1、skb_gso_segment函数
static inline
struct sk_buff *skb_gso_segment(struct sk_buff *skb, netdev_features_t features)
{
return __skb_gso_segment(skb, features, true);
}
2、__skb_gso_segment函数
struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
netdev_features_t features, bool tx_path)
{
if (unlikely(skb_needs_check(skb, tx_path))) { // 判断等于 skb->ip_summed != CHECKSUM_PARTIAL
int err;
skb_warn_bad_offload(skb); //打印告警信息,说明GSO报文skb->ip_summed == CHECKSUM_PARTIAL
err = skb_cow_head(skb, 0); //如果skb是克隆,则需要重新分配线性区
if (err < 0)
return ERR_PTR(err);
}
SKB_GSO_CB(skb)->mac_offset = skb_headroom(skb); //设置mac_offset, 用于skb_segment分段拷贝外层报文
SKB_GSO_CB(skb)->encap_level = 0; //encap_level为零,说明是最外层的报文
skb_reset_mac_header