From nobody@FreeBSD.org  Fri Feb 28 21:09:07 2014
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115])
	(using TLSv1 with cipher ADH-AES256-SHA (256/256 bits))
	(No client certificate requested)
	by hub.freebsd.org (Postfix) with ESMTPS id 0F44595A
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 28 Feb 2014 21:09:07 +0000 (UTC)
Received: from newred.freebsd.org (cgiserv.freebsd.org [IPv6:2001:1900:2254:206a::50:4])
	(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
	(No client certificate requested)
	by mx1.freebsd.org (Postfix) with ESMTPS id D50DE183F
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 28 Feb 2014 21:09:06 +0000 (UTC)
Received: from cgiserv.freebsd.org ([127.0.1.6])
	by newred.freebsd.org (8.14.7/8.14.7) with ESMTP id s1SL96D8092464
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 28 Feb 2014 21:09:06 GMT
	(envelope-from nobody@cgiserv.freebsd.org)
Received: (from nobody@localhost)
	by cgiserv.freebsd.org (8.14.7/8.14.7/Submit) id s1SL96KS092459;
	Fri, 28 Feb 2014 21:09:06 GMT
	(envelope-from nobody)
Message-Id: <201402282109.s1SL96KS092459@cgiserv.freebsd.org>
Date: Fri, 28 Feb 2014 21:09:06 GMT
From: Olivier Cochard-Labbe <olivier@cochard.me>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Patch for fixng netmap's pkt-gen behavior with IP addresses or port range
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         187149
>Category:       kern
>Synopsis:       [patch] [netmap] fix netmap's pkt-gen behavior with IP addresses or port range
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-net
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Feb 28 21:10:00 UTC 2014
>Closed-Date:    
>Last-Modified:  Wed Apr 16 01:42:56 UTC 2014
>Originator:     Olivier Cochard-Labbe
>Release:        -current
>Organization:
BSD Router Project
>Environment:
FreeBSD R1 11.0-CURRENT FreeBSD 11.0-CURRENT #0 r262618M: Fri Feb 28 21:07:26 CET 2014     root@orange.bsdrp.net:/usr/obj/BSDRPcur.amd64/usr/local/BSDRP/BSDRPcur/FreeBSD/src/sys/amd64  amd64
>Description:
Using range option of netmap's pkt-gen generate packets with bad IP and UDP checksum.
>How-To-Repeat:
If you pkt-gen this this kind of range option:
-f tx -l 60 -d 2.1.3.1-2.1.3.10 -s 1.1.3.1-1.1.3.10

A tcpdump on the receiving host will display that it's recveing lot's of packets with bad checksums:

19:31:28.029702 IP (tos 0x10, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 46, bad cksum 31ac (->31a1)!)
    1.1.3.9.0 > 2.1.3.4.0: [bad udp cksum 0x2a23 -> 0x2a18!] UDP, length 18
19:31:28.029704 IP (tos 0x10, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 46, bad cksum 31ac (->31a3)!)
    1.1.3.10.0 > 2.1.3.1.0: [bad udp cksum 0x2a23 -> 0x2a1a!] UDP, length 18
19:31:28.029705 IP (tos 0x10, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 46, bad cksum 31ac (->31a6)!)
    1.1.3.4.0 > 2.1.3.4.0: [bad udp cksum 0x2a23 -> 0x2a1d!] UDP, length 18
19:31:28.029706 IP (tos 0x10, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 46, bad cksum 31ac (->31a4)!)
>Fix:
Applying the attached patch.

Patch attached with submission follows:

Index: tools/tools/netmap/pkt-gen.c
===================================================================
--- tools/tools/netmap/pkt-gen.c	(revision 262618)
+++ tools/tools/netmap/pkt-gen.c	(working copy)
@@ -546,6 +546,7 @@
 {
 	uint32_t a;
 	uint16_t p;
+	struct ether_header *eh = &pkt->eh;
 	struct ip *ip = &pkt->ip;
 	struct udphdr *udp = &pkt->udp;
 
@@ -580,6 +581,25 @@
 	ip->ip_dst.s_addr = htonl(g->dst_ip.start);
     } while (0);
     // update checksum
+	/* Missing code here ? the comment "update checksum" should be followed
+	 * by updating IP & UDP checksum. I will try to fix by simply copy/past
+	 * checksum code from initialize_packet function */
+
+	ip->ip_sum = 0;
+	ip->ip_sum = wrapsum(checksum(ip, sizeof(*ip), 0));
+
+	/* UDP checksum */
+	uint16_t paylen = g->pkt_size - sizeof(*eh) - sizeof(struct ip);
+	udp->uh_sum = 0;
+	udp->uh_sum = wrapsum(checksum(udp, sizeof(*udp),
+                    checksum(pkt->body,
+                        paylen - sizeof(*udp),
+                        checksum(&ip->ip_src, 2 * sizeof(ip->ip_src),
+                            IPPROTO_UDP + (u_int32_t)ntohs(udp->uh_ulen)
+                        )
+                    )
+                ));
+
 }
 
 /*


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-net 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Wed Apr 16 01:42:19 UTC 2014 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=187149 
>Unformatted:
