2 * Copyright (c) 2010 Nicira Networks.
3 * Distributed under the terms of the GNU GPL version 2.
5 * Significant portions of this file may be copied from parts of the Linux
6 * kernel, by Linus Torvalds and others.
9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13 #include <linux/tcp.h>
14 #include <linux/udp.h>
19 /* Types of checksums that we can receive (these all refer to L4 checksums):
20 * 1. CHECKSUM_NONE: Device that did not compute checksum, contains full
21 * (though not verified) checksum in packet but not in skb->csum. Packets
22 * from the bridge local port will also have this type.
23 * 2. CHECKSUM_COMPLETE (CHECKSUM_HW): Good device that computes checksums,
24 * also the GRE module. This is the same as CHECKSUM_NONE, except it has
25 * a valid skb->csum. Importantly, both contain a full checksum (not
26 * verified) in the packet itself. The only difference is that if the
27 * packet gets to L4 processing on this machine (not in DomU) we won't
28 * have to recompute the checksum to verify. Most hardware devices do not
29 * produce packets with this type, even if they support receive checksum
30 * offloading (they produce type #5).
31 * 3. CHECKSUM_PARTIAL (CHECKSUM_HW): Packet without full checksum and needs to
32 * be computed if it is sent off box. Unfortunately on earlier kernels,
33 * this case is impossible to distinguish from #2, despite having opposite
34 * meanings. Xen adds an extra field on earlier kernels (see #4) in order
35 * to distinguish the different states.
36 * 4. CHECKSUM_UNNECESSARY (with proto_csum_blank true): This packet was
37 * generated locally by a Xen DomU and has a partial checksum. If it is
38 * handled on this machine (Dom0 or DomU), then the checksum will not be
39 * computed. If it goes off box, the checksum in the packet needs to be
40 * completed. Calling skb_checksum_setup converts this to CHECKSUM_HW
41 * (CHECKSUM_PARTIAL) so that the checksum can be completed. In later
42 * kernels, this combination is replaced with CHECKSUM_PARTIAL.
43 * 5. CHECKSUM_UNNECESSARY (with proto_csum_blank false): Packet with a correct
44 * full checksum or using a protocol without a checksum. skb->csum is
45 * undefined. This is common from devices with receive checksum
46 * offloading. This is somewhat similar to CHECKSUM_NONE, except that
47 * nobody will try to verify the checksum with CHECKSUM_UNNECESSARY.
49 * Note that on earlier kernels, CHECKSUM_COMPLETE and CHECKSUM_PARTIAL are
50 * both defined as CHECKSUM_HW. Normally the meaning of CHECKSUM_HW is clear
51 * based on whether it is on the transmit or receive path. After the datapath
52 * it will be intepreted as CHECKSUM_PARTIAL. If the packet already has a
53 * checksum, we will panic. Since we can receive packets with checksums, we
54 * assume that all CHECKSUM_HW packets have checksums and map them to
55 * CHECKSUM_NONE, which has a similar meaning (the it is only different if the
56 * packet is processed by the local IP stack, in which case it will need to
57 * be reverified). If we receive a packet with CHECKSUM_HW that really means
58 * CHECKSUM_PARTIAL, it will be sent with the wrong checksum. However, there
59 * shouldn't be any devices that do this with bridging.
61 #ifdef NEED_CSUM_NORMALIZE
62 void compute_ip_summed(struct sk_buff *skb, bool xmit)
64 /* For our convenience these defines change repeatedly between kernel
65 * versions, so we can't just copy them over...
67 switch (skb->ip_summed) {
69 OVS_CB(skb)->ip_summed = OVS_CSUM_NONE;
71 case CHECKSUM_UNNECESSARY:
72 OVS_CB(skb)->ip_summed = OVS_CSUM_UNNECESSARY;
75 /* In theory this could be either CHECKSUM_PARTIAL or CHECKSUM_COMPLETE.
76 * However, on the receive side we should only get CHECKSUM_PARTIAL
77 * packets from Xen, which uses some special fields to represent this
78 * (see below). Since we can only make one type work, pick the one
79 * that actually happens in practice.
81 * On the transmit side (basically after skb_checksum_setup()
82 * has been run or on internal dev transmit), packets with
83 * CHECKSUM_COMPLETE aren't generated, so assume CHECKSUM_PARTIAL.
87 OVS_CB(skb)->ip_summed = OVS_CSUM_COMPLETE;
89 OVS_CB(skb)->ip_summed = OVS_CSUM_PARTIAL;
93 case CHECKSUM_COMPLETE:
94 OVS_CB(skb)->ip_summed = OVS_CSUM_COMPLETE;
96 case CHECKSUM_PARTIAL:
97 OVS_CB(skb)->ip_summed = OVS_CSUM_PARTIAL;
102 #if defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID)
103 /* Xen has a special way of representing CHECKSUM_PARTIAL on older
104 * kernels. It should not be set on the transmit path though.
106 if (skb->proto_csum_blank)
107 OVS_CB(skb)->ip_summed = OVS_CSUM_PARTIAL;
109 WARN_ON_ONCE(skb->proto_csum_blank && xmit);
113 u8 get_ip_summed(struct sk_buff *skb)
115 return OVS_CB(skb)->ip_summed;
117 #endif /* NEED_CSUM_NORMALIZE */
119 #if defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID)
120 /* This code is based on skb_checksum_setup() from Xen's net/dev/core.c. We
121 * can't call this function directly because it isn't exported in all
123 int vswitch_skb_checksum_setup(struct sk_buff *skb)
128 __u16 csum_start, csum_offset;
130 if (!skb->proto_csum_blank)
133 if (skb->protocol != htons(ETH_P_IP))
136 if (!pskb_may_pull(skb, skb_network_header(skb) + sizeof(struct iphdr) - skb->data))
140 th = skb_network_header(skb) + 4 * iph->ihl;
142 csum_start = th - skb->head;
143 switch (iph->protocol) {
145 csum_offset = offsetof(struct tcphdr, check);
148 csum_offset = offsetof(struct udphdr, check);
152 pr_err("Attempting to checksum a non-TCP/UDP packet, "
153 "dropping a protocol %d packet",
158 if (!pskb_may_pull(skb, th + csum_offset + 2 - skb->data))
161 skb->ip_summed = CHECKSUM_PARTIAL;
162 skb->proto_csum_blank = 0;
163 set_skb_csum_pointers(skb, csum_start, csum_offset);
170 #endif /* CONFIG_XEN && HAVE_PROTO_DATA_VALID */