aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorSabrina Dubroca <sd@queasysnail.net>2015-02-04 17:08:50 -0500
committerDavid S. Miller <davem@davemloft.net>2015-02-05 18:41:34 -0500
commit7744b5f3693cc06695cb9d6667671c790282730f (patch)
tree5c444515404a89170ab1b10c353682a5573d9024 /net/core
parentc58da4c659803ac12eca5275c8a7064222adb4c7 (diff)
pktgen: fix UDP checksum computation
This patch fixes two issues in UDP checksum computation in pktgen. First, the pseudo-header uses the source and destination IP addresses. Currently, the ports are used for IPv4. Second, the UDP checksum covers both header and data. So we need to generate the data earlier (move pktgen_finalize_skb up), and compute the checksum for UDP header + data. Fixes: c26bf4a51308c ("pktgen: Add UDPCSUM flag to support UDP checksums") Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Acked-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/pktgen.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index da934fc3faa8..9fa25b0ea145 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2842,25 +2842,25 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2842 skb->dev = odev; 2842 skb->dev = odev;
2843 skb->pkt_type = PACKET_HOST; 2843 skb->pkt_type = PACKET_HOST;
2844 2844
2845 pktgen_finalize_skb(pkt_dev, skb, datalen);
2846
2845 if (!(pkt_dev->flags & F_UDPCSUM)) { 2847 if (!(pkt_dev->flags & F_UDPCSUM)) {
2846 skb->ip_summed = CHECKSUM_NONE; 2848 skb->ip_summed = CHECKSUM_NONE;
2847 } else if (odev->features & NETIF_F_V4_CSUM) { 2849 } else if (odev->features & NETIF_F_V4_CSUM) {
2848 skb->ip_summed = CHECKSUM_PARTIAL; 2850 skb->ip_summed = CHECKSUM_PARTIAL;
2849 skb->csum = 0; 2851 skb->csum = 0;
2850 udp4_hwcsum(skb, udph->source, udph->dest); 2852 udp4_hwcsum(skb, iph->saddr, iph->daddr);
2851 } else { 2853 } else {
2852 __wsum csum = udp_csum(skb); 2854 __wsum csum = skb_checksum(skb, skb_transport_offset(skb), datalen + 8, 0);
2853 2855
2854 /* add protocol-dependent pseudo-header */ 2856 /* add protocol-dependent pseudo-header */
2855 udph->check = csum_tcpudp_magic(udph->source, udph->dest, 2857 udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
2856 datalen + 8, IPPROTO_UDP, csum); 2858 datalen + 8, IPPROTO_UDP, csum);
2857 2859
2858 if (udph->check == 0) 2860 if (udph->check == 0)
2859 udph->check = CSUM_MANGLED_0; 2861 udph->check = CSUM_MANGLED_0;
2860 } 2862 }
2861 2863
2862 pktgen_finalize_skb(pkt_dev, skb, datalen);
2863
2864#ifdef CONFIG_XFRM 2864#ifdef CONFIG_XFRM
2865 if (!process_ipsec(pkt_dev, skb, protocol)) 2865 if (!process_ipsec(pkt_dev, skb, protocol))
2866 return NULL; 2866 return NULL;
@@ -2976,6 +2976,8 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2976 skb->dev = odev; 2976 skb->dev = odev;
2977 skb->pkt_type = PACKET_HOST; 2977 skb->pkt_type = PACKET_HOST;
2978 2978
2979 pktgen_finalize_skb(pkt_dev, skb, datalen);
2980
2979 if (!(pkt_dev->flags & F_UDPCSUM)) { 2981 if (!(pkt_dev->flags & F_UDPCSUM)) {
2980 skb->ip_summed = CHECKSUM_NONE; 2982 skb->ip_summed = CHECKSUM_NONE;
2981 } else if (odev->features & NETIF_F_V6_CSUM) { 2983 } else if (odev->features & NETIF_F_V6_CSUM) {
@@ -2984,7 +2986,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2984 skb->csum_offset = offsetof(struct udphdr, check); 2986 skb->csum_offset = offsetof(struct udphdr, check);
2985 udph->check = ~csum_ipv6_magic(&iph->saddr, &iph->daddr, udplen, IPPROTO_UDP, 0); 2987 udph->check = ~csum_ipv6_magic(&iph->saddr, &iph->daddr, udplen, IPPROTO_UDP, 0);
2986 } else { 2988 } else {
2987 __wsum csum = udp_csum(skb); 2989 __wsum csum = skb_checksum(skb, skb_transport_offset(skb), udplen, 0);
2988 2990
2989 /* add protocol-dependent pseudo-header */ 2991 /* add protocol-dependent pseudo-header */
2990 udph->check = csum_ipv6_magic(&iph->saddr, &iph->daddr, udplen, IPPROTO_UDP, csum); 2992 udph->check = csum_ipv6_magic(&iph->saddr, &iph->daddr, udplen, IPPROTO_UDP, csum);
@@ -2993,8 +2995,6 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2993 udph->check = CSUM_MANGLED_0; 2995 udph->check = CSUM_MANGLED_0;
2994 } 2996 }
2995 2997
2996 pktgen_finalize_skb(pkt_dev, skb, datalen);
2997
2998 return skb; 2998 return skb;
2999} 2999}
3000 3000