aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/udp.c')
-rw-r--r--net/ipv4/udp.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 766e6bab9113..74d2c95db57f 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -704,7 +704,7 @@ EXPORT_SYMBOL(udp_flush_pending_frames);
704 * @src: source IP address 704 * @src: source IP address
705 * @dst: destination IP address 705 * @dst: destination IP address
706 */ 706 */
707static void udp4_hwcsum(struct sk_buff *skb, __be32 src, __be32 dst) 707void udp4_hwcsum(struct sk_buff *skb, __be32 src, __be32 dst)
708{ 708{
709 struct udphdr *uh = udp_hdr(skb); 709 struct udphdr *uh = udp_hdr(skb);
710 struct sk_buff *frags = skb_shinfo(skb)->frag_list; 710 struct sk_buff *frags = skb_shinfo(skb)->frag_list;
@@ -740,6 +740,7 @@ static void udp4_hwcsum(struct sk_buff *skb, __be32 src, __be32 dst)
740 uh->check = CSUM_MANGLED_0; 740 uh->check = CSUM_MANGLED_0;
741 } 741 }
742} 742}
743EXPORT_SYMBOL_GPL(udp4_hwcsum);
743 744
744static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4) 745static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4)
745{ 746{
@@ -2158,7 +2159,7 @@ static void udp4_format_sock(struct sock *sp, struct seq_file *f,
2158 __u16 srcp = ntohs(inet->inet_sport); 2159 __u16 srcp = ntohs(inet->inet_sport);
2159 2160
2160 seq_printf(f, "%5d: %08X:%04X %08X:%04X" 2161 seq_printf(f, "%5d: %08X:%04X %08X:%04X"
2161 " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %pK %d%n", 2162 " %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %d%n",
2162 bucket, src, srcp, dest, destp, sp->sk_state, 2163 bucket, src, srcp, dest, destp, sp->sk_state,
2163 sk_wmem_alloc_get(sp), 2164 sk_wmem_alloc_get(sp),
2164 sk_rmem_alloc_get(sp), 2165 sk_rmem_alloc_get(sp),
@@ -2336,7 +2337,7 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb,
2336 uh->len = htons(skb->len - udp_offset); 2337 uh->len = htons(skb->len - udp_offset);
2337 2338
2338 /* csum segment if tunnel sets skb with csum. */ 2339 /* csum segment if tunnel sets skb with csum. */
2339 if (unlikely(uh->check)) { 2340 if (protocol == htons(ETH_P_IP) && unlikely(uh->check)) {
2340 struct iphdr *iph = ip_hdr(skb); 2341 struct iphdr *iph = ip_hdr(skb);
2341 2342
2342 uh->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, 2343 uh->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
@@ -2347,7 +2348,18 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb,
2347 if (uh->check == 0) 2348 if (uh->check == 0)
2348 uh->check = CSUM_MANGLED_0; 2349 uh->check = CSUM_MANGLED_0;
2349 2350
2351 } else if (protocol == htons(ETH_P_IPV6)) {
2352 struct ipv6hdr *ipv6h = ipv6_hdr(skb);
2353 u32 len = skb->len - udp_offset;
2354
2355 uh->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr,
2356 len, IPPROTO_UDP, 0);
2357 uh->check = csum_fold(skb_checksum(skb, udp_offset, len, 0));
2358 if (uh->check == 0)
2359 uh->check = CSUM_MANGLED_0;
2360 skb->ip_summed = CHECKSUM_NONE;
2350 } 2361 }
2362
2351 skb->protocol = protocol; 2363 skb->protocol = protocol;
2352 } while ((skb = skb->next)); 2364 } while ((skb = skb->next));
2353out: 2365out: