Just for my memo
In IPv4, the UDP checksum is not a forced definition, if you do not do checksum. it is still ok to talk each other. How ever, to switch off the checksum, you have to modify the source code of UDP protocol.
Priciple: in UDP Protocol. checksum=0 equals to checksum off. Therefore what we need to do is to find the part which do checksum calculation, and then replace it with 0.
The replaced part is put here
ndex: net/ipv4/udp.c =================================================================== --- net/ipv4/udp.c (revision 4935) +++ net/ipv4/udp.c (working copy) @@ -681,7 +681,9 @@ */ skb->csum_start = skb_transport_header(skb) - skb->head; skb->csum_offset = offsetof(struct udphdr, check); +/* uh->check = ~csum_tcpudp_magic(src, dst, len, IPPROTO_UDP, 0); +*/ uh->check = 0; } else { /* * HW-checksum won't work as there are two or more @@ -696,10 +698,12 @@ skb_queue_walk(&sk->sk_write_queue, skb) { csum = csum_add(csum, skb->csum); } - +/*Jeff commment uh->check = csum_tcpudp_magic(src, dst, len, IPPROTO_UDP, csum); if (uh->check == 0) uh->check = CSUM_MANGLED_0; +*/ + uh->check = 0; } } @@ -747,10 +751,14 @@ csum = udp_csum_outgoing(sk, skb); /* add protocol-dependent pseudo-header */ +/*Jeff comment uh->check = csum_tcpudp_magic(fl->fl4_src, fl->fl4_dst, up->len, sk->sk_protocol, csum); if (uh->check == 0) + uh->check = CSUM_MANGLED_0; +*/ + uh->check = 0; send: err = ip_push_pending_frames(sk); @@ -1546,9 +1554,10 @@ if (uh->check == 0) { skb->ip_summed = CHECKSUM_UNNECESSARY; } else if (skb->ip_summed == CHECKSUM_COMPLETE) { +/*Jeff comment if (!csum_tcpudp_magic(iph->saddr, iph->daddr, skb->len, proto, skb->csum)) - skb->ip_summed = CHECKSUM_UNNECESSARY; +*/ skb->ip_summed = CHECKSUM_UNNECESSARY; } if (!skb_csum_unnecessary(skb)) skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr, @@ -2193,8 +2202,11 @@ iph = ip_hdr(skb); uh = udp_hdr(skb); +/*Jeff comment uh->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, skb->len, IPPROTO_UDP, 0); +*/ uh->check = 0; + skb->csum_start = skb_transport_header(skb) - skb->head; skb->csum_offset = offsetof(struct udphdr, check); skb->ip_summed = CHECKSUM_PARTIAL; |