1 #ifndef __XEN_NETUTIL_H__
2 #define __XEN_NETUTIL_H__
4 #include <linux/kernel.h>
5 #include <linux/skbuff.h>
10 static inline int skb_checksum_setup(struct sk_buff *skb,
11 unsigned long *fixup_counter)
13 struct iphdr *iph = (void *)skb->data;
18 if (skb->ip_summed != CHECKSUM_PARTIAL) {
19 /* A non-CHECKSUM_PARTIAL SKB does not require setup. */
24 * A GSO SKB must be CHECKSUM_PARTIAL. However some buggy
25 * peers can fail to set NETRXF_csum_blank when sending a GSO
26 * frame. In this case force the SKB to CHECKSUM_PARTIAL and
27 * recalculate the partial checksum.
33 if (skb->protocol != htons(ETH_P_IP))
36 th = skb->data + 4 * iph->ihl;
37 if (th >= skb_tail_pointer(skb))
40 skb->csum_start = th - skb->head;
41 switch (iph->protocol) {
43 skb->csum_offset = offsetof(struct tcphdr, check);
45 csum = &((struct tcphdr *)th)->check;
48 skb->csum_offset = offsetof(struct udphdr, check);
50 csum = &((struct udphdr *)th)->check;
54 pr_err("Attempting to checksum a non-"
55 "TCP/UDP packet, dropping a protocol"
56 " %d packet\n", iph->protocol);
60 if ((th + skb->csum_offset + sizeof(*csum)) > skb_tail_pointer(skb))
64 *csum = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
65 skb->len - iph->ihl*4,
67 skb->ip_summed = CHECKSUM_PARTIAL;
75 #endif /* __XEN_NETUTIL_H__ */