aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/udp_offload.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/udp_offload.c')
-rw-r--r--net/ipv4/udp_offload.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index 83206de2bc76..79c62bdcd3c5 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -41,6 +41,14 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb,
41{ 41{
42 struct sk_buff *segs = ERR_PTR(-EINVAL); 42 struct sk_buff *segs = ERR_PTR(-EINVAL);
43 unsigned int mss; 43 unsigned int mss;
44 int offset;
45 __wsum csum;
46
47 if (skb->encapsulation &&
48 skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) {
49 segs = skb_udp_tunnel_segment(skb, features);
50 goto out;
51 }
44 52
45 mss = skb_shinfo(skb)->gso_size; 53 mss = skb_shinfo(skb)->gso_size;
46 if (unlikely(skb->len <= mss)) 54 if (unlikely(skb->len <= mss))
@@ -63,27 +71,20 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb,
63 goto out; 71 goto out;
64 } 72 }
65 73
74 /* Do software UFO. Complete and fill in the UDP checksum as
75 * HW cannot do checksum of UDP packets sent as multiple
76 * IP fragments.
77 */
78 offset = skb_checksum_start_offset(skb);
79 csum = skb_checksum(skb, offset, skb->len - offset, 0);
80 offset += skb->csum_offset;
81 *(__sum16 *)(skb->data + offset) = csum_fold(csum);
82 skb->ip_summed = CHECKSUM_NONE;
83
66 /* Fragment the skb. IP headers of the fragments are updated in 84 /* Fragment the skb. IP headers of the fragments are updated in
67 * inet_gso_segment() 85 * inet_gso_segment()
68 */ 86 */
69 if (skb->encapsulation && skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) 87 segs = skb_segment(skb, features);
70 segs = skb_udp_tunnel_segment(skb, features);
71 else {
72 int offset;
73 __wsum csum;
74
75 /* Do software UFO. Complete and fill in the UDP checksum as
76 * HW cannot do checksum of UDP packets sent as multiple
77 * IP fragments.
78 */
79 offset = skb_checksum_start_offset(skb);
80 csum = skb_checksum(skb, offset, skb->len - offset, 0);
81 offset += skb->csum_offset;
82 *(__sum16 *)(skb->data + offset) = csum_fold(csum);
83 skb->ip_summed = CHECKSUM_NONE;
84
85 segs = skb_segment(skb, features);
86 }
87out: 88out:
88 return segs; 89 return segs;
89} 90}