From owner-freebsd-net@FreeBSD.ORG Wed Aug 28 10:45:50 2013 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 532D1CB5 for ; Wed, 28 Aug 2013 10:45:50 +0000 (UTC) (envelope-from misc+freebsd@talk2dom.com) Received: from mail.shmtech.biz (unknown [IPv6:2001:41c8:10:8c::4:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id CBD562CFC for ; Wed, 28 Aug 2013 10:45:49 +0000 (UTC) Received: from wingwang.domlan.talk2dom.com (5ac6e914.bb.sky.com [90.198.233.20] (may be forged)) (authenticated bits=0) by mail.shmtech.biz (8.14.7/8.14.5) with ESMTP id r7SAjlgw000621 (version=TLSv1/SSLv3 cipher=DHE-RSA-CAMELLIA256-SHA bits=256 verify=NO) for ; Wed, 28 Aug 2013 11:45:47 +0100 (BST) (envelope-from misc+freebsd@talk2dom.com) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=talk2dom.com; s=shmtech1; t=1377686748; bh=JKm1Nt9V/5KQ4oL2en+KhFt18KX5Eng/i55KNXFjcw0=; h=Date:From:To:Subject:References:In-Reply-To; b=0c2vUHNNkY3JZNZbLqrPJI4pDxAmexVUbwEPI/0x0/junj1V4DEmSyIzuqLEqYUVM JjoHC3edpBWLMlo13C38uzg6B/m0BGhe45IaCqQxOBhrJdw6SCVq4bJRavDlK/ryKh mW7/M/NUQy6Am6ZLCL9Kzwl+F9DFLTqHQUIWjoiY= X-Authentication-Warning: sendmail: Host 5ac6e914.bb.sky.com [90.198.233.20] (may be forged) claimed to be wingwang.domlan.talk2dom.com Message-ID: <521DD4D6.7010403@talk2dom.com> Date: Wed, 28 Aug 2013 11:45:42 +0100 From: Dom F User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:17.0) Gecko/20130809 Thunderbird/17.0.8 MIME-Version: 1.0 To: freebsd-net@freebsd.org Subject: [IPFW] [DIVERT] IP header checksums - why calculate twice? References: In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Aug 2013 10:45:50 -0000 [Copy of my post to FreeBSD Firewalls forum sent here by suggestion from moderator] I've been toying with using IPDIVERT to adjust values in an IPv4 header. When adjusting an incoming IP header, the man page for divert(4) says: Quote: Packets written as incoming and having incorrect checksums will be dropped. My main issue was with trying to leverage the optimised kernel functions for checksumming an IP header, for example in_cksum_hdr(). Processes that connect to DIVERT sockets are based in user-land so in_cksum_hdr() isn't readily available during compile. Eventually the thought hit me that if some part of the kernel has to validate checksums (to decide whether to drop a packet) AND if my user-land process has to calculate a checksum to avoid its packet being dropped THEN surely there are two wasted checksum calculations going on? If a root-owned process, root needed for RAW socket, can be trusted to inject packets back into the IP stack then surely we can skip the checksum test and save a few CPU cycles plus a bit of latency. Very simple patch for /usr/src/sys/netinet/ip_divert.c (based on rev 224575): Code: --- ip_divert.c.orig 2013-08-26 20:52:18.000000000 +0100 +++ ip_divert.c 2013-08-26 20:52:44.000000000 +0100 @@ -496,6 +496,12 @@ /* Send packet to input processing via netisr */ switch (ip->ip_v) { case IPVERSION: + /* mark mbuf as having valid checksum + to save userland divert process from + calculating checksum, and kernel having + to check it */ + m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED | + CSUM_IP_VALID; netisr_queue_src(NETISR_IP, (uintptr_t)so, m); break; #ifdef INET6