UDP checksum可以分為四個部分
1. Pseudo Header
2. UDP Header
3. UDP Data
4. Padding
通常新式的網卡都會支援計算udp checksum
可以透過ethtool -k 網卡名稱檢查
而在Linux kernel Layer4中有定義在接收或送出packet時用到的幾個macro
- 接收packet
skb->ip_summed是判斷是否計算checksum的重點,可決定skb->csum帶的pseudo header的checksum值是否有意義,又可分為下列幾種macro的情況
#define CHECKSUM_NONE 0
#define CHECKSUM_UNNECESSARY 1
#define CHECKSUM_COMPLETE 2
CHECKSUM_NONE表示csum代表的值無意義,需要kernel中Layer4自行計算。有可能是硬體計算出錯或是硬體不支援計算功能
CHECKSUM_UNNECESSARY表示網卡或protocol stack已經計算了checksum值。
CHECKSUM_COMPLETE表示網卡已經計算了Layer4 payload的驗算,並且已經塞到csum中,此时Layer4的接收者只需要加pseudo header並驗算结果。
下面是步驟
1) 在Layer4發現如果udp->check被設為0,那麼skb->ip_summed直接設為CHECKSUM_UNNECESSARY,放行packet。
2) 如果skb->ip_summed為CHECKSUM_COMPLETE,則把skb->csum加上pseudo header進行驗算,成功則將skb->ip_summed設為CHECKSUM_UNNECESSARY, 放行該packet。
3) 通過上述後skb->ip_summed還不是CHECKSUM_UNNECESSARY,那麼重新計算pseudo header给skb->csum。
4) 將還不是CHECKSUM_UNNECESSARY的packet的payload加上skb->csum進行checksum計算,成功將設為CHECKSUM_UNNECESSARY並放行,失敗則丟棄
- 送出packet
ip->summed有下列兩種可能
#define CHECKSUM_NONE 0
#define CHECKSUM_PARTIAL 3
CHECKSUM_NONE 表示protocol stack計算好了checksum,網卡不需要做任何事。CHECKSUM_PARTIAL表示protocol stack算好了pseudo header需要網卡計算payload checksum。
下面是步驟
1)對於UDP socket開啟UDP_CSUM_NOXMIT /* UDP csum disabled */
uh->check = 0;
skb->ip_summed = CHECKSUM_NONE;
2)軟體udp checksum
struct iphdr *iph = ip_hdr(skb);
struct udphdr *uh = udp_hdr(skb);
uh->check = 0;
skb->csum = csum_partial(skb_transport_header (skb), skb->len, 0); //skb->da
uh->check = csum_tcpudp_magic(iph->saddr, iph->daddr, skb->len, iph->protocol, skb->csum);
skb->ip_summed = CHECKSUM_NONE;
//Todo: scatter and gather
3) 硬體checksum: 只能是ip报文長度小於mtu的数据报(没有分片的报文)。
CHECKSUM_PARTIAL表示使用網卡checksum ,Layer4的pseudo header的驗算已經完成,並且已經加入uh->check中,此时只需要硬體計算剩下的部分。
(對於支援scatter and gather的报文必須要transport header在線性空間才能使用硬體checksum功能)
uh->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, skb->len, IPPROTO_UDP, 0);
skb->csum_start = skb_transport_header (skb) - skb->head;
skb->csum_offset = offsetof(struct udphdr, check);
skb->ip_summed = CHECKSUM_PARTIAL;
4) 最後在dev_queue_xmit發送的时候發現網卡不支援硬體checksum就會進行軟體運算
ref : http://wenx05124561.blog.163.com/blog/static/124000805201242032041268/
留言列表