vxlan报文的csum处理逻辑由VXLAN_F_UDP_CSUM、VXLAN_F_REMCSUM_TX、VXLAN_F_REMCSUM_RX、VXLAN_F_REMCSUM_NOPARTIAL等等标记决定,本篇从发包流程来看实现逻辑:
vxlan_xmit_skb函数,还包括iptunnel_handle_offloads函数,实现功能如下图:
总结下:
1)如果报文是gso报文,那么设置csum或remcsum只是决定了skb的gso_type中添加的属性;
2)如果报文不是gso报文,那么skb的ip_summed最终会设置为CHECKSUM_NONE;
2.1 设置csum但是未设置remcsum,则报文的encapsulation会被置为0;
2.2 设置csum但是未设置remcsum,且报文的ip_summed为CHECKSUM_PARTIAL,则需要软件计算内层报文的csum值;
udp_set_csum函数(udp_tunnel_xmit_skb函数封装UDP头时,计算csum值)
void udp_set_csum(bool nocheck, struct sk_buff *skb,
__be32 saddr, __be32 daddr, int len)
{
struct udphdr *uh = udp_hdr(skb);
if (nocheck) //如果ovs的vxlan设备支持VXLAN_F_UDP_CSUM标记,则该值为true,默认为false
uh->check = 0;
else if (skb_is_gso(skb)) //对于gso报文,仅需要计算UDP头的csum值
uh->check = ~udp_v4_check(len, saddr, daddr, 0); //如果是gso报文,仅计算UDP伪首部的csum值
else if (skb_dst(skb) && skb_dst(skb)->dev &&
(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) { //virtio-net设备不支持该特性,硬件网卡一般都支持
BUG_ON(skb->ip_summed == CHECKSUM_PARTIAL); //非gso报文,ip_summed不可能为CHECKSUM_PARTIAL,见vxlan_xmit_skb函数分析