linux内核 checksum,Checksum in Linux Kernel

calculate IP/TCP/UDP checsum

简单来说,就是对要计算的数据,以16bit为单元进行累加,然后取反。

TCP收包时,检查校验和:

static __sum16 tcp_v4_checksum_init(struct sk_buff *skb)

{

const struct iphdr *iph = ip_hdr(skb);

if (skb->ip_summed == CHECKSUM_COMPLETE) {

if (!tcp_v4_check(skb->len, iph->saddr, ///check TCP/UDP pseudo-header checksum

iph->daddr, skb->csum)) {

skb->ip_summed = CHECKSUM_UNNECESSARY;

return 0;

}

}

skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr,

skb->len, IPPROTO_TCP, 0); ///calc pseudo header checksum

if (skb->len <= 76) {

return __skb_checksum_complete(skb); /// 基于伪头累加和,计算整个数据包的checksum

}

return 0;

}

csum_tcpudp_nofold用于计算伪头的checksum,__skb_checksum_complete基于伪头累加和(skb->csum)计算整个skb的校验和。

net_device->features

net_device->features字段表示设备的各种特性。其中一些位用于表示硬件校验和的计算能力:

#define NETIF_F_IP_CSUM__NETIF_F(HW_CSUM)

#define NETIF_F_IP_CSUM__NETIF_F(IP_CSUM) ///ipv4 + TCP/UDP

#define NETIF_F_IPV6_CSUM__NETIF_F(IPV6_CSUM)

NETIF_F_IP_CSUM表示硬件可以计算L4 checksum,但是只针对IPV4的TCP和UDP。但是一些设备扩展支持VXLAN和NVGRE。

NETIF_F_IP_CSUM是一种协议感知的计算checksum的方法。具体来说,上层提供两个CSUM的参数(csum_start和csum_offset)。

NETIF_F_HW_CSUM is a protocol agnostic method to offload the transmit checksum. In this method the host

provides checksum related parameters in a transmit descriptor for a packet. These parameters include the

starting offset of data to checksum and the offset in the packet where the computed checksum is to be written. The

length of data to checksum is implicitly the length of the packet minus the starting offset.

值得一提的是,igb/ixgbe使用的NETIF_F_IP_CSUM.

sk_buff

取决于skb是接收封包,还是发送封包,skb->csum和skb->ip_summed的意义会不同。

/*

*@csum: Checksum (must incl

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值