From owner-freebsd-net@FreeBSD.ORG Mon Sep 11 05:46:59 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1D9BD16A403; Mon, 11 Sep 2006 05:46:59 +0000 (UTC) (envelope-from if@hetzner.co.za) Received: from hetzner.co.za (office.cpt2.host-h.net [196.7.147.230]) by mx1.FreeBSD.org (Postfix) with ESMTP id 973B943D49; Mon, 11 Sep 2006 05:46:57 +0000 (GMT) (envelope-from if@hetzner.co.za) Received: from localhost ([127.0.0.1] helo=ian.hetzner.africa) by hetzner.co.za with esmtp (Exim 4.62 (FreeBSD)) (envelope-from ) id 1GMedA-0003eD-Vj; Mon, 11 Sep 2006 07:46:52 +0200 To: Prafulla Deuskar From: Ian FREISLICH In-Reply-To: Message from Prafulla Deuskar of "Sat, 09 Sep 2006 07:00:15 GMT." <20060909070015.GA71855@hub.freebsd.org> X-Attribution: BOFH Date: Mon, 11 Sep 2006 07:46:52 +0200 Message-Id: Cc: Pyun YongHyeon , freebsd-net , freebsd-current , Jack Vogel Subject: Re: RFC: TSO patch for current X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Sep 2006 05:46:59 -0000 Prafulla Deuskar wrote: > Pyun YongHyeon [pyunyh@gmail.com] wrote: > >What happen if users disable hardware > > VLAN tag insertion with ifconfig(8)? > > TSO requires that VLAN tag insertion is done by hardware This is bad news. I use CARP interfaces in all my VLANs which places the interface in promiscuous mode. I've noted that the em driver stops tagging ethernet frames when hardware tag insertion is enabled and the interface is in promiscuous mode. I don't know enough to determine whether this is a hardware or software bug. Ian -- Ian Freislich From owner-freebsd-net@FreeBSD.ORG Mon Sep 11 10:14:08 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3C09F16A412; Mon, 11 Sep 2006 10:14:08 +0000 (UTC) (envelope-from mlh@ispinfo.fr) Received: from viviane.ispinfo.fr (viviane.ispinfo.fr [81.255.64.46]) by mx1.FreeBSD.org (Postfix) with ESMTP id 977AD43D45; Mon, 11 Sep 2006 10:14:06 +0000 (GMT) (envelope-from mlh@ispinfo.fr) Received: from srvnet.acces-industrie.com (smtp0.ispinfo.fr [81.255.64.47]) by viviane.ispinfo.fr (8.12.11/8.12.11) with ESMTP id k8BAE5lj075055; Mon, 11 Sep 2006 12:14:05 +0200 (CEST) (envelope-from mlh@ispinfo.fr) Received: from pm2.awape.fr (pm2.awape.fr [81.255.64.42]) by srvnet.acces-industrie.com (8.11.1/8.11.1) with ESMTP id k8BAE4069447; Mon, 11 Sep 2006 12:14:05 +0200 (CEST) (envelope-from mlh@ispinfo.fr) Received: from smtpe.ispinfo.fr (smtpe.ispinfo.fr [81.255.64.52]) by pm2.awape.fr (8.13.4/8.13.4) with ESMTP id k8BA93oT039431; Mon, 11 Sep 2006 12:09:03 +0200 (CEST) (envelope-from mlh@ispinfo.fr) Received: from [192.168.0.82] ([192.168.0.82]) by smtpe.ispinfo.fr (8.12.8p1/8.12.3) with ESMTP id k8BAE2QT053406; Mon, 11 Sep 2006 12:14:03 +0200 (CEST) (envelope-from mlh@ispinfo.fr) Message-ID: <450536E9.2010106@ispinfo.fr> Date: Mon, 11 Sep 2006 12:14:01 +0200 From: Administrators User-Agent: Thunderbird 1.5.0.5 (X11/20060728) MIME-Version: 1.0 To: freebsd-questions@freebsd.org, freebsd-net@freebsd.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit Cc: Subject: NAT+IPSEC toubles X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Sep 2006 10:14:08 -0000 Hi, I'm building VPN connected to CISCO device. I NEED to translate my LAN adress to a given adress. The VPN work well when I try doing ifconfig em0 alias _given_@_ ping -S _given_@_ dest_@ but I didn't manage to translate LAN adresse AND having VPN used. I can pass throug VPN using actual adress but the CISCO endpoint drop it or I translate, but packets didn't go in the VPN. Any idea ? Using 4.9-RELEASE-p4, ipf and ipnat Hubert Adgié. Administrateur Système. From owner-freebsd-net@FreeBSD.ORG Mon Sep 11 11:08:21 2006 Return-Path: X-Original-To: freebsd-net@FreeBSD.org Delivered-To: freebsd-net@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 484DB16A403 for ; Mon, 11 Sep 2006 11:08:21 +0000 (UTC) (envelope-from owner-bugmaster@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id D9D6543D53 for ; Mon, 11 Sep 2006 11:08:20 +0000 (GMT) (envelope-from owner-bugmaster@FreeBSD.org) Received: from freefall.freebsd.org (linimon@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id k8BB8KYF063250 for ; Mon, 11 Sep 2006 11:08:20 GMT (envelope-from owner-bugmaster@FreeBSD.org) Received: (from linimon@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id k8BB8I4I063246 for freebsd-net@FreeBSD.org; Mon, 11 Sep 2006 11:08:18 GMT (envelope-from owner-bugmaster@FreeBSD.org) Date: Mon, 11 Sep 2006 11:08:18 GMT Message-Id: <200609111108.k8BB8I4I063246@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: linimon set sender to owner-bugmaster@FreeBSD.org using -f From: FreeBSD bugmaster To: freebsd-net@FreeBSD.org Cc: Subject: Current problem reports assigned to you X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Sep 2006 11:08:21 -0000 Current FreeBSD problem reports Critical problems Serious problems S Tracker Resp. Description -------------------------------------------------------------------------------- o kern/92552 net A serious bug in most network drivers from 5.X to 6.X f kern/93220 net [inet6] nd6_lookup: failed to add route for a neighbor 2 problems total. Non-critical problems S Tracker Resp. Description -------------------------------------------------------------------------------- s kern/19875 net A new protocol family, PF_IPOPTION, to handle IP optio o conf/23063 net [PATCH] for static ARP tables in rc.network o kern/54383 net [nfs] [patch] NFS root configurations without dynamic s kern/60293 net FreeBSD arp poison patch o kern/95267 net packet drops periodically appear o kern/102035 net [plip] plip networking disables parallel port printing o conf/102502 net [patch] ifconfig name does't rename netgraph node in n o kern/102607 net [if_bridge] don't generate random L2 address 8 problems total. From owner-freebsd-net@FreeBSD.ORG Mon Sep 11 13:09:30 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 52F5B16A407 for ; Mon, 11 Sep 2006 13:09:30 +0000 (UTC) (envelope-from vanhu@zeninc.net) Received: from leia.fdn.fr (ns0.fdn.org [80.67.169.12]) by mx1.FreeBSD.org (Postfix) with ESMTP id C850743D53 for ; Mon, 11 Sep 2006 13:09:29 +0000 (GMT) (envelope-from vanhu@zeninc.net) Received: from smtp.zeninc.net (reverse-25.fdn.fr [80.67.176.25]) by leia.fdn.fr (8.13.3/8.13.3/FDN) with ESMTP id k8BD9PIW012136 for ; Mon, 11 Sep 2006 15:09:27 +0200 Received: by smtp.zeninc.net (smtpd, from userid 1000) id B0F2A3F17; Mon, 11 Sep 2006 15:09:19 +0200 (CEST) Date: Mon, 11 Sep 2006 15:09:19 +0200 From: VANHULLEBUS Yvan To: freebsd-net@freebsd.org Message-ID: <20060911130919.GA23541@zen.inc> References: <450536E9.2010106@ispinfo.fr> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <450536E9.2010106@ispinfo.fr> User-Agent: All mail clients suck. This one just sucks less. Subject: Re: NAT+IPSEC toubles X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Sep 2006 13:09:30 -0000 On Mon, Sep 11, 2006 at 12:14:01PM +0200, Administrators wrote: > Hi, Hi. > I'm building VPN connected to CISCO device. > > I NEED to translate my LAN adress to a given adress. > > The VPN work well when I try doing > ifconfig em0 alias _given_@_ > ping -S _given_@_ dest_@ > > but I didn't manage to translate LAN adresse AND having VPN used. > > I can pass throug VPN using actual adress but the CISCO endpoint drop it > or I translate, but packets didn't go in the VPN. > > Any idea ? The IPSec stack is hooked before NAT process (AFAIK), so it is not possible to do that on a single box. It is still possible to do what you want, but you'll have to revert IPSec and NAT part in ip_input / ip_output sources. If lots of people are interested in that, I can add "doing a NAT/VPN order patch" to my TODO list... Yvan. -- NETASQ http://www.netasq.com From owner-freebsd-net@FreeBSD.ORG Mon Sep 11 13:14:12 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E49A916A403 for ; Mon, 11 Sep 2006 13:14:12 +0000 (UTC) (envelope-from steph@gabswave.net) Received: from smtp.bbi.co.bw (smtp.bbi.co.bw [193.219.214.13]) by mx1.FreeBSD.org (Postfix) with ESMTP id 81BE443D55 for ; Mon, 11 Sep 2006 13:14:04 +0000 (GMT) (envelope-from steph@gabswave.net) Received: from STEPHANFCN56VN (warez.bbi.co.bw [10.6.0.24]) by smtp.bbi.co.bw (8.13.4/8.13.4) with ESMTP id k8BFHVMU025911 for ; Mon, 11 Sep 2006 15:17:39 GMT From: "Steph" To: Date: Mon, 11 Sep 2006 15:12:20 +0200 Message-ID: <00ee01c6d5a3$ed86ae50$1800060a@STEPHANFCN56VN> MIME-Version: 1.0 X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook, Build 10.0.2627 Importance: Normal X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2180 X-bbi.co.bw-MailScanner-Information: Please contact the ISP for more information X-bbi.co.bw-MailScanner: Found to be clean X-bbi.co.bw-MailScanner-From: steph@gabswave.net X-Spam-Status: No Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Subject: Network Card problems in FreeBSD 4.9 X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Sep 2006 13:14:13 -0000 Hi There, I've recompiled my kernel since I needed to add a new Driver for some bandwidth management software I'm running and for some reason when I reboot the box with the new kernel it doesn't show my Network Interfaces when doing an ifconfig -a. The one device is a Dual Intel Pro/1000 Adaptor and the other is a Dual Broadcom I think. I've compiled the drivers for these devices directly into the kernel without any errors. They do show up when doing a pciconf -lv. I'm new to FreeBSD so the chances that I've screwed something up somewhere is quite good :-) Is there anything else I should be looking out for? none3@pci2:1:0: class=0x020000 card=0x00291374 chip=0x00291374 rev=0x03 hdr=0x00 vendor = 'Silicom Ltd' class = network subclass = ethernet none4@pci2:1:1: class=0x020000 card=0x00291374 chip=0x00291374 rev=0x03 hdr=0x00 vendor = 'Silicom Ltd' class = network subclass = ethernet none5@pci4:0:0: class=0x020000 card=0x02c615d9 chip=0x165914e4 rev=0x11 hdr=0x00 vendor = 'Broadcom Corporation' class = network subclass = ethernet none6@pci5:0:0: class=0x020000 card=0x02c615d9 chip=0x165914e4 rev=0x11 hdr=0x00 vendor = 'Broadcom Corporation' class = network subclass = Ethernet Thanks in advance. -steph From owner-freebsd-net@FreeBSD.ORG Mon Sep 11 13:41:54 2006 Return-Path: X-Original-To: net@freebsd.org Delivered-To: freebsd-net@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 91A8016A49E; Mon, 11 Sep 2006 13:41:54 +0000 (UTC) (envelope-from sa@nkz.delikates-nk.ru) Received: from nkz.delikates-nk.ru (nkz.delikates-nk.ru [81.16.143.102]) by mx1.FreeBSD.org (Postfix) with ESMTP id 92B7B43D49; Mon, 11 Sep 2006 13:41:53 +0000 (GMT) (envelope-from sa@nkz.delikates-nk.ru) Received: from nkz.delikates-nk.ru (localhost [127.0.0.1]) by nkz.delikates-nk.ru (8.13.8/8.13.8) with ESMTP id k8BDfogL020222; Mon, 11 Sep 2006 21:41:50 +0800 (KRAST) (envelope-from sa@nkz.delikates-nk.ru) Received: (from sa@localhost) by nkz.delikates-nk.ru (8.13.8/8.13.8/Submit) id k8BDfneZ020221; Mon, 11 Sep 2006 21:41:49 +0800 (KRAST) (envelope-from sa) Date: Mon, 11 Sep 2006 21:41:49 +0800 (KRAST) Message-Id: <200609111341.k8BDfneZ020221@nkz.delikates-nk.ru> To: FreeBSD-gnats-submit@freebsd.org From: Eugene Grosbein X-send-pr-version: 3.113 X-GNATS-Notify: X-Virus-Scanned: ClamAV 0.88.4/1855/Mon Sep 11 20:50:29 2006 on nkz.delikates-nk.ru X-Virus-Status: Clean Cc: net@freebsd.org Subject: ipsec with ipfw divert (not NAT) encodes a packet twice breaking PMTUD X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Sep 2006 13:41:54 -0000 >Submitter-Id: current-users >Originator: Eugene Grosbein >Organization: Svyaz Service JSC >Confidential: no >Synopsis: ipsec with ipfw divert (not NAT) encodes a packet twice breaking PMTUD >Severity: serious >Priority: high >Category: kern >Class: sw-bug >Release: FreeBSD 6.1-STABLE i386 >Environment: System: FreeBSD nkz.delikates-nk.ru 6.1-STABLE FreeBSD 6.1-STABLE #1: Thu Sep 7 13:31:53 KRAST 2006 root@nkz.delikates-nk.ru:/home/obj/home/src/sys/NKZ i386 options IPDIVERT options IPSEC options IPSEC_ESP >Description: When outgoing packet encoded due to corresponding IPSEC policy is passed to divert socket (f.e. to ipacctd for accounting), it is encoded second time with IPSEC then. Besides obvious logic error, this also results in broken Path MTU Discovery. >How-To-Repeat: Use a kernel with options IPDIVERT, IPSEC, IPSEC_ESP (my kernel also contains IPSEC_FILTERGIF, but this should not matter). Suppose there are two local nets numbered 192.168.1.0/24 and 192.168.2.0/24, each has a FreeBSD router (192.168.1.1 and 192.168.2.1). Routers make gif(4) tunnel between and use IPSEC transport mode to encrypt its contents. Their external IP addresses are 1.1.1.1 and 2.2.2.2 Here is /etc/ipsec.conf: add 1.1.1.1 81.16.143.102 esp 1007 -m transport -E blowfish-cbc "xxx"; add 2.2.2.2 1.1.1.1 esp 2007 -m transport -E blowfish-cbc "yyy"; spdadd 1.1.1.1/32 2.2.2.2/32 any -P in ipsec esp/transport/1.1.1.1-2.2.2.2/require; spdadd 2.2.2.2/32 1.1.1.1/32 any -P out ipsec esp/transport/2.2.2.2-1.1.1.1/require; Another router has similar /etc/ipsec.conf. Use this script to prepare IPSEC keys for tcpdump: #!/bin/sh setkey -D | awk ' /^[1-9]/ { ip=$2; } $1=="esp" { sub(/spi=[^(]+\(/, "", $3); sub(/\)/, "", $3); printf"%s@%s ",$3,ip; } $1=="E:" { printf "%s:0x%s%s%s%s\n", $2, $3, $4, $5, $6; } ' > /tmp/keys.txt When we use one of the routers to run "tcpdump -s0 -n -p -i $iface -E /tmp/keys.txt esp", we see that traffic is encoded with ESP and decoded properly, still good. Now install ports/net-mgmt/ipacctd, run it manually with "ipacctd -p 4000", then command: "ipfw add 10 divert 4000 ip from any to any out" and rerun tcpdump command shown above. You'll see that outgoing packets are encapsulated with ESP twice. The same you'll see at the other side for incoming packets. >Fix: Unknown. The only known workaround is to avoid diverting ESP. This workaroung is not always acceptable. Eugene Grosbein From owner-freebsd-net@FreeBSD.ORG Mon Sep 11 19:56:19 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5BC4016A4D1; Mon, 11 Sep 2006 19:56:19 +0000 (UTC) (envelope-from marcelo@registro.br) Received: from clone.registro.br (clone.registro.br [200.160.2.4]) by mx1.FreeBSD.org (Postfix) with ESMTP id BB0B043D98; Mon, 11 Sep 2006 19:55:22 +0000 (GMT) (envelope-from marcelo@registro.br) Received: by clone.registro.br (Postfix, from userid 1014) id 83C8C2A586; Mon, 11 Sep 2006 16:55:21 -0300 (BRT) Date: Mon, 11 Sep 2006 16:55:21 -0300 From: Marcelo Gardini do Amaral To: freebsd-stable@freebsd.org Message-ID: <20060911195521.GD63300@registro.br> References: <2a41acea0608301145j7bbed961j33ce903a27d8963d@mail.gmail.com> <20060904130827.GE12975@registro.br> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20060904130827.GE12975@registro.br> User-Agent: Mutt/1.4.2.1i Cc: freebsd-net@freebsd.org Subject: DNS query performance X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Sep 2006 19:56:19 -0000 I would like to discuss a little bit more about UDP performance. I've made some tests and the results may have some value here. In this test is easy to see that there is something different in the FreeBSD 6 branch. I made a benchmark with bind 9.3.2 (without threads support) and nsd 3.0.1 (1 server forked) on a HP Proliant Dual AMD Opteron 2.4GHz among FreeBSD 4.11, 6.1 and Linux kernel 2.6.15, all of them for i386 systems. I used this simple zone file: # cat db.FOO.BAR $TTL 86400 @ 172800 in soa foo.dns.bar. hostmaster.foo.bar. ( 2006090601 ;serial 1800 ;refresh 30 minutos 900 ;retry 15 minutos 604800 ;expire 7 dias 900 ) ;negative caching 15 minutos 172800 in ns foo.dns.bar. ; zone delegation begin test1 IN NS qq1.bsd. test2 IN NS qq2.bsd. test3 IN NS qq3.bsd. test4 IN NS qq4.bsd. test5 IN NS qq5.bsd. test6 IN NS qq6.bsd. test7 IN NS qq7.bsd. test8 IN NS qq8.bsd. test9 IN NS qq9.bsd. In another box with the same hardware I used FreeBSD 4.11 and queryperf (DNS Query Performance Testing Tool) as a client to realize 1.000.000 of NS queries on the servers. Below I show the results: queries per second OS Bind 9.3.2 NSD 3.0.1 ---- ---- ---- Linux 2.6 SMP 38845 59645 FreeBSD 4.11 SMP 34977 59417 FreeBSD 4.11 UP 33926 59547 FreeBSD 6.1 SMP 14953 15908 FreeBSD 6.1 UP 15516 14752 Comments: Linux had a performance just 10% better than FreeBSD 4.11 with bind. With nsd I didn't see any difference between them. There is no difference also tweaking the kernel from UP to SMP. With nsd the performance was improved to ~60k queries per second on 4.11 and Linux, i.e., it was almost doubled comparing with bind. I couldn't see any packet loss in any case. On the other hand, on FreeBSD 6.1 the result was lower than half of bind's performance on the others systems tested. And with nsd the result didn't get better (unlike happend on FreeBSD 4.11). I also got some 'timeout' on FreeBSD 6.1 - about 200 from 1M packets were lost. In actual fact, I think that is important to emphasize that the same limit was reached on both name servers - no more than ~15k queries per second was possible on 6.1. I think there is an issue on the system, not on bind neither nsd. Besides this, I've noticed some problems with bge interface driver. Many times the interface is up and running and suddenly goes down, without any reason, or after a reboot it doesn't go up. And if you just remove and insert again the cable, everything returns to work. On up-to-date FreeBSD 6 boxes I don't see this problem so often, but with 'netstat -i' it's possible to find some input errors - I was used to see no errors on 4.11 and others. Does anybody noticed this behavior? For my purpose, the UDP performance is very important. I would be glad with any kind of help to tune my box and improve its performance. For those who wants to try, the queryperf can be found in the bind source tree, at bind-9.3.2/contrib/queryperf. I used a query load file like this (1M of lines making reference to the zones in db.FOO.BAR): # cat query.txt test1.foo.bar NS test7.foo.bar NS test8.foo.bar NS test9.foo.bar NS test2.foo.bar NS ... Cheers, Marcelo Gardini From owner-freebsd-net@FreeBSD.ORG Mon Sep 11 21:02:59 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id F269016A403 for ; Mon, 11 Sep 2006 21:02:59 +0000 (UTC) (envelope-from jfvogel@gmail.com) Received: from nz-out-0102.google.com (nz-out-0102.google.com [64.233.162.206]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4442143D53 for ; Mon, 11 Sep 2006 21:02:59 +0000 (GMT) (envelope-from jfvogel@gmail.com) Received: by nz-out-0102.google.com with SMTP id 13so583990nzn for ; Mon, 11 Sep 2006 14:02:58 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:mime-version:content-type:content-transfer-encoding:content-disposition; b=uCsYujiflBPHVvGA3BaaK6corlRA4qKUgT6uqPJ4HPUja/aMu0t7CAVFhHJPY/cPJjHMhgIi22LgkZfCcteiFZAwH16fQstm+rVnr9Xb4sz9TBPUVm/qa0OdC+H7LyOa1zASq74p1bAyxprncYqARtra/DfFR9xOMrnhnSaYNmc= Received: by 10.35.61.17 with SMTP id o17mr9611390pyk; Mon, 11 Sep 2006 14:02:58 -0700 (PDT) Received: by 10.35.119.1 with HTTP; Mon, 11 Sep 2006 14:02:58 -0700 (PDT) Message-ID: <2a41acea0609111402g68741d86ib185e9bb77908658@mail.gmail.com> Date: Mon, 11 Sep 2006 14:02:58 -0700 From: "Jack Vogel" To: freebsd-net , "Prafulla Deuskar" MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline Cc: Subject: Stale PCI ID X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Sep 2006 21:03:00 -0000 In the last attempt to merge community CVS with Intel internal code I came across an issue I'd like to bring up. There is an ancient e1000 card, pci id 1000, an 82542, that we don't have in our source, yet community cvs still does. Support for this was removed from Linux long ago because the card did not even work. I just had our test group hunt up one of these and test, and sure enough, the driver recognizes it, but it does NOT pass traffic. Clearly no one is using these, at least not with STABLE :) and as Intel does not want to support this I would recommend removing the ID from the driver. Comments? Jack From owner-freebsd-net@FreeBSD.ORG Mon Sep 11 21:22:47 2006 Return-Path: X-Original-To: net@freebsd.org Delivered-To: freebsd-net@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3FC1516A40F for ; Mon, 11 Sep 2006 21:22:47 +0000 (UTC) (envelope-from kbyanc@posi.net) Received: from ylpvm12.prodigy.net (ylpvm12-ext.prodigy.net [207.115.57.43]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0C1A743D4C for ; Mon, 11 Sep 2006 21:22:04 +0000 (GMT) (envelope-from kbyanc@posi.net) X-ORBL: [70.231.128.103] Received: from gateway.posi.net (adsl-70-231-128-103.dsl.snfc21.sbcglobal.net [70.231.128.103]) by ylpvm12.prodigy.net (8.13.7 out spool5000 dk/8.13.7) with ESMTP id k8BLLRSc029021; Mon, 11 Sep 2006 17:21:28 -0400 Received: from localhost (localhost [127.0.0.1]) by gateway.posi.net (Postfix) with ESMTP id 3660275E05F; Mon, 11 Sep 2006 14:22:00 -0700 (PDT) Date: Mon, 11 Sep 2006 14:22:00 -0700 (PDT) From: Kelly Yancey To: Eugene Grosbein In-Reply-To: <200609111341.k8BDfneZ020221@nkz.delikates-nk.ru> Message-ID: <20060911131513.S27693@gateway.posi.net> References: <200609111341.k8BDfneZ020221@nkz.delikates-nk.ru> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Cc: VANHULLEBUS Yvan , net@freebsd.org Subject: Re: ipsec with ipfw divert (not NAT) encodes a packet twice breaking PMTUD X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Sep 2006 21:22:47 -0000 On Mon, 11 Sep 2006, Eugene Grosbein wrote: > > >Submitter-Id: current-users > >Originator: Eugene Grosbein > >Organization: Svyaz Service JSC > >Confidential: no > >Synopsis: ipsec with ipfw divert (not NAT) encodes a packet twice breaking PMTUD > >Severity: serious > >Priority: high > >Category: kern > >Class: sw-bug > >Release: FreeBSD 6.1-STABLE i386 > >Environment: > System: FreeBSD nkz.delikates-nk.ru 6.1-STABLE FreeBSD 6.1-STABLE #1: Thu Sep 7 13:31:53 KRAST 2006 root@nkz.delikates-nk.ru:/home/obj/home/src/sys/NKZ i386 > options IPDIVERT > options IPSEC > options IPSEC_ESP > > >Description: > When outgoing packet encoded due to corresponding IPSEC policy > is passed to divert socket (f.e. to ipacctd for accounting), > it is encoded second time with IPSEC then. Besides obvious > logic error, this also results in broken Path MTU Discovery. > > >How-To-Repeat: > > Use a kernel with options IPDIVERT, IPSEC, IPSEC_ESP > (my kernel also contains IPSEC_FILTERGIF, but this should not matter). > > Suppose there are two local nets numbered 192.168.1.0/24 > and 192.168.2.0/24, each has a FreeBSD router > (192.168.1.1 and 192.168.2.1). Routers make gif(4) tunnel between > and use IPSEC transport mode to encrypt its contents. > Their external IP addresses are 1.1.1.1 and 2.2.2.2 > Just FYI, when we implemented the enc interface for FreeBSD 4.10 for one of our products at work, we encountered a similar issue. The problem is that you need to add a flag to the sockaddr_in passed to the divert(4) consumer; when that consumer re-injects the packets into the network stack, ip_output() needs to check for the flag and goto skip_ipsec to avoid re-encapsulation. The next issue is that there is no room in the sockaddr_in structure for such a flag. We resorted to a hack (eventually, we re-implemented the divert interface to have its own sockaddr_div rather than overloading sockaddr_in, but that is another story). We stuck the flag indicating whether to skip IPsec encapsulation on input in the high bit of the first byte in the sin_zero array. This only works because natd(8) doesn't inspect the (partial) interface name stored in the sockaddr_in's sin_zero array. "Hack" doesn't really being to describe the hideousness of this workaround, but it will get the job done. It looks like the same effect might be able to be achieved by modifying natd to be able to set the policy on the divert socket to IPSEC_POLICY_NONE via the IP_IPSEC_POLICY socket option, but I don't know enough about that code path to say for sure. Good luck, Kelly -- Kelly Yancey - kbyanc@posi.net - kelly@nttmcl.com From owner-freebsd-net@FreeBSD.ORG Mon Sep 11 21:29:31 2006 Return-Path: X-Original-To: net@freebsd.org Delivered-To: freebsd-net@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A64CE16A4C8; Mon, 11 Sep 2006 21:29:31 +0000 (UTC) (envelope-from prvs=julian=402a94683@elischer.org) Received: from a50.ironport.com (a50.ironport.com [63.251.108.112]) by mx1.FreeBSD.org (Postfix) with ESMTP id EC27343E99; Mon, 11 Sep 2006 21:27:47 +0000 (GMT) (envelope-from prvs=julian=402a94683@elischer.org) Received: from unknown (HELO [10.251.18.229]) ([10.251.18.229]) by a50.ironport.com with ESMTP; 11 Sep 2006 14:27:26 -0700 Message-ID: <4505D4BE.10801@elischer.org> Date: Mon, 11 Sep 2006 14:27:26 -0700 From: Julian Elischer User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.13) Gecko/20060414 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Eugene Grosbein References: <200609111341.k8BDfneZ020221@nkz.delikates-nk.ru> In-Reply-To: <200609111341.k8BDfneZ020221@nkz.delikates-nk.ru> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: FreeBSD-gnats-submit@freebsd.org, net@freebsd.org Subject: Re: ipsec with ipfw divert (not NAT) encodes a packet twice breaking PMTUD X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Sep 2006 21:29:31 -0000 Eugene Grosbein wrote: >>Submitter-Id: current-users >>Originator: Eugene Grosbein >>Organization: Svyaz Service JSC >>Confidential: no >>Synopsis: ipsec with ipfw divert (not NAT) encodes a packet twice breaking PMTUD >>Severity: serious >>Priority: high >>Category: kern >>Class: sw-bug >>Release: FreeBSD 6.1-STABLE i386 >>Environment: >> >> >System: FreeBSD nkz.delikates-nk.ru 6.1-STABLE FreeBSD 6.1-STABLE #1: Thu Sep 7 13:31:53 KRAST 2006 root@nkz.delikates-nk.ru:/home/obj/home/src/sys/NKZ i386 > options IPDIVERT > options IPSEC > options IPSEC_ESP > > > >>Description: >> >> > When outgoing packet encoded due to corresponding IPSEC policy > is passed to divert socket (f.e. to ipacctd for accounting), > it is encoded second time with IPSEC then. Besides obvious > logic error, this also results in broken Path MTU Discovery. > > unfortunatly this comes from the fact that divert returns packets to the kernel by passing them to the IP stack and letting them be processed again. There is a flag that is set to allow the ipfw to know that they have been seen before, and it is possible that one could make IPSEC notice that flag as well but it would be pretty hacky. One other solution would be to make some way in which ipdivert can really inject a packet back at the point where it was extracted but that would probably require spliting ip_output() into two functions, (as was done in ether_output() ) but that would probably not 'fly' very well. > > >>How-To-Repeat: >> >> > > Use a kernel with options IPDIVERT, IPSEC, IPSEC_ESP > (my kernel also contains IPSEC_FILTERGIF, but this should not matter). > > Suppose there are two local nets numbered 192.168.1.0/24 > and 192.168.2.0/24, each has a FreeBSD router > (192.168.1.1 and 192.168.2.1). Routers make gif(4) tunnel between > and use IPSEC transport mode to encrypt its contents. > Their external IP addresses are 1.1.1.1 and 2.2.2.2 > > Here is /etc/ipsec.conf: > >add 1.1.1.1 81.16.143.102 esp 1007 -m transport -E blowfish-cbc "xxx"; >add 2.2.2.2 1.1.1.1 esp 2007 -m transport -E blowfish-cbc "yyy"; > >spdadd 1.1.1.1/32 2.2.2.2/32 any -P in ipsec esp/transport/1.1.1.1-2.2.2.2/require; >spdadd 2.2.2.2/32 1.1.1.1/32 any -P out ipsec esp/transport/2.2.2.2-1.1.1.1/require; > > Another router has similar /etc/ipsec.conf. > > Use this script to prepare IPSEC keys for tcpdump: > >#!/bin/sh > >setkey -D | awk ' > /^[1-9]/ { ip=$2; } > $1=="esp" { > sub(/spi=[^(]+\(/, "", $3); > sub(/\)/, "", $3); > printf"%s@%s ",$3,ip; > } > $1=="E:" { printf "%s:0x%s%s%s%s\n", $2, $3, $4, $5, $6; } >' > /tmp/keys.txt > > When we use one of the routers to run > "tcpdump -s0 -n -p -i $iface -E /tmp/keys.txt esp", > we see that traffic is encoded with ESP and decoded properly, > still good. > > Now install ports/net-mgmt/ipacctd, run it manually with > "ipacctd -p 4000", then command: > "ipfw add 10 divert 4000 ip from any to any out" > and rerun tcpdump command shown above. You'll see that > outgoing packets are encapsulated with ESP twice. > The same you'll see at the other side for incoming packets. > > > >>Fix: >> >> > > Unknown. The only known workaround is to avoid diverting ESP. > This workaroung is not always acceptable. > > >Eugene Grosbein >_______________________________________________ >freebsd-net@freebsd.org mailing list >http://lists.freebsd.org/mailman/listinfo/freebsd-net >To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org" > > From owner-freebsd-net@FreeBSD.ORG Mon Sep 11 21:43:37 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id F337116A412; Mon, 11 Sep 2006 21:43:36 +0000 (UTC) (envelope-from jmg@hydrogen.funkthat.com) Received: from hydrogen.funkthat.com (gate.funkthat.com [69.17.45.168]) by mx1.FreeBSD.org (Postfix) with ESMTP id A824B43D4C; Mon, 11 Sep 2006 21:43:34 +0000 (GMT) (envelope-from jmg@hydrogen.funkthat.com) Received: from hydrogen.funkthat.com (jdh33ehxxzsyc9fr@localhost.funkthat.com [127.0.0.1]) by hydrogen.funkthat.com (8.13.6/8.13.3) with ESMTP id k8BLhY4M023566; Mon, 11 Sep 2006 14:43:34 -0700 (PDT) (envelope-from jmg@hydrogen.funkthat.com) Received: (from jmg@localhost) by hydrogen.funkthat.com (8.13.6/8.13.3/Submit) id k8BLhYTL023565; Mon, 11 Sep 2006 14:43:34 -0700 (PDT) (envelope-from jmg) Date: Mon, 11 Sep 2006 14:43:33 -0700 From: John-Mark Gurney To: Jack Vogel Message-ID: <20060911214333.GM9421@funkthat.com> Mail-Followup-To: Jack Vogel , freebsd-net , Prafulla Deuskar References: <2a41acea0609111402g68741d86ib185e9bb77908658@mail.gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <2a41acea0609111402g68741d86ib185e9bb77908658@mail.gmail.com> User-Agent: Mutt/1.4.2.1i X-Operating-System: FreeBSD 5.4-RELEASE-p6 i386 X-PGP-Fingerprint: B7 EC EF F8 AE ED A7 31 96 7A 22 B3 D8 56 36 F4 X-Files: The truth is out there X-URL: http://resnet.uoregon.edu/~gurney_j/ X-Resume: http://resnet.uoregon.edu/~gurney_j/resume.html Cc: freebsd-net Subject: Re: Stale PCI ID X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: John-Mark Gurney List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Sep 2006 21:43:37 -0000 Jack Vogel wrote this message on Mon, Sep 11, 2006 at 14:02 -0700: > I just had our test group hunt up one of these and test, and sure > enough, the driver recognizes it, but it does NOT pass traffic. > > Clearly no one is using these, at least not with STABLE :) and > as Intel does not want to support this I would recommend removing > the ID from the driver. if it doesn't pass traffic and isn't planned on being fixed, drop it.. -- John-Mark Gurney Voice: +1 415 225 5579 "All that I will do, has been done, All that I have, has not." From owner-freebsd-net@FreeBSD.ORG Mon Sep 11 22:30:59 2006 Return-Path: X-Original-To: net@FreeBSD.org Delivered-To: freebsd-net@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D520E16A47B; Mon, 11 Sep 2006 22:30:59 +0000 (UTC) (envelope-from FreeBSD-gnats-submit@FreeBSD.org) Received: from mail.borderware.com (mail.borderware.com [207.236.65.231]) by mx1.FreeBSD.org (Postfix) with ESMTP id 317E043D76; Mon, 11 Sep 2006 22:30:50 +0000 (GMT) (envelope-from FreeBSD-gnats-submit@FreeBSD.org) Delivered-To: cmills@borderware.com X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Resent-Date: Mon, 11 Sep 2006 13:50:17 GMT Resent-Message-Id: <200609111350.k8BDoHFP086858@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Eugene Grosbein Message-Id: <200609111341.k8BDfneZ020221@nkz.delikates-nk.ru> Date: Mon, 11 Sep 2006 21:41:49 +0800 (KRAST) From: Eugene Grosbein To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Sender: owner-freebsd-bugs@freebsd.org Errors-To: owner-freebsd-bugs@freebsd.org X-STA-Metric: 0 (engine=022) X-STA-NotSpam: url:mailman from:addr:eugen url:listinfo skip:__ 40 workaround X-STA-Spam: kern $2, tcpdump diverting breaking X-BTI-AntiSpam: score:0, sta:0/022, dcc:passed, dnsbl:passed, sw:passed, bsn:50/passed, spf:off, dk:off, pbmf:none, ipr:0/7, trusted:no, ts:no, ubl:passed X-OriginalArrivalTime: 11 Sep 2006 13:51:05.0220 (UTC) FILETIME=[5368BC40:01C6D5A9] Cc: net@FreeBSD.org Subject: kern/103135: ipsec with ipfw divert (not NAT) encodes a packet twice breaking PMTUD X-BeenThere: freebsd-net@freebsd.org List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Sep 2006 22:31:00 -0000 >Number: 103135 >Category: kern >Synopsis: ipsec with ipfw divert (not NAT) encodes a packet twice breaking PMTUD >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Sep 11 13:50:16 GMT 2006 >Closed-Date: >Last-Modified: >Originator: Eugene Grosbein >Release: FreeBSD 6.1-STABLE i386 >Organization: Svyaz Service JSC >Environment: System: FreeBSD nkz.delikates-nk.ru 6.1-STABLE FreeBSD 6.1-STABLE #1: Thu Sep 7 13:31:53 KRAST 2006 root@nkz.delikates-nk.ru:/home/obj/home/src/sys/NKZ i386 options IPDIVERT options IPSEC options IPSEC_ESP >Description: When outgoing packet encoded due to corresponding IPSEC policy is passed to divert socket (f.e. to ipacctd for accounting), it is encoded second time with IPSEC then. Besides obvious logic error, this also results in broken Path MTU Discovery. >How-To-Repeat: Use a kernel with options IPDIVERT, IPSEC, IPSEC_ESP (my kernel also contains IPSEC_FILTERGIF, but this should not matter). Suppose there are two local nets numbered 192.168.1.0/24 and 192.168.2.0/24, each has a FreeBSD router (192.168.1.1 and 192.168.2.1). Routers make gif(4) tunnel between and use IPSEC transport mode to encrypt its contents. Their external IP addresses are 1.1.1.1 and 2.2.2.2 Here is /etc/ipsec.conf: add 1.1.1.1 81.16.143.102 esp 1007 -m transport -E blowfish-cbc "xxx"; add 2.2.2.2 1.1.1.1 esp 2007 -m transport -E blowfish-cbc "yyy"; spdadd 1.1.1.1/32 2.2.2.2/32 any -P in ipsec esp/transport/1.1.1.1-2.2.2.2/require; spdadd 2.2.2.2/32 1.1.1.1/32 any -P out ipsec esp/transport/2.2.2.2-1.1.1.1/require; Another router has similar /etc/ipsec.conf. Use this script to prepare IPSEC keys for tcpdump: #!/bin/sh setkey -D | awk ' /^[1-9]/ { ip=$2; } $1=="esp" { sub(/spi=[^(]+\(/, "", $3); sub(/\)/, "", $3); printf"%s@%s ",$3,ip; } $1=="E:" { printf "%s:0x%s%s%s%s\n", $2, $3, $4, $5, $6; } ' > /tmp/keys.txt When we use one of the routers to run "tcpdump -s0 -n -p -i $iface -E /tmp/keys.txt esp", we see that traffic is encoded with ESP and decoded properly, still good. Now install ports/net-mgmt/ipacctd, run it manually with "ipacctd -p 4000", then command: "ipfw add 10 divert 4000 ip from any to any out" and rerun tcpdump command shown above. You'll see that outgoing packets are encapsulated with ESP twice. The same you'll see at the other side for incoming packets. >Fix: Unknown. The only known workaround is to avoid diverting ESP. This workaroung is not always acceptable. Eugene Grosbein >Release-Note: >Audit-Trail: >Unformatted: _______________________________________________ freebsd-bugs@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscribe@freebsd.org" From owner-freebsd-net@FreeBSD.ORG Tue Sep 12 03:44:49 2006 Return-Path: X-Original-To: net@freebsd.org Delivered-To: freebsd-net@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id EDFE216A407 for ; Tue, 12 Sep 2006 03:44:49 +0000 (UTC) (envelope-from eugen@kuzbass.ru) Received: from www.svzserv.kemerovo.su (www.svzserv.kemerovo.su [213.184.65.80]) by mx1.FreeBSD.org (Postfix) with ESMTP id 31BD143D46 for ; Tue, 12 Sep 2006 03:44:48 +0000 (GMT) (envelope-from eugen@kuzbass.ru) Received: from kuzbass.ru (kost [213.184.65.82]) by www.svzserv.kemerovo.su (8.13.8/8.13.8) with ESMTP id k8C3ihOQ035903; Tue, 12 Sep 2006 11:44:43 +0800 (KRAST) (envelope-from eugen@kuzbass.ru) Message-ID: <45062D2C.D5F95D6B@kuzbass.ru> Date: Tue, 12 Sep 2006 11:44:44 +0800 From: Eugene Grosbein Organization: SVZServ X-Mailer: Mozilla 4.8 [en] (Windows NT 5.0; U) X-Accept-Language: ru,en MIME-Version: 1.0 To: Kelly Yancey References: <200609111341.k8BDfneZ020221@nkz.delikates-nk.ru> <20060911131513.S27693@gateway.posi.net> Content-Type: text/plain; charset=koi8-r Content-Transfer-Encoding: 7bit Cc: VANHULLEBUS Yvan , Eugene Grosbein , net@freebsd.org Subject: Re: ipsec with ipfw divert (not NAT) encodes a packet twice breaking PMTUD X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Sep 2006 03:44:50 -0000 Kelly Yancey wrote: > Just FYI, when we implemented the enc interface for FreeBSD 4.10 for > one of our products at work, we encountered a similar issue. The > problem is that you need to add a flag to the sockaddr_in passed to the > divert(4) consumer; when that consumer re-injects the packets into the > network stack, ip_output() needs to check for the flag and goto > skip_ipsec to avoid re-encapsulation. The next issue is that > there is no room in the sockaddr_in structure for such a flag. Another problem with divert is described in detail here: http://freebsd.rambler.ru/bsdmail/freebsd-net_2004/msg01736.html In short: divert of a packet removes multicast options that it may have and bad things happen with RIPv2 multicast packets. Eugene From owner-freebsd-net@FreeBSD.ORG Tue Sep 12 06:42:10 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 58CD816A40F for ; Tue, 12 Sep 2006 06:42:10 +0000 (UTC) (envelope-from jhay@meraka.csir.co.za) Received: from zibbi.meraka.csir.co.za (zibbi.meraka.csir.co.za [146.64.24.58]) by mx1.FreeBSD.org (Postfix) with ESMTP id AC11B43D45 for ; Tue, 12 Sep 2006 06:42:08 +0000 (GMT) (envelope-from jhay@meraka.csir.co.za) Received: by zibbi.meraka.csir.co.za (Postfix, from userid 3973) id A017033C9C; Tue, 12 Sep 2006 08:42:00 +0200 (SAST) Date: Tue, 12 Sep 2006 08:42:00 +0200 From: John Hay To: freebsd-net@freebsd.org Message-ID: <20060912064200.GA61525@zibbi.meraka.csir.co.za> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.2.1i Subject: CFR: netinet6/nd6.c - route add -inet X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Sep 2006 06:42:10 -0000 Is there anybody that would care to look over this change please? Or is it ok to commit it? For my test setup I have two machines, the first called rtrg, which I'm working on and rtr2, the one I want to "route" to. So my /etc/hosts have this in: 2001:4200:7000:15:202:6fff:fe22:9547 rtrg 2001:4200:7000:15:202:6fff:fe41:1927 rtr2 If I add a route (on rtrg) like this, I do not get an error while adding it: route add -inet6 rtr2 rtrg -interface -llinfo But the first time I use it, the kernel spits out this message: nd6_storelladdr: sdl_alen == 0 So I had a look and tweaked sys/netinet6/nd6.c:nd6_rtrequest() a little and now it is working. Now I won't pretend that I have my head around all the IPv6 routing/ndp intricasies, so I would really like some more eyes over this. With this and my FreeBSD/IPv6 port of olsrd I can run multiple wireless interfaces with the same IPv6 subnet and olsrd can make it all work. The diff is against RELENG_6 Index: nd6.c =================================================================== RCS file: /home/ncvs/src/sys/netinet6/nd6.c,v retrieving revision 1.48.2.13 diff -u -r1.48.2.13 nd6.c --- nd6.c 17 Jun 2006 17:58:33 -0000 1.48.2.13 +++ nd6.c 8 Sep 2006 09:16:58 -0000 @@ -1392,6 +1392,8 @@ ip6_sprintf(&llsol), error)); } } + } else if (req == RTM_ADD && SDL(gate)->sdl_alen == 0) { + ln->ln_state = ND6_LLINFO_INCOMPLETE; } break; John -- John Hay -- John.Hay@meraka.csir.co.za / jhay@FreeBSD.org From owner-freebsd-net@FreeBSD.ORG Tue Sep 12 08:42:38 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2DE1B16A407 for ; Tue, 12 Sep 2006 08:42:38 +0000 (UTC) (envelope-from jad@nominet.org.uk) Received: from mx4.nominet.org.uk (mx4.nominet.org.uk [213.248.199.24]) by mx1.FreeBSD.org (Postfix) with ESMTP id 65F6E43D4C for ; Tue, 12 Sep 2006 08:42:37 +0000 (GMT) (envelope-from jad@nominet.org.uk) Received: from wds1.okna.nominet.org.uk (HELO notes1.nominet.org.uk) ([213.248.197.128]) by mx4.nominet.org.uk with ESMTP; 12 Sep 2006 09:42:36 +0100 X-IronPort-AV: i="4.09,149,1157324400"; d="scan'208"; a="4670171:sNHT31247124" In-Reply-To: <20060911195521.GD63300@registro.br> To: Marcelo Gardini do Amaral MIME-Version: 1.0 X-Mailer: Lotus Notes Release 6.5.5 November 30, 2005 Message-ID: From: "John Dickinson" Date: Tue, 12 Sep 2006 09:42:32 +0100 X-MIMETrack: Serialize by Router on notes1/Nominet(Release 6.5.3|September 14, 2004) at 09/12/2006 09:42:19 AM, Serialize complete at 09/12/2006 09:42:19 AM Content-Type: text/plain; charset="US-ASCII" Cc: freebsd-net@freebsd.org Subject: Re: DNS query performance X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Sep 2006 08:42:38 -0000 Hi Marcelo, Marcelo Gardini do Amaral wrote on 11/09/2006 16:55:21: > I would like to discuss a little bit more about UDP performance. I've > made some tests and the results may have some value here. > > In this test is easy to see that there is something different in the > FreeBSD 6 branch. > > I made a benchmark with bind 9.3.2 (without threads support) and nsd > 3.0.1 (1 server forked) on a HP Proliant Dual AMD Opteron 2.4GHz among > FreeBSD 4.11, 6.1 and Linux kernel 2.6.15, all of them for i386 > systems. I used this simple zone file: I have also been testing bind and nsd on HP proliant and Sun hardware. In my tests I ran queryperf on several HP BL25p blade servers running FreeBSD 6.X. These servers sent queries to BIND or NSD running on a Sun T2000 (Solaris) or another HP blade (Linux). snip... > queries per second > > OS Bind 9.3.2 NSD 3.0.1 > ---- ---- ---- > > Linux 2.6 SMP 38845 59645 > > FreeBSD 4.11 SMP 34977 59417 > > FreeBSD 4.11 UP 33926 59547 > > FreeBSD 6.1 SMP 14953 15908 > > FreeBSD 6.1 UP 15516 14752 > FYI I see similar results for BIND on Linux ( I got about 42000 q/s for BIND 9.4.0b2) > Comments: > > Linux had a performance just 10% better than FreeBSD 4.11 with > bind. With nsd I didn't see any difference between them. There is no > difference also tweaking the kernel from UP to SMP. > > With nsd the performance was improved to ~60k queries per second on > 4.11 and Linux, i.e., it was almost doubled comparing with bind. I > couldn't see any packet loss in any case. > > On the other hand, on FreeBSD 6.1 the result was lower than half of > bind's performance on the others systems tested. And with nsd the > result didn't get better (unlike happend on FreeBSD 4.11). I also got > some 'timeout' on FreeBSD 6.1 - about 200 from 1M packets were lost. > I saw significant numbers of lost queries reported by queryperf when it was running on FreeBSD 6.1. I did not see this issue when I ran queryperf on FreeBSD 6.0. I have not had time to fully investigate this issue but it appeared that some queries from queryperf never made it out of the FreeBSD 6.1 box. When I ran netstat -s -p udp I saw that that the numbers for delivered and datagrams output differed by the number of queries that queryperf was reporting as lost. However I am yet to figure out what this means. > In actual fact, I think that is important to emphasize that the same > limit was reached on both name servers - no more than ~15k queries per > second was possible on 6.1. I think there is an issue on the system, > not on bind neither nsd. > > Besides this, I've noticed some problems with bge interface > driver. Many times the interface is up and running and suddenly goes > down, without any reason, or after a reboot it doesn't go up. And if > you just remove and insert again the cable, everything returns to > work. On up-to-date FreeBSD 6 boxes I don't see this problem so often, > but with 'netstat -i' it's possible to find some input errors - I was > used to see no errors on 4.11 and others. > > Does anybody noticed this behavior? I have not seen the interfaces issue but my test servers never stay up very long before being reinstalled. If anyone has any ideas of things to try then please let me know. Thanks John From owner-freebsd-net@FreeBSD.ORG Tue Sep 12 11:43:17 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 01DE616A40F; Tue, 12 Sep 2006 11:43:17 +0000 (UTC) (envelope-from yar@comp.chem.msu.su) Received: from comp.chem.msu.su (comp.chem.msu.su [158.250.32.97]) by mx1.FreeBSD.org (Postfix) with ESMTP id F119143D6B; Tue, 12 Sep 2006 11:43:15 +0000 (GMT) (envelope-from yar@comp.chem.msu.su) Received: from comp.chem.msu.su (localhost [127.0.0.1]) by comp.chem.msu.su (8.13.4/8.13.3) with ESMTP id k8CBhDQ8009486; Tue, 12 Sep 2006 15:43:13 +0400 (MSD) (envelope-from yar@comp.chem.msu.su) Received: (from yar@localhost) by comp.chem.msu.su (8.13.4/8.13.3/Submit) id k8CBhDEi009485; Tue, 12 Sep 2006 15:43:13 +0400 (MSD) (envelope-from yar) Date: Tue, 12 Sep 2006 15:43:13 +0400 From: Yar Tikhiy To: Andre Oppermann Message-ID: <20060912114312.GE8639@comp.chem.msu.su> References: <450035AD.3040600@freebsd.org> <20060908010835.GA6334@heff.fud.org.nz> <45012EAA.4010303@freebsd.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <45012EAA.4010303@freebsd.org> User-Agent: Mutt/1.5.9i Cc: freebsd-net@freebsd.org, Andrew Thompson , freebsd-arch@freebsd.org Subject: Re: Moving ethernet VLAN tags into the mbuf packet header (from mtags) X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Sep 2006 11:43:17 -0000 On Fri, Sep 08, 2006 at 10:49:46AM +0200, Andre Oppermann wrote: > Andrew Thompson wrote: > >On Thu, Sep 07, 2006 at 05:07:25PM +0200, Andre Oppermann wrote: > >>With the recent addition of a 16bit field for TSO into the mbuf packet > >>header we've got 16bits left over. I've reserved these bits for the > >>ethernet VLAN tagging of packet to do away with the allocated mbuf mtag. > >> > >>The change is rather mechanical. Patch available here: > >> > >> http://people.freebsd.org/~andre/vlan_pkthdr-20060907.diff > >> > > > >RCS file: /home/ncvs/src/sys/netgraph/ng_vlan.c,v > >retrieving revision 1.3 > >diff -u -p -r1.3 ng_vlan.c > >--- netgraph/ng_vlan.c 20 Apr 2005 14:19:20 -0000 1.3 > >+++ netgraph/ng_vlan.c 7 Sep 2006 15:03:58 -0000 > > > ><...> > > > >- vlan = EVL_VLANOFTAG(VLAN_TAG_VALUE(mtag)); > >+ vlan = m->m_pkthdr.ether_vlan; > > (void)&evl; /* XXX silence GCC */ > > > >I think this is a typeo, EVL_VLANOFTAG is still needed. I like the > >change and it helps out a few related projects that people are working > >on. > > Fixed. Thanks for the review! It seems to me that the typo just highlighted not-so-optimal naming of the new field. We must distinguish between VLAN ID's and VLAN tags clearly. A VLAN ID is what can be passed to "ifconfig foo0 vlan ___". A VLAN tag is a 16-bit value ready to be stored in the respective field of the 802.1Q header, except for its byte order. I'd rather have the new field renamed to just "vlan_tag" to avoid further confusion. In long perspective, however, stuffing protocol-specific fields in the generic mbuf header is no good. I share Julian's point here. We already can allocate simple mbufs as well as mbufs with m_pkthdr. This scheme is begging to be generalised. Then we should be able to allocate mbufs crafted for a particular protcol at once. Now I can't but do some nitpicking :-) In if_vlan.c, the "inenc" variable is set to 0 or 1 depending on the branch taken in the if-else clause. Then why to initialize it at its definition? I think that the better style would be: int inenc; if (m->m_flags & M_VLAN) { ... inenc = 0; } else { ... inenc = 1; } AFAIK, C compilers are clever enough to avoid false "uninitialized variable" warning for the code. Lastly, I've just noticed that the M_VLAN flag isn't documented in mbuf(9) yet. Could you document it along with the results of your work when it's finished? ;-) -- Yar From owner-freebsd-net@FreeBSD.ORG Tue Sep 12 12:56:24 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id DD32E16A552 for ; Tue, 12 Sep 2006 12:56:23 +0000 (UTC) (envelope-from andre@freebsd.org) Received: from c00l3r.networx.ch (c00l3r.networx.ch [62.48.2.2]) by mx1.FreeBSD.org (Postfix) with ESMTP id 15E7F43D82 for ; Tue, 12 Sep 2006 12:56:12 +0000 (GMT) (envelope-from andre@freebsd.org) Received: (qmail 11854 invoked from network); 12 Sep 2006 12:40:07 -0000 Received: from c00l3r.networx.ch (HELO [127.0.0.1]) ([62.48.2.2]) (envelope-sender ) by c00l3r.networx.ch (qmail-ldap-1.03) with SMTP for ; 12 Sep 2006 12:40:07 -0000 Message-ID: <4506AE6D.1010300@freebsd.org> Date: Tue, 12 Sep 2006 14:56:13 +0200 From: Andre Oppermann User-Agent: Thunderbird 1.5.0.5 (Windows/20060719) MIME-Version: 1.0 To: Yar Tikhiy References: <450035AD.3040600@freebsd.org> <20060908010835.GA6334@heff.fud.org.nz> <45012EAA.4010303@freebsd.org> <20060912114312.GE8639@comp.chem.msu.su> In-Reply-To: <20060912114312.GE8639@comp.chem.msu.su> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-net@freebsd.org, Andrew Thompson , freebsd-arch@freebsd.org Subject: Re: Moving ethernet VLAN tags into the mbuf packet header (from mtags) X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Sep 2006 12:56:24 -0000 Yar Tikhiy wrote: > On Fri, Sep 08, 2006 at 10:49:46AM +0200, Andre Oppermann wrote: >> Andrew Thompson wrote: >>> On Thu, Sep 07, 2006 at 05:07:25PM +0200, Andre Oppermann wrote: >>>> With the recent addition of a 16bit field for TSO into the mbuf packet >>>> header we've got 16bits left over. I've reserved these bits for the >>>> ethernet VLAN tagging of packet to do away with the allocated mbuf mtag. >>>> >>>> The change is rather mechanical. Patch available here: >>>> >>>> http://people.freebsd.org/~andre/vlan_pkthdr-20060907.diff >>>> >>> RCS file: /home/ncvs/src/sys/netgraph/ng_vlan.c,v >>> retrieving revision 1.3 >>> diff -u -p -r1.3 ng_vlan.c >>> --- netgraph/ng_vlan.c 20 Apr 2005 14:19:20 -0000 1.3 >>> +++ netgraph/ng_vlan.c 7 Sep 2006 15:03:58 -0000 >>> >>> <...> >>> >>> - vlan = EVL_VLANOFTAG(VLAN_TAG_VALUE(mtag)); >>> + vlan = m->m_pkthdr.ether_vlan; >>> (void)&evl; /* XXX silence GCC */ >>> >>> I think this is a typeo, EVL_VLANOFTAG is still needed. I like the >>> change and it helps out a few related projects that people are working >>> on. >> Fixed. Thanks for the review! > > It seems to me that the typo just highlighted not-so-optimal naming > of the new field. We must distinguish between VLAN ID's and VLAN > tags clearly. A VLAN ID is what can be passed to "ifconfig foo0 > vlan ___". A VLAN tag is a 16-bit value ready to be stored in the > respective field of the 802.1Q header, except for its byte order. > I'd rather have the new field renamed to just "vlan_tag" to avoid > further confusion. I'd like to keep the ether_ prefix to make it clear who this pkthdr field belongs to. What do you think of pkthdr.ether_vtag? Is that more descriptive for this purpose to avoid the confusion you are referring to? > In long perspective, however, stuffing protocol-specific fields in > the generic mbuf header is no good. I share Julian's point here. > We already can allocate simple mbufs as well as mbufs with m_pkthdr. > This scheme is begging to be generalised. Then we should be able > to allocate mbufs crafted for a particular protcol at once. What you describe here is not an approach currently done by the BSD mbuf system (that is having protocol specific mbuf headers). The current way of doing these things is to attach mtags to the mbufs as it is currently done with ethernet vlans. The trouble here is the additional overhead for allocating the mtags and the potential cache busting of following an mtag chain. Actually I agree that having protocol specific fields in the mbuf pkthdr is not clean design. But on the other hand it's always a tradeoff between clean design, performance and ugliness. Mach has a very clean design but simply doesn't perform. We have to find a balance without getting into ugly because then the tradeoff gets negative and causes lots of pain and complicated maintenance in the future. > Now I can't but do some nitpicking :-) In if_vlan.c, the "inenc" > variable is set to 0 or 1 depending on the branch taken in the > if-else clause. Then why to initialize it at its definition? I > think that the better style would be: > > int inenc; > > if (m->m_flags & M_VLAN) { > ... > inenc = 0; > } else { > ... > inenc = 1; > } > > AFAIK, C compilers are clever enough to avoid false "uninitialized > variable" warning for the code. Good point. This can certainly be improved. For the first patch I tried to be as mechanical as I could be. > Lastly, I've just noticed that the M_VLAN flag isn't documented in > mbuf(9) yet. Could you document it along with the results of your > work when it's finished? ;-) Sure. Thanks for your comments. -- Andre From owner-freebsd-net@FreeBSD.ORG Tue Sep 12 15:04:16 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2034416A415 for ; Tue, 12 Sep 2006 15:04:16 +0000 (UTC) (envelope-from jon.otterholm@ide.resurscentrum.se) Received: from mail1.cil.se (mail1.cil.se [217.197.56.125]) by mx1.FreeBSD.org (Postfix) with ESMTP id 817BA43D53 for ; Tue, 12 Sep 2006 15:04:14 +0000 (GMT) (envelope-from jon.otterholm@ide.resurscentrum.se) Received: from [192.168.2.10] ([192.168.2.10]) by mail1.cil.se with Microsoft SMTPSVC(6.0.3790.0); Tue, 12 Sep 2006 17:04:12 +0200 Message-ID: <4506CC6C.4030308@ide.resurscentrum.se> Date: Tue, 12 Sep 2006 17:04:12 +0200 From: Jon Otterholm User-Agent: Thunderbird 1.5 (X11/20060204) MIME-Version: 1.0 To: freebsd-net@freebsd.org Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-OriginalArrivalTime: 12 Sep 2006 15:04:12.0559 (UTC) FILETIME=[B4E149F0:01C6D67C] Subject: Limit arp on bridge X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Sep 2006 15:04:16 -0000 Hello. I am trying to limit arp-broadcast between member-IF on a bridge (if_bridge) with no luck. I have the following sysctls set: net.link.bridge.pfil_member: 1 net.link.bridge.pfil_bridge: 1 net.link.bridge.pfil_onlyip: 1 I am using PF for filtering - do I have to use IPFW to limit arp-broadcast between memeber-ifs? /Jon From owner-freebsd-net@FreeBSD.ORG Tue Sep 12 16:42:34 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A9ACD16A416; Tue, 12 Sep 2006 16:42:34 +0000 (UTC) (envelope-from cswiger@mac.com) Received: from smtpout.mac.com (smtpout.mac.com [17.250.248.183]) by mx1.FreeBSD.org (Postfix) with ESMTP id 61C2F43D45; Tue, 12 Sep 2006 16:42:34 +0000 (GMT) (envelope-from cswiger@mac.com) Received: from mac.com (smtpin02-en2 [10.13.10.147]) by smtpout.mac.com (Xserve/8.12.11/smtpout13/MantshX 4.0) with ESMTP id k8CGgXfh028777; Tue, 12 Sep 2006 09:42:33 -0700 (PDT) Received: from [17.214.13.96] (a17-214-13-96.apple.com [17.214.13.96]) (authenticated bits=0) by mac.com (Xserve/smtpin02/MantshX 4.0) with ESMTP id k8CGgUA6005920; Tue, 12 Sep 2006 09:42:32 -0700 (PDT) In-Reply-To: <4506AE6D.1010300@freebsd.org> References: <450035AD.3040600@freebsd.org> <20060908010835.GA6334@heff.fud.org.nz> <45012EAA.4010303@freebsd.org> <20060912114312.GE8639@comp.chem.msu.su> <4506AE6D.1010300@freebsd.org> Mime-Version: 1.0 (Apple Message framework v752.2) Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed Message-Id: <2EDD6C39-62ED-4DE1-B5BF-368E8E701B2E@mac.com> Content-Transfer-Encoding: 7bit From: Chuck Swiger Date: Tue, 12 Sep 2006 09:42:30 -0700 To: Andre Oppermann X-Mailer: Apple Mail (2.752.2) X-Brightmail-Tracker: AAAAAQAAA+k= X-Language-Identified: TRUE Cc: freebsd-net@freebsd.org, freebsd-arch@freebsd.org Subject: Re: Moving ethernet VLAN tags into the mbuf packet header (from mtags) X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Sep 2006 16:42:34 -0000 On Sep 12, 2006, at 5:56 AM, Andre Oppermann wrote: >> Now I can't but do some nitpicking :-) In if_vlan.c, the "inenc" >> variable is set to 0 or 1 depending on the branch taken in the >> if-else clause. Then why to initialize it at its definition? I >> think that the better style would be: >> int inenc; >> if (m->m_flags & M_VLAN) { >> ... >> inenc = 0; >> } else { >> ... >> inenc = 1; >> } >> AFAIK, C compilers are clever enough to avoid false "uninitialized >> variable" warning for the code. > > Good point. This can certainly be improved. For the first patch > I tried to be as mechanical as I could be. So long as there does not exist another code path (via break, continue, goto, etc) which can avoid passing one statement or the other-- and so long as nobody later on adds code which changes the underlying assumption. In terms of efficiency, zero'ing a bunch of automatic variables which get put on the stack during function entry is usually cheaper to do than doing conditional initialization later on in the code. It depends on the underlying CPU architecture, but many have an instruction which can perform a bzero() or memset() rapidly. -- -Chuck From owner-freebsd-net@FreeBSD.ORG Wed Sep 13 06:50:19 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0880F16A416 for ; Wed, 13 Sep 2006 06:50:19 +0000 (UTC) (envelope-from freebsd@dwec.ru) Received: from mail.dwec.ru (mail.dwec.ru [194.84.175.18]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9767243D4C for ; Wed, 13 Sep 2006 06:50:14 +0000 (GMT) (envelope-from freebsd@dwec.ru) Received: from mail.dwec.ru (delivery-agent [127.0.0.200]) by mail.dwec.ru (8.13.8/8.13.1/no info ; )) with ESMTP id k8D6oCww003370 for ; Wed, 13 Sep 2006 10:50:12 +0400 (MSD) (envelope-from freebsd@dwec.ru) From: freebsd@dwec.ru Received: from oivanovmob (gw [194.84.175.30]) by mail.dwec.ru (8.13.8/8.13.1/no info ; )) with SMTP id k8D6oCh6003365 for ; Wed, 13 Sep 2006 10:50:12 +0400 (MSD) (envelope-from freebsd@dwec.ru) Message-ID: <12d701c6d700$f48904b0$6407a8c0@oivanovmob> To: Date: Wed, 13 Sep 2006 10:50:18 +0400 MIME-Version: 1.0 Content-Type: text/plain; format=flowed; charset="koi8-r"; reply-type=original Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2900.2869 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869 X-SpamTest-Version: SMTP-Filter Version 2.0.0 [0125], KAS/Release X-Spamtest-Info: Pass through X-Anti-Virus: Kaspersky Anti-Virus for MailServers 5.5.10/RELEASE, bases: 13092006 #209922, status: clean Subject: ipfw forward X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 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, 13 Sep 2006 06:50:19 -0000 Hello all I'm confused a bit. Here's what I have: a firewall (with address A) and a proxy host (in internal network) with address B. Both running latest FBSD 6.1-stable. Addresses are (samples) "A" -192.168.0.1 and "B" - 192.168.0.2. Both kernel are compiled with options "ipfirewall" and "ipfirewall_forward". The firewall is supposed to forward outgoing POP3 traffic (from internal LAN) to the proxy (the obviuos). The scheme: [internal lan + proxy] <---> [firewall] <---> [elsewhere] So, on the firewall I add rule "ipfw add fwd B tcp from internal_net to any 110 in recv internal_intf" On the proxy server I add rule "ipfw fwd 127.0.0.1,PROXY_PORT tcp from any to any 110". What I get: I get firewall which is trying to forward packets to default gateway (plenty of DENIES on the external interface of the firewall). Question: what am I doing wrong? PS the same configuration works perfectly on FBSD 4.11 Oleg Y. Ivanov IT Manager Daewoo Electronics Europe GmbH Moscow Representative Office From owner-freebsd-net@FreeBSD.ORG Wed Sep 13 08:07:28 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 6B86816A407 for ; Wed, 13 Sep 2006 08:07:28 +0000 (UTC) (envelope-from regnauld@catpipe.net) Received: from moof.catpipe.net (moof.catpipe.net [195.249.214.130]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6DD3743D60 for ; Wed, 13 Sep 2006 08:07:24 +0000 (GMT) (envelope-from regnauld@catpipe.net) Received: from localhost (moof.catpipe.net [195.249.214.130]) by localhost.catpipe.net (Postfix) with ESMTP id 80BD16343D9; Wed, 13 Sep 2006 10:07:22 +0200 (CEST) Received: from moof.catpipe.net ([195.249.214.130]) by localhost (moof.catpipe.net [195.249.214.130]) (amavisd-new, port 10024) with ESMTP id 53221-07; Wed, 13 Sep 2006 10:07:21 +0200 (CEST) Received: from vinyl.catpipe.net (vinyl.catpipe.net [195.249.214.189]) by moof.catpipe.net (Postfix) with ESMTP id CFF506343DC; Wed, 13 Sep 2006 10:07:21 +0200 (CEST) Received: by vinyl.catpipe.net (Postfix, from userid 1006) id B367478C31; Wed, 13 Sep 2006 10:06:09 +0200 (CEST) Date: Wed, 13 Sep 2006 10:06:09 +0200 From: Phil Regnauld To: Marcelo Gardini do Amaral Message-ID: <20060913080609.GC73370@catpipe.net> References: <20060911215506.GA2040@catpipe.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20060911195521.GD63300@registro.br> X-Operating-System: FreeBSD 6.1-PRERELEASE i386 Organization: catpipe Systems ApS User-Agent: Mutt/1.5.11 X-Virus-Scanned: amavisd-new at catpipe.net Cc: freebsd-net@freebsd.org Subject: Re: DNS query performance X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 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, 13 Sep 2006 08:07:28 -0000 Marcelo Gardini do Amaral writes: > > I would like to discuss a little bit more about UDP performance. I've > made some tests and the results may have some value here. > > In this test is easy to see that there is something different in the > FreeBSD 6 branch. 1. Can you try this with another network card ? em for example ? 2. Have you tried device polling ? Just curious. From owner-freebsd-net@FreeBSD.ORG Wed Sep 13 13:06:54 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D3E0716A403 for ; Wed, 13 Sep 2006 13:06:54 +0000 (UTC) (envelope-from p.chadwick@internode.on.net) Received: from smtp1.adl2.internode.on.net (smtp1.adl2.internode.on.net [203.16.214.181]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4EA2B43D45 for ; Wed, 13 Sep 2006 13:06:54 +0000 (GMT) (envelope-from p.chadwick@internode.on.net) Received: from kt400.internode.on.net (ppp54-236.lns1.cbr1.internode.on.net [59.167.54.236]) by smtp1.adl2.internode.on.net (8.13.6/8.13.5) with ESMTP id k8DD6pK6081080 for ; Wed, 13 Sep 2006 22:36:52 +0930 (CST) (envelope-from p.chadwick@internode.on.net) Received: from kt400.internode.on.net (localhost.internode.on.net [127.0.0.1]) by kt400.internode.on.net (8.13.6/8.13.4) with ESMTP id k8DD8WIw001267 for ; Wed, 13 Sep 2006 23:08:32 +1000 (EST) (envelope-from p.chadwick@internode.on.net) Received: (from phil@localhost) by kt400.internode.on.net (8.13.6/8.13.4/Submit) id k8DD8Vrq001266 for freebsd-net@freebsd.org; Wed, 13 Sep 2006 23:08:31 +1000 (EST) (envelope-from phil) Message-Id: <200609131308.k8DD8Vrq001266@kt400.internode.on.net> To: freebsd-net@freebsd.org Date: Wed, 13 Sep 2006 23:08:31 +1000 (EST) Sender: p.chadwick@internode.on.net From: Phil Chadwick X-Mailer: ELM [version 2.4ME+ PL121h (25)] MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII Subject: FreeBSD 6.1 + ath0 + NAT X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Phil Chadwick List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Sep 2006 13:06:54 -0000 Hi all, This is my first post, so please be gentle :-) I have a Linksys WAG54G V.2 ADSL modem (Firmware Version: 1.00.39) connection to the Internet, and a Netgear WG311T wireless Ethernet card running on FreeBSD 6.1 (PC#1). Recently I added a second FreeBSD 6.1 system (PC#2) which has no wireless card (well it does, but it's a TI chipset not supported in FreeBSD). So I connected it to PC#1 with a Gigabit copper wire connection. I also added firewall and NATing on PC#1 to provide PC#2 with a route to the Internet. When I boot PC#1, the connection between ath0 and the ADSL modem will run as expected (routing to the Internet for itself and PC#2) for some time (roughly anywhere from 0 to 30 minutes), but always eventually hangs. It's then not possible to ping the ADSL modem. The hang happens regardless of whether the new (PC#2) system is booted or not. The PC#1 ath0 wireless connection has been woking flawlessly (without the firewall and NAT changs) for nearly a year (originally under FreeBSD 6.0 with Sam Lefflers ath patches) and more recently on FreeBSD 6.1. Can anybody spot anything obviously wrong with the new setup, or know of any bug reports that might impact a NATing gateway on a wireless connection? I have also recently discovered the link goes up and down every 20 or 30 minutes with what looks like a DHCP lease renewal. This extracted from /var/log/messages: Sep 13 19:42:21 kt400 kernel: ath0: link state changed to DOWN Sep 13 19:42:23 kt400 kernel: ath0: link state changed to UP Sep 13 19:42:23 kt400 dhclient: New IP Address (ath0): 192.168.1.64 Sep 13 19:42:23 kt400 dhclient: New Subnet Mask (ath0): 255.255.255.0 Sep 13 19:42:23 kt400 dhclient: New Broadcast Address (ath0): 192.168.1.255 Sep 13 19:42:23 kt400 dhclient: New Routers (ath0): 192.168.1.1 Sep 13 20:12:21 kt400 kernel: ath0: link state changed to DOWN Sep 13 20:12:23 kt400 kernel: ath0: link state changed to UP Sep 13 20:12:23 kt400 dhclient: New IP Address (ath0): 192.168.1.64 Sep 13 20:12:23 kt400 dhclient: New Subnet Mask (ath0): 255.255.255.0 Sep 13 20:12:23 kt400 dhclient: New Broadcast Address (ath0): 192.168.1.255 Sep 13 20:12:23 kt400 dhclient: New Routers (ath0): 192.168.1.1 Sep 13 21:32:21 kt400 kernel: ath0: link state changed to DOWN Sep 13 21:32:24 kt400 kernel: ath0: link state changed to UP Looks like a smoking gun? Is this likely to upset the firewall/NATing? [I have not yet had a chance to correlate the hang with the lease renewal, but will test that tomorrow.] In the kernel config file I have added: options IPFIREWALL options IPDIVERT In /etc/rc.conf I have: # See also /etc/wpa_supplicant.conf ifconfig_ath0="WPA DHCP" # Private x-over to printer ifconfig_rl0="inet kt400pr netmask 255.255.255.0 broadcast 10.0.0.255" # Private x-over to Dell 350 (PC#2) ifconfig_sk0="inet gbkt400 netmask 255.255.255.0 broadcast 192.168.2.255" # These added for firewall/NATing gateway_enable="YES" firewall_enable="YES" firewall_type="OPEN" natd_enable="YES" natd_interface="ath0" natd_flags="" [kt400.145] cat /etc/wpa_supplicant.conf network={ ssid="linksys" key_mgmt=NONE wep_key0=xxxxxxxxxx wep_tx_keyidx=0 } [kt400.146] ifconfig -a sk0: flags=8843 mtu 1500 options=8 inet6 fe80::215:e9ff:feb0:e5b0%sk0 prefixlen 64 scopeid 0x1 inet 192.168.2.1 netmask 0xffffff00 broadcast 192.168.2.255 ether 00:15:e9:b0:e5:b0 media: Ethernet autoselect (none) status: no carrier ath0: flags=8843 mtu 1500 inet6 fe80::20f:b5ff:fef6:28eb%ath0 prefixlen 64 scopeid 0x2 inet 192.168.1.64 netmask 0xffffff00 broadcast 192.168.1.255 ether 00:0f:b5:f6:28:eb media: IEEE 802.11 Wireless Ethernet autoselect (DS/11Mbps) status: associated ssid linksys channel 11 bssid 00:14:bf:7a:57:94 authmode OPEN privacy ON deftxkey 1 wepkey 1:40-bit txpowmax 37 protmode CTS burst roaming MANUAL bintval 100 rl0: flags=8843 mtu 1500 options=8 inet6 fe80::220:edff:fe70:471a%rl0 prefixlen 64 scopeid 0x3 inet 10.0.0.254 netmask 0xffffff00 broadcast 10.0.0.255 ether 00:20:ed:70:47:1a media: Ethernet autoselect (none) status: no carrier fwe0: flags=108802 mtu 1500 options=8 ether 02:00:20:71:b9:a6 ch 1 dma -1 lo0: flags=8049 mtu 16384 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x5 inet 127.0.0.1 netmask 0xff000000 Thanks, -- Phil I don't do drugs anymore 'cause I find I get the same effect just by standing up really fast. -- Johnathan Katz From owner-freebsd-net@FreeBSD.ORG Wed Sep 13 13:09:59 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id C07F216A492 for ; Wed, 13 Sep 2006 13:09:59 +0000 (UTC) (envelope-from slawek.zak@gmail.com) Received: from ug-out-1314.google.com (ug-out-1314.google.com [66.249.92.170]) by mx1.FreeBSD.org (Postfix) with ESMTP id 284DA43D45 for ; Wed, 13 Sep 2006 13:09:58 +0000 (GMT) (envelope-from slawek.zak@gmail.com) Received: by ug-out-1314.google.com with SMTP id m2so2082331uge for ; Wed, 13 Sep 2006 06:09:57 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:mime-version:content-type:content-transfer-encoding:content-disposition; b=Rw90ErMJyyDbGuYgXHQHDASquugS8rwXYh1FpIdkrz+3d31KquisyzSuBkM5U9ynMduyHx8PxUrVGl2oPdo/gVJiswMQ5dOEuT8K1oXiGt+vJaSZVCcuyTEOTX5G3Qt84vDvXjuQ4PwKLHyQGO3v9dsSlAZlQfg3EbhDgJf09ME= Received: by 10.66.216.20 with SMTP id o20mr4053045ugg; Wed, 13 Sep 2006 06:09:57 -0700 (PDT) Received: by 10.66.234.18 with HTTP; Wed, 13 Sep 2006 06:09:54 -0700 (PDT) Message-ID: <787bbe1c0609130609l33fb29dawc465b7bcfb2f430e@mail.gmail.com> Date: Wed, 13 Sep 2006 15:09:56 +0200 From: "Slawek Zak" To: freebsd-net@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-2; format=flowed Content-Transfer-Encoding: base64 Content-Disposition: inline Subject: Rapid link state changes on bge(4) interface X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 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, 13 Sep 2006 13:09:59 -0000 SGksCgpJJ20gdGVzdGluZyBuZXR3b3JrIGZhaWxvdmVyIG9uIElCTSBCbGFkZUNlbnRlciBydW5u aW5nIEZyZWVCU0QgNi4xClNUQUJMRSBmb3IgU2VwIDZ0aC4KCkkgc3VzcGVjdCBhIHByb2JsZW0g d2l0aCBsaW5rIHN0YXRlIGNoYW5nZSBkZXRlY3Rpb24gaW4gYmdlIGNvZGUuIFdoZW4KSSBkaXNh YmxlIGludGVybmFsIHBvcnQgb24gY2hhc3NpcyBidWlsdC1pbiBldGhlcm5ldCBzd2l0Y2gsIGtl cm5lbApmbG9vZHMgc3lzbG9nIHdpdGggbWVzc2FnZXMgYWJvdXQgbGluayBzdGF0ZSBjaGFuZ2Vz IGFuZCBjb2FsZXNjaW5nCnRoZW0uIExvZyBzbmlwcGV0IGZvbGxvd3M6CgpTZXAgMTMgMTQ6NTg6 MjggdzMtNiBrZXJuZWw6IGJnZTE6IGxpbmsgc3RhdGUgY2hhbmdlZCB0byBET1dOClNlcCAxMyAx NDo1ODoyOCB3My02IGtlcm5lbDogYmdlMTogbGluayBzdGF0ZSBjaGFuZ2VkIHRvIFVQClNlcCAx MyAxNDo1ODoyOSB3My02IGtlcm5lbDogYmdlMTogbGluayBzdGF0ZSBjaGFuZ2VkIHRvIERPV04K U2VwIDEzIDE0OjU4OjI5IHczLTYga2VybmVsOiBiZ2UxOiBsaW5rIHN0YXRlIGNoYW5nZWQgdG8g VVAKU2VwIDEzIDE0OjU4OjI5IHczLTYga2VybmVsOiBiZ2UxOiBsaW5rIHN0YXRlIGNoYW5nZWQg dG8gRE9XTgpTZXAgMTMgMTQ6NTg6MjkgdzMtNiBrZXJuZWw6IGJnZTE6IDQgbGluayBzdGF0ZXMg Y29hbGVzY2VkClNlcCAxMyAxNDo1ODoyOSB3My02IGtlcm5lbDogYmdlMTogbGluayBzdGF0ZSBj aGFuZ2VkIHRvIERPV04KU2VwIDEzIDE0OjU4OjI5IHczLTYga2VybmVsOiBiZ2UxOiAxMSBsaW5r IHN0YXRlcyBjb2FsZXNjZWQKU2VwIDEzIDE0OjU4OjI5IHczLTYga2VybmVsOiBiZ2UxOiBsaW5r IHN0YXRlIGNoYW5nZWQgdG8gVVAKU2VwIDEzIDE0OjU4OjMwIHczLTYga2VybmVsOiBiZ2UxOiBs aW5rIHN0YXRlIGNoYW5nZWQgdG8gRE9XTgpTZXAgMTMgMTQ6NTg6MzAgdzMtNiBrZXJuZWw6IGJn ZTE6IDMgbGluayBzdGF0ZXMgY29hbGVzY2VkClNlcCAxMyAxNDo1ODozMCB3My02IGtlcm5lbDog YmdlMTogbGluayBzdGF0ZSBjaGFuZ2VkIHRvIFVQClNlcCAxMyAxNDo1ODozMCB3My02IGtlcm5l bDogYmdlMTogNyBsaW5rIHN0YXRlcyBjb2FsZXNjZWQKU2VwIDEzIDE0OjU4OjMwIHczLTYga2Vy bmVsOiBiZ2UxOiBsaW5rIHN0YXRlIGNoYW5nZWQgdG8gRE9XTgpTZXAgMTMgMTQ6NTg6MzAgdzMt NiBrZXJuZWw6IGJnZTE6IDQgbGluayBzdGF0ZXMgY29hbGVzY2VkClNlcCAxMyAxNDo1ODozMCB3 My02IGtlcm5lbDogYmdlMTogbGluayBzdGF0ZSBjaGFuZ2VkIHRvIERPV04KU2VwIDEzIDE0OjU4 OjMwIHczLTYga2VybmVsOiBiZ2UxOiAyIGxpbmsgc3RhdGVzIGNvYWxlc2NlZAoKQXMgeW91IGNh biBzZWUsIG1lc3NhZ2VzIGFyZSBnZW5lcmF0ZWQgaW4gcmFwaWQgc3VjY2Vzc2lvbiBhbmQKdGhl cmVmb3JlIGFueSBwcm9iaW5nIG9mIGxpbmsgc3RhdGUgY2hhbmdlIGJ5IG5nX29uZTJtYW55IGZv cgppbnRlcmZhY2UgZmFpbG92ZXIgaXMgbWVhbmluZ2xlc3MuIEV0aGVybmV0IHN3aXRjaCBkb2Vz bid0IHJlZ2lzdGVyCmFuZCBsb2cgYW55IGludGVyZmFjZSBzdGF0ZSBjaGFuZ2VzIGFmdGVyIGRp c2FibGluZyB0aGlzIHBvcnQuIExTMjAKYmxhZGVzIHVzZSBjaGlwc2V0IDg4NTAuIE15IGZpcm13 YXJlIGlzIDMuMzgsIGZ1bGwgY2hhbmdlbG9nLCBpZiBpdCBpcwpvZiBhbnkgaGVscCwgaXMgaGVy ZToKCmh0dHA6Ly93d3ctMzA3LmlibS5jb20vcGMvc3VwcG9ydC9zaXRlLndzcy9saWNlbnNlLmRv P2ZpbGVuYW1lPXBjX3NlcnZlcnMvYnJjbV9md19uaWNfMTIwMjFfYW55b3NfYW55Y3B1LmNoZwoK QW55IGlkZWFzIHdoYXQgbWlnaHQgYmUgd3Jvbmc/CgovUwotLSAKU7Nhd2VrIK9hayAvIFVOSVgg U3lzdGVtcyBBZG1pbmlzdHJhdG9yCg== From owner-freebsd-net@FreeBSD.ORG Wed Sep 13 13:13:52 2006 Return-Path: X-Original-To: freebsd-net@FreeBSD.org Delivered-To: freebsd-net@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A3C6716A5D0 for ; Wed, 13 Sep 2006 13:13:52 +0000 (UTC) (envelope-from vanhu@zeninc.net) Received: from leia.fdn.fr (ns0.fdn.org [80.67.169.12]) by mx1.FreeBSD.org (Postfix) with ESMTP id 13FBB43D4C for ; Wed, 13 Sep 2006 13:13:51 +0000 (GMT) (envelope-from vanhu@zeninc.net) Received: from smtp.zeninc.net (reverse-25.fdn.fr [80.67.176.25]) by leia.fdn.fr (8.13.3/8.13.3/FDN) with ESMTP id k8DDDnYQ016499 for ; Wed, 13 Sep 2006 15:13:50 +0200 Received: by smtp.zeninc.net (smtpd, from userid 1000) id 92F0D3F17; Wed, 13 Sep 2006 15:13:43 +0200 (CEST) Date: Wed, 13 Sep 2006 15:13:43 +0200 From: VANHULLEBUS Yvan To: freebsd-net@FreeBSD.org Message-ID: <20060913131343.GA19069@zen.inc> References: <20060905022120.19c6d62d.nork@FreeBSD.org> <20060904172700.W44392@maildrop.int.zabbadoz.net> <20060904175127.F44392@maildrop.int.zabbadoz.net> <20060906070135.GA1003@jayce.zen.inc> <20060909203147.219ae160.nork@FreeBSD.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20060909203147.219ae160.nork@FreeBSD.org> User-Agent: All mail clients suck. This one just sucks less. Cc: Subject: Re: Where is IPSec NAT-T support? X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 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, 13 Sep 2006 13:13:52 -0000 On Sat, Sep 09, 2006 at 08:31:47PM +0900, Norikatsu Shigemura wrote: > On Wed, 6 Sep 2006 09:01:35 +0200 [NAT-T patches] > > - The public patch (A) works for IPSEC, and should apply on both > > RELENG_6 and RELENG_6_1 (some minor patching issues may need to be > > solved by hand, but it's just some indentation changes in the source > > code between the two versions). > > - This public patch does NOT provide support for multiple peers behind > > the same NAT device. > > - I have a newer version of the patch (B), against RELENG_6_1, which > > provides such support for multiples peers behind the same NAT > > device. I was about to put it in public place when someone raised a > > discutable implementation choice in the way ipsec-tools and kernel > > exchange some datas specific to that NAT-T support (I ported it from > > Manu's work on NetBSD). > > How to get the patch(B)? I'm interesting new version of the patch. I just updated the public patch, it should be available on ipsec-tools website in a few hours (it replaces the old one, same address, MD5 sum is 81d535363981b5e84be77cbf26918ccc). [....] > I'm interesting FAST_IPSEC support:-). if Larry or someone else have quickly some time to do it, please let me know. If no one else port that (it shouldn't be too difficult, but takes some time), I'll do it "ASAP"..... Yvan. -- NETASQ http://www.netasq.com From owner-freebsd-net@FreeBSD.ORG Wed Sep 13 13:20:25 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id C3D4616A412 for ; Wed, 13 Sep 2006 13:20:25 +0000 (UTC) (envelope-from lab@gta.com) Received: from gta.com (gta-edge-199-20.gta.com [199.120.225.20]) by mx1.FreeBSD.org (Postfix) with SMTP id C3D2D43D73 for ; Wed, 13 Sep 2006 13:20:24 +0000 (GMT) (envelope-from lab@gta.com) Received: (qmail 2365 invoked by uid 1000); 13 Sep 2006 13:20:23 -0000 Date: 13 Sep 2006 13:20:23 -0000 Message-ID: <20060913132023.2364.qmail@gta.com> From: Larry Baird To: vanhu_bsd@zeninc.net (VANHULLEBUS Yvan) In-Reply-To: <20060913131343.GA19069@zen.inc> X-Newsgroups: freebsd.net User-Agent: tin/1.5.9-20010723 ("Chord of Souls") (UNIX) (FreeBSD/4.10-RELEASE (i386)) Cc: freebsd-net@freebsd.org Subject: Re: Where is IPSec NAT-T support? X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 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, 13 Sep 2006 13:20:25 -0000 >> I'm interesting FAST_IPSEC support:-). > > if Larry or someone else have quickly some time to do it, please let > me know. > > If no one else port that (it shouldn't be too difficult, but takes > some time), I'll do it "ASAP"..... I'll make the time. Should have something in the next day or two. Larry -- ------------------------------------------------------------------------ Larry Baird | http://www.gta.com Global Technology Associates, Inc. | Orlando, FL Email: lab@gta.com | TEL 407-380-0220, FAX 407-380-6080 From owner-freebsd-net@FreeBSD.ORG Wed Sep 13 14:15:42 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4E41616A407 for ; Wed, 13 Sep 2006 14:15:42 +0000 (UTC) (envelope-from marcelo@registro.br) Received: from clone.registro.br (clone.registro.br [200.160.2.4]) by mx1.FreeBSD.org (Postfix) with ESMTP id DEE7B43D46 for ; Wed, 13 Sep 2006 14:15:41 +0000 (GMT) (envelope-from marcelo@registro.br) Received: by clone.registro.br (Postfix, from userid 1014) id 097DE2A418; Wed, 13 Sep 2006 11:15:40 -0300 (BRT) Date: Wed, 13 Sep 2006 11:15:40 -0300 From: Marcelo Gardini do Amaral To: John Dickinson Message-ID: <20060913141540.GK63300@registro.br> References: <20060911195521.GD63300@registro.br> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.4.2.1i Cc: freebsd-net@freebsd.org Subject: Re: DNS query performance X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 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, 13 Sep 2006 14:15:42 -0000 Hi John, > I have not had time to fully investigate this issue but it appeared that > some queries from queryperf never made it out of the FreeBSD 6.1 box. When > I ran netstat -s -p udp I saw that that the numbers for delivered and > datagrams output differed by the number of queries that queryperf was > reporting as lost. However I am yet to figure out what this means. With my FreeBSD 4.11 client box the number of queries lost in the queryperf is the same as the reported by netstat command. I made a new test in another hardware, because with HP Blade Proliant is impossible to add an aditional NIC: there isn't any PCI slot and the bge interfaces are onboard. So, I used a Dell 1750, Xeon 3.06GHz with 'bge' interfaces onboard and an 'em' inserted in a slot, both running at 1Gbit/s. The results, for the same zone and queries: queries/s Server NIC F4.11-UP F6.1-UP F6.1-SMP ------ --- -------- ------- -------- bind bge 24846 15900 14700 em 22703 18800 17477 nsd bge 58948 18000 14009 em 67454 42000 35571 In general, em has a better performance than bge. But the performance on F6.1 is not so good if compared with F4.11, even for em interface. This is very vivid for NSD 3.0.1 results. On F4.11, the bge has a performance around 3 times better than F6.1. em is at least 1.5 times better. On F6.1, em has a performance about twice better than bge. On F4.11, there is no such big difference - just about 20% With this numbers, I think I can say there are something wrong with bge driver and also with F6.1 branch, because I didn't get similar results, even with em NIC. -- Att., Marcelo Gardini From owner-freebsd-net@FreeBSD.ORG Wed Sep 13 15:19:06 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D1C5616A416; Wed, 13 Sep 2006 15:19:06 +0000 (UTC) (envelope-from is@rambler-co.ru) Received: from yam.park.rambler.ru (yam.park.rambler.ru [81.19.64.116]) by mx1.FreeBSD.org (Postfix) with ESMTP id 3F40443D6A; Wed, 13 Sep 2006 15:19:05 +0000 (GMT) (envelope-from is@rambler-co.ru) Received: from is.park.rambler.ru (is.park.rambler.ru [81.19.64.102]) by yam.park.rambler.ru (8.13.6/8.13.3) with ESMTP id k8DFJ4N1055507; Wed, 13 Sep 2006 19:19:04 +0400 (MSD) (envelope-from is@rambler-co.ru) Date: Wed, 13 Sep 2006 19:19:04 +0400 (MSD) From: Igor Sysoev X-X-Sender: is@is.park.rambler.ru To: Andre Oppermann In-Reply-To: <44FAE332.4010209@freebsd.org> Message-ID: <20060913190241.S13138@is.park.rambler.ru> References: <44FAE332.4010209@freebsd.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: freebsd-net@freebsd.org, silby@freebsd.org Subject: Re: Improved TCP syncookie implementation X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 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, 13 Sep 2006 15:19:06 -0000 On Sun, 3 Sep 2006, Andre Oppermann wrote: > I've pretty much rewritten our implementation of TCP syncookies to get > rid of some locking in TCP syncache and to improve their functionality. > > The RFC1323 timestamp option is used to carry the full TCP SYN+SYN/ACK > optional feature information. This means that a FreeBSD host may run > with syncookies only and not degrade TCP connections made through it. > All important TCP connection setup negotiated options are preserved > (send/receive window scaling, SACK, MSS) without storing any state on > the host during the SYN-SYN/ACK phase. As a nice side effect the > timestamps we respond with are randomized instead of directly using > ticks (which reveals out uptime). As I understand syncache is used to retransmit SYN/ACK. What would be if 1) a client sent SYN, 2) we sent SYN/ACK with cookie, 3) the client sent ACK, but the ACK was lost ? I suppose the client will see timed out error. Igor Sysoev http://sysoev.ru/en/ From owner-freebsd-net@FreeBSD.ORG Wed Sep 13 17:03:27 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3116216A47E for ; Wed, 13 Sep 2006 17:03:27 +0000 (UTC) (envelope-from davidch@broadcom.com) Received: from MMS3.broadcom.com (mms3.broadcom.com [216.31.210.19]) by mx1.FreeBSD.org (Postfix) with ESMTP id CE46C43D95 for ; Wed, 13 Sep 2006 17:03:00 +0000 (GMT) (envelope-from davidch@broadcom.com) Received: from 10.10.64.154 by MMS3.broadcom.com with ESMTP (Broadcom SMTP Relay (Email Firewall v6.2.2)); Wed, 13 Sep 2006 10:02:47 -0700 X-Server-Uuid: 450F6D01-B290-425C-84F8-E170B39A25C9 Received: by mail-irva-10.broadcom.com (Postfix, from userid 47) id 613E12AF; Wed, 13 Sep 2006 10:02:47 -0700 (PDT) Received: from mail-irva-8.broadcom.com (mail-irva-8 [10.10.64.221]) by mail-irva-10.broadcom.com (Postfix) with ESMTP id 3E3142AE; Wed, 13 Sep 2006 10:02:47 -0700 (PDT) Received: from mail-irva-12.broadcom.com (mail-irva-12.broadcom.com [10.10.64.146]) by mail-irva-8.broadcom.com (MOS 3.7.5a-GA) with ESMTP id EEZ39426; Wed, 13 Sep 2006 10:02:46 -0700 (PDT) Received: from NT-IRVA-0750.brcm.ad.broadcom.com (nt-irva-0750 [10.8.194.64]) by mail-irva-12.broadcom.com (Postfix) with ESMTP id 5F26869CA3; Wed, 13 Sep 2006 10:02:46 -0700 (PDT) X-MimeOLE: Produced By Microsoft Exchange V6.5 Content-class: urn:content-classes:message MIME-Version: 1.0 Date: Wed, 13 Sep 2006 10:02:45 -0700 Message-ID: <09BFF2FA5EAB4A45B6655E151BBDD90301F133F0@NT-IRVA-0750.brcm.ad.broadcom.com> In-Reply-To: <787bbe1c0609130609l33fb29dawc465b7bcfb2f430e@mail.gmail.com> Thread-Topic: Rapid link state changes on bge(4) interface Thread-Index: AcbXNf+rMuLpmU8hToqxrVEnck8boAAH871A From: "David Christensen" To: "Slawek Zak" , freebsd-net@freebsd.org X-TMWD-Spam-Summary: TS=20060913170250; SEV=2.0.2; DFV=A2006091306; IFV=2.0.4,4.0-8; RPD=4.00.0004; ENG=IBF; RPDID=303030312E30413031303230342E34353038333830342E303035382D452D4A4456364D43776A676C427A6D4741774B73695447673D3D; CAT=NONE; CON=NONE X-MMS-Spam-Filter-ID: A2006091306_4.00.0004_4.0-8 X-WSS-ID: 6916E63D230999763-01-01 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Cc: Subject: RE: Rapid link state changes on bge(4) interface X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 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, 13 Sep 2006 17:03:27 -0000 > I'm testing network failover on IBM BladeCenter running FreeBSD 6.1 > STABLE for Sep 6th. >=20 > I suspect a problem with link state change detection in bge code. When > I disable internal port on chassis built-in ethernet switch, kernel > floods syslog with messages about link state changes and coalescing > them. Log snippet follows: >=20 > Sep 13 14:58:28 w3-6 kernel: bge1: link state changed to DOWN > Sep 13 14:58:28 w3-6 kernel: bge1: link state changed to UP > Sep 13 14:58:29 w3-6 kernel: bge1: link state changed to DOWN > Sep 13 14:58:29 w3-6 kernel: bge1: link state changed to UP > Sep 13 14:58:29 w3-6 kernel: bge1: link state changed to DOWN > Sep 13 14:58:29 w3-6 kernel: bge1: 4 link states coalesced > Sep 13 14:58:29 w3-6 kernel: bge1: link state changed to DOWN > Sep 13 14:58:29 w3-6 kernel: bge1: 11 link states coalesced > Sep 13 14:58:29 w3-6 kernel: bge1: link state changed to UP > Sep 13 14:58:30 w3-6 kernel: bge1: link state changed to DOWN > Sep 13 14:58:30 w3-6 kernel: bge1: 3 link states coalesced > Sep 13 14:58:30 w3-6 kernel: bge1: link state changed to UP > Sep 13 14:58:30 w3-6 kernel: bge1: 7 link states coalesced > Sep 13 14:58:30 w3-6 kernel: bge1: link state changed to DOWN > Sep 13 14:58:30 w3-6 kernel: bge1: 4 link states coalesced > Sep 13 14:58:30 w3-6 kernel: bge1: link state changed to DOWN > Sep 13 14:58:30 w3-6 kernel: bge1: 2 link states coalesced >=20 > As you can see, messages are generated in rapid succession and > therefore any probing of link state change by ng_one2many for > interface failover is meaningless. Ethernet switch doesn't register > and log any interface state changes after disabling this port. LS20 > blades use chipset 8850. My firmware is 3.38, full changelog, if it is > of any help, is here: >=20 > http://www-307.ibm.com/pc/support/site.wss/license.do?filename =3Dpc_servers/brcm_fw_nic_12021_anyos_anycpu.chg >=20 > Any ideas what might be wrong? I can't access the information on this web site through Mozilla after clicking "I Accept". Is this a 5704 controller using a SerDes link? I'm familiar with some Blade Center problems in the past (which I think were related to Sigdet) though I'm not in the office and can't=20 look into it right away. A comparison between the serdes code in the Linux driver vs. the FreeBSD driver is probably the first area to investigate. Dave From owner-freebsd-net@FreeBSD.ORG Wed Sep 13 17:22:55 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3709116A403; Wed, 13 Sep 2006 17:22:55 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from cyrus.watson.org (cyrus.watson.org [209.31.154.42]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0083343D6D; Wed, 13 Sep 2006 17:22:53 +0000 (GMT) (envelope-from rwatson@FreeBSD.org) Received: from fledge.watson.org (fledge.watson.org [209.31.154.41]) by cyrus.watson.org (Postfix) with ESMTP id E95A546BFF; Wed, 13 Sep 2006 13:22:46 -0400 (EDT) Date: Wed, 13 Sep 2006 18:22:46 +0100 (BST) From: Robert Watson X-X-Sender: robert@fledge.watson.org To: Marcelo Gardini do Amaral In-Reply-To: <20060911195521.GD63300@registro.br> Message-ID: <20060913182019.R50147@fledge.watson.org> References: <2a41acea0608301145j7bbed961j33ce903a27d8963d@mail.gmail.com> <20060904130827.GE12975@registro.br> <20060911195521.GD63300@registro.br> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: freebsd-net@freebsd.org, freebsd-stable@freebsd.org Subject: Re: DNS query performance X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 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, 13 Sep 2006 17:22:55 -0000 On Mon, 11 Sep 2006, Marcelo Gardini do Amaral wrote: > I would like to discuss a little bit more about UDP performance. I've made > some tests and the results may have some value here. > > In this test is easy to see that there is something different in the FreeBSD > 6 branch. > > I made a benchmark with bind 9.3.2 (without threads support) and nsd 3.0.1 > (1 server forked) on a HP Proliant Dual AMD Opteron 2.4GHz among FreeBSD > 4.11, 6.1 and Linux kernel 2.6.15, all of them for i386 systems. I used this > simple zone file: Are you able to boot a 7.x kernel on this box? An as yet un-MFC'd optimization to the UDP send path is present in the 7.x kernel, suggested by ISC, which significantly improves threaded BIND9 performance. I've not benchmarked unthreaded BIND9 with the change. If you want to test specifically the before/after case for that change, you can find the reference to sosend_dgram in src/sys/netinet/udp_usrreq.c and swap it to sosend, which restores the old behavior. Robert N M Watson Computer Laboratory University of Cambridge From owner-freebsd-net@FreeBSD.ORG Wed Sep 13 17:27:19 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2C58A16A4A0; Wed, 13 Sep 2006 17:27:19 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from cyrus.watson.org (cyrus.watson.org [209.31.154.42]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1577D43D8E; Wed, 13 Sep 2006 17:27:12 +0000 (GMT) (envelope-from rwatson@FreeBSD.org) Received: from fledge.watson.org (fledge.watson.org [209.31.154.41]) by cyrus.watson.org (Postfix) with ESMTP id 0246646C1D; Wed, 13 Sep 2006 13:27:11 -0400 (EDT) Date: Wed, 13 Sep 2006 18:27:11 +0100 (BST) From: Robert Watson X-X-Sender: robert@fledge.watson.org To: Marcelo Gardini do Amaral In-Reply-To: <20060913182019.R50147@fledge.watson.org> Message-ID: <20060913182457.W50147@fledge.watson.org> References: <2a41acea0608301145j7bbed961j33ce903a27d8963d@mail.gmail.com> <20060904130827.GE12975@registro.br> <20060911195521.GD63300@registro.br> <20060913182019.R50147@fledge.watson.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: freebsd-net@freebsd.org, freebsd-stable@freebsd.org Subject: Re: DNS query performance X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 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, 13 Sep 2006 17:27:19 -0000 On Wed, 13 Sep 2006, Robert Watson wrote: > On Mon, 11 Sep 2006, Marcelo Gardini do Amaral wrote: > >> I would like to discuss a little bit more about UDP performance. I've made >> some tests and the results may have some value here. >> >> In this test is easy to see that there is something different in the >> FreeBSD 6 branch. >> >> I made a benchmark with bind 9.3.2 (without threads support) and nsd 3.0.1 >> (1 server forked) on a HP Proliant Dual AMD Opteron 2.4GHz among FreeBSD >> 4.11, 6.1 and Linux kernel 2.6.15, all of them for i386 systems. I used >> this simple zone file: > > Are you able to boot a 7.x kernel on this box? An as yet un-MFC'd > optimization to the UDP send path is present in the 7.x kernel, suggested by > ISC, which significantly improves threaded BIND9 performance. I've not > benchmarked unthreaded BIND9 with the change. If you want to test > specifically the before/after case for that change, you can find the > reference to sosend_dgram in src/sys/netinet/udp_usrreq.c and swap it to > sosend, which restores the old behavior. The other common optimization advice that you may already have received is to check which time counter FreeBSD has selected. Right now, 6.x/7.x err on the side of accurate over fast. There's been quite a bit of debate about this approach, and it's useful to investigate the issue. You can view and set the current choice by looking at the sysctl kern.timecounter.hardware, and you can see the choices on your hardware by looking at kern.timecounter.choice. Typically, TSC is the fastest, but may suffer from drift as the CPU changes speed (as a result of temperature, power saving, etc). Set it to TSC if it's not already TSC, and see what the effect is. As many event libraries read time stamps frequently to set up sleeping in user space, it can have a substantial performance impact. Robert N M Watson Computer Laboratory University of Cambridge From owner-freebsd-net@FreeBSD.ORG Wed Sep 13 17:49:46 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9BCA916A407; Wed, 13 Sep 2006 17:49:46 +0000 (UTC) (envelope-from mike@sentex.net) Received: from smarthost1.sentex.ca (smarthost1.sentex.ca [64.7.153.18]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2D11B43D70; Wed, 13 Sep 2006 17:49:45 +0000 (GMT) (envelope-from mike@sentex.net) Received: from lava.sentex.ca (pyroxene.sentex.ca [199.212.134.18]) by smarthost1.sentex.ca (8.13.6/8.13.6) with ESMTP id k8DHni6U039282; Wed, 13 Sep 2006 13:49:44 -0400 (EDT) (envelope-from mike@sentex.net) Received: from mdt-xp.sentex.net (simeon.sentex.ca [192.168.43.27]) by lava.sentex.ca (8.13.6/8.13.3) with ESMTP id k8DHnihK057510 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 13 Sep 2006 13:49:44 -0400 (EDT) (envelope-from mike@sentex.net) Message-Id: <7.0.1.0.0.20060913134509.159096f0@sentex.net> X-Mailer: QUALCOMM Windows Eudora Version 7.0.1.0 Date: Wed, 13 Sep 2006 13:49:44 -0400 To: Robert Watson From: Mike Tancsa In-Reply-To: <20060913182457.W50147@fledge.watson.org> References: <2a41acea0608301145j7bbed961j33ce903a27d8963d@mail.gmail.com> <20060904130827.GE12975@registro.br> <20060911195521.GD63300@registro.br> <20060913182019.R50147@fledge.watson.org> <20060913182457.W50147@fledge.watson.org> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii"; format=flowed X-Virus-Scanned: ClamAV version 0.88.3, clamav-milter version 0.88.3 on clamscanner2 X-Virus-Status: Clean Cc: freebsd-net@freebsd.org, freebsd-stable@freebsd.org Subject: Re: DNS query performance X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 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, 13 Sep 2006 17:49:46 -0000 At 01:27 PM 9/13/2006, Robert Watson wrote: >The other common optimization advice that you may already have >received is to check which time counter FreeBSD has selected. Right >now, 6.x/7.x err on the side of accurate over fast. There's been >quite a bit of debate about this approach, and it's useful to >investigate the issue. You can view and set the current choice by >looking at the sysctl kern.timecounter.hardware, and you can see the >choices on your hardware by looking at kern.timecounter.choice. >Typically, TSC is the fastest, but may suffer from drift as the CPU changes Hi, How safe is TSC on SMP systems on RELENG_6 ? Do you still have to boot with kern.timecounter.smp_tsc="1" in /boot/loader.conf ? I was able to set it to TSC on my SMP box # sysctl kern.timecounter kern.timecounter.tick: 1 kern.timecounter.choice: TSC(-100) ACPI-fast(1000) i8254(0) dummy(-1000000) kern.timecounter.hardware: TSC kern.timecounter.nsetclock: 4 kern.timecounter.ngetmicrotime: 1710689523 kern.timecounter.ngetnanotime: 0 kern.timecounter.ngetbintime: 0 kern.timecounter.ngetmicrouptime: 417696361 kern.timecounter.ngetnanouptime: 6622371 kern.timecounter.ngetbinuptime: 17943777 kern.timecounter.nmicrotime: 2454574760 kern.timecounter.nnanotime: 1315721638 kern.timecounter.nbintime: 3770262461 kern.timecounter.nmicrouptime: 407340 kern.timecounter.nnanouptime: 1397760 kern.timecounter.nbinuptime: 3787035688 kern.timecounter.stepwarnings: 0 kern.timecounter.smp_tsc: 0 But the console fills up with Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335379728 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335379758 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335379789 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335379819 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335379849 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335379879 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335379910 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335379940 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335379970 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335380002 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335380032 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335380065 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335380096 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335380126 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335380156 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335380186 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335380216 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335380247 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335380277 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335380307 usec for pid 66442 (clamd) Sep 13 13:47:57 pumice1 kernel: calcru: runtime went backwards from 6336196518 usec to 6335380337 usec for pid 66442 (clamd) So I set things back to kern.timecounter.hardware: ACPI-fast ---Mike From owner-freebsd-net@FreeBSD.ORG Wed Sep 13 18:19:51 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 07C4B16A403 for ; Wed, 13 Sep 2006 18:19:51 +0000 (UTC) (envelope-from jon.otterholm@ide.resurscentrum.se) Received: from mail1.cil.se (mail1.cil.se [217.197.56.125]) by mx1.FreeBSD.org (Postfix) with ESMTP id 5011943D73 for ; Wed, 13 Sep 2006 18:19:46 +0000 (GMT) (envelope-from jon.otterholm@ide.resurscentrum.se) Received: from [192.168.98.245] ([192.168.44.2]) by mail1.cil.se with Microsoft SMTPSVC(6.0.3790.0); Wed, 13 Sep 2006 20:19:44 +0200 Message-ID: <45084BBD.7090903@ide.resurscentrum.se> Date: Wed, 13 Sep 2006 20:19:41 +0200 From: Jon Otterholm User-Agent: Thunderbird 1.5 (X11/20060204) MIME-Version: 1.0 To: freebsd-net@freebsd.org Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-OriginalArrivalTime: 13 Sep 2006 18:19:44.0062 (UTC) FILETIME=[2FD055E0:01C6D761] Subject: Bridge X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 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, 13 Sep 2006 18:19:51 -0000 Hi. According to man if_bridge one could filter L2-traffic with ipfw: From man if_bridge: ARP and REVARP packets are forwarded without being filtered and others that are not IP nor IPv6 packets are not forwarded when pfil_onlyip is enabled. IPFW can filter Ethernet types using mac-type so all packets are passed to the filter for processing. ARP is still forwarded though I have the following config: I have the following sysctl set: net.link.bridge.ipfw: 1 net.link.bridge.pfil_member: 1 net.link.bridge.pfil_bridge: 1 net.link.bridge.pfil_onlyip: 1 ipfw list: 65533 deny ip from any to any MAC any any 65534 deny ip from any to any layer2 65535 deny ip from any to any ifconfig: em0: flags=8943 mtu 1500 options=b inet6 fe80::204:23ff:febd:2342%em0 prefixlen 64 scopeid 0x1 ether 00:04:23:bd:23:42 media: Ethernet autoselect (100baseTX ) status: active em1: flags=8802 mtu 1500 options=b ether 00:04:23:bd:23:43 media: Ethernet autoselect status: no carrier plip0: flags=108810 mtu 1500 lo0: flags=8049 mtu 16384 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x4 inet 127.0.0.1 netmask 0xff000000 vlan1000: flags=8843 mtu 1500 inet6 fe80::204:23ff:febd:2342%vlan1000 prefixlen 64 scopeid 0x5 inet 10.0.0.2 netmask 0xffffff00 broadcast 10.0.0.255 ether 00:04:23:bd:23:42 media: Ethernet autoselect (100baseTX ) status: active vlan: 1000 parent interface: em0 vlan1001: flags=8943 mtu 1500 inet6 fe80::204:23ff:febd:2342%vlan1001 prefixlen 64 scopeid 0x6 ether 00:04:23:bd:23:42 media: Ethernet autoselect (100baseTX ) status: active vlan: 1001 parent interface: em0 vlan1002: flags=8943 mtu 1500 inet6 fe80::204:23ff:febd:2342%vlan1002 prefixlen 64 scopeid 0x7 ether 00:04:23:bd:23:42 media: Ethernet autoselect (100baseTX ) status: active vlan: 1002 parent interface: em0 bridge0: flags=8043 mtu 1500 ether ac:de:48:83:8d:c6 priority 32768 hellotime 2 fwddelay 15 maxage 20 member: vlan1002 flags=3 member: vlan1001 flags=3 member: vlan10 flags=3 vlan10: flags=8943 mtu 1500 inet 10.1.1.1 netmask 0xffffff00 broadcast 10.1.1.255 inet6 fe80::204:23ff:febd:2342%vlan10 prefixlen 64 scopeid 0x9 ether 00:04:23:bd:23:42 media: Ethernet autoselect (100baseTX ) status: active vlan: 10 parent interface: em0 ARP-broadcast can still travel between member IFs in bridge0. Have I missed something here? Do I have to use bridge instead of if_bridge? /Jon From owner-freebsd-net@FreeBSD.ORG Wed Sep 13 18:56:57 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B68F116A5CF for ; Wed, 13 Sep 2006 18:56:57 +0000 (UTC) (envelope-from andre@freebsd.org) Received: from c00l3r.networx.ch (c00l3r.networx.ch [62.48.2.2]) by mx1.FreeBSD.org (Postfix) with ESMTP id 5FC9A43D5A for ; Wed, 13 Sep 2006 18:56:48 +0000 (GMT) (envelope-from andre@freebsd.org) Received: (qmail 23778 invoked from network); 13 Sep 2006 18:40:29 -0000 Received: from c00l3r.networx.ch (HELO [127.0.0.1]) ([62.48.2.2]) (envelope-sender ) by c00l3r.networx.ch (qmail-ldap-1.03) with SMTP for ; 13 Sep 2006 18:40:29 -0000 Message-ID: <45085472.5040903@freebsd.org> Date: Wed, 13 Sep 2006 20:56:50 +0200 From: Andre Oppermann User-Agent: Thunderbird 1.5.0.5 (Windows/20060719) MIME-Version: 1.0 To: Igor Sysoev References: <44FAE332.4010209@freebsd.org> <20060913190241.S13138@is.park.rambler.ru> In-Reply-To: <20060913190241.S13138@is.park.rambler.ru> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-net@freebsd.org, silby@freebsd.org Subject: Re: Improved TCP syncookie implementation X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 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, 13 Sep 2006 18:56:57 -0000 Igor Sysoev wrote: > On Sun, 3 Sep 2006, Andre Oppermann wrote: > >> I've pretty much rewritten our implementation of TCP syncookies to get >> rid of some locking in TCP syncache and to improve their functionality. >> >> The RFC1323 timestamp option is used to carry the full TCP SYN+SYN/ACK >> optional feature information. This means that a FreeBSD host may run >> with syncookies only and not degrade TCP connections made through it. >> All important TCP connection setup negotiated options are preserved >> (send/receive window scaling, SACK, MSS) without storing any state on >> the host during the SYN-SYN/ACK phase. As a nice side effect the >> timestamps we respond with are randomized instead of directly using >> ticks (which reveals out uptime). > > As I understand syncache is used to retransmit SYN/ACK. > What would be if > > 1) a client sent SYN, > 2) we sent SYN/ACK with cookie, > 3) the client sent ACK, but the ACK was lost If the client sent ACK it will retry again after the normal retransmit timeout. If our SYN-ACK back to client is lost we won't resend it with syncookies. The client then has to try again which is does after the syn retransmit timeout. The only brokeness with syncookies used to be that we would not be able to use RFC1323 features, most prominently window scaling. This would seriously affect throughput on todays links. The improved syncookies can carry all that information in the timestamp if present and thus get rid of the limitations of the original syncookie concept and implementation. -- Andre From owner-freebsd-net@FreeBSD.ORG Wed Sep 13 19:21:48 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D58D316A407; Wed, 13 Sep 2006 19:21:48 +0000 (UTC) (envelope-from is@rambler-co.ru) Received: from yam.park.rambler.ru (yam.park.rambler.ru [81.19.64.116]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2156143D53; Wed, 13 Sep 2006 19:21:47 +0000 (GMT) (envelope-from is@rambler-co.ru) Received: from is.park.rambler.ru (is.park.rambler.ru [81.19.64.102]) by yam.park.rambler.ru (8.13.6/8.13.3) with ESMTP id k8DJLj4j071284; Wed, 13 Sep 2006 23:21:45 +0400 (MSD) (envelope-from is@rambler-co.ru) Date: Wed, 13 Sep 2006 23:21:45 +0400 (MSD) From: Igor Sysoev X-X-Sender: is@is.park.rambler.ru To: Andre Oppermann In-Reply-To: <45085472.5040903@freebsd.org> Message-ID: <20060913230748.P14337@is.park.rambler.ru> References: <44FAE332.4010209@freebsd.org> <20060913190241.S13138@is.park.rambler.ru> <45085472.5040903@freebsd.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: freebsd-net@freebsd.org, silby@freebsd.org Subject: Re: Improved TCP syncookie implementation X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 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, 13 Sep 2006 19:21:48 -0000 On Wed, 13 Sep 2006, Andre Oppermann wrote: > Igor Sysoev wrote: >> On Sun, 3 Sep 2006, Andre Oppermann wrote: >> >>> I've pretty much rewritten our implementation of TCP syncookies to get >>> rid of some locking in TCP syncache and to improve their functionality. >>> >>> The RFC1323 timestamp option is used to carry the full TCP SYN+SYN/ACK >>> optional feature information. This means that a FreeBSD host may run >>> with syncookies only and not degrade TCP connections made through it. >>> All important TCP connection setup negotiated options are preserved >>> (send/receive window scaling, SACK, MSS) without storing any state on >>> the host during the SYN-SYN/ACK phase. As a nice side effect the >>> timestamps we respond with are randomized instead of directly using >>> ticks (which reveals out uptime). >> >> As I understand syncache is used to retransmit SYN/ACK. >> What would be if >> >> 1) a client sent SYN, >> 2) we sent SYN/ACK with cookie, >> 3) the client sent ACK, but the ACK was lost > > If the client sent ACK it will retry again after the normal retransmit > timeout. Well, suppose protocol similar to SSH or SMTP: 1) the client calls connect(), it sends SYN; 2) the server receives SYN and sends SYN/ACK with cookie; 3) the client receives SYN/ACK and sends ACK; 4) the client returns successfully from connect() and calls read(); 5) the ACK is lost; 6) the server does not about this connection, so application can not accept() it, and it can not send() HELO message. 7) the client gets ETIMEDOUT from read(). Where in this sequence client may retransmit its ACK ? > If our SYN-ACK back to client is lost we won't resend it with syncookies. > The client then has to try again which is does after the syn retransmit > timeout. Yes. Igor Sysoev http://sysoev.ru/en/ From owner-freebsd-net@FreeBSD.ORG Wed Sep 13 20:31:46 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 8D9F316A47C for ; Wed, 13 Sep 2006 20:31:46 +0000 (UTC) (envelope-from andre@freebsd.org) Received: from c00l3r.networx.ch (c00l3r.networx.ch [62.48.2.2]) by mx1.FreeBSD.org (Postfix) with ESMTP id 75DDC43D76 for ; Wed, 13 Sep 2006 20:31:41 +0000 (GMT) (envelope-from andre@freebsd.org) Received: (qmail 24414 invoked from network); 13 Sep 2006 20:15:21 -0000 Received: from c00l3r.networx.ch (HELO [127.0.0.1]) ([62.48.2.2]) (envelope-sender ) by c00l3r.networx.ch (qmail-ldap-1.03) with SMTP for ; 13 Sep 2006 20:15:21 -0000 Message-ID: <45086AAF.108@freebsd.org> Date: Wed, 13 Sep 2006 22:31:43 +0200 From: Andre Oppermann User-Agent: Thunderbird 1.5.0.5 (Windows/20060719) MIME-Version: 1.0 To: Igor Sysoev References: <44FAE332.4010209@freebsd.org> <20060913190241.S13138@is.park.rambler.ru> <45085472.5040903@freebsd.org> <20060913230748.P14337@is.park.rambler.ru> In-Reply-To: <20060913230748.P14337@is.park.rambler.ru> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-net@freebsd.org, silby@freebsd.org Subject: Re: Improved TCP syncookie implementation X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 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, 13 Sep 2006 20:31:46 -0000 Igor Sysoev wrote: > On Wed, 13 Sep 2006, Andre Oppermann wrote: > >> Igor Sysoev wrote: >>> On Sun, 3 Sep 2006, Andre Oppermann wrote: >>> >>>> I've pretty much rewritten our implementation of TCP syncookies to get >>>> rid of some locking in TCP syncache and to improve their functionality. >>>> >>>> The RFC1323 timestamp option is used to carry the full TCP SYN+SYN/ACK >>>> optional feature information. This means that a FreeBSD host may run >>>> with syncookies only and not degrade TCP connections made through it. >>>> All important TCP connection setup negotiated options are preserved >>>> (send/receive window scaling, SACK, MSS) without storing any state on >>>> the host during the SYN-SYN/ACK phase. As a nice side effect the >>>> timestamps we respond with are randomized instead of directly using >>>> ticks (which reveals out uptime). >>> >>> As I understand syncache is used to retransmit SYN/ACK. >>> What would be if >>> >>> 1) a client sent SYN, >>> 2) we sent SYN/ACK with cookie, >>> 3) the client sent ACK, but the ACK was lost >> >> If the client sent ACK it will retry again after the normal retransmit >> timeout. > > Well, suppose protocol similar to SSH or SMTP: > > 1) the client calls connect(), it sends SYN; > 2) the server receives SYN and sends SYN/ACK with cookie; > 3) the client receives SYN/ACK and sends ACK; > 4) the client returns successfully from connect() and calls read(); > 5) the ACK is lost; > 6) the server does not about this connection, so application can not > accept() it, and it can not send() HELO message. > 7) the client gets ETIMEDOUT from read(). > > Where in this sequence client may retransmit its ACK ? Never. You're correct. There is no data that would cause a retransmit if the application is waiting for a server prompt first. I shouldn't write wrong explanations when I'm tired, hungry and in between two tasks. ;) This problem is the reason why we don't switch entirely to syncookies and still keep syncache as is. >> If our SYN-ACK back to client is lost we won't resend it with syncookies. >> The client then has to try again which is does after the syn retransmit >> timeout. > > Yes. -- Andre From owner-freebsd-net@FreeBSD.ORG Wed Sep 13 21:42:54 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 364C516A40F for ; Wed, 13 Sep 2006 21:42:54 +0000 (UTC) (envelope-from thompsa@freebsd.org) Received: from grunt3.ihug.co.nz (grunt3.ihug.co.nz [203.109.254.43]) by mx1.FreeBSD.org (Postfix) with ESMTP id D006A43D4C for ; Wed, 13 Sep 2006 21:42:53 +0000 (GMT) (envelope-from thompsa@freebsd.org) Received: from 203-109-251-39.static.bliink.ihug.co.nz (heff.fud.org.nz) [203.109.251.39] by grunt3.ihug.co.nz with esmtp (Exim 3.35 #1 (Debian)) id 1GNcVO-0004qh-00; Thu, 14 Sep 2006 09:42:50 +1200 Received: by heff.fud.org.nz (Postfix, from userid 1001) id 200071CC23; Thu, 14 Sep 2006 09:42:50 +1200 (NZST) Date: Thu, 14 Sep 2006 09:42:50 +1200 From: Andrew Thompson To: Jon Otterholm Message-ID: <20060913214250.GB6334@heff.fud.org.nz> References: <4506CC6C.4030308@ide.resurscentrum.se> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <4506CC6C.4030308@ide.resurscentrum.se> User-Agent: Mutt/1.5.11 Cc: freebsd-net@freebsd.org Subject: Re: Limit arp on bridge X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 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, 13 Sep 2006 21:42:54 -0000 On Tue, Sep 12, 2006 at 05:04:12PM +0200, Jon Otterholm wrote: > Hello. > > I am trying to limit arp-broadcast between member-IF on a bridge > (if_bridge) with no luck. > > I have the following sysctls set: > > net.link.bridge.pfil_member: 1 > net.link.bridge.pfil_bridge: 1 > net.link.bridge.pfil_onlyip: 1 > > I am using PF for filtering - do I have to use IPFW to limit > arp-broadcast between memeber-ifs? See this snippit of code from if_bridge * (Note that since pfil doesn't understand ARP it will pass *ALL* * ARP traffic.) */ switch (ether_type) { case ETHERTYPE_ARP: case ETHERTYPE_REVARP: return (0); /* Automatically pass */ The only way that you will be able to filter ARP packets is by setting pfil_onlyip=0, ipfw=1 and use the IPFW layer2 filtering. cheers, Andrew From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 04:20:15 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 07C6916A40F for ; Thu, 14 Sep 2006 04:20:14 +0000 (UTC) (envelope-from thompsa@freebsd.org) Received: from grunt6.ihug.co.nz (grunt6.ihug.co.nz [203.109.254.46]) by mx1.FreeBSD.org (Postfix) with ESMTP id 8AD3643D45 for ; Thu, 14 Sep 2006 04:20:14 +0000 (GMT) (envelope-from thompsa@freebsd.org) Received: from 203-109-251-39.static.bliink.ihug.co.nz (heff.fud.org.nz) [203.109.251.39] by grunt6.ihug.co.nz with esmtp (Exim 3.35 #1 (Debian)) id 1GNihv-0004xA-00; Thu, 14 Sep 2006 16:20:11 +1200 Received: by heff.fud.org.nz (Postfix, from userid 1001) id CFFCB1CC23; Thu, 14 Sep 2006 16:20:10 +1200 (NZST) Date: Thu, 14 Sep 2006 16:20:10 +1200 From: Andrew Thompson To: Jon Otterholm Message-ID: <20060914042010.GA35371@heff.fud.org.nz> References: <45084BBD.7090903@ide.resurscentrum.se> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <45084BBD.7090903@ide.resurscentrum.se> User-Agent: Mutt/1.5.11 Cc: freebsd-net@freebsd.org Subject: Re: Bridge X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 04:20:15 -0000 On Wed, Sep 13, 2006 at 08:19:41PM +0200, Jon Otterholm wrote: > Hi. > > According to man if_bridge one could filter L2-traffic with ipfw: > > From man if_bridge: > ARP and REVARP packets are forwarded without being filtered and others > that are not IP nor IPv6 packets are not forwarded when pfil_onlyip is > enabled. IPFW can filter Ethernet types using mac-type so all packets > are passed to the filter for processing. > > ARP is still forwarded though I have the following config: > > I have the following sysctl set: > > net.link.bridge.ipfw: 1 > net.link.bridge.pfil_member: 1 > net.link.bridge.pfil_bridge: 1 > net.link.bridge.pfil_onlyip: 1 > > ipfw list: > > 65533 deny ip from any to any MAC any any > 65534 deny ip from any to any layer2 > 65535 deny ip from any to any The check for ARP happens before the ipfw layer2 code so it isnt currently possible to filter them. switch (ether_type) { case ETHERTYPE_ARP: case ETHERTYPE_REVARP: return (0); /* Automatically pass */ You are the second person in so many days to ask this, is it something that should be changed? Andrew From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 04:38:14 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id BF20316A403; Thu, 14 Sep 2006 04:38:14 +0000 (UTC) (envelope-from rea@codelabs.ru) Received: from pobox.codelabs.ru (pobox.codelabs.ru [144.206.177.45]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1F56343D49; Thu, 14 Sep 2006 04:38:13 +0000 (GMT) (envelope-from rea@codelabs.ru) DomainKey-Signature: a=rsa-sha1; q=dns; c=simple; s=one; d=codelabs.ru; h=Received:Date:From:To:Cc:Message-ID:References:MIME-Version:Content-Type:Content-Disposition:In-Reply-To:Sender:X-Spam-Status:Subject; b=WX0vW0hMEIftlLY2xlalFgNjqc8NW6HQv9R4K8uK2XKfmyTVES/BR+s9DJIQqmqODdJz/GGIipnJEc8/idTzVVjsTKZhX7jhGnOrh6LGF0PF8xwZUosG1kOedkr7GLlQH2bEWlJlKXTHhXnRdokocG6Q7HwiFO6BC16UnzVFkro=; Received: from codelabs.ru (pobox.codelabs.ru [144.206.177.45]) by pobox.codelabs.ru with esmtpsa (TLSv1:AES256-SHA:256) id 1GNizH-000DjW-Bw (envelope-from ); Thu, 14 Sep 2006 08:38:07 +0400 Date: Thu, 14 Sep 2006 08:38:02 +0400 From: Eygene Ryabinkin To: Andrew Thompson Message-ID: <20060914043802.GZ1221@codelabs.ru> References: <45084BBD.7090903@ide.resurscentrum.se> <20060914042010.GA35371@heff.fud.org.nz> MIME-Version: 1.0 Content-Type: text/plain; charset=koi8-r Content-Disposition: inline In-Reply-To: <20060914042010.GA35371@heff.fud.org.nz> Sender: rea@codelabs.ru X-Spam-Status: No, score=-1.8 required=4.0 tests=ALL_TRUSTED,AWL,BAYES_40, DK_POLICY_SIGNALL Cc: freebsd-net@freebsd.org, Jon Otterholm Subject: Re: Bridge X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 04:38:14 -0000 Andrew, good day! > The check for ARP happens before the ipfw layer2 code so it isnt > currently possible to filter them. > > switch (ether_type) { > case ETHERTYPE_ARP: > case ETHERTYPE_REVARP: > return (0); /* Automatically pass */ I am a bit confused because in the another thread (also created by Jon Otterholm) you've answered that ----- The only way that you will be able to filter ARP packets is by setting pfil_onlyip=0, ipfw=1 and use the IPFW layer2 filtering. ----- citing the same code. Am I understand something incorrectly or these two answers do contradict with each other? -- Eygene From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 04:48:49 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 6752316A4D4 for ; Thu, 14 Sep 2006 04:48:49 +0000 (UTC) (envelope-from thompsa@freebsd.org) Received: from grunt8.ihug.co.nz (grunt8.ihug.co.nz [203.109.254.48]) by mx1.FreeBSD.org (Postfix) with ESMTP id CDE8543D58 for ; Thu, 14 Sep 2006 04:48:48 +0000 (GMT) (envelope-from thompsa@freebsd.org) Received: from 203-109-251-39.static.bliink.ihug.co.nz (heff.fud.org.nz) [203.109.251.39] by grunt8.ihug.co.nz with esmtp (Exim 3.35 #1 (Debian)) id 1GNj9X-0001rH-00; Thu, 14 Sep 2006 16:48:43 +1200 Received: by heff.fud.org.nz (Postfix, from userid 1001) id 9A3A91CC23; Thu, 14 Sep 2006 16:48:42 +1200 (NZST) Date: Thu, 14 Sep 2006 16:48:42 +1200 From: Andrew Thompson To: Eygene Ryabinkin Message-ID: <20060914044842.GC35371@heff.fud.org.nz> References: <45084BBD.7090903@ide.resurscentrum.se> <20060914042010.GA35371@heff.fud.org.nz> <20060914043802.GZ1221@codelabs.ru> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="LZvS9be/3tNcYl/X" Content-Disposition: inline In-Reply-To: <20060914043802.GZ1221@codelabs.ru> User-Agent: Mutt/1.5.11 Cc: freebsd-net@freebsd.org, Jon Otterholm Subject: Re: Bridge X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 04:48:49 -0000 --LZvS9be/3tNcYl/X Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Thu, Sep 14, 2006 at 08:38:02AM +0400, Eygene Ryabinkin wrote: > Andrew, good day! > > > The check for ARP happens before the ipfw layer2 code so it isnt > > currently possible to filter them. > > > > switch (ether_type) { > > case ETHERTYPE_ARP: > > case ETHERTYPE_REVARP: > > return (0); /* Automatically pass */ > I am a bit confused because in the another thread (also created by > Jon Otterholm) you've answered that > ----- > The only way that you will be able to filter ARP packets is by setting > pfil_onlyip=0, ipfw=1 and use the IPFW layer2 filtering. > ----- > citing the same code. Am I understand something incorrectly or these > two answers do contradict with each other? Yes, thats just me being stupid :) My first answer to Jon was not correct, you can not currently filter ARP. I have attached a patch that should make this possible my rearranging things. Thanks for pointing it out. Andrew --LZvS9be/3tNcYl/X Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="bridge_filterarp.diff" Index: if_bridge.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_bridge.c,v retrieving revision 1.79 diff -u -p -r1.79 if_bridge.c --- if_bridge.c 25 Aug 2006 20:11:56 -0000 1.79 +++ if_bridge.c 14 Sep 2006 04:38:50 -0000 @@ -490,11 +490,9 @@ sysctl_pfil_ipfw(SYSCTL_HANDLER_ARGS) /* * Disable pfil so that ipfw doesnt run twice, if the user * really wants both then they can re-enable pfil_bridge and/or - * pfil_member. Also allow non-ip packets as ipfw can filter by - * layer2 type. + * pfil_member. */ if (pfil_ipfw) { - pfil_onlyip = 0; pfil_bridge = 0; pfil_member = 0; } @@ -2736,34 +2734,6 @@ bridge_pfil(struct mbuf **mp, struct ifn } } - /* - * If we're trying to filter bridge traffic, don't look at anything - * other than IP and ARP traffic. If the filter doesn't understand - * IPv6, don't allow IPv6 through the bridge either. This is lame - * since if we really wanted, say, an AppleTalk filter, we are hosed, - * but of course we don't have an AppleTalk filter to begin with. - * (Note that since pfil doesn't understand ARP it will pass *ALL* - * ARP traffic.) - */ - switch (ether_type) { - case ETHERTYPE_ARP: - case ETHERTYPE_REVARP: - return (0); /* Automatically pass */ - case ETHERTYPE_IP: -#ifdef INET6 - case ETHERTYPE_IPV6: -#endif /* INET6 */ - break; - default: - /* - * Check to see if the user wants to pass non-ip - * packets, these will not be checked by pfil(9) and - * passed unconditionally so the default is to drop. - */ - if (pfil_onlyip) - goto bad; - } - /* Strip off the Ethernet header and keep a copy. */ m_copydata(*mp, 0, ETHER_HDR_LEN, (caddr_t) &eh2); m_adj(*mp, ETHER_HDR_LEN); @@ -2836,9 +2806,14 @@ ipfwpass: error = 0; /* - * Run the packet through pfil + * Run the packet through pfil. (Note that since pfil doesn't understand + * ARP it will pass *ALL* ARP traffic.) */ switch (ether_type) { + case ETHERTYPE_ARP: + case ETHERTYPE_REVARP: + return (0); /* Automatically pass */ + case ETHERTYPE_IP: /* * before calling the firewall, swap fields the same as @@ -2930,7 +2905,14 @@ ipfwpass: break; #endif default: - error = 0; + /* + * Check to see if the user wants to pass non-ip + * packets. + */ + if (pfil_onlyip) { + error = -1; + goto bad; + } break; } --LZvS9be/3tNcYl/X-- From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 06:52:34 2006 Return-Path: X-Original-To: freebsd-net@FreeBSD.org Delivered-To: freebsd-net@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0D93616A40F for ; Thu, 14 Sep 2006 06:52:34 +0000 (UTC) (envelope-from sivakumar.subramani@wipro.com) Received: from wip-ectls-mx3.wipro.com (wip-ectls-mx3.wipro.com [203.91.193.23]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2F66243D62 for ; Thu, 14 Sep 2006 06:51:59 +0000 (GMT) (envelope-from sivakumar.subramani@wipro.com) Received: from wip-ectls-mx3.wipro.com (localhost.localdomain [127.0.0.1]) by localhost (Postfix) with ESMTP id B64752243CB for ; Thu, 14 Sep 2006 12:21:44 +0530 (IST) Received: from blr-ec-bh01.wipro.com (blr-ec-bh01.wipro.com [10.201.50.91]) by wip-ectls-mx3.wipro.com (Postfix) with ESMTP id 5A5CC224007 for ; Thu, 14 Sep 2006 12:21:44 +0530 (IST) Received: from blr-m3-msg.wipro.com ([10.114.50.99]) by blr-ec-bh01.wipro.com with Microsoft SMTPSVC(6.0.3790.1830); Thu, 14 Sep 2006 12:21:44 +0530 X-MimeOLE: Produced By Microsoft Exchange V6.5 Content-class: urn:content-classes:message MIME-Version: 1.0 Date: Thu, 14 Sep 2006 12:16:17 +0530 Message-ID: <956E7FA2615F3B4595FC5F22870A7221067206@blr-m3-msg.wipro.com> X-MS-Has-Attach: X-MS-TNEF-Correlator: Thread-Topic: Reading a configuration file from a driver code during intialization. Thread-Index: AcbXyi70vxMG6AygSsqcgDXge8szUg== From: To: X-OriginalArrivalTime: 14 Sep 2006 06:51:44.0338 (UTC) FILETIME=[3D981320:01C6D7CA] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Cc: Subject: Reading a configuration file from a driver code during intialization. X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 06:52:34 -0000 Hi all, =0D For our driver we have following requirement. We have a configuration file that will be updated by the user and while loading the driver, the initialization code should read the configuration file to get the value and use it in the driver code.=0D =0D Is there is any way to read a configuration file from driver code?=0D =0D Currently I have written a small kernel module that will create a sysctl variable and update with a default value. After loading this module, using shell scripts, I read the configuration file and get the user set values and update the sysctl variable in that value. Then I will load my driver where I read the sysctl variable to get the required values set by the user in the configuration file. =0D Is there is any other solution to the above problem? =0D Actually I am looking for some thing similar to Module loadable parameters in the Linux Device Driver. =0D Thanks, ~Siva The information contained in this electronic message and any attachments to= this message are intended for the exclusive use of the addressee(s) and= may contain proprietary, confidential or privileged information. If you= are not the intended recipient, you should not disseminate, distribute or= copy this e-mail. Please notify the sender immediately and destroy all= copies of this message and any attachments.=0D WARNING: Computer viruses can be transmitted via email. The recipient= should check this email and any attachments for the presence of viruses.= The company accepts no liability for any damage caused by any virus= transmitted by this email. =0D www.wipro.com From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 09:30:11 2006 Return-Path: X-Original-To: freebsd-net@FreeBSD.org Delivered-To: freebsd-net@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 63A5916A4AB; Thu, 14 Sep 2006 09:30:11 +0000 (UTC) (envelope-from ru@rambler-co.ru) Received: from relay0.rambler.ru (relay0.rambler.ru [81.19.66.187]) by mx1.FreeBSD.org (Postfix) with ESMTP id BEEDC43D55; Thu, 14 Sep 2006 09:30:03 +0000 (GMT) (envelope-from ru@rambler-co.ru) Received: from relay0.rambler.ru (localhost [127.0.0.1]) by relay0.rambler.ru (Postfix) with ESMTP id A3AC85C96; Thu, 14 Sep 2006 13:30:02 +0400 (MSD) Received: from edoofus.park.rambler.ru (unknown [81.19.65.108]) by relay0.rambler.ru (Postfix) with ESMTP id 971365C67; Thu, 14 Sep 2006 13:30:02 +0400 (MSD) Received: (from ru@localhost) by edoofus.park.rambler.ru (8.13.8/8.13.8) id k8E9U6tZ026801; Thu, 14 Sep 2006 13:30:06 +0400 (MSD) (envelope-from ru) Date: Thu, 14 Sep 2006 13:30:06 +0400 From: Ruslan Ermilov To: Andre Oppermann Message-ID: <20060914093006.GE26261@rambler-co.ru> References: <44FAE332.4010209@freebsd.org> <20060913190241.S13138@is.park.rambler.ru> <45085472.5040903@freebsd.org> <20060913230748.P14337@is.park.rambler.ru> <45086AAF.108@freebsd.org> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="ZwgA9U+XZDXt4+m+" Content-Disposition: inline In-Reply-To: <45086AAF.108@freebsd.org> User-Agent: Mutt/1.5.13 (2006-08-11) X-Virus-Scanned: No virus found Cc: freebsd-net@FreeBSD.org, Igor Sysoev , silby@FreeBSD.org Subject: Re: Improved TCP syncookie implementation X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 09:30:11 -0000 --ZwgA9U+XZDXt4+m+ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, Sep 13, 2006 at 10:31:43PM +0200, Andre Oppermann wrote: > Igor Sysoev wrote: > >Well, suppose protocol similar to SSH or SMTP: > > > >1) the client calls connect(), it sends SYN; > >2) the server receives SYN and sends SYN/ACK with cookie; > >3) the client receives SYN/ACK and sends ACK; > >4) the client returns successfully from connect() and calls read(); > >5) the ACK is lost; > >6) the server does not about this connection, so application can not > > accept() it, and it can not send() HELO message. > >7) the client gets ETIMEDOUT from read(). > > > >Where in this sequence client may retransmit its ACK ? >=20 > Never. You're correct. There is no data that would cause a retransmit > if the application is waiting for a server prompt first. I shouldn't > write wrong explanations when I'm tired, hungry and in between two tasks.= ;) >=20 > This problem is the reason why we don't switch entirely to syncookies > and still keep syncache as is. >=20 Perhaps it would be a good idea to remove net.inet.tcp.syncookies_only then? In any case, please don't forget to update the syncache(4) manpage to reflect your changes, and if you decide not to remove this sysctl, please add a warning of its potential to break a protocol. Cheers, --=20 Ruslan Ermilov ru@FreeBSD.org FreeBSD committer --ZwgA9U+XZDXt4+m+ Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.5 (FreeBSD) iD8DBQFFCSEeqRfpzJluFF4RAts1AJ9RMcvus0lo8ag4/X41W1+gSip2jQCZAU+9 QuQJsMytIv7ja4rzuOEY8XY= =4K+D -----END PGP SIGNATURE----- --ZwgA9U+XZDXt4+m+-- From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 09:58:06 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 57BF316A591 for ; Thu, 14 Sep 2006 09:58:06 +0000 (UTC) (envelope-from slawek.zak@gmail.com) Received: from ug-out-1314.google.com (ug-out-1314.google.com [66.249.92.168]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9D13143D49 for ; Thu, 14 Sep 2006 09:58:05 +0000 (GMT) (envelope-from slawek.zak@gmail.com) Received: by ug-out-1314.google.com with SMTP id m2so87498uge for ; Thu, 14 Sep 2006 02:58:04 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=gacrFotKWZ0O9GY7NshIJAEvKOsUmILx0ueGhTln9xlWTe/NM49ZW10tA6Chk2y3wSbJQNAzV1DCMDIk8Zg0glUjKInnsmTc8eWA/bJag3emhyoTIa9mPZqpNF+0+9RG4kJmLE2CvC+4jAPBR2FrNIIUnVupAH9NV0hf9n7L4vc= Received: by 10.67.100.17 with SMTP id c17mr4636633ugm; Thu, 14 Sep 2006 02:58:04 -0700 (PDT) Received: by 10.66.234.18 with HTTP; Thu, 14 Sep 2006 02:58:04 -0700 (PDT) Message-ID: <787bbe1c0609140258m77feb66fnb709b873ca9c14f8@mail.gmail.com> Date: Thu, 14 Sep 2006 11:58:04 +0200 From: "Slawek Zak" To: freebsd-net@freebsd.org In-Reply-To: <787bbe1c0609140257x53719b6as5849bdf866c954b7@mail.gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-2; format=flowed Content-Transfer-Encoding: base64 Content-Disposition: inline References: <787bbe1c0609130609l33fb29dawc465b7bcfb2f430e@mail.gmail.com> <09BFF2FA5EAB4A45B6655E151BBDD90301F133F0@NT-IRVA-0750.brcm.ad.broadcom.com> <787bbe1c0609140257x53719b6as5849bdf866c954b7@mail.gmail.com> Subject: Re: Rapid link state changes on bge(4) interface X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 09:58:06 -0000 T24gOS8xMy8wNiwgRGF2aWQgQ2hyaXN0ZW5zZW4gPGRhdmlkY2hAYnJvYWRjb20uY29tPiB3cm90 ZToKPiBJIGNhbid0IGFjY2VzcyB0aGUgaW5mb3JtYXRpb24gb24gdGhpcyB3ZWIgc2l0ZSB0aHJv dWdoIE1vemlsbGEgYWZ0ZXIKPiBjbGlja2luZyAiSSBBY2NlcHQiLgoKSG0uIEkndmUganVzdCBm b3VuZCBvdXQgdGhhdCBwb3N0aW5nIGRpcmVjdCBsaW5rcyB0byBkb2N1bWVudHMgaXMgdG9vCldl YiAxLjAgZm9yIGlibS5jb20uIEhlcmUgaXMgbGluayB0byB0aGUgcGFyZW50IHBhZ2UgLSB3b3Jr cyBmb3IgbWU6CgpodHRwOi8vd3d3LTMwNy5pYm0uY29tL3BjL3N1cHBvcnQvc2l0ZS53c3MvZG9j dW1lbnQuZG8/bG5kb2NpZD1NSUdSLTUzNjkzCgo+IElzIHRoaXMgYSA1NzA0IGNvbnRyb2xsZXIg dXNpbmcgYSBTZXJEZXMgbGluaz8KClRoZSBhYm92ZSBwYWdlIHNheXM6CgotIElCTSBCbGFkZUNl bnRlciBMUzIwIChUeXBlIDg4NTApCgpEdW5ubyBpZiBpdCBpcyBCcm9hZGNvbSBvciBJQk0gcGFy bGFuY2UuCgo+IEknbSBmYW1pbGlhciB3aXRoIHNvbWUgQmxhZGUgQ2VudGVyIHByb2JsZW1zIGlu IHRoZSBwYXN0ICh3aGljaCBJCj4gdGhpbmsgd2VyZSByZWxhdGVkIHRvIFNpZ2RldCkgdGhvdWdo IEknbSBub3QgaW4gdGhlIG9mZmljZSBhbmQgY2FuJ3QKPiBsb29rIGludG8gaXQgcmlnaHQgYXdh eS4gIEEgY29tcGFyaXNvbiBiZXR3ZWVuIHRoZSBzZXJkZXMgY29kZSBpbgo+IHRoZSBMaW51eCBk cml2ZXIgdnMuIHRoZSBGcmVlQlNEIGRyaXZlciBpcyBwcm9iYWJseSB0aGUgZmlyc3QgYXJlYSB0 bwo+IGludmVzdGlnYXRlLgoKSSBoYXZlIGZyYW5rbHkgbm8gaWRlYSB3aGVyZSB0byBsb29rLgoK VGhhbmtzIGZvciBhbnkgaGVscCwgL1MKLS0KU7Nhd2VrIK9hayAvIFVOSVggU3lzdGVtcyBBZG1p bmlzdHJhdG9yCg== From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 10:36:01 2006 Return-Path: X-Original-To: freebsd-net@FreeBSD.org Delivered-To: freebsd-net@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4388C16A403; Thu, 14 Sep 2006 10:36:01 +0000 (UTC) (envelope-from is@rambler-co.ru) Received: from yam.park.rambler.ru (yam.park.rambler.ru [81.19.64.116]) by mx1.FreeBSD.org (Postfix) with ESMTP id 8A60043D45; Thu, 14 Sep 2006 10:35:59 +0000 (GMT) (envelope-from is@rambler-co.ru) Received: from is.park.rambler.ru (is.park.rambler.ru [81.19.64.102]) by yam.park.rambler.ru (8.13.6/8.13.3) with ESMTP id k8EAZwHD034584; Thu, 14 Sep 2006 14:35:58 +0400 (MSD) (envelope-from is@rambler-co.ru) Date: Thu, 14 Sep 2006 14:35:58 +0400 (MSD) From: Igor Sysoev X-X-Sender: is@is.park.rambler.ru To: Ruslan Ermilov In-Reply-To: <20060914093006.GE26261@rambler-co.ru> Message-ID: <20060914143059.T16483@is.park.rambler.ru> References: <44FAE332.4010209@freebsd.org> <20060913190241.S13138@is.park.rambler.ru> <45085472.5040903@freebsd.org> <20060913230748.P14337@is.park.rambler.ru> <45086AAF.108@freebsd.org> <20060914093006.GE26261@rambler-co.ru> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: freebsd-net@FreeBSD.org, silby@FreeBSD.org, Andre Oppermann Subject: Re: Improved TCP syncookie implementation X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 10:36:01 -0000 On Thu, 14 Sep 2006, Ruslan Ermilov wrote: > On Wed, Sep 13, 2006 at 10:31:43PM +0200, Andre Oppermann wrote: >> Igor Sysoev wrote: >>> Well, suppose protocol similar to SSH or SMTP: >>> >>> 1) the client calls connect(), it sends SYN; >>> 2) the server receives SYN and sends SYN/ACK with cookie; >>> 3) the client receives SYN/ACK and sends ACK; >>> 4) the client returns successfully from connect() and calls read(); >>> 5) the ACK is lost; >>> 6) the server does not about this connection, so application can not >>> accept() it, and it can not send() HELO message. >>> 7) the client gets ETIMEDOUT from read(). >>> >>> Where in this sequence client may retransmit its ACK ? >> >> Never. You're correct. There is no data that would cause a retransmit >> if the application is waiting for a server prompt first. I shouldn't >> write wrong explanations when I'm tired, hungry and in between two tasks. ;) >> >> This problem is the reason why we don't switch entirely to syncookies >> and still keep syncache as is. >> > Perhaps it would be a good idea to remove net.inet.tcp.syncookies_only > then? In any case, please don't forget to update the syncache(4) manpage > to reflect your changes, and if you decide not to remove this sysctl, > please add a warning of its potential to break a protocol. I think that setting syncookies only not globally, but on per port basis, say, for HTTP would be helpfull. Setting it for other protocols, e.g, SSH, rsync, SMTP, IMAP, POP3 may break them. Igor Sysoev http://sysoev.ru/en/ From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 13:28:15 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1D34E16A407 for ; Thu, 14 Sep 2006 13:28:15 +0000 (UTC) (envelope-from wjw@digiware.nl) Received: from freebee.digiware.nl (www.tegenbosch28.nl [217.21.251.97]) by mx1.FreeBSD.org (Postfix) with ESMTP id 929B743D70 for ; Thu, 14 Sep 2006 13:28:10 +0000 (GMT) (envelope-from wjw@digiware.nl) Received: from [212.61.27.67] (opteron.digiware.nl [212.61.27.67]) by freebee.digiware.nl (Postfix) with ESMTP id 1413B2AAA0 for ; Thu, 14 Sep 2006 15:28:09 +0200 (CEST) Message-ID: <4509592A.3040602@digiware.nl> Date: Thu, 14 Sep 2006 15:29:14 +0200 From: Willem Jan Withagen User-Agent: Thunderbird 1.5.0.5 (Windows/20060719) MIME-Version: 1.0 To: freebsd-net@freebsd.org Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: blocking a string in a packet using ipfw X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 13:28:15 -0000 [ I guess I haven't been paying too much attention during ipwf class :( And I got the suggestion to try FreeBSD-net@ instead of security. But I'm not subscribed to this list, so please Cc: me. ] Hi, perhaps somebody could give some pointers. I received a call from a customer this morning that all of his websites were no longer on line. So After some resetting and more I turnout that there was a serious overload on his server. Over 500 clients connected. (norm is 50) and they were all trying to get this file 777.gif. (Which is not on any of the sites). After reducing the max servers to a 100, the sites are now more or less up. Then I created a swatch script to actually block the offenders thru ipwl. (Which was already used to do most of the protection). It is already a solution, because they keep trying it multiple times. But it turns out that the generic name of the server is in a new virus on a list of server to get a file from. And it's on high place in that list. So I can confirm that there are at least 35.000 pc's infected with this Bagle.FY virus. And these are now all in the block list in IPFW. I contacted the maintainer for the generic FQDN name of the server to reset the IP-number for that name to 127.0.0.1 but that'll take another 24 hours to propagate thru the whole of the internet. Now I'm pretty shure that ipfw does not stretch indefinitely to contain perhaps something like 100.000 ip-numbers (would be a nice test. :) ) So I'd like to see if there is something to do with divert and some matching on a string in the packet to drop those packets. That would prevent me from having humongous set of rules in ipfw. Or any other suggestion that would make sense. Thanx, --WjW From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 13:30:39 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 67F0F16A40F for ; Thu, 14 Sep 2006 13:30:39 +0000 (UTC) (envelope-from lab@gta.com) Received: from gta.com (gta-edge-199-20.gta.com [199.120.225.20]) by mx1.FreeBSD.org (Postfix) with SMTP id C8CF443D53 for ; Thu, 14 Sep 2006 13:30:35 +0000 (GMT) (envelope-from lab@gta.com) Received: (qmail 85724 invoked by uid 1000); 14 Sep 2006 13:30:34 -0000 Date: Thu, 14 Sep 2006 09:30:34 -0400 From: Larry Baird To: freebsd-net@freebsd.org Message-ID: <20060914093034.A83805@gta.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="NzB8fVQJ5HfG6fxh" Content-Disposition: inline User-Agent: Mutt/1.2.5i Subject: FAST_IPSEC NAT-T support X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 13:30:39 -0000 --NzB8fVQJ5HfG6fxh Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Please find attached two patches for adding FAST_IPSEC NAT-T support to FreeBSD 6.x. The patch "freebsd6-fastipsec-natt.diff" is dependent upon Yvan's IPSEC NAT-T patch "freebsd6-natt.diff" which can be found at http://ipsec-tools.cvs.sourceforge.net/ipsec-tools/htdocs/. The second patch "freebsd6-ipsec-fastipsec-natt.diff" is a cumulative patch combining both patches together. -- ------------------------------------------------------------------------ Larry Baird | http://www.gta.com Global Technology Associates, Inc. | Orlando, FL Email: lab@gta.com | TEL 407-380-0220, FAX 407-380-6080 --NzB8fVQJ5HfG6fxh Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="freebsd6-fastipsec-natt.diff" Index: netinet/udp_usrreq.c =================================================================== --- netinet/udp_usrreq.c (.../6.x-IPSEC-NATT) (revision 8180) +++ netinet/udp_usrreq.c (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -1170,7 +1170,7 @@ m_tag_prepend(n, tag); #ifdef FAST_IPSEC - ipsec4_common_input(n, iphdrlen); + ipsec4_common_input(n, iphdrlen, ip->ip_p); #else /* IPSEC */ esp4_input(n, iphdrlen); #endif Index: netipsec/ipsec.c =================================================================== --- netipsec/ipsec.c (.../6.x-IPSEC-NATT) (revision 8180) +++ netipsec/ipsec.c (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -1808,15 +1808,15 @@ /* Return a printable string for the IPv4 address. */ static char * -inet_ntoa4(struct in_addr ina) +inet_ntoa4(const struct sockaddr_in *sin) { - static char buf[4][4 * sizeof "123" + 4]; - unsigned char *ucp = (unsigned char *) &ina; + static char buf[4][4 * sizeof "123" + 4 + 10]; + const unsigned char *ucp = (const unsigned char *)&sin->sin_addr; static int i = 3; i = (i + 1) % 4; - sprintf(buf[i], "%d.%d.%d.%d", ucp[0] & 0xff, ucp[1] & 0xff, - ucp[2] & 0xff, ucp[3] & 0xff); + sprintf(buf[i], "%d.%d.%d.%d[%u]", ucp[0] & 0xff, ucp[1] & 0xff, + ucp[2] & 0xff, ucp[3] & 0xff, ntohs(sin->sin_port)); return (buf[i]); } @@ -1827,7 +1827,7 @@ switch (sa->sa.sa_family) { #if INET case AF_INET: - return inet_ntoa4(sa->sin.sin_addr); + return inet_ntoa4(&sa->sin); #endif /* INET */ #if INET6 Index: netipsec/keydb.h =================================================================== --- netipsec/keydb.h (.../6.x-IPSEC-NATT) (revision 8180) +++ netipsec/keydb.h (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -117,6 +117,12 @@ struct secashead *sah; /* back pointer to the secashead */ /* + * NAT-Traversal + */ + u_int16_t natt_type; + u_int16_t esp_frag; + + /* * NB: Fields with a tdb_ prefix are part of the "glue" used * to interface to the OpenBSD crypto support. This was done * to distinguish this code from the mainline KAME code. Index: netipsec/ipsec_input.c =================================================================== --- netipsec/ipsec_input.c (.../6.x-IPSEC-NATT) (revision 8180) +++ netipsec/ipsec_input.c (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -110,6 +110,9 @@ struct secasvar *sav; u_int32_t spi; int error; +#ifdef IPSEC_NAT_T + struct m_tag *tag; +#endif IPSEC_ISTAT(sproto, espstat.esps_input, ahstat.ahs_input, ipcompstat.ipcomps_input); @@ -160,6 +163,13 @@ m_copydata(m, offsetof(struct ip, ip_dst), sizeof(struct in_addr), (caddr_t) &dst_address.sin.sin_addr); +#ifdef IPSEC_NAT_T + /* find the source port for NAT_T */ + if ((tag = m_tag_find(m, PACKET_TAG_IPSEC_NAT_T_PORTS, NULL)) + != NULL) { + dst_address.sin.sin_port = ((u_int16_t *)(tag + 1))[1]; + } +#endif /* IPSEC_NAT_T */ break; #endif /* INET */ #ifdef INET6 @@ -179,7 +189,7 @@ } /* NB: only pass dst since key_allocsa follows RFC2401 */ - sav = KEY_ALLOCSA(&dst_address, sproto, spi); + sav = KEY_ALLOCSA( &dst_address, sproto, spi); if (sav == NULL) { DPRINTF(("%s: no key association found for SA %s/%08lx/%u\n", __func__, ipsec_address(&dst_address), Index: netipsec/ipsec_output.c =================================================================== --- netipsec/ipsec_output.c (.../6.x-IPSEC-NATT) (revision 8180) +++ netipsec/ipsec_output.c (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -81,6 +81,10 @@ #include +#ifdef IPSEC_NAT_T +#include +#endif + int ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr) { @@ -173,6 +177,51 @@ ip->ip_len = ntohs(ip->ip_len); ip->ip_off = ntohs(ip->ip_off); +#ifdef IPSEC_NAT_T + /* + * If NAT-T is enabled, now that all IPSEC processing is done + * insert UDP encapsulation header after IP header. + */ + if (sav->natt_type != 0) { + int size = sizeof(struct udphdr); +#ifdef _IP_VHL + int hlen = IP_VHL_HL(ip->ip_vhl); +#else + int hlen = (ip->ip_hl << 2); +#endif + int off; + struct mbuf *mi; + struct udphdr *udp; + + if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE) + size += sizeof(u_int64_t); + + if ( (mi = m_makespace(m, hlen, size, &off)) == NULL ) { + error = ENOBUFS; + goto bad; + } + + udp = (struct udphdr *)(mtod(mi, caddr_t) + off); + + if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE) + udp->uh_sport = htons(UDP_ENCAP_ESPINUDP_PORT); + else + udp->uh_sport = + KEY_PORTFROMSADDR(&sav->sah->saidx.src); + + udp->uh_dport = KEY_PORTFROMSADDR(&sav->sah->saidx.dst); + udp->uh_sum = 0; + udp->uh_ulen = htons(m->m_pkthdr.len - hlen); + ip->ip_len = m->m_pkthdr.len; + ip->ip_p = IPPROTO_UDP; + + if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE) { + u_int64_t *marker = (u_int64_t *)(udp + 1); + *marker = 0; + } + } +#endif /* IPSEC_NAT_T */ + return ip_output(m, NULL, NULL, IP_RAWOUTPUT, NULL, NULL); #endif /* INET */ #ifdef INET6 Index: netipsec/key.c =================================================================== --- netipsec/key.c (.../6.x-IPSEC-NATT) (revision 8180) +++ netipsec/key.c (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -210,6 +210,11 @@ 0, /* SADB_X_EXT_KMPRIVATE */ sizeof(struct sadb_x_policy), /* SADB_X_EXT_POLICY */ sizeof(struct sadb_x_sa2), /* SADB_X_SA2 */ + sizeof(struct sadb_x_nat_t_type), /* SADB_X_EXT_NAT_T_TYPE */ + sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_SPORT */ + sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_DPORT */ + sizeof(struct sadb_address), /* SADB_X_EXT_NAT_T_OA */ + sizeof(struct sadb_x_nat_t_frag),/* SADB_X_EXT_NAT_T_FRAG */ }; static const int maxsize[] = { sizeof(struct sadb_msg), /* SADB_EXT_RESERVED */ @@ -232,6 +237,11 @@ 0, /* SADB_X_EXT_KMPRIVATE */ 0, /* SADB_X_EXT_POLICY */ sizeof(struct sadb_x_sa2), /* SADB_X_SA2 */ + sizeof(struct sadb_x_nat_t_type), /* SADB_X_EXT_NAT_T_TYPE */ + sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_SPORT */ + sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_DPORT */ + 0, /* SADB_X_EXT_NAT_T_OA */ + sizeof(struct sadb_x_nat_t_frag), /* SADB_X_EXT_NAT_T_FRAG */ }; static int ipsec_esp_keymin = 256; @@ -393,6 +403,10 @@ const struct sadb_msghdr *)); static int key_spddump __P((struct socket *, struct mbuf *, const struct sadb_msghdr *)); +#ifdef IPSEC_NAT_T +static int key_nat_map(struct socket *, struct mbuf *, + const struct sadb_msghdr *); +#endif static struct mbuf *key_setdumpsp __P((struct secpolicy *, u_int8_t, u_int32_t, u_int32_t)); static u_int key_getspreqmsglen __P((struct secpolicy *)); @@ -418,6 +432,13 @@ static struct mbuf *key_setsadbsa __P((struct secasvar *)); static struct mbuf *key_setsadbaddr __P((u_int16_t, const struct sockaddr *, u_int8_t, u_int16_t)); +#ifdef IPSEC_NAT_T +static struct mbuf *key_setsadbxport __P((u_int16_t, u_int16_t)); +static struct mbuf *key_setsadbxtype __P((u_int16_t)); +#endif +static void key_porttosaddr __P((struct sockaddr *, u_int16_t)); +#define KEY_PORTTOSADDR(saddr, port) \ + key_porttosaddr((struct sockaddr *)(saddr), (port)) static struct mbuf *key_setsadbxsa2 __P((u_int8_t, u_int32_t, u_int32_t)); static struct mbuf *key_setsadbxpolicy __P((u_int16_t, u_int8_t, u_int32_t)); @@ -1042,12 +1063,20 @@ struct secasvar *sav; u_int stateidx, arraysize, state; const u_int *saorder_state_valid; + int chkport = 0; IPSEC_ASSERT(dst != NULL, ("null dst address")); KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP %s from %s:%u\n", __func__, where, tag)); +#ifdef IPSEC_NAT_T + if (dst->sa.sa_family == AF_INET && + dst->sa.sa_len == sizeof(struct sockaddr_in) && + dst->sin.sin_port != 0) + chkport = 1; +#endif + /* * searching SAD. * XXX: to be checked internal IP header somewhere. Also when @@ -1079,11 +1108,11 @@ continue; #if 0 /* don't check src */ /* check src address */ - if (key_sockaddrcmp(&src->sa, &sav->sah->saidx.src.sa, 0) != 0) + if (key_sockaddrcmp(&src->sa, &sav->sah->saidx.src.sa, chkport) != 0) continue; #endif /* check dst address */ - if (key_sockaddrcmp(&dst->sa, &sav->sah->saidx.dst.sa, 0) != 0) + if (key_sockaddrcmp(&dst->sa, &sav->sah->saidx.dst.sa, chkport) != 0) continue; sa_addref(sav); goto done; @@ -1847,6 +1876,52 @@ return key_senderror(so, m, error); } +#ifndef IPSEC_NAT_T + for (isr = newsp->req; isr; isr = isr->next) { + struct sockaddr *sa; + + /* + * port spec is not permitted for tunnel mode + */ + if (isr->saidx.mode == IPSEC_MODE_TUNNEL && src0 && dst0) { + sa = (struct sockaddr *)(src0 + 1); + switch (sa->sa_family) { + case AF_INET: + if (((struct sockaddr_in *)sa)->sin_port) { + keydb_delsecpolicy(newsp); + return key_senderror(so, m, EINVAL); + } + break; + case AF_INET6: + if (((struct sockaddr_in6 *)sa)->sin6_port) { + keydb_delsecpolicy(newsp); + return key_senderror(so, m, EINVAL); + } + break; + default: + break; + } + sa = (struct sockaddr *)(dst0 + 1); + switch (sa->sa_family) { + case AF_INET: + if (((struct sockaddr_in *)sa)->sin_port) { + keydb_delsecpolicy(newsp); + return key_senderror(so, m, EINVAL); + } + break; + case AF_INET6: + if (((struct sockaddr_in6 *)sa)->sin6_port) { + keydb_delsecpolicy(newsp); + return key_senderror(so, m, EINVAL); + } + break; + default: + break; + } + } + } +#endif /* !IPSEC_NAT_T */ + if ((newsp->id = key_getnewspid()) == 0) { _key_delsp(newsp); return key_senderror(so, m, ENOBUFS); @@ -2355,6 +2430,71 @@ return key_sendup_mbuf(so, m, KEY_SENDUP_ALL); } +#ifdef IPSEC_NAT_T +/* + * SADB_X_NAT_T_NEW_MAPPING + */ +static int +key_nat_map(so, m, mhp) + struct socket *so; + struct mbuf *m; + const struct sadb_msghdr *mhp; +{ + struct sadb_x_nat_t_type *type; + struct sadb_x_nat_t_port *sport; + struct sadb_x_nat_t_port *dport; + struct sadb_address *addr; + struct sadb_x_nat_t_frag *frag; + + /* sanity check */ + if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) + panic("key_nat_map: NULL pointer is passed."); + + if (mhp->ext[SADB_X_EXT_NAT_T_TYPE] == NULL || + mhp->ext[SADB_X_EXT_NAT_T_SPORT] == NULL || + mhp->ext[SADB_X_EXT_NAT_T_DPORT] == NULL) { + ipseclog((LOG_DEBUG, "key_nat_map: invalid message.\n")); + return key_senderror(so, m, EINVAL); + } + if ((mhp->extlen[SADB_X_EXT_NAT_T_TYPE] < sizeof(*type)) || + (mhp->extlen[SADB_X_EXT_NAT_T_SPORT] < sizeof(*sport)) || + (mhp->extlen[SADB_X_EXT_NAT_T_DPORT] < sizeof(*dport))) { + ipseclog((LOG_DEBUG, "key_nat_map: invalid message.\n")); + return key_senderror(so, m, EINVAL); + } + + if ((mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) && + (mhp->extlen[SADB_X_EXT_NAT_T_OA] < sizeof(*addr))) { + ipseclog((LOG_DEBUG, "key_nat_map: invalid message\n")); + return key_senderror(so, m, EINVAL); + } + + if ((mhp->ext[SADB_X_EXT_NAT_T_FRAG] != NULL) && + (mhp->extlen[SADB_X_EXT_NAT_T_FRAG] < sizeof(*frag))) { + ipseclog((LOG_DEBUG, "key_nat_map: invalid message\n")); + return key_senderror(so, m, EINVAL); + } + + type = (struct sadb_x_nat_t_type *)mhp->ext[SADB_X_EXT_NAT_T_TYPE]; + sport = (struct sadb_x_nat_t_port *)mhp->ext[SADB_X_EXT_NAT_T_SPORT]; + dport = (struct sadb_x_nat_t_port *)mhp->ext[SADB_X_EXT_NAT_T_DPORT]; + addr = (struct sadb_address *)mhp->ext[SADB_X_EXT_NAT_T_OA]; + frag = (struct sadb_x_nat_t_frag *) mhp->ext[SADB_X_EXT_NAT_T_FRAG]; + + printf("sadb_nat_map: type %d, sport = %d, dport = %d\n", + type->sadb_x_nat_t_type_type, + sport->sadb_x_nat_t_port_port, + dport->sadb_x_nat_t_port_port); + + /* + * XXX handle that, it should also contain a SA, or anything + * that enable to update the SA information. + */ + + return 0; +} +#endif /* IPSEC_NAT_T */ + /* * SADB_SPDDUMP processing * receive @@ -2984,6 +3124,10 @@ sav->lft_c = NULL; sav->lft_h = NULL; sav->lft_s = NULL; +#ifdef IPSEC_NAT_T + sav->natt_type = 0; + sav->esp_frag = 0; +#endif sav->tdb_xform = NULL; /* transform */ sav->tdb_encalgxform = NULL; /* encoding algorithm */ sav->tdb_authalgxform = NULL; /* authentication algorithm */ @@ -3294,6 +3438,11 @@ SADB_EXT_ADDRESS_DST, SADB_EXT_ADDRESS_PROXY, SADB_EXT_KEY_AUTH, SADB_EXT_KEY_ENCRYPT, SADB_EXT_IDENTITY_SRC, SADB_EXT_IDENTITY_DST, SADB_EXT_SENSITIVITY, +#ifdef IPSEC_NAT_T + SADB_X_EXT_NAT_T_TYPE, SADB_X_EXT_NAT_T_SPORT, + SADB_X_EXT_NAT_T_DPORT, SADB_X_EXT_NAT_T_OA, + SADB_X_EXT_NAT_T_FRAG, +#endif }; m = key_setsadbmsg(type, 0, satype, seq, pid, sav->refcnt); @@ -3370,6 +3519,31 @@ p = sav->lft_s; break; +#ifdef IPSEC_NAT_T + case SADB_X_EXT_NAT_T_TYPE: + if ((m = key_setsadbxtype(sav->natt_type)) == NULL) + goto fail; + break; + + case SADB_X_EXT_NAT_T_DPORT: + if ((m = key_setsadbxport(KEY_PORTFROMSADDR + (&sav->sah->saidx.dst), + SADB_X_EXT_NAT_T_DPORT)) == NULL) + goto fail; + break; + + case SADB_X_EXT_NAT_T_SPORT: + if ((m = key_setsadbxport(KEY_PORTFROMSADDR + (&sav->sah->saidx.src), + SADB_X_EXT_NAT_T_SPORT)) == NULL) + goto fail; + break; + + case SADB_X_EXT_NAT_T_OA: + case SADB_X_EXT_NAT_T_FRAG: + continue; +#endif + case SADB_EXT_ADDRESS_PROXY: case SADB_EXT_IDENTITY_SRC: case SADB_EXT_IDENTITY_DST: @@ -3588,7 +3762,134 @@ return m; } +#ifdef IPSEC_NAT_T /* + * set a type in sadb_x_nat_t_type + */ +static struct mbuf * +key_setsadbxtype(type) + u_int16_t type; +{ + struct mbuf *m; + size_t len; + struct sadb_x_nat_t_type *p; + + len = PFKEY_ALIGN8(sizeof(struct sadb_x_nat_t_type)); + + m = key_alloc_mbuf(len); + if (!m || m->m_next) { /*XXX*/ + if (m) + m_freem(m); + return NULL; + } + + p = mtod(m, struct sadb_x_nat_t_type *); + + bzero(p, len); + p->sadb_x_nat_t_type_len = PFKEY_UNIT64(len); + p->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE; + p->sadb_x_nat_t_type_type = type; + + return m; +} +/* + * set a port in sadb_x_nat_t_port. port is in network order + */ +static struct mbuf * +key_setsadbxport(port, type) + u_int16_t port; + u_int16_t type; +{ + struct mbuf *m; + size_t len; + struct sadb_x_nat_t_port *p; + + len = PFKEY_ALIGN8(sizeof(struct sadb_x_nat_t_port)); + + m = key_alloc_mbuf(len); + if (!m || m->m_next) { /*XXX*/ + if (m) + m_freem(m); + return NULL; + } + + p = mtod(m, struct sadb_x_nat_t_port *); + + bzero(p, len); + p->sadb_x_nat_t_port_len = PFKEY_UNIT64(len); + p->sadb_x_nat_t_port_exttype = type; + p->sadb_x_nat_t_port_port = port; + + return m; +} + +/* + * Get port from sockaddr, port is in network order + */ +u_int16_t +key_portfromsaddr(saddr) + struct sockaddr *saddr; +{ + u_int16_t port; + + switch (saddr->sa_family) { + case AF_INET: { + struct sockaddr_in *sin = (struct sockaddr_in *)saddr; + + port = sin->sin_port; + break; + } +#ifdef INET6 + case AF_INET6: { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)saddr; + + port = sin6->sin6_port; + break; + } +#endif + default: + printf("key_portfromsaddr: unexpected address family\n"); + port = 0; + break; + } + + return port; +} +#endif /* IPSEC_NAT_T */ + +/* + * Set port is struct sockaddr. port is in network order + */ +static void +key_porttosaddr(saddr, port) + struct sockaddr *saddr; + u_int16_t port; +{ + switch (saddr->sa_family) { + case AF_INET: { + struct sockaddr_in *sin = (struct sockaddr_in *)saddr; + + sin->sin_port = port; + break; + } +#ifdef INET6 + case AF_INET6: { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)saddr; + + sin6->sin6_port = port; + break; + } +#endif + default: + printf("key_porttosaddr: unexpected address family %d\n", + saddr->sa_family); + break; + } + + return; +} + +/* * set data into sadb_x_policy */ static struct mbuf * @@ -3738,6 +4039,8 @@ const struct secasindex *saidx1, int flag) { + int chkport = 0; + /* sanity */ if (saidx0 == NULL && saidx1 == NULL) return 1; @@ -3761,13 +4064,30 @@ /* CMP_MODE_REQID, CMP_REQID, CMP_HEAD */ if (flag == CMP_MODE_REQID ||flag == CMP_REQID) { +#ifdef IPSEC_NAT_T /* + * If NAT-T is enabled, check ports for tunnel mode. + * Don't do it for transport mode, as there is no + * port information available in the SP. + * XXX also don't check ports if they are set to zero in the SPD: + * This means we bave a non-generated SPD, which can't know UDP ports. + */ + if (saidx1->mode == IPSEC_MODE_TUNNEL && + ((const struct sockaddr_in *)(&saidx1->src))->sin_port && + ((const struct sockaddr_in *)(&saidx1->dst))->sin_port ) + chkport = 1; +#endif /* IPSEC_NAT_T */ + /* * If reqid of SPD is non-zero, unique SA is required. * The result must be of same reqid in this case. */ if (saidx1->reqid != 0 && saidx0->reqid != saidx1->reqid) return 0; } +#ifdef IPSEC_NAT_T + else + chkport = 1; +#endif if (flag == CMP_MODE_REQID) { if (saidx0->mode != IPSEC_MODE_ANY @@ -3775,10 +4095,10 @@ return 0; } - if (key_sockaddrcmp(&saidx0->src.sa, &saidx1->src.sa, 0) != 0) { + if (key_sockaddrcmp(&saidx0->src.sa, &saidx1->src.sa, chkport) != 0) { return 0; } - if (key_sockaddrcmp(&saidx0->dst.sa, &saidx1->dst.sa, 0) != 0) { + if (key_sockaddrcmp(&saidx0->dst.sa, &saidx1->dst.sa, chkport) != 0) { return 0; } } @@ -4398,13 +4718,17 @@ if (((struct sockaddr *)(src0 + 1))->sa_len != sizeof(struct sockaddr_in)) return key_senderror(so, m, EINVAL); +#ifndef IPSEC_NAT_T ((struct sockaddr_in *)(src0 + 1))->sin_port = 0; +#endif break; case AF_INET6: if (((struct sockaddr *)(src0 + 1))->sa_len != sizeof(struct sockaddr_in6)) return key_senderror(so, m, EINVAL); +#ifndef IPSEC_NAT_T ((struct sockaddr_in6 *)(src0 + 1))->sin6_port = 0; +#endif break; default: ; /*???*/ @@ -4414,13 +4738,17 @@ if (((struct sockaddr *)(dst0 + 1))->sa_len != sizeof(struct sockaddr_in)) return key_senderror(so, m, EINVAL); +#ifndef IPSEC_NAT_T ((struct sockaddr_in *)(dst0 + 1))->sin_port = 0; +#endif break; case AF_INET6: if (((struct sockaddr *)(dst0 + 1))->sa_len != sizeof(struct sockaddr_in6)) return key_senderror(so, m, EINVAL); +#ifndef IPSEC_NAT_T ((struct sockaddr_in6 *)(dst0 + 1))->sin6_port = 0; +#endif break; default: ; /*???*/ @@ -4429,6 +4757,12 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); + /* If not using NAT-T, make sure port numbers are set to zero. */ +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + /* SPI allocation */ spi = key_do_getnewspi((struct sadb_spirange *)mhp->ext[SADB_EXT_SPIRANGE], &saidx); @@ -4684,6 +5018,12 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); + /* If not using NAT-T, make sure if port number is zero. */ +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + /* get a SA header */ if ((sah = key_getsah(&saidx)) == NULL) { ipseclog((LOG_DEBUG, "%s: no SA index found.\n", __func__)); @@ -4750,6 +5090,68 @@ return key_senderror(so, m, 0); } +#ifdef IPSEC_NAT_T + /* + * Handle NAT-T info if present + */ + if (mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) + printf("update: NAT-T OA present\n"); + + if ((mhp->ext[SADB_X_EXT_NAT_T_TYPE] != NULL) && + (mhp->ext[SADB_X_EXT_NAT_T_SPORT] != NULL) && + (mhp->ext[SADB_X_EXT_NAT_T_DPORT] != NULL)) { + struct sadb_x_nat_t_type *type; + struct sadb_x_nat_t_port *sport; + struct sadb_x_nat_t_port *dport; + struct sadb_address *addr; + struct sadb_x_nat_t_frag *frag; + + if ((mhp->extlen[SADB_X_EXT_NAT_T_TYPE] < sizeof(*type)) || + (mhp->extlen[SADB_X_EXT_NAT_T_SPORT] < sizeof(*sport)) || + (mhp->extlen[SADB_X_EXT_NAT_T_DPORT] < sizeof(*dport))) { + ipseclog((LOG_DEBUG, "key_update: " + "invalid message.\n")); + return key_senderror(so, m, EINVAL); + } + + if ((mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) && + (mhp->extlen[SADB_X_EXT_NAT_T_OA] < sizeof(*addr))) { + ipseclog((LOG_DEBUG, "key_update: invalid message\n")); + return key_senderror(so, m, EINVAL); + } + + if ((mhp->ext[SADB_X_EXT_NAT_T_FRAG] != NULL) && + (mhp->extlen[SADB_X_EXT_NAT_T_FRAG] < sizeof(*frag))) { + ipseclog((LOG_DEBUG, "key_update: invalid message\n")); + return key_senderror(so, m, EINVAL); + } + + type = (struct sadb_x_nat_t_type *) + mhp->ext[SADB_X_EXT_NAT_T_TYPE]; + sport = (struct sadb_x_nat_t_port *) + mhp->ext[SADB_X_EXT_NAT_T_SPORT]; + dport = (struct sadb_x_nat_t_port *) + mhp->ext[SADB_X_EXT_NAT_T_DPORT]; + addr = (struct sadb_address *) + mhp->ext[SADB_X_EXT_NAT_T_OA]; + frag = (struct sadb_x_nat_t_frag *) + mhp->ext[SADB_X_EXT_NAT_T_FRAG]; + + if (type) + sav->natt_type = type->sadb_x_nat_t_type_type; + if (sport) + KEY_PORTTOSADDR(&sav->sah->saidx.src, + sport->sadb_x_nat_t_port_port); + if (dport) + KEY_PORTTOSADDR(&sav->sah->saidx.dst, + dport->sadb_x_nat_t_port_port); + if (frag) + sav->esp_frag = frag->sadb_x_nat_t_frag_fraglen; + else + sav->esp_frag = IP_MAXPACKET; + } +#endif /* IPSEC_NAT_T */ + { struct mbuf *n; @@ -4882,6 +5284,11 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + /* get a SA header */ if ((newsah = key_getsah(&saidx)) == NULL) { /* create a new SA header */ @@ -4918,7 +5325,69 @@ return key_senderror(so, m, error); } +#ifdef IPSEC_NAT_T /* + * Handle NAT-T info if present + */ + if (mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) + printf("add: NAT-T OA present\n"); + + if ((mhp->ext[SADB_X_EXT_NAT_T_TYPE] != NULL) && + (mhp->ext[SADB_X_EXT_NAT_T_SPORT] != NULL) && + (mhp->ext[SADB_X_EXT_NAT_T_DPORT] != NULL)) { + struct sadb_x_nat_t_type *type; + struct sadb_x_nat_t_port *sport; + struct sadb_x_nat_t_port *dport; + struct sadb_address *addr; + struct sadb_x_nat_t_frag *frag; + + if ((mhp->extlen[SADB_X_EXT_NAT_T_TYPE] < sizeof(*type)) || + (mhp->extlen[SADB_X_EXT_NAT_T_SPORT] < sizeof(*sport)) || + (mhp->extlen[SADB_X_EXT_NAT_T_DPORT] < sizeof(*dport))) { + ipseclog((LOG_DEBUG, "key_add: " + "invalid message.\n")); + return key_senderror(so, m, EINVAL); + } + + if ((mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) && + (mhp->extlen[SADB_X_EXT_NAT_T_OA] < sizeof(*addr))) { + ipseclog((LOG_DEBUG, "key_add: invalid message\n")); + return key_senderror(so, m, EINVAL); + } + + if ((mhp->ext[SADB_X_EXT_NAT_T_FRAG] != NULL) && + (mhp->extlen[SADB_X_EXT_NAT_T_FRAG] < sizeof(*frag))) { + ipseclog((LOG_DEBUG, "key_update: invalid message\n")); + return key_senderror(so, m, EINVAL); + } + + type = (struct sadb_x_nat_t_type *) + mhp->ext[SADB_X_EXT_NAT_T_TYPE]; + sport = (struct sadb_x_nat_t_port *) + mhp->ext[SADB_X_EXT_NAT_T_SPORT]; + dport = (struct sadb_x_nat_t_port *) + mhp->ext[SADB_X_EXT_NAT_T_DPORT]; + addr = (struct sadb_address *) + mhp->ext[SADB_X_EXT_NAT_T_OA]; + frag = (struct sadb_x_nat_t_frag *) + mhp->ext[SADB_X_EXT_NAT_T_FRAG]; + + if (type) + newsav->natt_type = type->sadb_x_nat_t_type_type; + if (sport) + KEY_PORTTOSADDR(&newsav->sah->saidx.src, + sport->sadb_x_nat_t_port_port); + if (dport) + KEY_PORTTOSADDR(&newsav->sah->saidx.dst, + dport->sadb_x_nat_t_port_port); + if (frag) + newsav->esp_frag = frag->sadb_x_nat_t_frag_fraglen; + else + newsav->esp_frag = IP_MAXPACKET; + } +#endif + + /* * don't call key_freesav() here, as we would like to keep the SA * in the database on success. */ @@ -5118,6 +5587,11 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + /* get a SA header */ SAHTREE_LOCK(); LIST_FOREACH(sah, &sahtree, chain) { @@ -5187,6 +5661,11 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + SAHTREE_LOCK(); LIST_FOREACH(sah, &sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) @@ -5301,6 +5780,11 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + /* get a SA header */ SAHTREE_LOCK(); LIST_FOREACH(sah, &sahtree, chain) { @@ -5988,6 +6472,11 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + /* get a SA index */ SAHTREE_LOCK(); LIST_FOREACH(sah, &sahtree, chain) { @@ -6596,6 +7085,11 @@ key_spdadd, /* SADB_X_SPDSETIDX */ NULL, /* SADB_X_SPDEXPIRE */ key_spddelete2, /* SADB_X_SPDDELETE2 */ +#ifdef IPSEC_NAT_T + key_nat_map, /* SADB_X_NAT_T_NEW_MAPPING */ +#else + NULL, +#endif }; /* @@ -6932,6 +7426,13 @@ case SADB_EXT_SPIRANGE: case SADB_X_EXT_POLICY: case SADB_X_EXT_SA2: +#ifdef IPSEC_NAT_T + case SADB_X_EXT_NAT_T_TYPE: + case SADB_X_EXT_NAT_T_SPORT: + case SADB_X_EXT_NAT_T_DPORT: + case SADB_X_EXT_NAT_T_OA: + case SADB_X_EXT_NAT_T_FRAG: +#endif /* duplicate check */ /* * XXX Are there duplication payloads of either Index: netipsec/key.h =================================================================== --- netipsec/key.h (.../6.x-IPSEC-NATT) (revision 8180) +++ netipsec/key.h (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -99,6 +99,10 @@ extern void key_sa_recordxfer __P((struct secasvar *, struct mbuf *)); extern void key_sa_routechange __P((struct sockaddr *)); extern void key_sa_stir_iv __P((struct secasvar *)); +#ifdef IPSEC_NAT_T +u_int16_t key_portfromsaddr __P((struct sockaddr *)); +#define KEY_PORTFROMSADDR(saddr) key_portfromsaddr((struct sockaddr *)(saddr)) +#endif #ifdef MALLOC_DECLARE MALLOC_DECLARE(M_IPSEC_SA); --NzB8fVQJ5HfG6fxh Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="freebsd6-ipsec-fastipsec-natt.diff" Index: conf/options =================================================================== --- conf/options (.../6.x) (revision 8180) +++ conf/options (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -352,6 +352,7 @@ INET6 opt_inet6.h IPSEC opt_ipsec.h IPSEC_ESP opt_ipsec.h +IPSEC_NAT_T opt_ipsec.h IPSEC_DEBUG opt_ipsec.h IPSEC_FILTERGIF opt_ipsec.h FAST_IPSEC opt_ipsec.h Index: netinet/udp_var.h =================================================================== --- netinet/udp_var.h (.../6.x) (revision 8180) +++ netinet/udp_var.h (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -100,6 +100,7 @@ extern int log_in_vain; void udp_ctlinput(int, struct sockaddr *, void *); +int udp_ctloutput(struct socket *, struct sockopt *sopt); void udp_init(void); void udp_input(struct mbuf *, int); Index: netinet/udp.h =================================================================== --- netinet/udp.h (.../6.x) (revision 8180) +++ netinet/udp.h (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -44,4 +44,17 @@ u_short uh_sum; /* udp checksum */ }; +/* socket options for UDP */ +#define UDP_ENCAP 100 + +/* Encapsulation types */ +#define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */ +#define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-02+ */ + +/* Default encapsulation port */ +#define UDP_ENCAP_ESPINUDP_PORT 500 + +/* Maximum UDP fragment size for ESP over UDP */ +#define UDP_ENCAP_ESPINUDP_MAXFRAGLEN 552 + #endif Index: netinet/in_pcb.h =================================================================== --- netinet/in_pcb.h (.../6.x) (revision 8180) +++ netinet/in_pcb.h (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -298,6 +298,11 @@ #define IN6P_RFC2292 0x40000000 /* used RFC2292 API on the socket */ #define IN6P_MTU 0x80000000 /* receive path MTU */ +/* XXX should move to an UDP control block */ +#define INP_ESPINUDP 0x1000 /* ESP over UDP for NAT-T */ +#define INP_ESPINUDP_NON_IKE 0x2000 /* ESP over UDP for NAT-T */ +#define INP_ESPINUDP_ALL (INP_ESPINUDP|INP_ESPINUDP_NON_IKE) + #define INP_CONTROLOPTS (INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR|\ INP_RECVIF|INP_RECVTTL|\ IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_HOPOPTS|\ Index: netinet/ip_output.c =================================================================== --- netinet/ip_output.c (.../6.x) (revision 8180) +++ netinet/ip_output.c (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -58,6 +58,10 @@ #include #include +#ifdef IPSEC_NAT_T +#include +#endif + #include static MALLOC_DEFINE(M_IPMOPTS, "ip_moptions", "internet multicast options"); Index: netinet/in_proto.c =================================================================== --- netinet/in_proto.c (.../6.x) (revision 8180) +++ netinet/in_proto.c (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -122,7 +122,7 @@ .pr_flags = PR_ATOMIC|PR_ADDR, .pr_input = udp_input, .pr_ctlinput = udp_ctlinput, - .pr_ctloutput = ip_ctloutput, + .pr_ctloutput = udp_ctloutput, .pr_init = udp_init, .pr_usrreqs = &udp_usrreqs }, Index: netinet/udp_usrreq.c =================================================================== --- netinet/udp_usrreq.c (.../6.x) (revision 8180) +++ netinet/udp_usrreq.c (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -78,10 +78,12 @@ #ifdef FAST_IPSEC #include +#include #endif /*FAST_IPSEC*/ #ifdef IPSEC #include +#include #endif /*IPSEC*/ #include @@ -128,6 +130,11 @@ static int udp_detach(struct socket *so); static int udp_output(struct inpcb *, struct mbuf *, struct sockaddr *, struct mbuf *, struct thread *); +#ifdef INET +#ifdef IPSEC_NAT_T +static int udp4_espinudp (struct mbuf *, int, struct sockaddr *, struct socket *); +#endif +#endif static void udp_zone_change(void *tag) @@ -464,6 +471,41 @@ return; } #endif /*IPSEC || FAST_IPSEC*/ +#ifdef IPSEC_NAT_T + /* Handle ESP over UDP */ + if (last->inp_flags & INP_ESPINUDP_ALL) { + struct sockaddr_in src; + struct sockaddr *sa = (struct sockaddr *)(&src); + size_t minlen; + + bzero(&src, sizeof(src)); + src.sin_family = AF_INET; + src.sin_len = sizeof(struct sockaddr_in); + bcopy(&ip->ip_src, &src.sin_addr, sizeof(src.sin_addr)); + src.sin_port = udp_in->sin_port; + + /* + * Collapse the mbuf chain if the first mbuf is too short + * The longest case is: UDP + non ESP marker + ESP + */ + minlen = off + sizeof(struct udphdr) + sizeof(u_int64_t) + sizeof(struct esp); + if (minlen > n->m_pkthdr.len) + minlen = n->m_pkthdr.len; + + if ((n = m_pullup(n, minlen)) == NULL) { + printf("udp_append: m_pullup failed\n"); + m_freem(n); + return; + } + + if (udp4_espinudp(n, off, sa, last->inp_socket) != 0) { + m_freem(n); + return; + } + + /* Normal UDP processing will take place */ + } +#endif #ifdef MAC if (mac_check_inpcb_deliver(last, n) != 0) { m_freem(n); @@ -702,6 +744,82 @@ CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_PRISON, 0, 0, udp_getcred, "S,xucred", "Get the xucred of a UDP connection"); + +int +udp_ctloutput(so, sopt) + struct socket *so; + struct sockopt *sopt; +{ + int error, optval, s; + struct inpcb *inp; + int family; + + error = 0; + family = so->so_proto->pr_domain->dom_family; + + s = splnet(); + if (sopt->sopt_level != IPPROTO_UDP) { +#ifdef INET6 + if (INP_CHECK_SOCKAF(so, AF_INET6)) + error = ip6_ctloutput(so, sopt); + else +#endif /* INET6 */ + error = ip_ctloutput(so, sopt); + splx(s); + return (error); + } + inp = sotoinpcb(so); + + switch (sopt->sopt_dir) { + case SOPT_SET: + switch (sopt->sopt_name) { + case UDP_ENCAP: + error = sooptcopyin(sopt, &optval, sizeof optval, + sizeof optval); + if (error) + break; + + switch(optval){ +#ifdef IPSEC_NAT_T + case 0: + inp->inp_flags &= ~INP_ESPINUDP_ALL; + break; + + case UDP_ENCAP_ESPINUDP: + inp->inp_flags |= INP_ESPINUDP; + break; + + case UDP_ENCAP_ESPINUDP_NON_IKE: + inp->inp_flags |= INP_ESPINUDP_NON_IKE; + break; +#endif + + default: + error = EINVAL; + goto end; + break; + } + break; + + default: + error = ENOPROTOOPT; + goto end; + break; + } + break; + + default: + error = EINVAL; + goto end; + break; + } + +end: + splx(s); + return error; +} + + static int udp_output(inp, m, addr, control, td) register struct inpcb *inp; @@ -923,6 +1041,146 @@ return (error); } +#ifdef INET +#ifdef IPSEC_NAT_T +/* + * Returns: + * 1 if the packet was processed + * 0 if normal UDP processing should take place + */ +static int +udp4_espinudp(m, off, src, so) + struct mbuf *m; + int off; + struct sockaddr *src; + struct socket *so; +{ + size_t len; + caddr_t data; + struct inpcb *inp; + size_t skip = 0; + size_t minlen; + size_t iphdrlen; + struct m_tag *tag; + struct ip *ip; + struct udphdr *udphdr; + u_int16_t sport, dport; + struct mbuf *n; + + /* + * Cannot collapse the mbuf chain here, must have been done in + * calling function + * The longest case is: UDP + non ESP marker + ESP + */ + minlen = off + sizeof(u_int64_t) + sizeof(struct esp); + if (minlen > m->m_pkthdr.len) + minlen = m->m_pkthdr.len; + + if (m->m_len < minlen) + return 0; + + len = m->m_len - off; + data = mtod(m, caddr_t) + off; + inp = sotoinpcb(so); + + /* Ignore keepalive packets */ + if ((len == 1) && (data[0] == '\xff')) { + return 1; + } + + /* + * Check that the payload is long enough to hold + * an ESP header and compute the length of encapsulation + * header to remove + */ + if (inp->inp_flags & INP_ESPINUDP) { + u_int32_t *st = (u_int32_t *)data; + + if ((len <= sizeof(struct esp)) || (*st == 0)) + return 0; /* Normal UDP processing */ + + skip = sizeof(struct udphdr); + } + + if (inp->inp_flags & INP_ESPINUDP_NON_IKE) { + u_int64_t *st = (u_int64_t *)data; + + if ((len <= sizeof(u_int64_t) + sizeof(struct esp)) + || (*st != 0)) + return 0; /* Normal UDP processing */ + + skip = sizeof(struct udphdr) + sizeof(u_int64_t); + } + + /* + * Get the UDP ports. They are handled in network + * order everywhere in IPSEC_NAT_T code. + */ + udphdr = (struct udphdr *)(data - skip); + sport = udphdr->uh_sport; + dport = udphdr->uh_dport; + + /* + * Remove the UDP header (and possibly the non ESP marker) + * IP header lendth is iphdrlen + * Before: + * <--- off ---> + * +----+------+-----+ + * | IP | UDP | ESP | + * +----+------+-----+ + * <-skip-> + * After: + * +----+-----+ + * | IP | ESP | + * +----+-----+ + * <-skip-> + */ + iphdrlen = off - sizeof(struct udphdr); + ovbcopy(mtod(m, caddr_t), mtod(m, caddr_t) + skip, iphdrlen); + m_adj(m, skip); + + ip = mtod(m, struct ip *); + ip->ip_len = htons(ntohs(ip->ip_len) - skip); + ip->ip_p = IPPROTO_ESP; + + /* + * Copy the mbuf to avoid multiple free, as both + * esp4_input (which we call) and udp_input (which + * called us) free the mbuf. + */ + if ((n = m_dup(m, M_DONTWAIT)) == NULL) { + printf("udp4_espinudp: m_dup failed\n"); + return 0; + } + + /* + * Add a PACKET_TAG_IPSEC_NAT_T_PORT tag to remember + * the source UDP port. This is required if we want + * to select the right SPD for multiple hosts behind + * same NAT + */ + if ((tag = m_tag_get(PACKET_TAG_IPSEC_NAT_T_PORTS, + sizeof(sport) + sizeof(dport), M_DONTWAIT)) == NULL) { + printf("udp4_espinudp: m_tag_get failed\n"); + m_freem(n); + return 0; + } + ((u_int16_t *)(tag + 1))[0] = sport; + ((u_int16_t *)(tag + 1))[1] = dport; + m_tag_prepend(n, tag); + +#ifdef FAST_IPSEC + ipsec4_common_input(n, iphdrlen, ip->ip_p); +#else /* IPSEC */ + esp4_input(n, iphdrlen); +#endif + + /* We handled it, it shoudln't be handled by UDP */ + return 1; +} +#endif +#endif + u_long udp_sendspace = 9216; /* really max datagram size */ /* 40 1K datagrams */ SYSCTL_INT(_net_inet_udp, UDPCTL_MAXDGRAM, maxdgram, CTLFLAG_RW, Index: net/pfkeyv2.h =================================================================== --- net/pfkeyv2.h (.../6.x) (revision 8180) +++ net/pfkeyv2.h (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -75,7 +75,8 @@ #define SADB_X_SPDSETIDX 20 #define SADB_X_SPDEXPIRE 21 #define SADB_X_SPDDELETE2 22 /* by policy id */ -#define SADB_MAX 22 +#define SADB_X_NAT_T_NEW_MAPPING 23 +#define SADB_MAX 23 struct sadb_msg { u_int8_t sadb_msg_version; @@ -255,6 +256,34 @@ */ }; +/* NAT traversal type, see RFC 3948 */ +/* sizeof(struct sadb_x_nat_t_type) == 8 */ +struct sadb_x_nat_t_type { + u_int16_t sadb_x_nat_t_type_len; + u_int16_t sadb_x_nat_t_type_exttype; + u_int8_t sadb_x_nat_t_type_type; + u_int8_t sadb_x_nat_t_type_reserved[3]; +}; + +/* NAT traversal source or destination port */ +/* sizeof(struct sadb_x_nat_t_port) == 8 */ +struct sadb_x_nat_t_port { + u_int16_t sadb_x_nat_t_port_len; + u_int16_t sadb_x_nat_t_port_exttype; + u_int16_t sadb_x_nat_t_port_port; + u_int16_t sadb_x_nat_t_port_reserved; +}; + +/* ESP fragmentation size */ +/* sizeof(struct sadb_x_nat_t_frag) == 8 */ +struct sadb_x_nat_t_frag { + u_int16_t sadb_x_nat_t_frag_len; + u_int16_t sadb_x_nat_t_frag_exttype; + u_int16_t sadb_x_nat_t_frag_fraglen; + u_int16_t sadb_x_nat_t_frag_reserved; +}; + + #define SADB_EXT_RESERVED 0 #define SADB_EXT_SA 1 #define SADB_EXT_LIFETIME_CURRENT 2 @@ -275,7 +304,12 @@ #define SADB_X_EXT_KMPRIVATE 17 #define SADB_X_EXT_POLICY 18 #define SADB_X_EXT_SA2 19 -#define SADB_EXT_MAX 19 +#define SADB_X_EXT_NAT_T_TYPE 20 +#define SADB_X_EXT_NAT_T_SPORT 21 +#define SADB_X_EXT_NAT_T_DPORT 22 +#define SADB_X_EXT_NAT_T_OA 23 +#define SADB_X_EXT_NAT_T_FRAG 24 +#define SADB_EXT_MAX 24 #define SADB_SATYPE_UNSPEC 0 #define SADB_SATYPE_AH 2 Index: netinet6/ipcomp_input.c =================================================================== --- netinet6/ipcomp_input.c (.../6.x) (revision 8180) +++ netinet6/ipcomp_input.c (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -36,6 +36,7 @@ #include "opt_inet.h" #include "opt_inet6.h" +#include "opt_ipsec.h" #include #include @@ -100,6 +101,11 @@ int error; size_t newlen, olen; struct secasvar *sav = NULL; + u_int16_t sport = 0; + u_int16_t dport = 0; +#ifdef IPSEC_NAT_T + struct m_tag *tag = NULL; +#endif if (m->m_pkthdr.len < off + sizeof(struct ipcomp)) { ipseclog((LOG_DEBUG, "IPv4 IPComp input: assumption failed " @@ -108,6 +114,14 @@ goto fail; } +#ifdef IPSEC_NAT_T + /* find the source port for NAT-T */ + if ((tag = m_tag_find(m, PACKET_TAG_IPSEC_NAT_T_PORTS, NULL)) != NULL) { + sport = ((u_int16_t *)(tag + 1))[0]; + dport = ((u_int16_t *)(tag + 1))[1]; + } +#endif + md = m_pulldown(m, off, sizeof(*ipcomp), NULL); if (!md) { m = NULL; /* already freed */ @@ -129,7 +143,7 @@ if (cpi >= IPCOMP_CPI_NEGOTIATE_MIN) { sav = key_allocsa(AF_INET, (caddr_t)&ip->ip_src, - (caddr_t)&ip->ip_dst, IPPROTO_IPCOMP, htonl(cpi)); + (caddr_t)&ip->ip_dst, IPPROTO_IPCOMP, htonl(cpi), sport, dport); if (sav != NULL && (sav->state == SADB_SASTATE_MATURE || sav->state == SADB_SASTATE_DYING)) { @@ -273,7 +287,7 @@ if (cpi >= IPCOMP_CPI_NEGOTIATE_MIN) { sav = key_allocsa(AF_INET6, (caddr_t)&ip6->ip6_src, - (caddr_t)&ip6->ip6_dst, IPPROTO_IPCOMP, htonl(cpi)); + (caddr_t)&ip6->ip6_dst, IPPROTO_IPCOMP, htonl(cpi), 0, 0); if (sav != NULL && (sav->state == SADB_SASTATE_MATURE || sav->state == SADB_SASTATE_DYING)) { Index: netinet6/esp_output.c =================================================================== --- netinet6/esp_output.c (.../6.x) (revision 8180) +++ netinet6/esp_output.c (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -32,6 +32,7 @@ #include "opt_inet.h" #include "opt_inet6.h" +#include "opt_ipsec.h" /* * RFC1827/2406 Encapsulated Security Payload. @@ -56,6 +57,10 @@ #include #include +#ifdef IPSEC_NAT_T +#include +#endif + #ifdef INET6 #include #include @@ -139,6 +144,17 @@ hdrsiz = sizeof(struct newesp) + ivlen + 9 + authlen; } +#ifdef IPSEC_NAT_T + /* + * If NAT-T is enabled, add the space for UDP encapsulation + */ + if (sav->natt_type != 0) { + hdrsiz += sizeof(struct udphdr); + if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE) + hdrsiz += sizeof(u_int64_t); + } +#endif + return hdrsiz; estimate: @@ -149,8 +165,15 @@ * 9 = (maximum padding length without random padding length) * + (Pad Length field) + (Next Header field). * 16 = maximum ICV we support. + * sizeof(u_int64_t) = non IKE marker (NAT-T) + * sizeof(struct udphdr) = UDP encapsulation (NAT-T) */ +#ifdef IPSEC_NAT_T + return sizeof(struct newesp) + esp_max_ivlen() + 9 + 16 + + sizeof(u_int64_t) + sizeof(struct udphdr); +#else return sizeof(struct newesp) + esp_max_ivlen() + 9 + 16; +#endif } /* @@ -196,6 +219,9 @@ size_t extendsiz; int error = 0; struct ipsecstat *stat; +#ifdef IPSEC_NAT_T + struct udphdr *udp = NULL; +#endif switch (af) { #ifdef INET @@ -334,10 +360,25 @@ espoff = m->m_pkthdr.len - plen; +#ifdef IPSEC_NAT_T + if (sav->natt_type != 0) { + esphlen += sizeof(struct udphdr); + espoff += sizeof(struct udphdr); + + if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE) { + /* NON-IKE marker */ + esphlen += sizeof(u_int64_t); + espoff += sizeof(u_int64_t); + } + } +#endif + /* * grow the mbuf to accomodate ESP header. * before: IP ... payload - * after: IP ... ESP IV payload + * after (without NAT-T): IP ... ESP IV payload + * after (with older NAT-T): IP ... UDP non-IKE-marker ESP IV payload + * after (with newer NAT-T): IP ... UDP ESP IV payload */ if (M_LEADINGSPACE(md) < esphlen || (md->m_flags & M_EXT) != 0) { MGET(n, M_DONTWAIT, MT_DATA); @@ -358,6 +399,21 @@ esp = mtod(md, struct esp *); } +#ifdef IPSEC_NAT_T + if (sav->natt_type != 0) { + udp = (struct udphdr *)esp; + esp = (struct esp *)(udp + 1); + + if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE) { + u_int64_t *data = (u_int64_t *)esp; + + *data = 0; /* NON-IKE marker */ + esp = (struct esp *)(data + 1); + } + } +#endif + + nxt = *nexthdrp; *nexthdrp = IPPROTO_ESP; switch (af) { @@ -523,6 +579,27 @@ break; } +#ifdef IPSEC_NAT_T + if (sav->natt_type != 0) { + *nexthdrp = IPPROTO_UDP; + + /* + * Create the UDP encapsulation header for NAT-T + * uh_len is set later, when the size is known. + */ + if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE) + udp->uh_sport = htons(UDP_ENCAP_ESPINUDP_PORT); + else + udp->uh_sport = KEY_PORTFROMSADDR(&sav->sah->saidx.src); + + + udp->uh_dport = KEY_PORTFROMSADDR(&sav->sah->saidx.dst); + udp->uh_sum = 0; + } else { + *nexthdrp = IPPROTO_ESP; + } +#endif + /* initialize esp trailer. */ esptail = (struct esptail *) (mtod(n, u_int8_t *) + n->m_len - sizeof(struct esptail)); @@ -666,6 +743,18 @@ } } +#ifdef IPSEC_NAT_T + if (sav->natt_type != 0) { + struct ip *ip; + ip = mtod(m, struct ip *); +#ifdef _IP_VHL + udp->uh_ulen = htons(ntohs(ip->ip_len) - (IP_VHL_HL(ip->ip_vhl) << 2)); +#else + udp->uh_ulen = htons(ntohs(ip->ip_len) - (ip->ip_hl << 2)); +#endif + } +#endif + noantireplay: if (!m) { ipseclog((LOG_ERR, Index: netinet6/esp_input.c =================================================================== --- netinet6/esp_input.c (.../6.x) (revision 8180) +++ netinet6/esp_input.c (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -36,6 +36,7 @@ #include "opt_inet.h" #include "opt_inet6.h" +#include "opt_ipsec.h" #include #include @@ -116,6 +117,11 @@ int ivlen; size_t hlen; size_t esplen; + u_int16_t sport = 0; + u_int16_t dport = 0; +#ifdef IPSEC_NAT_T + struct m_tag *tag = NULL; +#endif /* sanity check for alignment. */ if (off % 4 != 0 || m->m_pkthdr.len % 4 != 0) { @@ -135,6 +141,14 @@ } } +#ifdef IPSEC_NAT_T + /* find the source port for NAT_T */ + if ((tag = m_tag_find(m, PACKET_TAG_IPSEC_NAT_T_PORTS, NULL)) != NULL) { + sport = ((u_int16_t *)(tag + 1))[0]; + dport = ((u_int16_t *)(tag + 1))[1]; + } +#endif + ip = mtod(m, struct ip *); esp = (struct esp *)(((u_int8_t *)ip) + off); #ifdef _IP_VHL @@ -148,7 +162,7 @@ if ((sav = key_allocsa(AF_INET, (caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst, - IPPROTO_ESP, spi)) == 0) { + IPPROTO_ESP, spi, sport, dport)) == 0) { ipseclog((LOG_WARNING, "IPv4 ESP input: no key association found for spi %u\n", (u_int32_t)ntohl(spi))); @@ -509,7 +523,7 @@ if ((sav = key_allocsa(AF_INET6, (caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst, - IPPROTO_ESP, spi)) == 0) { + IPPROTO_ESP, spi, 0, 0)) == 0) { ipseclog((LOG_WARNING, "IPv6 ESP input: no key association found for spi %u\n", (u_int32_t)ntohl(spi))); @@ -951,7 +965,7 @@ sav = key_allocsa(AF_INET6, (caddr_t)&sa6_src->sin6_addr, (caddr_t)&sa6_dst->sin6_addr, - IPPROTO_ESP, espp->esp_spi); + IPPROTO_ESP, espp->esp_spi, 0, 0); if (sav) { if (sav->state == SADB_SASTATE_MATURE || sav->state == SADB_SASTATE_DYING) Index: netinet6/ah_input.c =================================================================== --- netinet6/ah_input.c (.../6.x) (revision 8180) +++ netinet6/ah_input.c (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -36,6 +36,7 @@ #include "opt_inet.h" #include "opt_inet6.h" +#include "opt_ipsec.h" #include #include @@ -113,6 +114,11 @@ u_int16_t nxt; size_t hlen; size_t stripsiz = 0; + u_int16_t sport = 0; + u_int16_t dport = 0; +#ifdef IPSEC_NAT_T + struct m_tag *tag = NULL; +#endif #ifndef PULLDOWN_TEST if (m->m_len < off + sizeof(struct newah)) { @@ -125,6 +131,14 @@ } } +#ifdef IPSEC_NAT_T + /* find the source port for NAT-T */ + if ((tag = m_tag_find(m, PACKET_TAG_IPSEC_NAT_T_PORTS, NULL)) != NULL) { + sport = ((u_int16_t *)(tag + 1))[0]; + dport = ((u_int16_t *)(tag + 1))[1]; + } +#endif + ip = mtod(m, struct ip *); ah = (struct ah *)(((caddr_t)ip) + off); #else @@ -149,7 +163,7 @@ if ((sav = key_allocsa(AF_INET, (caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst, - IPPROTO_AH, spi)) == 0) { + IPPROTO_AH, spi, sport, dport)) == 0) { ipseclog((LOG_WARNING, "IPv4 AH input: no key association found for spi %u\n", (u_int32_t)ntohl(spi))); @@ -599,7 +613,7 @@ if ((sav = key_allocsa(AF_INET6, (caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst, - IPPROTO_AH, spi)) == 0) { + IPPROTO_AH, spi, 0, 0)) == 0) { ipseclog((LOG_WARNING, "IPv6 AH input: no key association found for spi %u\n", (u_int32_t)ntohl(spi))); @@ -998,7 +1012,7 @@ sav = key_allocsa(AF_INET6, (caddr_t)&sa6_src->sin6_addr, (caddr_t)&sa6_dst->sin6_addr, - IPPROTO_AH, ahp->ah_spi); + IPPROTO_AH, ahp->ah_spi, 0, 0); if (sav) { if (sav->state == SADB_SASTATE_MATURE || sav->state == SADB_SASTATE_DYING) Index: netkey/keydb.h =================================================================== --- netkey/keydb.h (.../6.x) (revision 8180) +++ netkey/keydb.h (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -114,6 +114,10 @@ pid_t pid; /* message's pid */ struct secashead *sah; /* back pointer to the secashead */ + /* NAT-Traversal + */ + u_int16_t natt_type; + u_int16_t esp_frag; u_int32_t id; /* SA id */ }; Index: netkey/key.c =================================================================== --- netkey/key.c (.../6.x) (revision 8180) +++ netkey/key.c (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -194,6 +194,11 @@ 0, /* SADB_X_EXT_KMPRIVATE */ sizeof(struct sadb_x_policy), /* SADB_X_EXT_POLICY */ sizeof(struct sadb_x_sa2), /* SADB_X_SA2 */ + sizeof(struct sadb_x_nat_t_type), /* SADB_X_EXT_NAT_T_TYPE */ + sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_SPORT */ + sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_DPORT */ + sizeof(struct sadb_address), /* SADB_X_EXT_NAT_T_OA */ + sizeof(struct sadb_x_nat_t_frag),/* SADB_X_EXT_NAT_T_FRAG */ }; static const int maxsize[] = { sizeof(struct sadb_msg), /* SADB_EXT_RESERVED */ @@ -216,6 +221,11 @@ 0, /* SADB_X_EXT_KMPRIVATE */ 0, /* SADB_X_EXT_POLICY */ sizeof(struct sadb_x_sa2), /* SADB_X_SA2 */ + sizeof(struct sadb_x_nat_t_type), /* SADB_X_EXT_NAT_T_TYPE */ + sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_SPORT */ + sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_DPORT */ + 0, /* SADB_X_EXT_NAT_T_OA */ + sizeof(struct sadb_x_nat_t_frag), /* SADB_X_EXT_NAT_T_FRAG */ }; static int ipsec_esp_keymin = 256; @@ -384,6 +394,10 @@ const struct sadb_msghdr *); static int key_spddump(struct socket *, struct mbuf *, const struct sadb_msghdr *); +#ifdef IPSEC_NAT_T +static int key_nat_map(struct socket *, struct mbuf *, + const struct sadb_msghdr *); +#endif static struct mbuf *key_setdumpsp(struct secpolicy *, u_int8_t, u_int32_t, u_int32_t); static u_int key_getspreqmsglen(struct secpolicy *); @@ -406,6 +420,13 @@ static struct mbuf *key_setsadbsa(struct secasvar *); static struct mbuf *key_setsadbaddr(u_int16_t, struct sockaddr *, u_int8_t, u_int16_t); +#ifdef IPSEC_NAT_T +static struct mbuf *key_setsadbxport __P((u_int16_t, u_int16_t)); +static struct mbuf *key_setsadbxtype __P((u_int16_t)); +#endif +static void key_porttosaddr __P((struct sockaddr *, u_int16_t)); +#define KEY_PORTTOSADDR(saddr, port) \ + key_porttosaddr((struct sockaddr *)(saddr), (port)) #if 0 static struct mbuf *key_setsadbident(u_int16_t, u_int16_t, caddr_t, int, u_int64_t); @@ -927,10 +948,11 @@ * keep source address in IPsec SA. We see a tricky situation here. */ struct secasvar * -key_allocsa(family, src, dst, proto, spi) +key_allocsa(family, src, dst, proto, spi, sport, dport) u_int family, proto; caddr_t src, dst; u_int32_t spi; + u_int16_t sport, dport; { struct secasvar *sav, *match; u_int stateidx, state, tmpidx, matchidx; @@ -941,11 +963,17 @@ int s; const u_int *saorder_state_valid; int arraysize; + int chkport = 0; /* sanity check */ if (src == NULL || dst == NULL) panic("key_allocsa: NULL pointer is passed."); +#ifdef IPSEC_NAT_T + if ((sport != 0) && (dport != 0)) + chkport = 1; +#endif + /* * when both systems employ similar strategy to use a SA. * the search order is important even in the inbound case. @@ -1004,8 +1032,11 @@ switch (family) { case AF_INET: bcopy(src, &sin.sin_addr, sizeof(sin.sin_addr)); +#ifdef IPSEC_NAT_T + sin.sin_port = sport; +#endif if (key_sockaddrcmp((struct sockaddr*)&sin, - (struct sockaddr *)&sav->sah->saidx.src, 0) != 0) + (struct sockaddr *)&sav->sah->saidx.src, chkport) != 0) continue; break; @@ -1013,10 +1044,13 @@ case AF_INET6: bcopy(src, &sin6.sin6_addr, sizeof(sin6.sin6_addr)); sin6.sin6_scope_id = 0; +#ifdef IPSEC_NAT_T + sin6.sin6_port = sport; +#endif if (sa6_recoverscope(&sin6)) continue; if (key_sockaddrcmp((struct sockaddr *)&sin6, - (struct sockaddr *)&sav->sah->saidx.src, 0) != 0) + (struct sockaddr *)&sav->sah->saidx.src, chkport) != 0) continue; break; #endif @@ -1032,8 +1066,11 @@ switch (family) { case AF_INET: bcopy(dst, &sin.sin_addr, sizeof(sin.sin_addr)); +#ifdef IPSEC_NAT_T + sin.sin_port = dport; +#endif if (key_sockaddrcmp((struct sockaddr*)&sin, - (struct sockaddr *)&sav->sah->saidx.dst, 0) != 0) + (struct sockaddr *)&sav->sah->saidx.dst, chkport) != 0) continue; break; @@ -1041,10 +1078,13 @@ case AF_INET6: bcopy(dst, &sin6.sin6_addr, sizeof(sin6.sin6_addr)); sin6.sin6_scope_id = 0; +#ifdef IPSEC_NAT_T + sin6.sin6_port = dport; +#endif if (sa6_recoverscope(&sin6)) continue; if (key_sockaddrcmp((struct sockaddr *)&sin6, - (struct sockaddr *)&sav->sah->saidx.dst, 0) != 0) + (struct sockaddr *)&sav->sah->saidx.dst, chkport) != 0) continue; break; #endif @@ -1873,6 +1913,7 @@ } } +#ifndef IPSEC_NAT_T for (isr = newsp->req; isr; isr = isr->next) { struct sockaddr *sa; @@ -1916,6 +1957,7 @@ } } } +#endif /* !IPSEC_NAT_T */ /* * bark if we have different address family on tunnel address @@ -2475,6 +2517,72 @@ return 0; } +#ifdef IPSEC_NAT_T +/* + * SADB_X_NAT_T_NEW_MAPPING + */ +static int +key_nat_map(so, m, mhp) + struct socket *so; + struct mbuf *m; + const struct sadb_msghdr *mhp; +{ + struct sadb_x_nat_t_type *type; + struct sadb_x_nat_t_port *sport; + struct sadb_x_nat_t_port *dport; + struct sadb_address *addr; + struct sadb_x_nat_t_frag *frag; + + /* sanity check */ + if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) + panic("key_nat_map: NULL pointer is passed."); + + if (mhp->ext[SADB_X_EXT_NAT_T_TYPE] == NULL || + mhp->ext[SADB_X_EXT_NAT_T_SPORT] == NULL || + mhp->ext[SADB_X_EXT_NAT_T_DPORT] == NULL) { + ipseclog((LOG_DEBUG, "key_nat_map: invalid message.\n")); + return key_senderror(so, m, EINVAL); + } + if ((mhp->extlen[SADB_X_EXT_NAT_T_TYPE] < sizeof(*type)) || + (mhp->extlen[SADB_X_EXT_NAT_T_SPORT] < sizeof(*sport)) || + (mhp->extlen[SADB_X_EXT_NAT_T_DPORT] < sizeof(*dport))) { + ipseclog((LOG_DEBUG, "key_nat_map: invalid message.\n")); + return key_senderror(so, m, EINVAL); + } + + if ((mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) && + (mhp->extlen[SADB_X_EXT_NAT_T_OA] < sizeof(*addr))) { + ipseclog((LOG_DEBUG, "key_nat_map: invalid message\n")); + return key_senderror(so, m, EINVAL); + } + + if ((mhp->ext[SADB_X_EXT_NAT_T_FRAG] != NULL) && + (mhp->extlen[SADB_X_EXT_NAT_T_FRAG] < sizeof(*frag))) { + ipseclog((LOG_DEBUG, "key_nat_map: invalid message\n")); + return key_senderror(so, m, EINVAL); + } + + type = (struct sadb_x_nat_t_type *)mhp->ext[SADB_X_EXT_NAT_T_TYPE]; + sport = (struct sadb_x_nat_t_port *)mhp->ext[SADB_X_EXT_NAT_T_SPORT]; + dport = (struct sadb_x_nat_t_port *)mhp->ext[SADB_X_EXT_NAT_T_DPORT]; + addr = (struct sadb_address *)mhp->ext[SADB_X_EXT_NAT_T_OA]; + frag = (struct sadb_x_nat_t_frag *) mhp->ext[SADB_X_EXT_NAT_T_FRAG]; + + printf("sadb_nat_map: type %d, sport = %d, dport = %d\n", + type->sadb_x_nat_t_type_type, + sport->sadb_x_nat_t_port_port, + dport->sadb_x_nat_t_port_port); + + /* + * XXX handle that, it should also contain a SA, or anything + * that enable to update the SA information. + */ + + return 0; +} +#endif /* IPSEC_NAT_T */ + + static struct mbuf * key_setdumpsp(sp, type, seq, pid) struct secpolicy *sp; @@ -3025,6 +3133,10 @@ sav->lft_c = NULL; sav->lft_h = NULL; sav->lft_s = NULL; +#ifdef IPSEC_NAT_T + sav->natt_type = 0; + sav->esp_frag = 0; +#endif /* SA */ if (mhp->ext[SADB_EXT_SA] != NULL) { @@ -3491,6 +3603,11 @@ SADB_EXT_ADDRESS_DST, SADB_EXT_ADDRESS_PROXY, SADB_EXT_KEY_AUTH, SADB_EXT_KEY_ENCRYPT, SADB_EXT_IDENTITY_SRC, SADB_EXT_IDENTITY_DST, SADB_EXT_SENSITIVITY, +#ifdef IPSEC_NAT_T + SADB_X_EXT_NAT_T_TYPE, SADB_X_EXT_NAT_T_SPORT, + SADB_X_EXT_NAT_T_DPORT, SADB_X_EXT_NAT_T_OA, + SADB_X_EXT_NAT_T_FRAG, +#endif }; m = key_setsadbmsg(type, 0, satype, seq, pid, sav->refcnt); @@ -3567,6 +3684,31 @@ p = sav->lft_s; break; +#ifdef IPSEC_NAT_T + case SADB_X_EXT_NAT_T_TYPE: + if ((m = key_setsadbxtype(sav->natt_type)) == NULL) + goto fail; + break; + + case SADB_X_EXT_NAT_T_DPORT: + if ((m = key_setsadbxport(KEY_PORTFROMSADDR + (&sav->sah->saidx.dst), + SADB_X_EXT_NAT_T_DPORT)) == NULL) + goto fail; + break; + + case SADB_X_EXT_NAT_T_SPORT: + if ((m = key_setsadbxport(KEY_PORTFROMSADDR + (&sav->sah->saidx.src), + SADB_X_EXT_NAT_T_SPORT)) == NULL) + goto fail; + break; + + case SADB_X_EXT_NAT_T_OA: + case SADB_X_EXT_NAT_T_FRAG: + continue; +#endif + case SADB_EXT_ADDRESS_PROXY: case SADB_EXT_IDENTITY_SRC: case SADB_EXT_IDENTITY_DST: @@ -3825,7 +3967,134 @@ return m; } +#ifdef IPSEC_NAT_T /* + * set a type in sadb_x_nat_t_type + */ +static struct mbuf * +key_setsadbxtype(type) + u_int16_t type; +{ + struct mbuf *m; + size_t len; + struct sadb_x_nat_t_type *p; + + len = PFKEY_ALIGN8(sizeof(struct sadb_x_nat_t_type)); + + m = key_alloc_mbuf(len); + if (!m || m->m_next) { /*XXX*/ + if (m) + m_freem(m); + return NULL; + } + + p = mtod(m, struct sadb_x_nat_t_type *); + + bzero(p, len); + p->sadb_x_nat_t_type_len = PFKEY_UNIT64(len); + p->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE; + p->sadb_x_nat_t_type_type = type; + + return m; +} +/* + * set a port in sadb_x_nat_t_port. port is in network order + */ +static struct mbuf * +key_setsadbxport(port, type) + u_int16_t port; + u_int16_t type; +{ + struct mbuf *m; + size_t len; + struct sadb_x_nat_t_port *p; + + len = PFKEY_ALIGN8(sizeof(struct sadb_x_nat_t_port)); + + m = key_alloc_mbuf(len); + if (!m || m->m_next) { /*XXX*/ + if (m) + m_freem(m); + return NULL; + } + + p = mtod(m, struct sadb_x_nat_t_port *); + + bzero(p, len); + p->sadb_x_nat_t_port_len = PFKEY_UNIT64(len); + p->sadb_x_nat_t_port_exttype = type; + p->sadb_x_nat_t_port_port = port; + + return m; +} + +/* + * Get port from sockaddr, port is in network order + */ +u_int16_t +key_portfromsaddr(saddr) + struct sockaddr *saddr; +{ + u_int16_t port; + + switch (saddr->sa_family) { + case AF_INET: { + struct sockaddr_in *sin = (struct sockaddr_in *)saddr; + + port = sin->sin_port; + break; + } +#ifdef INET6 + case AF_INET6: { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)saddr; + + port = sin6->sin6_port; + break; + } +#endif + default: + printf("key_portfromsaddr: unexpected address family\n"); + port = 0; + break; + } + + return port; +} +#endif /* IPSEC_NAT_T */ + +/* + * Set port is struct sockaddr. port is in network order + */ +static void +key_porttosaddr(saddr, port) + struct sockaddr *saddr; + u_int16_t port; +{ + switch (saddr->sa_family) { + case AF_INET: { + struct sockaddr_in *sin = (struct sockaddr_in *)saddr; + + sin->sin_port = port; + break; + } +#ifdef INET6 + case AF_INET6: { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)saddr; + + sin6->sin6_port = port; + break; + } +#endif + default: + printf("key_porttosaddr: unexpected address family %d\n", + saddr->sa_family); + break; + } + + return; +} + +/* * set data into sadb_lifetime */ static struct mbuf * @@ -4015,6 +4284,8 @@ struct secasindex *saidx0, *saidx1; int flag; { + int chkport = 0; + /* sanity */ if (saidx0 == NULL && saidx1 == NULL) return 1; @@ -4037,13 +4308,30 @@ /* CMP_MODE_REQID, CMP_HEAD */ if (flag == CMP_MODE_REQID) { +#ifdef IPSEC_NAT_T /* + * If NAT-T is enabled, check ports for tunnel mode. + * Don't do it for transport mode, as there is no + * port information available in the SP. + * XXX also don't check ports if they are set to zero in the SPD: + * This means we bave a non-generated SPD, which can't know UDP ports. + */ + if (saidx1->mode == IPSEC_MODE_TUNNEL && + satosin(&saidx1->src)->sin_port && + satosin(&saidx1->dst)->sin_port ) + chkport = 1; +#endif + /* * If reqid of SPD is non-zero, unique SA is required. * The result must be of same reqid in this case. */ if (saidx1->reqid != 0 && saidx0->reqid != saidx1->reqid) return 0; } +#ifdef IPSEC_NAT_T + else + chkport = 1; +#endif if (flag == CMP_MODE_REQID) { if (saidx0->mode != IPSEC_MODE_ANY && @@ -4052,11 +4340,11 @@ } if (key_sockaddrcmp((struct sockaddr *)&saidx0->src, - (struct sockaddr *)&saidx1->src, 0) != 0) { + (struct sockaddr *)&saidx1->src, chkport) != 0) { return 0; } if (key_sockaddrcmp((struct sockaddr *)&saidx0->dst, - (struct sockaddr *)&saidx1->dst, 0) != 0) { + (struct sockaddr *)&saidx1->dst, chkport) != 0) { return 0; } } @@ -4704,19 +4992,23 @@ return key_senderror(so, m, EINVAL); } - /* make sure if port number is zero. */ + /* make sure if port number is zero if NAT-T support is NOT compiled. */ switch (((struct sockaddr *)(src0 + 1))->sa_family) { case AF_INET: if (((struct sockaddr *)(src0 + 1))->sa_len != sizeof(struct sockaddr_in)) return key_senderror(so, m, EINVAL); +#ifndef IPSEC_NAT_T ((struct sockaddr_in *)(src0 + 1))->sin_port = 0; +#endif break; case AF_INET6: if (((struct sockaddr *)(src0 + 1))->sa_len != sizeof(struct sockaddr_in6)) return key_senderror(so, m, EINVAL); +#ifndef IPSEC_NAT_T ((struct sockaddr_in6 *)(src0 + 1))->sin6_port = 0; +#endif break; default: ; /*???*/ @@ -4726,13 +5018,17 @@ if (((struct sockaddr *)(dst0 + 1))->sa_len != sizeof(struct sockaddr_in)) return key_senderror(so, m, EINVAL); +#ifndef IPSEC_NAT_T ((struct sockaddr_in *)(dst0 + 1))->sin_port = 0; +#endif break; case AF_INET6: if (((struct sockaddr *)(dst0 + 1))->sa_len != sizeof(struct sockaddr_in6)) return key_senderror(so, m, EINVAL); +#ifndef IPSEC_NAT_T ((struct sockaddr_in6 *)(dst0 + 1))->sin6_port = 0; +#endif break; default: ; /*???*/ @@ -4741,6 +5037,12 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); + /* If not using NAT-T, make sure port numbers are set to zero. */ +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + /* SPI allocation */ spi = key_do_getnewspi((struct sadb_spirange *)mhp->ext[SADB_EXT_SPIRANGE], &saidx); @@ -4994,6 +5296,12 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); + /* If not using NAT-T, make sure if port number is zero. */ +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + /* get a SA header */ if ((sah = key_getsah(&saidx)) == NULL) { ipseclog((LOG_DEBUG, "key_update: no SA index found.\n")); @@ -5060,6 +5368,68 @@ return key_senderror(so, m, error); } +#ifdef IPSEC_NAT_T + /* + * Handle NAT-T info if present + */ + if (mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) + printf("update: NAT-T OA present\n"); + + if ((mhp->ext[SADB_X_EXT_NAT_T_TYPE] != NULL) && + (mhp->ext[SADB_X_EXT_NAT_T_SPORT] != NULL) && + (mhp->ext[SADB_X_EXT_NAT_T_DPORT] != NULL)) { + struct sadb_x_nat_t_type *type; + struct sadb_x_nat_t_port *sport; + struct sadb_x_nat_t_port *dport; + struct sadb_address *addr; + struct sadb_x_nat_t_frag *frag; + + if ((mhp->extlen[SADB_X_EXT_NAT_T_TYPE] < sizeof(*type)) || + (mhp->extlen[SADB_X_EXT_NAT_T_SPORT] < sizeof(*sport)) || + (mhp->extlen[SADB_X_EXT_NAT_T_DPORT] < sizeof(*dport))) { + ipseclog((LOG_DEBUG, "key_update: " + "invalid message.\n")); + return key_senderror(so, m, EINVAL); + } + + if ((mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) && + (mhp->extlen[SADB_X_EXT_NAT_T_OA] < sizeof(*addr))) { + ipseclog((LOG_DEBUG, "key_update: invalid message\n")); + return key_senderror(so, m, EINVAL); + } + + if ((mhp->ext[SADB_X_EXT_NAT_T_FRAG] != NULL) && + (mhp->extlen[SADB_X_EXT_NAT_T_FRAG] < sizeof(*frag))) { + ipseclog((LOG_DEBUG, "key_update: invalid message\n")); + return key_senderror(so, m, EINVAL); + } + + type = (struct sadb_x_nat_t_type *) + mhp->ext[SADB_X_EXT_NAT_T_TYPE]; + sport = (struct sadb_x_nat_t_port *) + mhp->ext[SADB_X_EXT_NAT_T_SPORT]; + dport = (struct sadb_x_nat_t_port *) + mhp->ext[SADB_X_EXT_NAT_T_DPORT]; + addr = (struct sadb_address *) + mhp->ext[SADB_X_EXT_NAT_T_OA]; + frag = (struct sadb_x_nat_t_frag *) + mhp->ext[SADB_X_EXT_NAT_T_FRAG]; + + if (type) + sav->natt_type = type->sadb_x_nat_t_type_type; + if (sport) + KEY_PORTTOSADDR(&sav->sah->saidx.src, + sport->sadb_x_nat_t_port_port); + if (dport) + KEY_PORTTOSADDR(&sav->sah->saidx.dst, + dport->sadb_x_nat_t_port_port); + if (frag) + sav->esp_frag = frag->sadb_x_nat_t_frag_fraglen; + else + sav->esp_frag = IP_MAXPACKET; + } +#endif /* IPSEC_NAT_T */ + { struct mbuf *n; @@ -5189,6 +5559,11 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + /* get a SA header */ if ((newsah = key_getsah(&saidx)) == NULL) { /* create a new SA header */ @@ -5222,7 +5597,69 @@ return key_senderror(so, m, error); } +#ifdef IPSEC_NAT_T /* + * Handle NAT-T info if present + */ + if (mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) + printf("add: NAT-T OA present\n"); + + if ((mhp->ext[SADB_X_EXT_NAT_T_TYPE] != NULL) && + (mhp->ext[SADB_X_EXT_NAT_T_SPORT] != NULL) && + (mhp->ext[SADB_X_EXT_NAT_T_DPORT] != NULL)) { + struct sadb_x_nat_t_type *type; + struct sadb_x_nat_t_port *sport; + struct sadb_x_nat_t_port *dport; + struct sadb_address *addr; + struct sadb_x_nat_t_frag *frag; + + if ((mhp->extlen[SADB_X_EXT_NAT_T_TYPE] < sizeof(*type)) || + (mhp->extlen[SADB_X_EXT_NAT_T_SPORT] < sizeof(*sport)) || + (mhp->extlen[SADB_X_EXT_NAT_T_DPORT] < sizeof(*dport))) { + ipseclog((LOG_DEBUG, "key_add: " + "invalid message.\n")); + return key_senderror(so, m, EINVAL); + } + + if ((mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) && + (mhp->extlen[SADB_X_EXT_NAT_T_OA] < sizeof(*addr))) { + ipseclog((LOG_DEBUG, "key_add: invalid message\n")); + return key_senderror(so, m, EINVAL); + } + + if ((mhp->ext[SADB_X_EXT_NAT_T_FRAG] != NULL) && + (mhp->extlen[SADB_X_EXT_NAT_T_FRAG] < sizeof(*frag))) { + ipseclog((LOG_DEBUG, "key_update: invalid message\n")); + return key_senderror(so, m, EINVAL); + } + + type = (struct sadb_x_nat_t_type *) + mhp->ext[SADB_X_EXT_NAT_T_TYPE]; + sport = (struct sadb_x_nat_t_port *) + mhp->ext[SADB_X_EXT_NAT_T_SPORT]; + dport = (struct sadb_x_nat_t_port *) + mhp->ext[SADB_X_EXT_NAT_T_DPORT]; + addr = (struct sadb_address *) + mhp->ext[SADB_X_EXT_NAT_T_OA]; + frag = (struct sadb_x_nat_t_frag *) + mhp->ext[SADB_X_EXT_NAT_T_FRAG]; + + if (type) + newsav->natt_type = type->sadb_x_nat_t_type_type; + if (sport) + KEY_PORTTOSADDR(&newsav->sah->saidx.src, + sport->sadb_x_nat_t_port_port); + if (dport) + KEY_PORTTOSADDR(&newsav->sah->saidx.dst, + dport->sadb_x_nat_t_port_port); + if (frag) + newsav->esp_frag = frag->sadb_x_nat_t_frag_fraglen; + else + newsav->esp_frag = IP_MAXPACKET; + } +#endif + + /* * don't call key_freesav() here, as we would like to keep the SA * in the database on success. */ @@ -5416,6 +5853,11 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + /* get a SA header */ LIST_FOREACH(sah, &sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) @@ -5483,6 +5925,11 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + LIST_FOREACH(sah, &sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; @@ -5592,6 +6039,11 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + /* get a SA header */ LIST_FOREACH(sah, &sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) @@ -6272,6 +6724,11 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + /* get a SA index */ LIST_FOREACH(sah, &sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) @@ -6875,6 +7332,11 @@ key_spdadd, /* SADB_X_SPDSETIDX */ NULL, /* SADB_X_SPDEXPIRE */ key_spddelete2, /* SADB_X_SPDDELETE2 */ +#ifdef IPSEC_NAT_T + key_nat_map, /* SADB_X_NAT_T_NEW_MAPPING */ +#else + NULL, +#endif }; /* @@ -7227,6 +7689,13 @@ case SADB_EXT_SPIRANGE: case SADB_X_EXT_POLICY: case SADB_X_EXT_SA2: +#ifdef IPSEC_NAT_T + case SADB_X_EXT_NAT_T_TYPE: + case SADB_X_EXT_NAT_T_SPORT: + case SADB_X_EXT_NAT_T_DPORT: + case SADB_X_EXT_NAT_T_OA: + case SADB_X_EXT_NAT_T_FRAG: +#endif /* duplicate check */ /* * XXX Are there duplication payloads of either Index: netkey/key.h =================================================================== --- netkey/key.h (.../6.x) (revision 8180) +++ netkey/key.h (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -58,7 +58,8 @@ struct sockaddr *, struct sockaddr *, struct sockaddr *); extern int key_checkrequest (struct ipsecrequest *isr, struct secasindex *); -extern struct secasvar *key_allocsa(u_int, caddr_t, caddr_t, u_int, u_int32_t); +extern struct secasvar *key_allocsa(u_int, caddr_t, caddr_t, u_int, u_int32_t, + u_int16_t, u_int16_t); extern void key_freesp(struct secpolicy *); extern void key_freesav(struct secasvar *); extern struct secpolicy *key_newsp(u_int32_t); @@ -78,6 +79,10 @@ extern void key_sa_recordxfer(struct secasvar *, struct mbuf *); extern void key_sa_routechange(struct sockaddr *); extern void key_sa_stir_iv(struct secasvar *); +#ifdef IPSEC_NAT_T +u_int16_t key_portfromsaddr __P((struct sockaddr *)); +#define KEY_PORTFROMSADDR(saddr) key_portfromsaddr((struct sockaddr *)(saddr)) +#endif /* to keep compatibility with FAST_IPSEC */ #define KEY_ALLOCSA(dst, proto, spi) \ Index: netipsec/ipsec.c =================================================================== --- netipsec/ipsec.c (.../6.x) (revision 8180) +++ netipsec/ipsec.c (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -1808,15 +1808,15 @@ /* Return a printable string for the IPv4 address. */ static char * -inet_ntoa4(struct in_addr ina) +inet_ntoa4(const struct sockaddr_in *sin) { - static char buf[4][4 * sizeof "123" + 4]; - unsigned char *ucp = (unsigned char *) &ina; + static char buf[4][4 * sizeof "123" + 4 + 10]; + const unsigned char *ucp = (const unsigned char *)&sin->sin_addr; static int i = 3; i = (i + 1) % 4; - sprintf(buf[i], "%d.%d.%d.%d", ucp[0] & 0xff, ucp[1] & 0xff, - ucp[2] & 0xff, ucp[3] & 0xff); + sprintf(buf[i], "%d.%d.%d.%d[%u]", ucp[0] & 0xff, ucp[1] & 0xff, + ucp[2] & 0xff, ucp[3] & 0xff, ntohs(sin->sin_port)); return (buf[i]); } @@ -1827,7 +1827,7 @@ switch (sa->sa.sa_family) { #if INET case AF_INET: - return inet_ntoa4(sa->sin.sin_addr); + return inet_ntoa4(&sa->sin); #endif /* INET */ #if INET6 Index: netipsec/keydb.h =================================================================== --- netipsec/keydb.h (.../6.x) (revision 8180) +++ netipsec/keydb.h (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -117,6 +117,12 @@ struct secashead *sah; /* back pointer to the secashead */ /* + * NAT-Traversal + */ + u_int16_t natt_type; + u_int16_t esp_frag; + + /* * NB: Fields with a tdb_ prefix are part of the "glue" used * to interface to the OpenBSD crypto support. This was done * to distinguish this code from the mainline KAME code. Index: netipsec/ipsec_input.c =================================================================== --- netipsec/ipsec_input.c (.../6.x) (revision 8180) +++ netipsec/ipsec_input.c (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -110,6 +110,9 @@ struct secasvar *sav; u_int32_t spi; int error; +#ifdef IPSEC_NAT_T + struct m_tag *tag; +#endif IPSEC_ISTAT(sproto, espstat.esps_input, ahstat.ahs_input, ipcompstat.ipcomps_input); @@ -160,6 +163,13 @@ m_copydata(m, offsetof(struct ip, ip_dst), sizeof(struct in_addr), (caddr_t) &dst_address.sin.sin_addr); +#ifdef IPSEC_NAT_T + /* find the source port for NAT_T */ + if ((tag = m_tag_find(m, PACKET_TAG_IPSEC_NAT_T_PORTS, NULL)) + != NULL) { + dst_address.sin.sin_port = ((u_int16_t *)(tag + 1))[1]; + } +#endif /* IPSEC_NAT_T */ break; #endif /* INET */ #ifdef INET6 @@ -179,7 +189,7 @@ } /* NB: only pass dst since key_allocsa follows RFC2401 */ - sav = KEY_ALLOCSA(&dst_address, sproto, spi); + sav = KEY_ALLOCSA( &dst_address, sproto, spi); if (sav == NULL) { DPRINTF(("%s: no key association found for SA %s/%08lx/%u\n", __func__, ipsec_address(&dst_address), Index: netipsec/ipsec_output.c =================================================================== --- netipsec/ipsec_output.c (.../6.x) (revision 8180) +++ netipsec/ipsec_output.c (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -81,6 +81,10 @@ #include +#ifdef IPSEC_NAT_T +#include +#endif + int ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr) { @@ -173,6 +177,51 @@ ip->ip_len = ntohs(ip->ip_len); ip->ip_off = ntohs(ip->ip_off); +#ifdef IPSEC_NAT_T + /* + * If NAT-T is enabled, now that all IPSEC processing is done + * insert UDP encapsulation header after IP header. + */ + if (sav->natt_type != 0) { + int size = sizeof(struct udphdr); +#ifdef _IP_VHL + int hlen = IP_VHL_HL(ip->ip_vhl); +#else + int hlen = (ip->ip_hl << 2); +#endif + int off; + struct mbuf *mi; + struct udphdr *udp; + + if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE) + size += sizeof(u_int64_t); + + if ( (mi = m_makespace(m, hlen, size, &off)) == NULL ) { + error = ENOBUFS; + goto bad; + } + + udp = (struct udphdr *)(mtod(mi, caddr_t) + off); + + if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE) + udp->uh_sport = htons(UDP_ENCAP_ESPINUDP_PORT); + else + udp->uh_sport = + KEY_PORTFROMSADDR(&sav->sah->saidx.src); + + udp->uh_dport = KEY_PORTFROMSADDR(&sav->sah->saidx.dst); + udp->uh_sum = 0; + udp->uh_ulen = htons(m->m_pkthdr.len - hlen); + ip->ip_len = m->m_pkthdr.len; + ip->ip_p = IPPROTO_UDP; + + if (sav->natt_type == UDP_ENCAP_ESPINUDP_NON_IKE) { + u_int64_t *marker = (u_int64_t *)(udp + 1); + *marker = 0; + } + } +#endif /* IPSEC_NAT_T */ + return ip_output(m, NULL, NULL, IP_RAWOUTPUT, NULL, NULL); #endif /* INET */ #ifdef INET6 Index: netipsec/key.c =================================================================== --- netipsec/key.c (.../6.x) (revision 8180) +++ netipsec/key.c (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -210,6 +210,11 @@ 0, /* SADB_X_EXT_KMPRIVATE */ sizeof(struct sadb_x_policy), /* SADB_X_EXT_POLICY */ sizeof(struct sadb_x_sa2), /* SADB_X_SA2 */ + sizeof(struct sadb_x_nat_t_type), /* SADB_X_EXT_NAT_T_TYPE */ + sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_SPORT */ + sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_DPORT */ + sizeof(struct sadb_address), /* SADB_X_EXT_NAT_T_OA */ + sizeof(struct sadb_x_nat_t_frag),/* SADB_X_EXT_NAT_T_FRAG */ }; static const int maxsize[] = { sizeof(struct sadb_msg), /* SADB_EXT_RESERVED */ @@ -232,6 +237,11 @@ 0, /* SADB_X_EXT_KMPRIVATE */ 0, /* SADB_X_EXT_POLICY */ sizeof(struct sadb_x_sa2), /* SADB_X_SA2 */ + sizeof(struct sadb_x_nat_t_type), /* SADB_X_EXT_NAT_T_TYPE */ + sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_SPORT */ + sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_DPORT */ + 0, /* SADB_X_EXT_NAT_T_OA */ + sizeof(struct sadb_x_nat_t_frag), /* SADB_X_EXT_NAT_T_FRAG */ }; static int ipsec_esp_keymin = 256; @@ -393,6 +403,10 @@ const struct sadb_msghdr *)); static int key_spddump __P((struct socket *, struct mbuf *, const struct sadb_msghdr *)); +#ifdef IPSEC_NAT_T +static int key_nat_map(struct socket *, struct mbuf *, + const struct sadb_msghdr *); +#endif static struct mbuf *key_setdumpsp __P((struct secpolicy *, u_int8_t, u_int32_t, u_int32_t)); static u_int key_getspreqmsglen __P((struct secpolicy *)); @@ -418,6 +432,13 @@ static struct mbuf *key_setsadbsa __P((struct secasvar *)); static struct mbuf *key_setsadbaddr __P((u_int16_t, const struct sockaddr *, u_int8_t, u_int16_t)); +#ifdef IPSEC_NAT_T +static struct mbuf *key_setsadbxport __P((u_int16_t, u_int16_t)); +static struct mbuf *key_setsadbxtype __P((u_int16_t)); +#endif +static void key_porttosaddr __P((struct sockaddr *, u_int16_t)); +#define KEY_PORTTOSADDR(saddr, port) \ + key_porttosaddr((struct sockaddr *)(saddr), (port)) static struct mbuf *key_setsadbxsa2 __P((u_int8_t, u_int32_t, u_int32_t)); static struct mbuf *key_setsadbxpolicy __P((u_int16_t, u_int8_t, u_int32_t)); @@ -1042,12 +1063,20 @@ struct secasvar *sav; u_int stateidx, arraysize, state; const u_int *saorder_state_valid; + int chkport = 0; IPSEC_ASSERT(dst != NULL, ("null dst address")); KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP %s from %s:%u\n", __func__, where, tag)); +#ifdef IPSEC_NAT_T + if (dst->sa.sa_family == AF_INET && + dst->sa.sa_len == sizeof(struct sockaddr_in) && + dst->sin.sin_port != 0) + chkport = 1; +#endif + /* * searching SAD. * XXX: to be checked internal IP header somewhere. Also when @@ -1079,11 +1108,11 @@ continue; #if 0 /* don't check src */ /* check src address */ - if (key_sockaddrcmp(&src->sa, &sav->sah->saidx.src.sa, 0) != 0) + if (key_sockaddrcmp(&src->sa, &sav->sah->saidx.src.sa, chkport) != 0) continue; #endif /* check dst address */ - if (key_sockaddrcmp(&dst->sa, &sav->sah->saidx.dst.sa, 0) != 0) + if (key_sockaddrcmp(&dst->sa, &sav->sah->saidx.dst.sa, chkport) != 0) continue; sa_addref(sav); goto done; @@ -1847,6 +1876,52 @@ return key_senderror(so, m, error); } +#ifndef IPSEC_NAT_T + for (isr = newsp->req; isr; isr = isr->next) { + struct sockaddr *sa; + + /* + * port spec is not permitted for tunnel mode + */ + if (isr->saidx.mode == IPSEC_MODE_TUNNEL && src0 && dst0) { + sa = (struct sockaddr *)(src0 + 1); + switch (sa->sa_family) { + case AF_INET: + if (((struct sockaddr_in *)sa)->sin_port) { + keydb_delsecpolicy(newsp); + return key_senderror(so, m, EINVAL); + } + break; + case AF_INET6: + if (((struct sockaddr_in6 *)sa)->sin6_port) { + keydb_delsecpolicy(newsp); + return key_senderror(so, m, EINVAL); + } + break; + default: + break; + } + sa = (struct sockaddr *)(dst0 + 1); + switch (sa->sa_family) { + case AF_INET: + if (((struct sockaddr_in *)sa)->sin_port) { + keydb_delsecpolicy(newsp); + return key_senderror(so, m, EINVAL); + } + break; + case AF_INET6: + if (((struct sockaddr_in6 *)sa)->sin6_port) { + keydb_delsecpolicy(newsp); + return key_senderror(so, m, EINVAL); + } + break; + default: + break; + } + } + } +#endif /* !IPSEC_NAT_T */ + if ((newsp->id = key_getnewspid()) == 0) { _key_delsp(newsp); return key_senderror(so, m, ENOBUFS); @@ -2355,6 +2430,71 @@ return key_sendup_mbuf(so, m, KEY_SENDUP_ALL); } +#ifdef IPSEC_NAT_T +/* + * SADB_X_NAT_T_NEW_MAPPING + */ +static int +key_nat_map(so, m, mhp) + struct socket *so; + struct mbuf *m; + const struct sadb_msghdr *mhp; +{ + struct sadb_x_nat_t_type *type; + struct sadb_x_nat_t_port *sport; + struct sadb_x_nat_t_port *dport; + struct sadb_address *addr; + struct sadb_x_nat_t_frag *frag; + + /* sanity check */ + if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) + panic("key_nat_map: NULL pointer is passed."); + + if (mhp->ext[SADB_X_EXT_NAT_T_TYPE] == NULL || + mhp->ext[SADB_X_EXT_NAT_T_SPORT] == NULL || + mhp->ext[SADB_X_EXT_NAT_T_DPORT] == NULL) { + ipseclog((LOG_DEBUG, "key_nat_map: invalid message.\n")); + return key_senderror(so, m, EINVAL); + } + if ((mhp->extlen[SADB_X_EXT_NAT_T_TYPE] < sizeof(*type)) || + (mhp->extlen[SADB_X_EXT_NAT_T_SPORT] < sizeof(*sport)) || + (mhp->extlen[SADB_X_EXT_NAT_T_DPORT] < sizeof(*dport))) { + ipseclog((LOG_DEBUG, "key_nat_map: invalid message.\n")); + return key_senderror(so, m, EINVAL); + } + + if ((mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) && + (mhp->extlen[SADB_X_EXT_NAT_T_OA] < sizeof(*addr))) { + ipseclog((LOG_DEBUG, "key_nat_map: invalid message\n")); + return key_senderror(so, m, EINVAL); + } + + if ((mhp->ext[SADB_X_EXT_NAT_T_FRAG] != NULL) && + (mhp->extlen[SADB_X_EXT_NAT_T_FRAG] < sizeof(*frag))) { + ipseclog((LOG_DEBUG, "key_nat_map: invalid message\n")); + return key_senderror(so, m, EINVAL); + } + + type = (struct sadb_x_nat_t_type *)mhp->ext[SADB_X_EXT_NAT_T_TYPE]; + sport = (struct sadb_x_nat_t_port *)mhp->ext[SADB_X_EXT_NAT_T_SPORT]; + dport = (struct sadb_x_nat_t_port *)mhp->ext[SADB_X_EXT_NAT_T_DPORT]; + addr = (struct sadb_address *)mhp->ext[SADB_X_EXT_NAT_T_OA]; + frag = (struct sadb_x_nat_t_frag *) mhp->ext[SADB_X_EXT_NAT_T_FRAG]; + + printf("sadb_nat_map: type %d, sport = %d, dport = %d\n", + type->sadb_x_nat_t_type_type, + sport->sadb_x_nat_t_port_port, + dport->sadb_x_nat_t_port_port); + + /* + * XXX handle that, it should also contain a SA, or anything + * that enable to update the SA information. + */ + + return 0; +} +#endif /* IPSEC_NAT_T */ + /* * SADB_SPDDUMP processing * receive @@ -2984,6 +3124,10 @@ sav->lft_c = NULL; sav->lft_h = NULL; sav->lft_s = NULL; +#ifdef IPSEC_NAT_T + sav->natt_type = 0; + sav->esp_frag = 0; +#endif sav->tdb_xform = NULL; /* transform */ sav->tdb_encalgxform = NULL; /* encoding algorithm */ sav->tdb_authalgxform = NULL; /* authentication algorithm */ @@ -3294,6 +3438,11 @@ SADB_EXT_ADDRESS_DST, SADB_EXT_ADDRESS_PROXY, SADB_EXT_KEY_AUTH, SADB_EXT_KEY_ENCRYPT, SADB_EXT_IDENTITY_SRC, SADB_EXT_IDENTITY_DST, SADB_EXT_SENSITIVITY, +#ifdef IPSEC_NAT_T + SADB_X_EXT_NAT_T_TYPE, SADB_X_EXT_NAT_T_SPORT, + SADB_X_EXT_NAT_T_DPORT, SADB_X_EXT_NAT_T_OA, + SADB_X_EXT_NAT_T_FRAG, +#endif }; m = key_setsadbmsg(type, 0, satype, seq, pid, sav->refcnt); @@ -3370,6 +3519,31 @@ p = sav->lft_s; break; +#ifdef IPSEC_NAT_T + case SADB_X_EXT_NAT_T_TYPE: + if ((m = key_setsadbxtype(sav->natt_type)) == NULL) + goto fail; + break; + + case SADB_X_EXT_NAT_T_DPORT: + if ((m = key_setsadbxport(KEY_PORTFROMSADDR + (&sav->sah->saidx.dst), + SADB_X_EXT_NAT_T_DPORT)) == NULL) + goto fail; + break; + + case SADB_X_EXT_NAT_T_SPORT: + if ((m = key_setsadbxport(KEY_PORTFROMSADDR + (&sav->sah->saidx.src), + SADB_X_EXT_NAT_T_SPORT)) == NULL) + goto fail; + break; + + case SADB_X_EXT_NAT_T_OA: + case SADB_X_EXT_NAT_T_FRAG: + continue; +#endif + case SADB_EXT_ADDRESS_PROXY: case SADB_EXT_IDENTITY_SRC: case SADB_EXT_IDENTITY_DST: @@ -3588,7 +3762,134 @@ return m; } +#ifdef IPSEC_NAT_T /* + * set a type in sadb_x_nat_t_type + */ +static struct mbuf * +key_setsadbxtype(type) + u_int16_t type; +{ + struct mbuf *m; + size_t len; + struct sadb_x_nat_t_type *p; + + len = PFKEY_ALIGN8(sizeof(struct sadb_x_nat_t_type)); + + m = key_alloc_mbuf(len); + if (!m || m->m_next) { /*XXX*/ + if (m) + m_freem(m); + return NULL; + } + + p = mtod(m, struct sadb_x_nat_t_type *); + + bzero(p, len); + p->sadb_x_nat_t_type_len = PFKEY_UNIT64(len); + p->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE; + p->sadb_x_nat_t_type_type = type; + + return m; +} +/* + * set a port in sadb_x_nat_t_port. port is in network order + */ +static struct mbuf * +key_setsadbxport(port, type) + u_int16_t port; + u_int16_t type; +{ + struct mbuf *m; + size_t len; + struct sadb_x_nat_t_port *p; + + len = PFKEY_ALIGN8(sizeof(struct sadb_x_nat_t_port)); + + m = key_alloc_mbuf(len); + if (!m || m->m_next) { /*XXX*/ + if (m) + m_freem(m); + return NULL; + } + + p = mtod(m, struct sadb_x_nat_t_port *); + + bzero(p, len); + p->sadb_x_nat_t_port_len = PFKEY_UNIT64(len); + p->sadb_x_nat_t_port_exttype = type; + p->sadb_x_nat_t_port_port = port; + + return m; +} + +/* + * Get port from sockaddr, port is in network order + */ +u_int16_t +key_portfromsaddr(saddr) + struct sockaddr *saddr; +{ + u_int16_t port; + + switch (saddr->sa_family) { + case AF_INET: { + struct sockaddr_in *sin = (struct sockaddr_in *)saddr; + + port = sin->sin_port; + break; + } +#ifdef INET6 + case AF_INET6: { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)saddr; + + port = sin6->sin6_port; + break; + } +#endif + default: + printf("key_portfromsaddr: unexpected address family\n"); + port = 0; + break; + } + + return port; +} +#endif /* IPSEC_NAT_T */ + +/* + * Set port is struct sockaddr. port is in network order + */ +static void +key_porttosaddr(saddr, port) + struct sockaddr *saddr; + u_int16_t port; +{ + switch (saddr->sa_family) { + case AF_INET: { + struct sockaddr_in *sin = (struct sockaddr_in *)saddr; + + sin->sin_port = port; + break; + } +#ifdef INET6 + case AF_INET6: { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)saddr; + + sin6->sin6_port = port; + break; + } +#endif + default: + printf("key_porttosaddr: unexpected address family %d\n", + saddr->sa_family); + break; + } + + return; +} + +/* * set data into sadb_x_policy */ static struct mbuf * @@ -3738,6 +4039,8 @@ const struct secasindex *saidx1, int flag) { + int chkport = 0; + /* sanity */ if (saidx0 == NULL && saidx1 == NULL) return 1; @@ -3761,13 +4064,30 @@ /* CMP_MODE_REQID, CMP_REQID, CMP_HEAD */ if (flag == CMP_MODE_REQID ||flag == CMP_REQID) { +#ifdef IPSEC_NAT_T /* + * If NAT-T is enabled, check ports for tunnel mode. + * Don't do it for transport mode, as there is no + * port information available in the SP. + * XXX also don't check ports if they are set to zero in the SPD: + * This means we bave a non-generated SPD, which can't know UDP ports. + */ + if (saidx1->mode == IPSEC_MODE_TUNNEL && + ((const struct sockaddr_in *)(&saidx1->src))->sin_port && + ((const struct sockaddr_in *)(&saidx1->dst))->sin_port ) + chkport = 1; +#endif /* IPSEC_NAT_T */ + /* * If reqid of SPD is non-zero, unique SA is required. * The result must be of same reqid in this case. */ if (saidx1->reqid != 0 && saidx0->reqid != saidx1->reqid) return 0; } +#ifdef IPSEC_NAT_T + else + chkport = 1; +#endif if (flag == CMP_MODE_REQID) { if (saidx0->mode != IPSEC_MODE_ANY @@ -3775,10 +4095,10 @@ return 0; } - if (key_sockaddrcmp(&saidx0->src.sa, &saidx1->src.sa, 0) != 0) { + if (key_sockaddrcmp(&saidx0->src.sa, &saidx1->src.sa, chkport) != 0) { return 0; } - if (key_sockaddrcmp(&saidx0->dst.sa, &saidx1->dst.sa, 0) != 0) { + if (key_sockaddrcmp(&saidx0->dst.sa, &saidx1->dst.sa, chkport) != 0) { return 0; } } @@ -4398,13 +4718,17 @@ if (((struct sockaddr *)(src0 + 1))->sa_len != sizeof(struct sockaddr_in)) return key_senderror(so, m, EINVAL); +#ifndef IPSEC_NAT_T ((struct sockaddr_in *)(src0 + 1))->sin_port = 0; +#endif break; case AF_INET6: if (((struct sockaddr *)(src0 + 1))->sa_len != sizeof(struct sockaddr_in6)) return key_senderror(so, m, EINVAL); +#ifndef IPSEC_NAT_T ((struct sockaddr_in6 *)(src0 + 1))->sin6_port = 0; +#endif break; default: ; /*???*/ @@ -4414,13 +4738,17 @@ if (((struct sockaddr *)(dst0 + 1))->sa_len != sizeof(struct sockaddr_in)) return key_senderror(so, m, EINVAL); +#ifndef IPSEC_NAT_T ((struct sockaddr_in *)(dst0 + 1))->sin_port = 0; +#endif break; case AF_INET6: if (((struct sockaddr *)(dst0 + 1))->sa_len != sizeof(struct sockaddr_in6)) return key_senderror(so, m, EINVAL); +#ifndef IPSEC_NAT_T ((struct sockaddr_in6 *)(dst0 + 1))->sin6_port = 0; +#endif break; default: ; /*???*/ @@ -4429,6 +4757,12 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); + /* If not using NAT-T, make sure port numbers are set to zero. */ +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + /* SPI allocation */ spi = key_do_getnewspi((struct sadb_spirange *)mhp->ext[SADB_EXT_SPIRANGE], &saidx); @@ -4684,6 +5018,12 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); + /* If not using NAT-T, make sure if port number is zero. */ +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + /* get a SA header */ if ((sah = key_getsah(&saidx)) == NULL) { ipseclog((LOG_DEBUG, "%s: no SA index found.\n", __func__)); @@ -4750,6 +5090,68 @@ return key_senderror(so, m, 0); } +#ifdef IPSEC_NAT_T + /* + * Handle NAT-T info if present + */ + if (mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) + printf("update: NAT-T OA present\n"); + + if ((mhp->ext[SADB_X_EXT_NAT_T_TYPE] != NULL) && + (mhp->ext[SADB_X_EXT_NAT_T_SPORT] != NULL) && + (mhp->ext[SADB_X_EXT_NAT_T_DPORT] != NULL)) { + struct sadb_x_nat_t_type *type; + struct sadb_x_nat_t_port *sport; + struct sadb_x_nat_t_port *dport; + struct sadb_address *addr; + struct sadb_x_nat_t_frag *frag; + + if ((mhp->extlen[SADB_X_EXT_NAT_T_TYPE] < sizeof(*type)) || + (mhp->extlen[SADB_X_EXT_NAT_T_SPORT] < sizeof(*sport)) || + (mhp->extlen[SADB_X_EXT_NAT_T_DPORT] < sizeof(*dport))) { + ipseclog((LOG_DEBUG, "key_update: " + "invalid message.\n")); + return key_senderror(so, m, EINVAL); + } + + if ((mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) && + (mhp->extlen[SADB_X_EXT_NAT_T_OA] < sizeof(*addr))) { + ipseclog((LOG_DEBUG, "key_update: invalid message\n")); + return key_senderror(so, m, EINVAL); + } + + if ((mhp->ext[SADB_X_EXT_NAT_T_FRAG] != NULL) && + (mhp->extlen[SADB_X_EXT_NAT_T_FRAG] < sizeof(*frag))) { + ipseclog((LOG_DEBUG, "key_update: invalid message\n")); + return key_senderror(so, m, EINVAL); + } + + type = (struct sadb_x_nat_t_type *) + mhp->ext[SADB_X_EXT_NAT_T_TYPE]; + sport = (struct sadb_x_nat_t_port *) + mhp->ext[SADB_X_EXT_NAT_T_SPORT]; + dport = (struct sadb_x_nat_t_port *) + mhp->ext[SADB_X_EXT_NAT_T_DPORT]; + addr = (struct sadb_address *) + mhp->ext[SADB_X_EXT_NAT_T_OA]; + frag = (struct sadb_x_nat_t_frag *) + mhp->ext[SADB_X_EXT_NAT_T_FRAG]; + + if (type) + sav->natt_type = type->sadb_x_nat_t_type_type; + if (sport) + KEY_PORTTOSADDR(&sav->sah->saidx.src, + sport->sadb_x_nat_t_port_port); + if (dport) + KEY_PORTTOSADDR(&sav->sah->saidx.dst, + dport->sadb_x_nat_t_port_port); + if (frag) + sav->esp_frag = frag->sadb_x_nat_t_frag_fraglen; + else + sav->esp_frag = IP_MAXPACKET; + } +#endif /* IPSEC_NAT_T */ + { struct mbuf *n; @@ -4882,6 +5284,11 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + /* get a SA header */ if ((newsah = key_getsah(&saidx)) == NULL) { /* create a new SA header */ @@ -4918,7 +5325,69 @@ return key_senderror(so, m, error); } +#ifdef IPSEC_NAT_T /* + * Handle NAT-T info if present + */ + if (mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) + printf("add: NAT-T OA present\n"); + + if ((mhp->ext[SADB_X_EXT_NAT_T_TYPE] != NULL) && + (mhp->ext[SADB_X_EXT_NAT_T_SPORT] != NULL) && + (mhp->ext[SADB_X_EXT_NAT_T_DPORT] != NULL)) { + struct sadb_x_nat_t_type *type; + struct sadb_x_nat_t_port *sport; + struct sadb_x_nat_t_port *dport; + struct sadb_address *addr; + struct sadb_x_nat_t_frag *frag; + + if ((mhp->extlen[SADB_X_EXT_NAT_T_TYPE] < sizeof(*type)) || + (mhp->extlen[SADB_X_EXT_NAT_T_SPORT] < sizeof(*sport)) || + (mhp->extlen[SADB_X_EXT_NAT_T_DPORT] < sizeof(*dport))) { + ipseclog((LOG_DEBUG, "key_add: " + "invalid message.\n")); + return key_senderror(so, m, EINVAL); + } + + if ((mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) && + (mhp->extlen[SADB_X_EXT_NAT_T_OA] < sizeof(*addr))) { + ipseclog((LOG_DEBUG, "key_add: invalid message\n")); + return key_senderror(so, m, EINVAL); + } + + if ((mhp->ext[SADB_X_EXT_NAT_T_FRAG] != NULL) && + (mhp->extlen[SADB_X_EXT_NAT_T_FRAG] < sizeof(*frag))) { + ipseclog((LOG_DEBUG, "key_update: invalid message\n")); + return key_senderror(so, m, EINVAL); + } + + type = (struct sadb_x_nat_t_type *) + mhp->ext[SADB_X_EXT_NAT_T_TYPE]; + sport = (struct sadb_x_nat_t_port *) + mhp->ext[SADB_X_EXT_NAT_T_SPORT]; + dport = (struct sadb_x_nat_t_port *) + mhp->ext[SADB_X_EXT_NAT_T_DPORT]; + addr = (struct sadb_address *) + mhp->ext[SADB_X_EXT_NAT_T_OA]; + frag = (struct sadb_x_nat_t_frag *) + mhp->ext[SADB_X_EXT_NAT_T_FRAG]; + + if (type) + newsav->natt_type = type->sadb_x_nat_t_type_type; + if (sport) + KEY_PORTTOSADDR(&newsav->sah->saidx.src, + sport->sadb_x_nat_t_port_port); + if (dport) + KEY_PORTTOSADDR(&newsav->sah->saidx.dst, + dport->sadb_x_nat_t_port_port); + if (frag) + newsav->esp_frag = frag->sadb_x_nat_t_frag_fraglen; + else + newsav->esp_frag = IP_MAXPACKET; + } +#endif + + /* * don't call key_freesav() here, as we would like to keep the SA * in the database on success. */ @@ -5118,6 +5587,11 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + /* get a SA header */ SAHTREE_LOCK(); LIST_FOREACH(sah, &sahtree, chain) { @@ -5187,6 +5661,11 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + SAHTREE_LOCK(); LIST_FOREACH(sah, &sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) @@ -5301,6 +5780,11 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + /* get a SA header */ SAHTREE_LOCK(); LIST_FOREACH(sah, &sahtree, chain) { @@ -5988,6 +6472,11 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); +#ifndef IPSEC_NAT_T + KEY_PORTTOSADDR(&saidx.src, 0); + KEY_PORTTOSADDR(&saidx.dst, 0); +#endif + /* get a SA index */ SAHTREE_LOCK(); LIST_FOREACH(sah, &sahtree, chain) { @@ -6596,6 +7085,11 @@ key_spdadd, /* SADB_X_SPDSETIDX */ NULL, /* SADB_X_SPDEXPIRE */ key_spddelete2, /* SADB_X_SPDDELETE2 */ +#ifdef IPSEC_NAT_T + key_nat_map, /* SADB_X_NAT_T_NEW_MAPPING */ +#else + NULL, +#endif }; /* @@ -6932,6 +7426,13 @@ case SADB_EXT_SPIRANGE: case SADB_X_EXT_POLICY: case SADB_X_EXT_SA2: +#ifdef IPSEC_NAT_T + case SADB_X_EXT_NAT_T_TYPE: + case SADB_X_EXT_NAT_T_SPORT: + case SADB_X_EXT_NAT_T_DPORT: + case SADB_X_EXT_NAT_T_OA: + case SADB_X_EXT_NAT_T_FRAG: +#endif /* duplicate check */ /* * XXX Are there duplication payloads of either Index: netipsec/key.h =================================================================== --- netipsec/key.h (.../6.x) (revision 8180) +++ netipsec/key.h (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -99,6 +99,10 @@ extern void key_sa_recordxfer __P((struct secasvar *, struct mbuf *)); extern void key_sa_routechange __P((struct sockaddr *)); extern void key_sa_stir_iv __P((struct secasvar *)); +#ifdef IPSEC_NAT_T +u_int16_t key_portfromsaddr __P((struct sockaddr *)); +#define KEY_PORTFROMSADDR(saddr) key_portfromsaddr((struct sockaddr *)(saddr)) +#endif #ifdef MALLOC_DECLARE MALLOC_DECLARE(M_IPSEC_SA); Index: sys/mbuf.h =================================================================== --- sys/mbuf.h (.../6.x) (revision 8180) +++ sys/mbuf.h (.../6.x-FAST_IPSEC-NATT) (revision 8180) @@ -778,6 +778,7 @@ #define PACKET_TAG_PF_TRANSLATE_LOCALHOST 26 /* PF translate localhost */ #define PACKET_TAG_IPOPTIONS 27 /* Saved IP options */ #define PACKET_TAG_CARP 28 /* CARP info */ +#define PACKET_TAG_IPSEC_NAT_T_PORTS 29 /* two uint16_t */ /* Packet tag routines. */ struct m_tag *m_tag_alloc(u_int32_t, int, int, int); --NzB8fVQJ5HfG6fxh-- From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 13:44:38 2006 Return-Path: X-Original-To: net@freebsd.org Delivered-To: freebsd-net@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 871BC16A403; Thu, 14 Sep 2006 13:44:38 +0000 (UTC) (envelope-from jhs@berklix.org) Received: from flat.berklix.org (flat.berklix.org [83.236.223.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6536943D55; Thu, 14 Sep 2006 13:44:37 +0000 (GMT) (envelope-from jhs@berklix.org) Received: from flat.berklix.org (localhost [127.0.0.1]) by flat.berklix.org (8.13.1/8.13.1) with ESMTP id k8EDiTk8092841; Thu, 14 Sep 2006 15:44:29 +0200 (CEST) (envelope-from jhs@flat.berklix.org) Received: (from jhs@localhost) by flat.berklix.org (8.13.1/8.13.1/Submit) id k8EDiI42092840; Thu, 14 Sep 2006 15:44:18 +0200 (CEST) (envelope-from jhs) Date: Thu, 14 Sep 2006 15:44:18 +0200 (CEST) Message-Id: <200609141344.k8EDiI42092840@flat.berklix.org> To: net@freebsd.org From: "Julian Stacey" Organization: http://berklix.com BSD Unix C Net Consultancy, Munich/Muenchen User-agent: EXMH http://beedub.com/exmh/ on FreeBSD http://freebsd.org X-URL: http://berklix.com/~jhs/cv/ X-Fallback: jhs@mail.brierdr.com, jhs@freebsd.org, jhs@berklix.net Cc: Gary Jennejohn , brian@Awfulhak.org, Julian Stacey Subject: ppp command port does not listens on ipv4 unless no INET6 in kernel X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 13:44:38 -0000 Hi Net@ people, I posted this to hackers@ Mon, 11 Sep 2006 20:30:38 +0200 (CEST) & got no response. I've fixed typos in subject & body. Hopefuly net@ is more appropriate & can respond please :-) ------- (cc Brian@a. who's maybe expert, from examples seen in share :-) I'm not clear if this is a bug or a config error: It seems though my /usr/sbin/ppp was moving traffic to & from internet, it was only listening for commands (not data) on ipv6, not ipv4, thus I could not type commands like dial & drop, unless instead of running ppp -auto instead I invoked ppp manually in foreground on localhost. Detail: I have 2 alternate firewall/ gateways connected to world via DSL. Each ran 4.10-Release OK. I raised one to 6.1-Release. With a 6.1 Release custom kernel compiled with options INET6 & /etc/ppp/ppp.conf with set server +12345 mypasswd sockstat -l showed only: USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS root ppp 1020 9 tcp6 *:12345 *:* (& no 2nd line for ipv4), & so from my internal host, this failed: pppctl -p mypasswd dsl:12345 & in fact even on my host named dsl, this failed telnet localhost 12345 So I built a new kernel without INET6 & then sockstat -l showed root ppp 972 9 tcp4 *:12345 *:* & that works OK, I can finally manually control my PPP link up & down via pppctl -p mypasswd dsl:12345 On my 4.10 host which has a kernel with both options INET options INET6 (as also has 4.10 GENERIC), that has always worked OK, & sockstat -l shows root ppp 512 9 tcp46 *:12345 *:* & pppctl -p mypasswd dsl:12345 works OK. Questions: - - Did I misconfigure something ? - - Does ppp on 6.1 perhaps not now listen on ipv4 if INET6 is in kernel ? (Unfortunate if so, as INET6 in in GENERIC kernel) - - Should ppp have an extra flag added, forcing "Do listen on ipv4" ? - - Is this a bug ? Should I file a send-pr ? Did I misconfig something ? Julian - -- Julian Stacey. BSD Unix C Net Consultancy, Munich/Muenchen http://berklix.com Mail Ascii, not HTML. Ihr Rauch = mein allergischer Kopfschmerz. From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 13:47:31 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B97DB16A403 for ; Thu, 14 Sep 2006 13:47:31 +0000 (UTC) (envelope-from regnauld@catpipe.net) Received: from moof.catpipe.net (moof.catpipe.net [195.249.214.130]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0247243D5D for ; Thu, 14 Sep 2006 13:47:30 +0000 (GMT) (envelope-from regnauld@catpipe.net) Received: from localhost (moof.catpipe.net [195.249.214.130]) by localhost.catpipe.net (Postfix) with ESMTP id D7E346340BA; Thu, 14 Sep 2006 15:47:28 +0200 (CEST) Received: from moof.catpipe.net ([195.249.214.130]) by localhost (moof.catpipe.net [195.249.214.130]) (amavisd-new, port 10024) with ESMTP id 07293-06; Thu, 14 Sep 2006 15:47:28 +0200 (CEST) Received: from vinyl.catpipe.net (vinyl.catpipe.net [195.249.214.189]) by moof.catpipe.net (Postfix) with ESMTP id DB02C633B50; Thu, 14 Sep 2006 15:47:27 +0200 (CEST) Received: by vinyl.catpipe.net (Postfix, from userid 1006) id 06E6E78C31; Thu, 14 Sep 2006 15:46:12 +0200 (CEST) Date: Thu, 14 Sep 2006 15:46:12 +0200 From: Phil Regnauld To: Willem Jan Withagen Message-ID: <20060914134611.GW76403@catpipe.net> References: <4509592A.3040602@digiware.nl> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <4509592A.3040602@digiware.nl> X-Operating-System: FreeBSD 6.1-PRERELEASE i386 Organization: catpipe Systems ApS User-Agent: Mutt/1.5.11 X-Virus-Scanned: amavisd-new at catpipe.net Cc: freebsd-net@freebsd.org Subject: Re: blocking a string in a packet using ipfw X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 13:47:31 -0000 Willem Jan Withagen (wjw) writes: > > Now I'm pretty shure that ipfw does not stretch indefinitely to contain > perhaps something like 100.000 ip-numbers (would be a nice test. :) ) Actually, it should. > So I'd > like to see if there is something to do with divert and some matching on a > string in the packet to drop those packets. That will be quite expensive. Ideally ipfw/pf should allow for inspecting the contents of a packet (offset,value,[offset,value]) without leaving kernel space. > That would prevent me from having humongous set of rules in ipfw. > > Or any other suggestion that would make sense. Using pf with a table, and in ipfw as well, you can handle very large lists of IP addresses. From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 14:41:33 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4911016A47B for ; Thu, 14 Sep 2006 14:41:33 +0000 (UTC) (envelope-from gpalmer@freebsd.org) Received: from noop.in-addr.com (noop.in-addr.com [208.58.23.51]) by mx1.FreeBSD.org (Postfix) with ESMTP id 312C843D49 for ; Thu, 14 Sep 2006 14:41:32 +0000 (GMT) (envelope-from gpalmer@freebsd.org) Received: from gjp by noop.in-addr.com with local (Exim 4.54 (FreeBSD)) id 1GNsPC-000PXW-S4; Thu, 14 Sep 2006 10:41:30 -0400 Date: Thu, 14 Sep 2006 10:41:30 -0400 From: Gary Palmer To: Willem Jan Withagen Message-ID: <20060914144130.GB17002@in-addr.com> Mail-Followup-To: Willem Jan Withagen , freebsd-net@freebsd.org References: <4509592A.3040602@digiware.nl> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <4509592A.3040602@digiware.nl> Cc: freebsd-net@freebsd.org Subject: Re: blocking a string in a packet using ipfw X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 14:41:33 -0000 On Thu, Sep 14, 2006 at 03:29:14PM +0200, Willem Jan Withagen wrote: > I received a call from a customer this morning that all of his websites were > no longer on line. So After some resetting and more I turnout that there > was a > serious overload on his server. Over 500 clients connected. (norm is 50) and > they were all trying to get this file 777.gif. (Which is not on any of the > sites). Why not just create a 0 length file 777.gif and let people fetch it? Its probably a lot less work for the server. From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 15:09:35 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3027E16A412 for ; Thu, 14 Sep 2006 15:09:35 +0000 (UTC) (envelope-from barney@databus.com) Received: from mail1.acecape.com (mail1.acecape.com [66.114.74.12]) by mx1.FreeBSD.org (Postfix) with ESMTP id B3A2D43D49 for ; Thu, 14 Sep 2006 15:09:34 +0000 (GMT) (envelope-from barney@databus.com) Received: from pit.databus.com (pool-72-89-128-62.nycmny.fios.verizon.net [72.89.128.62]) (authenticated bits=0) by mail1.acecape.com (8.13.7/8.13.7) with ESMTP id k8EF930u025468 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Thu, 14 Sep 2006 11:09:03 -0400 Received: from pit.databus.com (localhost [127.0.0.1]) by pit.databus.com (8.13.8/8.13.8) with ESMTP id k8EF92Kf023779; Thu, 14 Sep 2006 11:09:02 -0400 (EDT) (envelope-from barney@pit.databus.com) Received: (from barney@localhost) by pit.databus.com (8.13.8/8.13.8/Submit) id k8EF92PZ023778; Thu, 14 Sep 2006 11:09:02 -0400 (EDT) (envelope-from barney) Date: Thu, 14 Sep 2006 11:09:02 -0400 From: Barney Wolff To: Phil Regnauld Message-ID: <20060914150902.GA17230@pit.databus.com> References: <4509592A.3040602@digiware.nl> <20060914134611.GW76403@catpipe.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20060914134611.GW76403@catpipe.net> User-Agent: Mutt/1.5.11 X-Scanned-By: MIMEDefang 2.56 on 72.89.128.62 Cc: freebsd-net@freebsd.org, Willem Jan Withagen Subject: Re: blocking a string in a packet using ipfw X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 15:09:35 -0000 On Thu, Sep 14, 2006 at 03:46:12PM +0200, Phil Regnauld wrote: > Willem Jan Withagen (wjw) writes: > > > > Now I'm pretty shure that ipfw does not stretch indefinitely to contain > > perhaps something like 100.000 ip-numbers (would be a nice test. :) ) > > Actually, it should. I have over 600000 addresses in an ipfw table with no observable trouble. But that rule is triggered only about 10000 times a day (part of a spam blocker). -- Barney Wolff I never met a computer I didn't like. From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 15:12:59 2006 Return-Path: X-Original-To: freebsd-net@FreeBSD.ORG Delivered-To: freebsd-net@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9F66916A407; Thu, 14 Sep 2006 15:12:59 +0000 (UTC) (envelope-from olli@lurza.secnetix.de) Received: from lurza.secnetix.de (lurza.secnetix.de [83.120.8.8]) by mx1.FreeBSD.org (Postfix) with ESMTP id D57DD43D45; Thu, 14 Sep 2006 15:12:58 +0000 (GMT) (envelope-from olli@lurza.secnetix.de) Received: from lurza.secnetix.de (bmtuhk@localhost [127.0.0.1]) by lurza.secnetix.de (8.13.4/8.13.4) with ESMTP id k8EFCl96053686; Thu, 14 Sep 2006 17:12:52 +0200 (CEST) (envelope-from oliver.fromme@secnetix.de) Received: (from olli@localhost) by lurza.secnetix.de (8.13.4/8.13.1/Submit) id k8EFClt9053685; Thu, 14 Sep 2006 17:12:47 +0200 (CEST) (envelope-from olli) Date: Thu, 14 Sep 2006 17:12:47 +0200 (CEST) Message-Id: <200609141512.k8EFClt9053685@lurza.secnetix.de> From: Oliver Fromme To: freebsd-net@FreeBSD.ORG, wjw@digiware.nl, gpalmer@FreeBSD.ORG In-Reply-To: <20060914144130.GB17002@in-addr.com> X-Newsgroups: list.freebsd-net User-Agent: tin/1.8.0-20051224 ("Ronay") (UNIX) (FreeBSD/4.11-STABLE (i386)) X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-2.1.2 (lurza.secnetix.de [127.0.0.1]); Thu, 14 Sep 2006 17:12:52 +0200 (CEST) Cc: Subject: Re: blocking a string in a packet using ipfw X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: freebsd-net@FreeBSD.ORG, wjw@digiware.nl, gpalmer@FreeBSD.ORG List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 15:12:59 -0000 Gary Palmer wrote: > Willem Jan Withagen wrote: > > I received a call from a customer this morning that all of his websites were > > no longer on line. So After some resetting and more I turnout that there > > was a > > serious overload on his server. Over 500 clients connected. (norm is 50) and > > they were all trying to get this file 777.gif. (Which is not on any of the > > sites). > > Why not just create a 0 length file 777.gif and let people fetch it? > Its probably a lot less work for the server. I don't think so. The overhead in Apache for serving a file is quite big. On the other hand, IPFW tables store IP addresses in a radix tree, which should be quite efficient even for 100,000 entries. By the way: If incoming bandwidth is a concern, it is probably better to use "reset" instead of "deny" in the IPFW rule. If you use deny, the packets are simply dropped, causing the clients to retransmit their SYN packets several times, while "reset" (which here means "connection refused") causes no TCP retransmits. Best regards Oliver -- Oliver Fromme, secnetix GmbH & Co. KG, Marktplatz 29, 85567 Grafing Dienstleistungen mit Schwerpunkt FreeBSD: http://www.secnetix.de/bsd Any opinions expressed in this message may be personal to the author and may not necessarily reflect the opinions of secnetix in any way. "That's what I love about GUIs: They make simple tasks easier, and complex tasks impossible." -- John William Chambless From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 15:13:53 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 6BDA316A492 for ; Thu, 14 Sep 2006 15:13:53 +0000 (UTC) (envelope-from wjw@withagen.nl) Received: from freebee.digiware.nl (www.tegenbosch28.nl [217.21.251.97]) by mx1.FreeBSD.org (Postfix) with ESMTP id C980E43D46 for ; Thu, 14 Sep 2006 15:13:52 +0000 (GMT) (envelope-from wjw@withagen.nl) Received: from [212.61.27.67] (opteron.digiware.nl [212.61.27.67]) by freebee.digiware.nl (Postfix) with ESMTP id 9771C2AAAA for ; Thu, 14 Sep 2006 17:13:50 +0200 (CEST) Message-ID: <450971EF.3020209@withagen.nl> Date: Thu, 14 Sep 2006 17:14:55 +0200 From: Willem Jan Withagen User-Agent: Thunderbird 1.5.0.5 (Windows/20060719) MIME-Version: 1.0 To: freebsd-net@freebsd.org References: <4509592A.3040602@digiware.nl> <20060914144130.GB17002@in-addr.com> In-Reply-To: <20060914144130.GB17002@in-addr.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: blocking a string in a packet using ipfw X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 15:13:53 -0000 Gary Palmer wrote: > On Thu, Sep 14, 2006 at 03:29:14PM +0200, Willem Jan Withagen wrote: >> I received a call from a customer this morning that all of his websites were >> no longer on line. So After some resetting and more I turnout that there >> was a >> serious overload on his server. Over 500 clients connected. (norm is 50) and >> they were all trying to get this file 777.gif. (Which is not on any of the >> sites). > > Why not just create a 0 length file 777.gif and let people fetch it? Its > probably a lot less work for the server. I had several suggestions this direction. And it does help a little. The math is however against me. I had over 50 request/sec for this file. Now if the virus uses anything which leaves the connection open for regular timeout, and the server uses keepAlive. Then you are running into trouble because you soon run out of server slots. And even if you were to up with the standard apache settings for 15 secs, you have to set it at 750 serverslots. A serverslot takes about 13Mb virtual memory of which is about 8M resident. The machine has 512mb real memory, so after about 60 servers the machine starts to swap. Which works until about 100-150 serverslots (empirical prove). Now imagine what 500 would do, which is the initial setting for the number of MaxServers. The machine comes to a grinding halt. Which was what we also painfully found out. So solutions here are: either a very short keepalive timeout or no keepalive at all. Note that since this morning over 45.000 infected systems tried to access this server. --WjW From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 15:20:06 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E02E016A412 for ; Thu, 14 Sep 2006 15:20:06 +0000 (UTC) (envelope-from wjw@withagen.nl) Received: from freebee.digiware.nl (www.tegenbosch28.nl [217.21.251.97]) by mx1.FreeBSD.org (Postfix) with ESMTP id E119843D6B for ; Thu, 14 Sep 2006 15:20:04 +0000 (GMT) (envelope-from wjw@withagen.nl) Received: from [212.61.27.67] (opteron.digiware.nl [212.61.27.67]) by freebee.digiware.nl (Postfix) with ESMTP id D308C2AAA2; Thu, 14 Sep 2006 17:20:03 +0200 (CEST) Message-ID: <45097364.1090905@withagen.nl> Date: Thu, 14 Sep 2006 17:21:08 +0200 From: Willem Jan Withagen User-Agent: Thunderbird 1.5.0.5 (Windows/20060719) MIME-Version: 1.0 To: Barney Wolff References: <4509592A.3040602@digiware.nl> <20060914134611.GW76403@catpipe.net> <20060914150902.GA17230@pit.databus.com> In-Reply-To: <20060914150902.GA17230@pit.databus.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: Willem Jan Withagen , freebsd-net@freebsd.org Subject: Re: blocking a string in a packet using ipfw X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 15:20:07 -0000 Barney Wolff wrote: > On Thu, Sep 14, 2006 at 03:46:12PM +0200, Phil Regnauld wrote: >> Willem Jan Withagen (wjw) writes: >>> Now I'm pretty shure that ipfw does not stretch indefinitely to contain >>> perhaps something like 100.000 ip-numbers (would be a nice test. :) ) >> Actually, it should. > > I have over 600000 addresses in an ipfw table with no observable trouble. > But that rule is triggered only about 10000 times a day (part of a spam > blocker). Well actually it does work. So once again, I'm impressed by FreeBSD. What no longer really works is 'ipfw l' since that takes longer than I care to wait for it. Forgot to mention: 4.7-PRERELEASE :( It's a box that I "inherited", and is supposed to go away/upgrade for already too long. It is so old, I only dear fix the most essential security, in fear of breaking or trashing the system. This however helps as a stick to get things moving. --WjW From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 15:21:26 2006 Return-Path: X-Original-To: freebsd-net@FreeBSD.org Delivered-To: freebsd-net@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0635D16A4AB for ; Thu, 14 Sep 2006 15:21:26 +0000 (UTC) (envelope-from andre@freebsd.org) Received: from c00l3r.networx.ch (c00l3r.networx.ch [62.48.2.2]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6C34B43D8F for ; Thu, 14 Sep 2006 15:21:07 +0000 (GMT) (envelope-from andre@freebsd.org) Received: (qmail 34778 invoked from network); 14 Sep 2006 15:04:39 -0000 Received: from c00l3r.networx.ch (HELO [127.0.0.1]) ([62.48.2.2]) (envelope-sender ) by c00l3r.networx.ch (qmail-ldap-1.03) with SMTP for ; 14 Sep 2006 15:04:39 -0000 Message-ID: <45097364.9090603@freebsd.org> Date: Thu, 14 Sep 2006 17:21:08 +0200 From: Andre Oppermann User-Agent: Thunderbird 1.5.0.5 (Windows/20060719) MIME-Version: 1.0 To: Ruslan Ermilov References: <44FAE332.4010209@freebsd.org> <20060913190241.S13138@is.park.rambler.ru> <45085472.5040903@freebsd.org> <20060913230748.P14337@is.park.rambler.ru> <45086AAF.108@freebsd.org> <20060914093006.GE26261@rambler-co.ru> In-Reply-To: <20060914093006.GE26261@rambler-co.ru> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-net@FreeBSD.org, Igor Sysoev , silby@FreeBSD.org Subject: Re: Improved TCP syncookie implementation X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 15:21:26 -0000 Ruslan Ermilov wrote: > On Wed, Sep 13, 2006 at 10:31:43PM +0200, Andre Oppermann wrote: >> Igor Sysoev wrote: >>> Well, suppose protocol similar to SSH or SMTP: >>> >>> 1) the client calls connect(), it sends SYN; >>> 2) the server receives SYN and sends SYN/ACK with cookie; >>> 3) the client receives SYN/ACK and sends ACK; >>> 4) the client returns successfully from connect() and calls read(); >>> 5) the ACK is lost; >>> 6) the server does not about this connection, so application can not >>> accept() it, and it can not send() HELO message. >>> 7) the client gets ETIMEDOUT from read(). >>> >>> Where in this sequence client may retransmit its ACK ? >> Never. You're correct. There is no data that would cause a retransmit >> if the application is waiting for a server prompt first. I shouldn't >> write wrong explanations when I'm tired, hungry and in between two tasks. ;) >> >> This problem is the reason why we don't switch entirely to syncookies >> and still keep syncache as is. >> > Perhaps it would be a good idea to remove net.inet.tcp.syncookies_only > then? In any case, please don't forget to update the syncache(4) manpage > to reflect your changes, and if you decide not to remove this sysctl, > please add a warning of its potential to break a protocol. This is a sysctl which is not enabled by default. TCP doesn't fall over if someone enables it. There is one case where a connection gets 'stuck' if the one ACK gets lost in the network. The advantage of doing syncookies only is that no memory is consumed for any amount of connection attempts. This may be of interest to certain uses like very high volume static content only servers (ie. picture servers). -- Andre From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 15:23:49 2006 Return-Path: X-Original-To: freebsd-net@FreeBSD.org Delivered-To: freebsd-net@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 87ABD16A407 for ; Thu, 14 Sep 2006 15:23:49 +0000 (UTC) (envelope-from andre@freebsd.org) Received: from c00l3r.networx.ch (c00l3r.networx.ch [62.48.2.2]) by mx1.FreeBSD.org (Postfix) with ESMTP id B80FF43D78 for ; Thu, 14 Sep 2006 15:23:47 +0000 (GMT) (envelope-from andre@freebsd.org) Received: (qmail 34803 invoked from network); 14 Sep 2006 15:07:19 -0000 Received: from c00l3r.networx.ch (HELO [127.0.0.1]) ([62.48.2.2]) (envelope-sender ) by c00l3r.networx.ch (qmail-ldap-1.03) with SMTP for ; 14 Sep 2006 15:07:19 -0000 Message-ID: <45097405.80304@freebsd.org> Date: Thu, 14 Sep 2006 17:23:49 +0200 From: Andre Oppermann User-Agent: Thunderbird 1.5.0.5 (Windows/20060719) MIME-Version: 1.0 To: Igor Sysoev References: <44FAE332.4010209@freebsd.org> <20060913190241.S13138@is.park.rambler.ru> <45085472.5040903@freebsd.org> <20060913230748.P14337@is.park.rambler.ru> <45086AAF.108@freebsd.org> <20060914093006.GE26261@rambler-co.ru> <20060914143059.T16483@is.park.rambler.ru> In-Reply-To: <20060914143059.T16483@is.park.rambler.ru> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-net@FreeBSD.org, silby@FreeBSD.org, Ruslan Ermilov Subject: Re: Improved TCP syncookie implementation X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 15:23:49 -0000 Igor Sysoev wrote: > On Thu, 14 Sep 2006, Ruslan Ermilov wrote: > >> On Wed, Sep 13, 2006 at 10:31:43PM +0200, Andre Oppermann wrote: >>> Igor Sysoev wrote: >>>> Well, suppose protocol similar to SSH or SMTP: >>>> >>>> 1) the client calls connect(), it sends SYN; >>>> 2) the server receives SYN and sends SYN/ACK with cookie; >>>> 3) the client receives SYN/ACK and sends ACK; >>>> 4) the client returns successfully from connect() and calls read(); >>>> 5) the ACK is lost; >>>> 6) the server does not about this connection, so application can not >>>> accept() it, and it can not send() HELO message. >>>> 7) the client gets ETIMEDOUT from read(). >>>> >>>> Where in this sequence client may retransmit its ACK ? >>> >>> Never. You're correct. There is no data that would cause a retransmit >>> if the application is waiting for a server prompt first. I shouldn't >>> write wrong explanations when I'm tired, hungry and in between two >>> tasks. ;) >>> >>> This problem is the reason why we don't switch entirely to syncookies >>> and still keep syncache as is. >>> >> Perhaps it would be a good idea to remove net.inet.tcp.syncookies_only >> then? In any case, please don't forget to update the syncache(4) manpage >> to reflect your changes, and if you decide not to remove this sysctl, >> please add a warning of its potential to break a protocol. > > I think that setting syncookies only not globally, but on per port basis, > say, for HTTP would be helpfull. Setting it for other protocols, e.g, SSH, > rsync, SMTP, IMAP, POP3 may break them. Syncookies are optional anyway and syncache is still there. I'm not going to over-engineer this whole thing. The primary purpose of syn- cookies is to be able to handle a large number of (potentially bogus) connection attempts. With syncookies you are able to serve more legitimate connections out of the bogus ones than with syncache only. -- Andre From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 15:25:15 2006 Return-Path: X-Original-To: freebsd-net@FreeBSD.ORG Delivered-To: freebsd-net@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 28C8716A47B; Thu, 14 Sep 2006 15:25:15 +0000 (UTC) (envelope-from wjw@withagen.nl) Received: from freebee.digiware.nl (www.tegenbosch28.nl [217.21.251.97]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7C06843D55; Thu, 14 Sep 2006 15:25:07 +0000 (GMT) (envelope-from wjw@withagen.nl) Received: from [212.61.27.67] (opteron.digiware.nl [212.61.27.67]) by freebee.digiware.nl (Postfix) with ESMTP id 2B3D42AAA0; Thu, 14 Sep 2006 17:25:06 +0200 (CEST) Message-ID: <45097493.8080108@withagen.nl> Date: Thu, 14 Sep 2006 17:26:11 +0200 From: Willem Jan Withagen User-Agent: Thunderbird 1.5.0.5 (Windows/20060719) MIME-Version: 1.0 To: freebsd-net@FreeBSD.ORG, wjw@digiware.nl, gpalmer@FreeBSD.ORG References: <200609141512.k8EFClt9053685@lurza.secnetix.de> In-Reply-To: <200609141512.k8EFClt9053685@lurza.secnetix.de> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: Subject: Re: blocking a string in a packet using ipfw X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 15:25:15 -0000 Oliver Fromme wrote: > Gary Palmer wrote: > > Willem Jan Withagen wrote: > > > I received a call from a customer this morning that all of his websites were > > > no longer on line. So After some resetting and more I turnout that there > > > was a > > > serious overload on his server. Over 500 clients connected. (norm is 50) and > > > they were all trying to get this file 777.gif. (Which is not on any of the > > > sites). > > > > Why not just create a 0 length file 777.gif and let people fetch it? > > Its probably a lot less work for the server. > > I don't think so. The overhead in Apache for serving > a file is quite big. On the other hand, IPFW tables > store IP addresses in a radix tree, which should be > quite efficient even for 100,000 entries. I tried addressing that in a previous message. And I concur with you. > > By the way: If incoming bandwidth is a concern, it is > probably better to use "reset" instead of "deny" in the > IPFW rule. If you use deny, the packets are simply > dropped, causing the clients to retransmit their SYN > packets several times, while "reset" (which here means > "connection refused") causes no TCP retransmits. Reason for not doing so, is that bandwidth is not really an issue here. 2*155mbit connections to both Amsterdam and Frankfurt. :) So people with viruses banging their heads against my door, and getting stalled because of timeouts, is IMHO a nice way of slowing the harassment down. I would even consider writing something that returns 1 char per 30 secs for like forever, if it not only made me run out of serverslots/sockets/other resources.... --WjW From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 15:34:34 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E77DE16A403 for ; Thu, 14 Sep 2006 15:34:34 +0000 (UTC) (envelope-from gpalmer@freebsd.org) Received: from noop.in-addr.com (noop.in-addr.com [208.58.23.51]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9CEE343D46 for ; Thu, 14 Sep 2006 15:34:34 +0000 (GMT) (envelope-from gpalmer@freebsd.org) Received: from gjp by noop.in-addr.com with local (Exim 4.54 (FreeBSD)) id 1GNtEY-000Pf5-3G for freebsd-net@freebsd.org; Thu, 14 Sep 2006 11:34:34 -0400 Date: Thu, 14 Sep 2006 11:34:34 -0400 From: Gary Palmer To: freebsd-net@freebsd.org Message-ID: <20060914153434.GC17002@in-addr.com> Mail-Followup-To: freebsd-net@freebsd.org References: <4509592A.3040602@digiware.nl> <20060914144130.GB17002@in-addr.com> <450971EF.3020209@withagen.nl> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <450971EF.3020209@withagen.nl> Subject: Re: blocking a string in a packet using ipfw X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 15:34:35 -0000 On Thu, Sep 14, 2006 at 05:14:55PM +0200, Willem Jan Withagen wrote: > I had several suggestions this direction. And it does help a little. > The math is however against me. > > I had over 50 request/sec for this file. Now if the virus uses anything > which leaves the connection open for regular timeout, and the server uses > keepAlive. Then you are running into trouble because you soon run out of > server slots. And even if you were to up with the standard apache settings > for 15 secs, you have to set it at 750 serverslots. > > A serverslot takes about 13Mb virtual memory of which is about 8M resident. > The machine has 512mb real memory, so after about 60 servers the machine > starts to swap. Which works until about 100-150 serverslots (empirical > prove). > Now imagine what 500 would do, which is the initial setting for the number > of MaxServers. The machine comes to a grinding halt. Which was what we also > painfully found out. > > So solutions here are: > either a very short keepalive timeout > or no keepalive at all. > > Note that since this morning over 45.000 infected systems tried to access > this server. Configure Apache to issue a HTTP 302 redirect to some big file on microsoft.com You might even be able to get them to download the Windows Defender thing to clean up their systems You might still have to turn off keepalives :-( From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 16:13:15 2006 Return-Path: X-Original-To: freebsd-net@FreeBSD.org Delivered-To: freebsd-net@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D3A4016A417 for ; Thu, 14 Sep 2006 16:13:15 +0000 (UTC) (envelope-from jmg@hydrogen.funkthat.com) Received: from hydrogen.funkthat.com (gate.funkthat.com [69.17.45.168]) by mx1.FreeBSD.org (Postfix) with ESMTP id E760B43D67 for ; Thu, 14 Sep 2006 16:13:10 +0000 (GMT) (envelope-from jmg@hydrogen.funkthat.com) Received: from hydrogen.funkthat.com (sbjjw7nbt3ty4qbb@localhost.funkthat.com [127.0.0.1]) by hydrogen.funkthat.com (8.13.6/8.13.3) with ESMTP id k8EGDAnI001130; Thu, 14 Sep 2006 09:13:10 -0700 (PDT) (envelope-from jmg@hydrogen.funkthat.com) Received: (from jmg@localhost) by hydrogen.funkthat.com (8.13.6/8.13.3/Submit) id k8EGD9Du001129; Thu, 14 Sep 2006 09:13:09 -0700 (PDT) (envelope-from jmg) Date: Thu, 14 Sep 2006 09:13:09 -0700 From: John-Mark Gurney To: sivakumar.subramani@wipro.com Message-ID: <20060914161309.GC9421@funkthat.com> Mail-Followup-To: sivakumar.subramani@wipro.com, freebsd-net@FreeBSD.org References: <956E7FA2615F3B4595FC5F22870A7221067206@blr-m3-msg.wipro.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <956E7FA2615F3B4595FC5F22870A7221067206@blr-m3-msg.wipro.com> User-Agent: Mutt/1.4.2.1i X-Operating-System: FreeBSD 5.4-RELEASE-p6 i386 X-PGP-Fingerprint: B7 EC EF F8 AE ED A7 31 96 7A 22 B3 D8 56 36 F4 X-Files: The truth is out there X-URL: http://resnet.uoregon.edu/~gurney_j/ X-Resume: http://resnet.uoregon.edu/~gurney_j/resume.html Cc: freebsd-net@FreeBSD.org Subject: Re: Reading a configuration file from a driver code during intialization. X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: John-Mark Gurney List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 16:13:15 -0000 sivakumar.subramani@wipro.com wrote this message on Thu, Sep 14, 2006 at 12:16 +0530: > Is there is any other solution to the above problem? > > > > Actually I am looking for some thing similar to Module loadable > parameters in the Linux Device Driver. look at kenv... It lets you set arbitrary values and access them in the kernel... you can use the TUNABLE_* macros provided by sys/kernel.h to make accessing them easier... If the variables need to change at run time, look at SYSCTL... -- John-Mark Gurney Voice: +1 415 225 5579 "All that I will do, has been done, All that I have, has not." From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 17:50:55 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 16AD716A415; Thu, 14 Sep 2006 17:50:55 +0000 (UTC) (envelope-from marcelo@registro.br) Received: from clone.registro.br (clone.registro.br [200.160.2.4]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7A22A43D7E; Thu, 14 Sep 2006 17:50:51 +0000 (GMT) (envelope-from marcelo@registro.br) Received: by clone.registro.br (Postfix, from userid 1014) id F35E62A576; Thu, 14 Sep 2006 14:50:49 -0300 (BRT) Date: Thu, 14 Sep 2006 14:50:49 -0300 From: Marcelo Gardini do Amaral To: Robert Watson Message-ID: <20060914175049.GH49126@registro.br> References: <2a41acea0608301145j7bbed961j33ce903a27d8963d@mail.gmail.com> <20060904130827.GE12975@registro.br> <20060911195521.GD63300@registro.br> <20060913182019.R50147@fledge.watson.org> <20060913182457.W50147@fledge.watson.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20060913182457.W50147@fledge.watson.org> User-Agent: Mutt/1.4.2.1i Cc: freebsd-net@freebsd.org, freebsd-stable@freebsd.org Subject: Re: DNS query performance X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 17:50:55 -0000 > >Are you able to boot a 7.x kernel on this box? An as yet un-MFC'd > >optimization to the UDP send path is present in the 7.x kernel, suggested > >by ISC, which significantly improves threaded BIND9 performance. I've not > >benchmarked unthreaded BIND9 with the change. If you want to test > >specifically the before/after case for that change, you can find the > >reference to sosend_dgram in src/sys/netinet/udp_usrreq.c and swap it to > >sosend, which restores the old behavior. I booted 7.x kernel UP and SMP on my blade. When I swaped both of them to sosend I got a panic to any DNS query: # dig @localhost test1.foo.bar panic: sosend: protocol calls sosend KDB: enter: panic [thread pid 671 tid 100053 ] Stopped at kdb_enter+0x2b: nop db> db> bt Tracing pid 671 tid 100053 td 0xc4a52bd0 kdb_enter(c091d7b6) at kdb_enter+0x2b panic(c0925143,e502dc10,c06e6511,c4f9c14c,c4a66370,...) at panic+0xbb sosend(c4f9c14c,c4a66370,e502dbe4,0,0,0,c4a52bd0) at sosend+0x1f kern_sendit(c4a52bd0,15,e502dc5c,0,0,0) at kern_sendit+0x101 sendit(c4a52bd0,15,e502dc5c,0,c4a66150,...) at sendit+0x87 sendmsg(c4a52bd0,e502dd04) at sendmsg+0x53 syscall(3b,3b,3b,1,0,...) at syscall+0x256 Xint0x80_syscall() at Xint0x80_syscall+0x1f --- syscall (28, FreeBSD ELF32, sendmsg), eip = 0x28353d6f, esp = 0xbfbfe8ec, eb p = 0xbfbfea68 --- db> c Uptime: 1m44s Physical memory: 2039 MB Dumping 99 MB: 84 68 52 36 20 4 Dump complete Automatic reboot in 15 seconds - press a key on the console to abort > The other common optimization advice that you may already have received is > to check which time counter FreeBSD has selected. Right now, 6.x/7.x err > on the side of accurate over fast. There's been quite a bit of debate > about this approach, and it's useful to investigate the issue. You can > view and set the current choice by looking at the sysctl > kern.timecounter.hardware, and you can see the choices on your hardware by > looking at kern.timecounter.choice. Typically, TSC is the fastest, but may > suffer from drift as the CPU changes speed (as a result of temperature, > power saving, etc). Set it to TSC if it's not already TSC, and see what > the effect is. As many event libraries read time stamps frequently to set > up sleeping in user space, it can have a substantial performance impact. With the 7.x kernel and no changes in src/sys/netinet/udp_usrreq.c I tried different timecounters and I couldn't see any performance difference. Here we see the results for bind 9.3.2, same zone file and queries: Kernel UP Timecounter queries/s ----------- --------- ACPI-safe 16200 TSC 16584 i8254 16319 Kernel SMP Timecounter queries/s ----------- --------- ACPI-safe 15323 TSC 15930 i8254 14155 Any other tip? -- Att., Marcelo Gardini From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 21:04:26 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3CB5516A417 for ; Thu, 14 Sep 2006 21:04:26 +0000 (UTC) (envelope-from prvs=julian=4054a8e64@elischer.org) Received: from a50.ironport.com (a50.ironport.com [63.251.108.112]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0D23543D55 for ; Thu, 14 Sep 2006 21:04:23 +0000 (GMT) (envelope-from prvs=julian=4054a8e64@elischer.org) Received: from unknown (HELO [192.168.2.6]) ([10.251.60.95]) by a50.ironport.com with ESMTP; 14 Sep 2006 14:04:22 -0700 Message-ID: <4509C3D7.4060302@elischer.org> Date: Thu, 14 Sep 2006 14:04:23 -0700 From: Julian Elischer User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.13) Gecko/20060414 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Willem Jan Withagen References: <4509592A.3040602@digiware.nl> In-Reply-To: <4509592A.3040602@digiware.nl> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-net@freebsd.org Subject: Re: blocking a string in a packet using ipfw X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 21:04:26 -0000 Willem Jan Withagen wrote: > [ I guess I haven't been paying too much attention during ipwf class :( > And I got the suggestion to try FreeBSD-net@ instead of security. But > I'm not subscribed to this list, so please Cc: me. > ] > > Hi, > > perhaps somebody could give some pointers. > > I received a call from a customer this morning that all of his > websites were > no longer on line. So After some resetting and more I turnout that > there was a > serious overload on his server. Over 500 clients connected. (norm is > 50) and > they were all trying to get this file 777.gif. (Which is not on any of > the sites). > > After reducing the max servers to a 100, the sites are now more or > less up. > Then I created a swatch script to actually block the offenders thru ipwl. > (Which was already used to do most of the protection). > It is already a solution, because they keep trying it multiple times. > > > But it turns out that the generic name of the server is in a new virus > on a > list of server to get a file from. And it's on high place in that list. > So I can confirm that there are at least 35.000 pc's infected with this > Bagle.FY virus. And these are now all in the block list in IPFW. I hope you are using an ipfw table to do this.. > > I contacted the maintainer for the generic FQDN name of the server to > reset > the IP-number for that name to 127.0.0.1 but that'll take another 24 > hours to > propagate thru the whole of the internet. > > Now I'm pretty shure that ipfw does not stretch indefinitely to contain > perhaps something like 100.000 ip-numbers (would be a nice test. :) ) > So I'd > like to see if there is something to do with divert and some matching > on a > string in the packet to drop those packets. > That would prevent me from having humongous set of rules in ipfw. use ipfw tables one table lookup would do the job that's one rule > > Or any other suggestion that would make sense. > > Thanx, > --WjW > > > > > _______________________________________________ > freebsd-net@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-net > To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org" From owner-freebsd-net@FreeBSD.ORG Thu Sep 14 21:08:13 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id BE59B16A403 for ; Thu, 14 Sep 2006 21:08:13 +0000 (UTC) (envelope-from prvs=julian=4054a8e64@elischer.org) Received: from a50.ironport.com (a50.ironport.com [63.251.108.112]) by mx1.FreeBSD.org (Postfix) with ESMTP id 758B643D46 for ; Thu, 14 Sep 2006 21:08:13 +0000 (GMT) (envelope-from prvs=julian=4054a8e64@elischer.org) Received: from unknown (HELO [192.168.2.6]) ([10.251.60.95]) by a50.ironport.com with ESMTP; 14 Sep 2006 14:08:12 -0700 Message-ID: <4509C4BC.3090000@elischer.org> Date: Thu, 14 Sep 2006 14:08:12 -0700 From: Julian Elischer User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.13) Gecko/20060414 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Willem Jan Withagen References: <4509592A.3040602@digiware.nl> <20060914134611.GW76403@catpipe.net> <20060914150902.GA17230@pit.databus.com> <45097364.1090905@withagen.nl> In-Reply-To: <45097364.1090905@withagen.nl> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: Barney Wolff , freebsd-net@freebsd.org, Willem Jan Withagen Subject: Re: blocking a string in a packet using ipfw X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Sep 2006 21:08:13 -0000 Willem Jan Withagen wrote: > Barney Wolff wrote: > >> On Thu, Sep 14, 2006 at 03:46:12PM +0200, Phil Regnauld wrote: >> >>> Willem Jan Withagen (wjw) writes: >>> >>>> Now I'm pretty shure that ipfw does not stretch indefinitely to >>>> contain >>>> perhaps something like 100.000 ip-numbers (would be a nice test. :) ) >>> >>> Actually, it should. >> >> >> I have over 600000 addresses in an ipfw table with no observable >> trouble. >> But that rule is triggered only about 10000 times a day (part of a spam >> blocker). > > > Well actually it does work. So once again, I'm impressed by FreeBSD. > What no longer really works is 'ipfw l' since that takes longer than I > care to wait for it. > > Forgot to mention: 4.7-PRERELEASE :( ugh... no tables and 45000 lines will be bad. load an old PC with 6.2 and seet it up as a bridge with 2 interfaces. and use ipfw table to filter on the bridge > It's a box that I "inherited", and is supposed to go away/upgrade for > already too long. > It is so old, I only dear fix the most essential security, in fear of > breaking or trashing the system. This however helps as a stick to get > things moving. > > --WjW > > _______________________________________________ > freebsd-net@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-net > To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org" From owner-freebsd-net@FreeBSD.ORG Fri Sep 15 00:02:42 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4CA6C16A40F for ; Fri, 15 Sep 2006 00:02:42 +0000 (UTC) (envelope-from kamanashisroy@gmail.com) Received: from py-out-1112.google.com (py-out-1112.google.com [64.233.166.180]) by mx1.FreeBSD.org (Postfix) with ESMTP id BE65743D45 for ; Fri, 15 Sep 2006 00:02:40 +0000 (GMT) (envelope-from kamanashisroy@gmail.com) Received: by py-out-1112.google.com with SMTP id o67so3514378pye for ; Thu, 14 Sep 2006 17:02:40 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:mime-version:content-type; b=LBMMuWqv43Zi3rAZBJ87JHKNaiRBQm3GS1KotcGXPbXPwKQnQk95qDu9CvCCgfGb/P8v+33S8BBzZ1/GluJvfoXgQS+T2DVJhMfo3VK8zS83K1DOBC7GLahG6g95aCE+uxpMJp/IpGpEkPwLjtlPlTXTCRn0/xICg0MFaQuPNdw= Received: by 10.35.78.13 with SMTP id f13mr16707900pyl; Thu, 14 Sep 2006 17:02:39 -0700 (PDT) Received: by 10.35.67.9 with HTTP; Thu, 14 Sep 2006 17:02:38 -0700 (PDT) Message-ID: Date: Fri, 15 Sep 2006 06:02:38 +0600 From: "Kamanashis Roy Shuva" To: freebsd-net@freebsd.org MIME-Version: 1.0 X-Mailman-Approved-At: Fri, 15 Sep 2006 01:16:09 +0000 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Subject: Where is IPSec NAT-T support? X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2006 00:02:42 -0000 Hi, You have done a great jop. And I find this useful today. Problem is things are not working fine. I have compiled freebsd with the patch MD5 (freebsd6-natt.diff) = 81d535363981b5e84be77cbf26918ccc for natt support. But I have problems both before and after compilation. Note, as I tried uname I find ------------------------------------- localhost# uname -v FreeBSD 6.0-RELEASE #7: Thu Sep 14 19:28:39 GMT 2006 tapan@localhost :/usr/obj/usr/src/sys/IPSEC ------------------------------------- Again I have the following line in my conf file for kernel ------------------------------------- options IPSEC options IPSEC_ESP options IPSEC_DEBUG options IPSEC_NAT_T ------------------------------------- and I have not compiled with fast ipsec support But there were two problems. 1. I cannot compile the ipsec-tools with '--enable-natt=yes'. It checks the presence of natt support and it fals to find that. There in configure file I find a c program -------------------------------------- #define _KERNEL #include #include int main () { static struct sadb_x_nat_t_type ac_aggr; if (ac_aggr.sadb_x_nat_t_type_len) return 0; ; return 0; } -------------------------------------- I has some compilation error as, -------------------------------------- storage size of 'ac_aggr' isn't known -------------------------------------- But the following code compiles fine. -------------------------------------- #define _KERNEL #include #include int main () { static struct sadb_x_nat_t_type *ac_aggr; return 0; } -------------------------------------- 2. the patch failed for src/sys/netkey/key.c and I have tried to do this manually , ------------------------- key.c.orig ------------------ /* $KAME: key.c,v 1.308 2003/09/07 20:35:59 itojun Exp $ */ /*- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD: src/sys/netkey/key.c,v 1.71.2.1 2005/09/03 16:13:05 ume Exp $"); /* * This code is referd to RFC 2367 */ #include "opt_inet.h" #include "opt_inet6.h" #include "opt_ipsec.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef INET6 #include #include #include #endif /* INET6 */ #ifdef INET #include #endif #ifdef INET6 #include #endif /* INET6 */ #include #include #include #include #include #include #ifdef INET6 #include #endif #include #ifdef INET6 #include #endif #ifdef IPSEC_ESP #include #ifdef INET6 #include #endif #endif #include #ifdef INET6 #include #endif #include /* randomness */ #include #include #ifndef satosin #define satosin(s) ((struct sockaddr_in *)s) #endif #define FULLMASK 0xff /* * Note on SA reference counting: * - SAs that are not in DEAD state will have (total external reference + 1) * following value in reference count field. they cannot be freed and are * referenced from SA header. * - SAs that are in DEAD state will have (total external reference) * in reference count field. they are ready to be freed. reference from * SA header will be removed in keydb_delsecasvar(), when the reference count * field hits 0 (= no external reference other than from SA header. */ u_int32_t key_debug_level = 0; static u_int key_spi_trycnt = 1000; static u_int32_t key_spi_minval = 0x100; static u_int32_t key_spi_maxval = 0x0fffffff; /* XXX */ static u_int key_larval_lifetime = 30; /* interval to expire acquiring, 30(s)*/ static int key_blockacq_count = 10; /* counter for blocking SADB_ACQUIRE.*/ static int key_blockacq_lifetime = 20; /* lifetime for blocking SADB_ACQUIRE.*/ static int key_preferred_oldsa = 1; /* preferred old sa rather than new sa.*/ static u_int32_t acq_seq = 0; struct _satailq satailq; /* list of all SAD entry */ struct _sptailq sptailq; /* SPD table + pcb */ static LIST_HEAD(_sptree, secpolicy) sptree[IPSEC_DIR_MAX]; /* SPD table */ static LIST_HEAD(_sahtree, secashead) sahtree; /* SAD */ static LIST_HEAD(_regtree, secreg) regtree[SADB_SATYPE_MAX + 1]; /* registed list */ #define SPIHASHSIZE 128 #define SPIHASH(x) (((x) ^ ((x) >> 16)) % SPIHASHSIZE) static LIST_HEAD(_spihash, secasvar) spihash[SPIHASHSIZE]; #ifndef IPSEC_NONBLOCK_ACQUIRE static LIST_HEAD(_acqtree, secacq) acqtree; /* acquiring list */ #endif static LIST_HEAD(_spacqtree, secspacq) spacqtree; /* SP acquiring list */ struct key_cb key_cb; /* search order for SAs */ static const u_int saorder_state_valid_prefer_old[] = { SADB_SASTATE_DYING, SADB_SASTATE_MATURE, }; static const u_int saorder_state_valid_prefer_new[] = { SADB_SASTATE_MATURE, SADB_SASTATE_DYING, }; static const u_int saorder_state_alive[] = { /* except DEAD */ SADB_SASTATE_MATURE, SADB_SASTATE_DYING, SADB_SASTATE_LARVAL }; static const u_int saorder_state_any[] = { SADB_SASTATE_MATURE, SADB_SASTATE_DYING, SADB_SASTATE_LARVAL, SADB_SASTATE_DEAD }; static const int minsize[] = { sizeof(struct sadb_msg), /* SADB_EXT_RESERVED */ sizeof(struct sadb_sa), /* SADB_EXT_SA */ sizeof(struct sadb_lifetime), /* SADB_EXT_LIFETIME_CURRENT */ sizeof(struct sadb_lifetime), /* SADB_EXT_LIFETIME_HARD */ sizeof(struct sadb_lifetime), /* SADB_EXT_LIFETIME_SOFT */ sizeof(struct sadb_address), /* SADB_EXT_ADDRESS_SRC */ sizeof(struct sadb_address), /* SADB_EXT_ADDRESS_DST */ sizeof(struct sadb_address), /* SADB_EXT_ADDRESS_PROXY */ sizeof(struct sadb_key), /* SADB_EXT_KEY_AUTH */ sizeof(struct sadb_key), /* SADB_EXT_KEY_ENCRYPT */ sizeof(struct sadb_ident), /* SADB_EXT_IDENTITY_SRC */ sizeof(struct sadb_ident), /* SADB_EXT_IDENTITY_DST */ sizeof(struct sadb_sens), /* SADB_EXT_SENSITIVITY */ sizeof(struct sadb_prop), /* SADB_EXT_PROPOSAL */ sizeof(struct sadb_supported), /* SADB_EXT_SUPPORTED_AUTH */ sizeof(struct sadb_supported), /* SADB_EXT_SUPPORTED_ENCRYPT */ sizeof(struct sadb_spirange), /* SADB_EXT_SPIRANGE */ 0, /* SADB_X_EXT_KMPRIVATE */ sizeof(struct sadb_x_policy), /* SADB_X_EXT_POLICY */ sizeof(struct sadb_x_sa2), /* SADB_X_SA2 */ }; static const int maxsize[] = { sizeof(struct sadb_msg), /* SADB_EXT_RESERVED */ sizeof(struct sadb_sa), /* SADB_EXT_SA */ sizeof(struct sadb_lifetime), /* SADB_EXT_LIFETIME_CURRENT */ sizeof(struct sadb_lifetime), /* SADB_EXT_LIFETIME_HARD */ sizeof(struct sadb_lifetime), /* SADB_EXT_LIFETIME_SOFT */ 0, /* SADB_EXT_ADDRESS_SRC */ 0, /* SADB_EXT_ADDRESS_DST */ 0, /* SADB_EXT_ADDRESS_PROXY */ 0, /* SADB_EXT_KEY_AUTH */ 0, /* SADB_EXT_KEY_ENCRYPT */ 0, /* SADB_EXT_IDENTITY_SRC */ 0, /* SADB_EXT_IDENTITY_DST */ 0, /* SADB_EXT_SENSITIVITY */ 0, /* SADB_EXT_PROPOSAL */ 0, /* SADB_EXT_SUPPORTED_AUTH */ 0, /* SADB_EXT_SUPPORTED_ENCRYPT */ sizeof(struct sadb_spirange), /* SADB_EXT_SPIRANGE */ 0, /* SADB_X_EXT_KMPRIVATE */ 0, /* SADB_X_EXT_POLICY */ sizeof(struct sadb_x_sa2), /* SADB_X_SA2 */ }; static int ipsec_esp_keymin = 256; #ifdef IPSEC_ESP static int ipsec_esp_auth = 0; #endif static int ipsec_ah_keymin = 128; SYSCTL_DECL(_net_key); SYSCTL_INT(_net_key, KEYCTL_DEBUG_LEVEL, debug, CTLFLAG_RW, \ &key_debug_level, 0, ""); /* max count of trial for the decision of spi value */ SYSCTL_INT(_net_key, KEYCTL_SPI_TRY, spi_trycnt, CTLFLAG_RW, \ &key_spi_trycnt, 0, ""); /* minimum spi value to allocate automatically. */ SYSCTL_INT(_net_key, KEYCTL_SPI_MIN_VALUE, spi_minval, CTLFLAG_RW, \ &key_spi_minval, 0, ""); /* maximun spi value to allocate automatically. */ SYSCTL_INT(_net_key, KEYCTL_SPI_MAX_VALUE, spi_maxval, CTLFLAG_RW, \ &key_spi_maxval, 0, ""); /* lifetime for larval SA */ SYSCTL_INT(_net_key, KEYCTL_LARVAL_LIFETIME, larval_lifetime, CTLFLAG_RW, \ &key_larval_lifetime, 0, ""); /* counter for blocking to send SADB_ACQUIRE to IKEd */ SYSCTL_INT(_net_key, KEYCTL_BLOCKACQ_COUNT, blockacq_count, CTLFLAG_RW, \ &key_blockacq_count, 0, ""); /* lifetime for blocking to send SADB_ACQUIRE to IKEd */ SYSCTL_INT(_net_key, KEYCTL_BLOCKACQ_LIFETIME, blockacq_lifetime, CTLFLAG_RW, \ &key_blockacq_lifetime, 0, ""); #ifdef IPSEC_ESP /* ESP auth */ SYSCTL_INT(_net_key, KEYCTL_ESP_AUTH, esp_auth, CTLFLAG_RW, \ &ipsec_esp_auth, 0, "ESP auth"); #endif /* minimum ESP key length */ SYSCTL_INT(_net_key, KEYCTL_ESP_KEYMIN, esp_keymin, CTLFLAG_RW, \ &ipsec_esp_keymin, 0, ""); /* minimum AH key length */ SYSCTL_INT(_net_key, KEYCTL_AH_KEYMIN, ah_keymin, CTLFLAG_RW, \ &ipsec_ah_keymin, 0, ""); /* perfered old SA rather than new SA */ SYSCTL_INT(_net_key, KEYCTL_PREFERED_OLDSA, preferred_oldsa, CTLFLAG_RW,\ &key_preferred_oldsa, 0, ""); #define __LIST_CHAINED(elm) \ (!((elm)->chain.le_next == NULL && (elm)->chain.le_prev == NULL)) #define LIST_INSERT_TAIL(head, elm, type, field) \ do {\ struct type *curelm = LIST_FIRST(head); \ if (curelm == NULL) {\ LIST_INSERT_HEAD(head, elm, field); \ } else { \ while (LIST_NEXT(curelm, field)) \ curelm = LIST_NEXT(curelm, field);\ LIST_INSERT_AFTER(curelm, elm, field);\ }\ } while (/*CONSTCOND*/ 0) #define KEY_CHKSASTATE(head, sav, name) \ do { \ if ((head) != (sav)) { \ ipseclog((LOG_DEBUG, "%s: state mismatched (TREE=%u SA=%u)\n", \ (name), (head), (sav))); \ continue; \ } \ } while (/*CONSTCOND*/ 0) #define KEY_CHKSPDIR(head, sp, name) \ do { \ if ((head) != (sp)) { \ ipseclog((LOG_DEBUG, "%s: direction mismatched (TREE=%u SP=%u), " \ "anyway continue.\n", \ (name), (head), (sp))); \ } \ } while (/*CONSTCOND*/ 0) #if 1 #define KMALLOC(p, t, n) \ ((p) = (t) malloc((unsigned long)(n), M_SECA, M_NOWAIT)) #define KFREE(p) \ free((caddr_t)(p), M_SECA) #else #define KMALLOC(p, t, n) \ do { \ ((p) = (t)malloc((unsigned long)(n), M_SECA, M_NOWAIT)); \ printf("%s %d: %p <- KMALLOC(%s, %d)\n", \ __FILE__, __LINE__, (p), #t, n); \ } while (/*CONSTCOND*/ 0) #define KFREE(p) \ do { \ printf("%s %d: %p -> KFREE()\n", __FILE__, __LINE__, (p)); \ free((caddr_t)(p), M_SECA); \ } while (/*CONSTCOND*/ 0) #endif /* * set parameters into secpolicyindex buffer. * Must allocate secpolicyindex buffer passed to this function. */ #define KEY_SETSECSPIDX(s, d, ps, pd, ulp, idx) \ do { \ bzero((idx), sizeof(struct secpolicyindex)); \ (idx)->prefs = (ps); \ (idx)->prefd = (pd); \ (idx)->ul_proto = (ulp); \ bcopy((s), &(idx)->src, ((struct sockaddr *)(s))->sa_len); \ bcopy((d), &(idx)->dst, ((struct sockaddr *)(d))->sa_len); \ } while (/*CONSTCOND*/ 0) /* * set parameters into secasindex buffer. * Must allocate secasindex buffer before calling this function. */ #define KEY_SETSECASIDX(p, m, r, s, d, idx) \ do { \ bzero((idx), sizeof(struct secasindex)); \ (idx)->proto = (p); \ (idx)->mode = (m); \ (idx)->reqid = (r); \ bcopy((s), &(idx)->src, ((struct sockaddr *)(s))->sa_len); \ bcopy((d), &(idx)->dst, ((struct sockaddr *)(d))->sa_len); \ } while (/*CONSTCOND*/ 0) /* key statistics */ struct _keystat { u_long getspi_count; /* the avarage of count to try to get new SPI */ } keystat; struct sadb_msghdr { struct sadb_msg *msg; struct sadb_ext *ext[SADB_EXT_MAX + 1]; int extoff[SADB_EXT_MAX + 1]; int extlen[SADB_EXT_MAX + 1]; }; static struct secasvar *key_allocsa_policy(struct secasindex *); static struct secasvar *key_do_allocsa_policy(struct secashead *, u_int); static void key_delsav(struct secasvar *); static void key_delsp(struct secpolicy *); static struct secpolicy *key_getsp(struct secpolicyindex *, int); static struct secpolicy *key_getspbyid(u_int32_t); static u_int32_t key_newreqid(void); static struct mbuf *key_gather_mbuf(struct mbuf *, const struct sadb_msghdr *, int, int, ...); static int key_spdadd(struct socket *, struct mbuf *, const struct sadb_msghdr *); static int key_spddelete(struct socket *, struct mbuf *, const struct sadb_msghdr *); static int key_spddelete2(struct socket *, struct mbuf *, const struct sadb_msghdr *); static int key_spdget(struct socket *, struct mbuf *, const struct sadb_msghdr *); static int key_spdflush(struct socket *, struct mbuf *, const struct sadb_msghdr *); static int key_spddump(struct socket *, struct mbuf *, const struct sadb_msghdr *); static struct mbuf *key_setdumpsp(struct secpolicy *, u_int8_t, u_int32_t, u_int32_t); static u_int key_getspreqmsglen(struct secpolicy *); static int key_spdexpire(struct secpolicy *); static struct secashead *key_newsah(struct secasindex *); static void key_delsah(struct secashead *); static struct secasvar *key_newsav(struct mbuf *, const struct sadb_msghdr *, struct secashead *, int *); static struct secashead *key_getsah(struct secasindex *); static struct secasvar *key_checkspidup(struct secasindex *, u_int32_t); static void key_setspi(struct secasvar *, u_int32_t); static struct secasvar *key_getsavbyspi(struct secashead *, u_int32_t); static int key_setsaval(struct secasvar *, struct mbuf *, const struct sadb_msghdr *); static int key_mature(struct secasvar *); static struct mbuf *key_setdumpsa(struct secasvar *, u_int8_t, u_int8_t, u_int32_t, u_int32_t); static struct mbuf *key_setsadbmsg(u_int8_t, u_int16_t, u_int8_t, u_int32_t, pid_t, u_int16_t); static struct mbuf *key_setsadbsa(struct secasvar *); static struct mbuf *key_setsadbaddr(u_int16_t, struct sockaddr *, u_int8_t, u_int16_t); #if 0 static struct mbuf *key_setsadbident(u_int16_t, u_int16_t, caddr_t, int, u_int64_t); #endif static struct mbuf *key_setsadbxsa2(u_int8_t, u_int32_t, u_int32_t); static struct mbuf *key_setsadblifetime(u_int16_t, u_int32_t, u_int64_t, u_int64_t, u_int64_t); static struct mbuf *key_setsadbxpolicy(u_int16_t, u_int8_t, u_int32_t); static void *key_newbuf(const void *, u_int); static int key_ismyaddr(struct sockaddr *); #ifdef INET6 static int key_ismyaddr6(struct sockaddr_in6 *); #endif /* flags for key_cmpsaidx() */ #define CMP_HEAD 1 /* protocol, addresses. */ #define CMP_MODE_REQID 2 /* additionally HEAD, reqid, mode. */ #define CMP_REQID 3 /* additionally HEAD, reqid. not used */ #define CMP_EXACTLY 4 /* all elements. */ static int key_cmpsaidx(struct secasindex *, struct secasindex *, int); static int key_sockaddrcmp(struct sockaddr *, struct sockaddr *, int); static int key_bbcmp(caddr_t, caddr_t, u_int); static u_long key_random(void); static u_int16_t key_satype2proto(u_int8_t); static u_int8_t key_proto2satype(u_int16_t); static int key_getspi(struct socket *, struct mbuf *, const struct sadb_msghdr *); static u_int32_t key_do_getnewspi(struct sadb_spirange *, struct secasindex *); static int key_update(struct socket *, struct mbuf *, const struct sadb_msghdr *); #ifdef IPSEC_DOSEQCHECK static struct secasvar *key_getsavbyseq(struct secashead *, u_int32_t); #endif static int key_add(struct socket *, struct mbuf *, const struct sadb_msghdr *); static int key_setident(struct secashead *, struct mbuf *, const struct sadb_msghdr *); static struct mbuf *key_getmsgbuf_x1(struct mbuf *, const struct sadb_msghdr *); static int key_delete(struct socket *, struct mbuf *, const struct sadb_msghdr *); static int key_get(struct socket *, struct mbuf *, const struct sadb_msghdr *); static void key_getcomb_setlifetime(struct sadb_comb *); #ifdef IPSEC_ESP static struct mbuf *key_getcomb_esp(void); #endif static struct mbuf *key_getcomb_ah(void); static struct mbuf *key_getcomb_ipcomp(void); static struct mbuf *key_getprop(const struct secasindex *); static int key_acquire(struct secasindex *, struct secpolicy *); #ifndef IPSEC_NONBLOCK_ACQUIRE static struct secacq *key_newacq(struct secasindex *); static struct secacq *key_getacq(struct secasindex *); static struct secacq *key_getacqbyseq(u_int32_t); #endif static struct secspacq *key_newspacq(struct secpolicyindex *); static struct secspacq *key_getspacq(struct secpolicyindex *); static int key_acquire2(struct socket *, struct mbuf *, const struct sadb_msghdr *); static int key_register(struct socket *, struct mbuf *, const struct sadb_msghdr *); static int key_expire(struct secasvar *); static int key_flush(struct socket *, struct mbuf *, const struct sadb_msghdr *); static int key_dump(struct socket *, struct mbuf *, const struct sadb_msghdr *); static int key_promisc(struct socket *, struct mbuf *, const struct sadb_msghdr *); static int key_senderror(struct socket *, struct mbuf *, int); static int key_validate_ext(struct sadb_ext *, int); static int key_align(struct mbuf *, struct sadb_msghdr *); #if 0 static const char *key_getfqdn(void); static const char *key_getuserfqdn(void); #endif static void key_sa_chgstate(struct secasvar *, u_int8_t); static void key_sp_dead(struct secpolicy *); static void key_sp_unlink(struct secpolicy *); static struct mbuf *key_alloc_mbuf(int); static struct callout key_timehandler_ch; /* %%% IPsec policy management */ /* * allocating a SP for OUTBOUND or INBOUND packet. * Must call key_freesp() later. * OUT: NULL: not found * others: found and return the pointer. */ struct secpolicy * key_allocsp(tag, spidx, dir) u_int16_t tag; struct secpolicyindex *spidx; u_int dir; { struct secpolicy *sp; int s; /* check direction */ switch (dir) { case IPSEC_DIR_INBOUND: case IPSEC_DIR_OUTBOUND: break; default: panic("key_allocsp: Invalid direction is passed."); } /* get a SP entry */ s = splnet(); /*called from softclock()*/ if (spidx) { KEYDEBUG(KEYDEBUG_IPSEC_DATA, printf("*** objects\n"); kdebug_secpolicyindex(spidx)); } LIST_FOREACH(sp, &sptree[dir], chain) { if (sp->state == IPSEC_SPSTATE_DEAD) continue; if (sp->spidx) { if (!spidx) continue; KEYDEBUG(KEYDEBUG_IPSEC_DATA, printf("*** in SPD\n"); kdebug_secpolicyindex(sp->spidx)); if (key_cmpspidx_withmask(sp->spidx, spidx)) goto found; } } splx(s); return NULL; found: /* sanity check */ KEY_CHKSPDIR(sp->dir, dir, "key_allocsp"); /* found a SPD entry */ sp->lastused = time_second; sp->refcnt++; splx(s); KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP key_allocsp cause refcnt++:%d SP:%p\n", sp->refcnt, sp)); return sp; } /* * return a policy that matches this particular inbound packet. * XXX slow */ struct secpolicy * key_gettunnel(osrc, odst, isrc, idst) struct sockaddr *osrc, *odst, *isrc, *idst; { struct secpolicy *sp; const int dir = IPSEC_DIR_INBOUND; int s; struct ipsecrequest *r1, *r2, *p; struct sockaddr *os, *od, *is, *id; struct secpolicyindex spidx; if (isrc->sa_family != idst->sa_family) { ipseclog((LOG_ERR, "protocol family mismatched %u != %u\n", isrc->sa_family, idst->sa_family)); return NULL; } s = splnet(); /*called from softclock()*/ LIST_FOREACH(sp, &sptree[dir], chain) { if (sp->state == IPSEC_SPSTATE_DEAD) continue; r1 = r2 = NULL; for (p = sp->req; p; p = p->next) { if (p->saidx.mode != IPSEC_MODE_TUNNEL) continue; r1 = r2; r2 = p; if (!r1) { if (sp->spidx) { /* * here we look at address matches * only */ spidx = *sp->spidx; if (isrc->sa_len > sizeof(spidx.src) || idst->sa_len > sizeof(spidx.dst)) continue; bcopy(isrc, &spidx.src, isrc->sa_len); bcopy(idst, &spidx.dst, idst->sa_len); if (!key_cmpspidx_withmask(sp->spidx, &spidx)) continue; } else ; /* can't check for tagged policy */ } else { is = (struct sockaddr *)&r1->saidx.src; id = (struct sockaddr *)&r1->saidx.dst; if (key_sockaddrcmp(is, isrc, 0) || key_sockaddrcmp(id, idst, 0)) continue; } os = (struct sockaddr *)&r2->saidx.src; od = (struct sockaddr *)&r2->saidx.dst; if (key_sockaddrcmp(os, osrc, 0) || key_sockaddrcmp(od, odst, 0)) continue; goto found; } } splx(s); return NULL; found: sp->lastused = time_second; sp->refcnt++; splx(s); return sp; } /* * allocating an SA entry for an *OUTBOUND* packet. * checking each request entries in SP, and acquire an SA if need. * OUT: 0: there are valid requests. * ENOENT: policy may be valid, but SA with REQUIRE is on acquiring. */ int key_checkrequest(isr, saidx) struct ipsecrequest *isr; struct secasindex *saidx; { u_int level; int error; /* sanity check */ if (isr == NULL || saidx == NULL) panic("key_checkrequest: NULL pointer is passed."); /* check mode */ switch (saidx->mode) { case IPSEC_MODE_TRANSPORT: case IPSEC_MODE_TUNNEL: break; case IPSEC_MODE_ANY: default: panic("key_checkrequest: Invalid policy defined."); } /* get current level */ level = ipsec_get_reqlevel(isr, saidx->src.ss_family); #if 0 /* * We do allocate new SA only if the state of SA in the holder is * SADB_SASTATE_DEAD. The SA for outbound must be the oldest. */ if (isr->sav != NULL) { if (isr->sav->sah == NULL) panic("key_checkrequest: sah is null."); if (isr->sav == LIST_FIRST(&isr->sav->sah->savtree[SADB_SASTATE_DEAD])) { KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP checkrequest calls free SA:%p\n", isr->sav)); key_freesav(isr->sav); isr->sav = NULL; } } #else /* * we free any SA stashed in the IPsec request because a different * SA may be involved each time this request is checked, either * because new SAs are being configured, or this request is * associated with an unconnected datagram socket, or this request * is associated with a system default policy. * * The operation may have negative impact to performance. We may * want to check cached SA carefully, rather than picking new SA * every time. */ if (isr->sav != NULL) { key_freesav(isr->sav); isr->sav = NULL; } #endif /* * new SA allocation if no SA found. * key_allocsa_policy should allocate the oldest SA available. * See key_do_allocsa_policy(), and draft-jenkins-ipsec-rekeying-03.txt. */ if (isr->sav == NULL) isr->sav = key_allocsa_policy(saidx); /* When there is SA. */ if (isr->sav != NULL) return 0; /* there is no SA */ if ((error = key_acquire(saidx, isr->sp)) != 0) { /* XXX What should I do ? */ ipseclog((LOG_DEBUG, "key_checkrequest: error %d returned " "from key_acquire.\n", error)); return error; } return level == IPSEC_LEVEL_REQUIRE ? ENOENT : 0; } /* * allocating a SA for policy entry from SAD. * NOTE: searching SAD of aliving state. * OUT: NULL: not found. * others: found and return the pointer. */ static struct secasvar * key_allocsa_policy(saidx) struct secasindex *saidx; { struct secashead *sah; struct secasvar *sav; u_int stateidx, state; const u_int *saorder_state_valid; int arraysize; LIST_FOREACH(sah, &sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; if (key_cmpsaidx(&sah->saidx, saidx, CMP_MODE_REQID)) goto found; } return NULL; found: /* * search a valid state list for outbound packet. * This search order is important. */ if (key_preferred_oldsa) { saorder_state_valid = saorder_state_valid_prefer_old; arraysize = _ARRAYLEN(saorder_state_valid_prefer_old); } else { saorder_state_valid = saorder_state_valid_prefer_new; arraysize = _ARRAYLEN(saorder_state_valid_prefer_new); } for (stateidx = 0; stateidx < arraysize; stateidx++) { state = saorder_state_valid[stateidx]; sav = key_do_allocsa_policy(sah, state); if (sav != NULL) return sav; } return NULL; } /* * searching SAD with direction, protocol, mode and state. * called by key_allocsa_policy(). * OUT: * NULL : not found * others : found, pointer to a SA. */ static struct secasvar * key_do_allocsa_policy(sah, state) struct secashead *sah; u_int state; { struct secasvar *sav, *nextsav, *candidate, *d; /* initilize */ candidate = NULL; for (sav = LIST_FIRST(&sah->savtree[state]); sav != NULL; sav = nextsav) { nextsav = LIST_NEXT(sav, chain); /* sanity check */ KEY_CHKSASTATE(sav->state, state, "key_do_allocsa_policy"); /* initialize */ if (candidate == NULL) { candidate = sav; continue; } /* Which SA is the better ? */ /* sanity check 2 */ if (candidate->lft_c == NULL || sav->lft_c == NULL) panic("key_do_allocsa_policy: " "lifetime_current is NULL."); /* What the best method is to compare ? */ if (key_preferred_oldsa) { if (candidate->lft_c->sadb_lifetime_addtime > sav->lft_c->sadb_lifetime_addtime) { candidate = sav; } continue; /*NOTREACHED*/ } /* preferred new sa rather than old sa */ if (candidate->lft_c->sadb_lifetime_addtime < sav->lft_c->sadb_lifetime_addtime) { d = candidate; candidate = sav; } else d = sav; /* * prepared to delete the SA when there is more * suitable candidate and the lifetime of the SA is not * permanent. */ if (d->lft_c->sadb_lifetime_addtime != 0) { struct mbuf *m, *result = NULL; key_sa_chgstate(d, SADB_SASTATE_DEAD); m = key_setsadbmsg(SADB_DELETE, 0, key_proto2satype(d->sah->saidx.proto), 0, 0, d->refcnt - 1); if (!m) goto msgfail; result = m; /* set sadb_address for saidx's. */ m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC, (struct sockaddr *)&d->sah->saidx.src, FULLMASK, IPSEC_ULPROTO_ANY); if (!m) goto msgfail; m_cat(result, m); /* set sadb_address for saidx's. */ m = key_setsadbaddr(SADB_EXT_ADDRESS_DST, (struct sockaddr *)&d->sah->saidx.dst, FULLMASK, IPSEC_ULPROTO_ANY); if (!m) goto msgfail; m_cat(result, m); /* create SA extension */ m = key_setsadbsa(d); if (!m) goto msgfail; m_cat(result, m); if (result->m_len < sizeof(struct sadb_msg)) { result = m_pullup(result, sizeof(struct sadb_msg)); if (result == NULL) goto msgfail; } result->m_pkthdr.len = 0; for (m = result; m; m = m->m_next) result->m_pkthdr.len += m->m_len; mtod(result, struct sadb_msg *)->sadb_msg_len = PFKEY_UNIT64(result->m_pkthdr.len); if (key_sendup_mbuf(NULL, result, KEY_SENDUP_REGISTERED)) goto msgfail; result = NULL; msgfail: if (result != NULL) m_freem(result); key_freesav(d); } } if (candidate) { candidate->refcnt++; KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP allocsa_policy cause " "refcnt++:%d SA:%p\n", candidate->refcnt, candidate)); } return candidate; } /* * allocating a SA entry for a *INBOUND* packet. * Must call key_freesav() later. * OUT: positive: pointer to a sav. * NULL: not found, or error occured. * * In the comparison, source address will be ignored for RFC2401 conformance. * To quote, from section 4.1: * A security association is uniquely identified by a triple consisting * of a Security Parameter Index (SPI), an IP Destination Address, and a * security protocol (AH or ESP) identifier. * Note that, however, we do need to keep source address in IPsec SA. * IKE specification and PF_KEY specification do assume that we * keep source address in IPsec SA. We see a tricky situation here. */ struct secasvar * key_allocsa(family, src, dst, proto, spi) u_int family, proto; caddr_t src, dst; u_int32_t spi; { struct secasvar *sav, *match; u_int stateidx, state, tmpidx, matchidx; struct sockaddr_in sin; struct sockaddr_in6 sin6; int s; const u_int *saorder_state_valid; int arraysize; /* sanity check */ if (src == NULL || dst == NULL) panic("key_allocsa: NULL pointer is passed."); /* * when both systems employ similar strategy to use a SA. * the search order is important even in the inbound case. */ if (key_preferred_oldsa) { saorder_state_valid = saorder_state_valid_prefer_old; arraysize = _ARRAYLEN(saorder_state_valid_prefer_old); } else { saorder_state_valid = saorder_state_valid_prefer_new; arraysize = _ARRAYLEN(saorder_state_valid_prefer_new); } /* * searching SAD. * XXX: to be checked internal IP header somewhere. Also when * IPsec tunnel packet is received. But ESP tunnel mode is * encrypted so we can't check internal IP header. */ s = splnet(); /*called from softclock()*/ /* * search a valid state list for inbound packet. * the search order is not important. */ match = NULL; matchidx = arraysize; LIST_FOREACH(sav, &spihash[SPIHASH(spi)], spihash) { if (sav->spi != spi) continue; if (proto != sav->sah->saidx.proto) continue; if (family != sav->sah->saidx.src.ss_family || family != sav->sah->saidx.dst.ss_family) continue; tmpidx = arraysize; for (stateidx = 0; stateidx < matchidx; stateidx++) { state = saorder_state_valid[stateidx]; if (sav->state == state) { tmpidx = stateidx; break; } } if (tmpidx >= matchidx) continue; #if 0 /* don't check src */ /* check src address */ switch (family) { case AF_INET: bzero(&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_len = sizeof(sin); bcopy(src, &sin.sin_addr, sizeof(sin.sin_addr)); if (key_sockaddrcmp((struct sockaddr*)&sin, (struct sockaddr *)&sav->sah->saidx.src, 0) != 0) continue; break; case AF_INET6: bzero(&sin6, sizeof(sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_len = sizeof(sin6); bcopy(src, &sin6.sin6_addr, sizeof(sin6.sin6_addr)); if (IN6_IS_SCOPE_LINKLOCAL(&sin6.sin6_addr)) { /* kame fake scopeid */ sin6.sin6_scope_id = ntohs(sin6.sin6_addr.s6_addr16[1]); sin6.sin6_addr.s6_addr16[1] = 0; } if (key_sockaddrcmp((struct sockaddr *)&sin6, (struct sockaddr *)&sav->sah->saidx.src, 0) != 0) continue; break; default: ipseclog((LOG_DEBUG, "key_allocsa: " "unknown address family=%d.\n", family)); continue; } #endif /* check dst address */ switch (family) { case AF_INET: bzero(&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_len = sizeof(sin); bcopy(dst, &sin.sin_addr, sizeof(sin.sin_addr)); if (key_sockaddrcmp((struct sockaddr*)&sin, (struct sockaddr *)&sav->sah->saidx.dst, 0) != 0) continue; break; case AF_INET6: bzero(&sin6, sizeof(sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_len = sizeof(sin6); bcopy(dst, &sin6.sin6_addr, sizeof(sin6.sin6_addr)); if (IN6_IS_SCOPE_LINKLOCAL(&sin6.sin6_addr)) { /* kame fake scopeid */ sin6.sin6_scope_id = ntohs(sin6.sin6_addr.s6_addr16[1]); sin6.sin6_addr.s6_addr16[1] = 0; } if (key_sockaddrcmp((struct sockaddr *)&sin6, (struct sockaddr *)&sav->sah->saidx.dst, 0) != 0) continue; break; default: ipseclog((LOG_DEBUG, "key_allocsa: " "unknown address family=%d.\n", family)); continue; } match = sav; matchidx = tmpidx; } if (match) goto found; /* not found */ splx(s); return NULL; found: match->refcnt++; splx(s); KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP allocsa cause refcnt++:%d SA:%p\n", match->refcnt, match)); return match; } /* * Must be called after calling key_allocsp(). * For both the packet without socket and key_freeso(). */ void key_freesp(sp) struct secpolicy *sp; { /* sanity check */ if (sp == NULL) panic("key_freesp: NULL pointer is passed."); sp->refcnt--; KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP freesp cause refcnt--:%d SP:%p\n", sp->refcnt, sp)); if (sp->refcnt == 0) key_delsp(sp); return; } /* * Must be called after calling key_allocsa(). * This function is called by key_freesp() to free some SA allocated * for a policy. */ void key_freesav(sav) struct secasvar *sav; { /* sanity check */ if (sav == NULL) panic("key_freesav: NULL pointer is passed."); sav->refcnt--; KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP freesav cause refcnt--:%d SA:%p SPI %u\n", sav->refcnt, sav, (u_int32_t)ntohl(sav->spi))); if (sav->refcnt > 0) return; key_delsav(sav); } static void key_delsav(sav) struct secasvar *sav; { int s; /* sanity check */ if (sav == NULL) panic("key_delsav: NULL pointer is passed."); if (sav->refcnt > 0) panic("key_delsav: called with positive refcnt"); s = splnet(); if (__LIST_CHAINED(sav)) LIST_REMOVE(sav, chain); if (sav->spihash.le_prev || sav->spihash.le_next) LIST_REMOVE(sav, spihash); if (sav->key_auth != NULL) { bzero(_KEYBUF(sav->key_auth), _KEYLEN(sav->key_auth)); KFREE(sav->key_auth); sav->key_auth = NULL; } if (sav->key_enc != NULL) { bzero(_KEYBUF(sav->key_enc), _KEYLEN(sav->key_enc)); KFREE(sav->key_enc); sav->key_enc = NULL; } if (sav->sched) { bzero(sav->sched, sav->schedlen); KFREE(sav->sched); sav->sched = NULL; } if (sav->replay != NULL) { keydb_delsecreplay(sav->replay); sav->replay = NULL; } if (sav->lft_c != NULL) { KFREE(sav->lft_c); sav->lft_c = NULL; } if (sav->lft_h != NULL) { KFREE(sav->lft_h); sav->lft_h = NULL; } if (sav->lft_s != NULL) { KFREE(sav->lft_s); sav->lft_s = NULL; } if (sav->iv != NULL) { KFREE(sav->iv); sav->iv = NULL; } keydb_delsecasvar(sav); splx(s); } /* %%% SPD management */ /* * free security policy entry. */ static void key_delsp(sp) struct secpolicy *sp; { int s; /* sanity check */ if (sp == NULL) panic("key_delsp: NULL pointer is passed."); if (sp->refcnt > 0) panic("key_delsp: called with positive refcnt"); s = splnet(); /*called from softclock()*/ { struct ipsecrequest *isr = sp->req, *nextisr; while (isr != NULL) { if (isr->sav != NULL) { KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP delsp calls free SA:%p\n", isr->sav)); key_freesav(isr->sav); isr->sav = NULL; } nextisr = isr->next; KFREE(isr); isr = nextisr; } } keydb_delsecpolicy(sp); splx(s); return; } /* * search SPD * OUT: NULL : not found * others : found, pointer to a SP. */ static struct secpolicy * key_getsp(spidx, dir) struct secpolicyindex *spidx; int dir; { struct secpolicy *sp; /* sanity check */ if (spidx == NULL) panic("key_getsp: NULL pointer is passed."); LIST_FOREACH(sp, &sptree[dir], chain) { if (sp->state == IPSEC_SPSTATE_DEAD) continue; if (!sp->spidx) continue; if (key_cmpspidx_exactly(spidx, sp->spidx)) { sp->refcnt++; return sp; } } return NULL; } /* * get SP by index. * OUT: NULL : not found * others : found, pointer to a SP. */ static struct secpolicy * key_getspbyid(id) u_int32_t id; { struct secpolicy *sp; TAILQ_FOREACH(sp, &sptailq, tailq) { if (sp->id == id) { sp->refcnt++; return sp; } } return NULL; } struct secpolicy * key_newsp(id) u_int32_t id; { struct secpolicy *newsp = NULL, *sp; u_int32_t newid; if (id > IPSEC_MANUAL_POLICYID_MAX) { ipseclog((LOG_DEBUG, "key_newsp: policy_id=%u range " "violation, updated by kernel.\n", id)); id = 0; } if (id == 0) { if ((newid = keydb_newspid()) == 0) { ipseclog((LOG_DEBUG, "key_newsp: new policy_id allocation failed.")); return NULL; } } else { sp = key_getspbyid(id); if (sp != NULL) { ipseclog((LOG_DEBUG, "key_newsp: policy_id(%u) has been used.\n", id)); key_freesp(sp); return NULL; } newid = id; } newsp = keydb_newsecpolicy(); if (!newsp) return newsp; newsp->id = newid; newsp->refcnt = 1; newsp->req = NULL; return newsp; } /* * create secpolicy structure from sadb_x_policy structure. * NOTE: `state', `secpolicyindex' in secpolicy structure are not set, * so must be set properly later. */ struct secpolicy * key_msg2sp(xpl0, len, error) struct sadb_x_policy *xpl0; size_t len; int *error; { struct secpolicy *newsp; /* sanity check */ if (xpl0 == NULL) panic("key_msg2sp: NULL pointer was passed."); if (len < sizeof(*xpl0)) panic("key_msg2sp: invalid length."); if (len != PFKEY_EXTLEN(xpl0)) { ipseclog((LOG_DEBUG, "key_msg2sp: Invalid msg length.\n")); *error = EINVAL; return NULL; } if ((newsp = key_newsp(xpl0->sadb_x_policy_id)) == NULL) { *error = ENOBUFS; return NULL; } newsp->dir = xpl0->sadb_x_policy_dir; newsp->policy = xpl0->sadb_x_policy_type; /* check policy */ switch (xpl0->sadb_x_policy_type) { case IPSEC_POLICY_DISCARD: case IPSEC_POLICY_NONE: case IPSEC_POLICY_ENTRUST: case IPSEC_POLICY_BYPASS: newsp->req = NULL; break; case IPSEC_POLICY_IPSEC: { int tlen; struct sadb_x_ipsecrequest *xisr; struct ipsecrequest **p_isr = &newsp->req; /* validity check */ if (PFKEY_EXTLEN(xpl0) < sizeof(*xpl0)) { ipseclog((LOG_DEBUG, "key_msg2sp: Invalid msg length.\n")); key_freesp(newsp); *error = EINVAL; return NULL; } tlen = PFKEY_EXTLEN(xpl0) - sizeof(*xpl0); xisr = (struct sadb_x_ipsecrequest *)(xpl0 + 1); while (tlen > 0) { /* length check */ if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) { ipseclog((LOG_DEBUG, "key_msg2sp: " "invalid ipsecrequest length.\n")); key_freesp(newsp); *error = EINVAL; return NULL; } /* allocate request buffer */ KMALLOC(*p_isr, struct ipsecrequest *, sizeof(**p_isr)); if ((*p_isr) == NULL) { ipseclog((LOG_DEBUG, "key_msg2sp: No more memory.\n")); key_freesp(newsp); *error = ENOBUFS; return NULL; } bzero(*p_isr, sizeof(**p_isr)); /* set values */ (*p_isr)->next = NULL; switch (xisr->sadb_x_ipsecrequest_proto) { case IPPROTO_ESP: case IPPROTO_AH: case IPPROTO_IPCOMP: break; default: ipseclog((LOG_DEBUG, "key_msg2sp: invalid proto type=%u\n", xisr->sadb_x_ipsecrequest_proto)); key_freesp(newsp); *error = EPROTONOSUPPORT; return NULL; } (*p_isr)->saidx.proto = xisr->sadb_x_ipsecrequest_proto; switch (xisr->sadb_x_ipsecrequest_mode) { case IPSEC_MODE_TRANSPORT: case IPSEC_MODE_TUNNEL: break; case IPSEC_MODE_ANY: default: ipseclog((LOG_DEBUG, "key_msg2sp: invalid mode=%u\n", xisr->sadb_x_ipsecrequest_mode)); key_freesp(newsp); *error = EINVAL; return NULL; } (*p_isr)->saidx.mode = xisr->sadb_x_ipsecrequest_mode; switch (xisr->sadb_x_ipsecrequest_level) { case IPSEC_LEVEL_DEFAULT: case IPSEC_LEVEL_USE: case IPSEC_LEVEL_REQUIRE: break; case IPSEC_LEVEL_UNIQUE: /* validity check */ /* * If range violation of reqid, kernel will * update it, don't refuse it. */ if (xisr->sadb_x_ipsecrequest_reqid > IPSEC_MANUAL_REQID_MAX) { ipseclog((LOG_DEBUG, "key_msg2sp: reqid=%u range " "violation, updated by kernel.\n", xisr->sadb_x_ipsecrequest_reqid)); xisr->sadb_x_ipsecrequest_reqid = 0; } /* allocate new reqid id if reqid is zero. */ if (xisr->sadb_x_ipsecrequest_reqid == 0) { u_int32_t reqid; if ((reqid = key_newreqid()) == 0) { key_freesp(newsp); *error = ENOBUFS; return NULL; } (*p_isr)->saidx.reqid = reqid; xisr->sadb_x_ipsecrequest_reqid = reqid; } else { /* set it for manual keying. */ (*p_isr)->saidx.reqid = xisr->sadb_x_ipsecrequest_reqid; } break; default: ipseclog((LOG_DEBUG, "key_msg2sp: invalid level=%u\n", xisr->sadb_x_ipsecrequest_level)); key_freesp(newsp); *error = EINVAL; return NULL; } (*p_isr)->level = xisr->sadb_x_ipsecrequest_level; /* set IP addresses if there */ if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) { struct sockaddr *paddr; paddr = (struct sockaddr *)(xisr + 1); /* validity check */ if (paddr->sa_len > sizeof((*p_isr)->saidx.src)) { ipseclog((LOG_DEBUG, "key_msg2sp: invalid request " "address length.\n")); key_freesp(newsp); *error = EINVAL; return NULL; } bcopy(paddr, &(*p_isr)->saidx.src, paddr->sa_len); paddr = (struct sockaddr *)((caddr_t)paddr + paddr->sa_len); /* validity check */ if (paddr->sa_len > sizeof((*p_isr)->saidx.dst)) { ipseclog((LOG_DEBUG, "key_msg2sp: invalid request " "address length.\n")); key_freesp(newsp); *error = EINVAL; return NULL; } bcopy(paddr, &(*p_isr)->saidx.dst, paddr->sa_len); } (*p_isr)->sav = NULL; (*p_isr)->sp = newsp; /* initialization for the next. */ p_isr = &(*p_isr)->next; tlen -= xisr->sadb_x_ipsecrequest_len; /* validity check */ if (tlen < 0) { ipseclog((LOG_DEBUG, "key_msg2sp: becoming tlen < 0.\n")); key_freesp(newsp); *error = EINVAL; return NULL; } xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xisr + xisr->sadb_x_ipsecrequest_len); } } break; default: ipseclog((LOG_DEBUG, "key_msg2sp: invalid policy type.\n")); key_freesp(newsp); *error = EINVAL; return NULL; } *error = 0; return newsp; } static u_int32_t key_newreqid() { static u_int32_t auto_reqid = IPSEC_MANUAL_REQID_MAX + 1; auto_reqid = (auto_reqid == ~0 ? IPSEC_MANUAL_REQID_MAX + 1 : auto_reqid + 1); /* XXX should be unique check */ return auto_reqid; } /* * copy secpolicy struct to sadb_x_policy structure indicated. */ struct mbuf * key_sp2msg(sp) struct secpolicy *sp; { struct sadb_x_policy *xpl; int tlen; caddr_t p; struct mbuf *m; /* sanity check. */ if (sp == NULL) panic("key_sp2msg: NULL pointer was passed."); tlen = key_getspreqmsglen(sp); m = key_alloc_mbuf(tlen); if (!m || m->m_next) { /*XXX*/ if (m) m_freem(m); return NULL; } m->m_len = tlen; m->m_next = NULL; xpl = mtod(m, struct sadb_x_policy *); bzero(xpl, tlen); xpl->sadb_x_policy_len = PFKEY_UNIT64(tlen); xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY; xpl->sadb_x_policy_type = sp->policy; xpl->sadb_x_policy_dir = sp->dir; xpl->sadb_x_policy_id = sp->id; p = (caddr_t)xpl + sizeof(*xpl); /* if is the policy for ipsec ? */ if (sp->policy == IPSEC_POLICY_IPSEC) { struct sadb_x_ipsecrequest *xisr; struct ipsecrequest *isr; for (isr = sp->req; isr != NULL; isr = isr->next) { xisr = (struct sadb_x_ipsecrequest *)p; xisr->sadb_x_ipsecrequest_proto = isr->saidx.proto; xisr->sadb_x_ipsecrequest_mode = isr->saidx.mode; xisr->sadb_x_ipsecrequest_level = isr->level; xisr->sadb_x_ipsecrequest_reqid = isr->saidx.reqid; p += sizeof(*xisr); bcopy(&isr->saidx.src, p, isr->saidx.src.ss_len); p += isr->saidx.src.ss_len; bcopy(&isr->saidx.dst, p, isr->saidx.dst.ss_len); p += isr->saidx.src.ss_len; xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(sizeof(*xisr) + isr->saidx.src.ss_len + isr->saidx.dst.ss_len); } } return m; } /* m will not be freed nor modified */ static struct mbuf * #ifdef __STDC__ key_gather_mbuf(struct mbuf *m, const struct sadb_msghdr *mhp, int ndeep, int nitem, ...) #else key_gather_mbuf(m, mhp, ndeep, nitem, va_alist) struct mbuf *m; const struct sadb_msghdr *mhp; int ndeep; int nitem; va_dcl #endif { va_list ap; int idx; int i; struct mbuf *result = NULL, *n; int len; if (m == NULL || mhp == NULL) panic("null pointer passed to key_gather"); va_start(ap, nitem); for (i = 0; i < nitem; i++) { idx = va_arg(ap, int); if (idx < 0 || idx > SADB_EXT_MAX) goto fail; /* don't attempt to pull empty extension */ if (idx == SADB_EXT_RESERVED && mhp->msg == NULL) continue; if (idx != SADB_EXT_RESERVED && (mhp->ext[idx] == NULL || mhp->extlen[idx] == 0)) continue; if (idx == SADB_EXT_RESERVED) { len = PFKEY_ALIGN8(sizeof(struct sadb_msg)); #ifdef DIAGNOSTIC if (len > MHLEN) panic("assumption failed"); #endif MGETHDR(n, M_DONTWAIT, MT_DATA); if (!n) goto fail; n->m_len = len; n->m_next = NULL; m_copydata(m, 0, sizeof(struct sadb_msg), mtod(n, caddr_t)); } else if (i < ndeep) { len = mhp->extlen[idx]; n = key_alloc_mbuf(len); if (!n || n->m_next) { /*XXX*/ if (n) m_freem(n); goto fail; } m_copydata(m, mhp->extoff[idx], mhp->extlen[idx], mtod(n, caddr_t)); } else { n = m_copym(m, mhp->extoff[idx], mhp->extlen[idx], M_DONTWAIT); } if (n == NULL) goto fail; if (result) m_cat(result, n); else result = n; } va_end(ap); if ((result->m_flags & M_PKTHDR) != 0) { result->m_pkthdr.len = 0; for (n = result; n; n = n->m_next) result->m_pkthdr.len += n->m_len; } return result; fail: va_end(ap); m_freem(result); return NULL; } /* * SADB_X_SPDADD, SADB_X_SPDSETIDX or SADB_X_SPDUPDATE processing * add an entry to SP database, when received * * from the user(?). * Adding to SP database, * and send * * to the socket which was send. * * SPDADD set a unique policy entry. * SPDSETIDX like SPDADD without a part of policy requests. * SPDUPDATE replace a unique policy entry. * * m will always be freed. */ static int key_spdadd(so, m, mhp) struct socket *so; struct mbuf *m; const struct sadb_msghdr *mhp; { struct sadb_address *src0 = NULL, *dst0 = NULL; struct sadb_x_policy *xpl0, *xpl; struct sadb_lifetime *lft = NULL; struct secpolicyindex spidx; struct secpolicy *newsp; struct ipsecrequest *isr; int error; int spidxmode; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_spdadd: NULL pointer is passed."); if (mhp->ext[SADB_EXT_ADDRESS_SRC] != NULL && mhp->ext[SADB_EXT_ADDRESS_DST] != NULL) { ; } else { ipseclog((LOG_DEBUG, "key_spdadd: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } if (mhp->ext[SADB_X_EXT_POLICY] == NULL) { ipseclog((LOG_DEBUG, "key_spdadd: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } if ((mhp->extlen[SADB_EXT_ADDRESS_SRC] && mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address)) || (mhp->extlen[SADB_EXT_ADDRESS_DST] && mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) || mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) { ipseclog((LOG_DEBUG, "key_spdadd: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } if (mhp->ext[SADB_EXT_LIFETIME_HARD] != NULL) { if (mhp->extlen[SADB_EXT_LIFETIME_HARD] < sizeof(struct sadb_lifetime)) { ipseclog((LOG_DEBUG, "key_spdadd: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } lft = (struct sadb_lifetime *)mhp->ext[SADB_EXT_LIFETIME_HARD]; } /* spidx mode, or tag mode */ spidxmode = (mhp->ext[SADB_EXT_ADDRESS_SRC] != NULL); if (spidxmode) { src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC]; dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST]; /* make secindex */ /* XXX boundary check against sa_len */ KEY_SETSECSPIDX(src0 + 1, dst0 + 1, src0->sadb_address_prefixlen, dst0->sadb_address_prefixlen, src0->sadb_address_proto, &spidx); } xpl0 = (struct sadb_x_policy *)mhp->ext[SADB_X_EXT_POLICY]; /* checking the direciton. */ switch (xpl0->sadb_x_policy_dir) { case IPSEC_DIR_INBOUND: case IPSEC_DIR_OUTBOUND: break; default: ipseclog((LOG_DEBUG, "key_spdadd: Invalid SP direction.\n")); mhp->msg->sadb_msg_errno = EINVAL; return 0; } /* check policy */ /* key_spdadd() accepts DISCARD, NONE and IPSEC. */ if (xpl0->sadb_x_policy_type == IPSEC_POLICY_ENTRUST || xpl0->sadb_x_policy_type == IPSEC_POLICY_BYPASS) { ipseclog((LOG_DEBUG, "key_spdadd: Invalid policy type.\n")); return key_senderror(so, m, EINVAL); } /* policy requests are mandatory when action is ipsec. */ if (mhp->msg->sadb_msg_type != SADB_X_SPDSETIDX && xpl0->sadb_x_policy_type == IPSEC_POLICY_IPSEC && mhp->extlen[SADB_X_EXT_POLICY] <= sizeof(*xpl0)) { ipseclog((LOG_DEBUG, "key_spdadd: some policy requests part required.\n")); return key_senderror(so, m, EINVAL); } /* * checking there is SP already or not. * SPDUPDATE doesn't depend on whether there is a SP or not. * If the type is either SPDADD or SPDSETIDX AND a SP is found, * then error. */ if (xpl0->sadb_x_policy_id != 0) newsp = key_getspbyid(xpl0->sadb_x_policy_id); else if (spidxmode) newsp = key_getsp(&spidx, xpl0->sadb_x_policy_dir); else newsp = NULL; if (newsp && (newsp->readonly || newsp->persist)) { ipseclog((LOG_DEBUG, "key_spdadd: tried to alter readonly/persistent SP.\n")); return key_senderror(so, m, EPERM); } if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) { if (newsp) { key_sp_dead(newsp); key_freesp(newsp); /* ref gained by key_getsp */ key_sp_unlink(newsp); newsp = NULL; } } else { if (newsp != NULL) { key_freesp(newsp); ipseclog((LOG_DEBUG, "key_spdadd: a SP entry exists already.\n")); return key_senderror(so, m, EEXIST); } } /* allocation new SP entry */ if ((newsp = key_msg2sp(xpl0, PFKEY_EXTLEN(xpl0), &error)) == NULL) { return key_senderror(so, m, error); } if (spidxmode) { error = keydb_setsecpolicyindex(newsp, &spidx); if (error) { keydb_delsecpolicy(newsp); return key_senderror(so, m, error); } /* sanity check on addr pair */ if (((struct sockaddr *)(src0 + 1))->sa_family != ((struct sockaddr *)(dst0 + 1))->sa_family) { keydb_delsecpolicy(newsp); return key_senderror(so, m, EINVAL); } if (((struct sockaddr *)(src0 + 1))->sa_len != ((struct sockaddr *)(dst0 + 1))->sa_len) { keydb_delsecpolicy(newsp); return key_senderror(so, m, EINVAL); } } for (isr = newsp->req; isr; isr = isr->next) { struct sockaddr *sa; /* * port spec is not permitted for tunnel mode */ if (isr->saidx.mode == IPSEC_MODE_TUNNEL && src0 && dst0) { sa = (struct sockaddr *)(src0 + 1); switch (sa->sa_family) { case AF_INET: if (((struct sockaddr_in *)sa)->sin_port) { keydb_delsecpolicy(newsp); return key_senderror(so, m, EINVAL); } break; case AF_INET6: if (((struct sockaddr_in6 *)sa)->sin6_port) { keydb_delsecpolicy(newsp); return key_senderror(so, m, EINVAL); } break; default: break; } sa = (struct sockaddr *)(dst0 + 1); switch (sa->sa_family) { case AF_INET: if (((struct sockaddr_in *)sa)->sin_port) { keydb_delsecpolicy(newsp); return key_senderror(so, m, EINVAL); } break; case AF_INET6: if (((struct sockaddr_in6 *)sa)->sin6_port) { keydb_delsecpolicy(newsp); return key_senderror(so, m, EINVAL); } break; default: break; } } } /* * bark if we have different address family on tunnel address * specification. applies only if we decapsulate in RFC2401 * IPsec (implementation limitation). */ for (isr = newsp->req; isr; isr = isr->next) { struct sockaddr *sa; if (isr->saidx.src.ss_family && src0) { sa = (struct sockaddr *)(src0 + 1); if (sa->sa_family != isr->saidx.src.ss_family) { keydb_delsecpolicy(newsp); return key_senderror(so, m, EINVAL); } } if (isr->saidx.dst.ss_family && dst0) { sa = (struct sockaddr *)(dst0 + 1); if (sa->sa_family != isr->saidx.dst.ss_family) { keydb_delsecpolicy(newsp); return key_senderror(so, m, EINVAL); } } } newsp->created = time_second; newsp->lastused = time_second; newsp->lifetime = lft ? lft->sadb_lifetime_addtime : 0; newsp->validtime = lft ? lft->sadb_lifetime_usetime : 0; newsp->state = IPSEC_SPSTATE_ALIVE; LIST_INSERT_TAIL(&sptree[newsp->dir], newsp, secpolicy, chain); /* delete the entry in spacqtree */ if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE && mhp->ext[SADB_EXT_ADDRESS_SRC]) { struct secspacq *spacq; if ((spacq = key_getspacq(&spidx)) != NULL) { /* reset counter in order to deletion by timehandler. */ spacq->created = time_second; spacq->count = 0; } } /* invalidate all cached SPD pointers on pcb */ ipsec_invalpcbcacheall(); { struct mbuf *n, *mpolicy; struct sadb_msg *newmsg; int off; /* create new sadb_msg to reply. */ if (lft) { n = key_gather_mbuf(m, mhp, 2, 5, SADB_EXT_RESERVED, SADB_X_EXT_POLICY, SADB_EXT_LIFETIME_HARD, SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST); } else { n = key_gather_mbuf(m, mhp, 2, 4, SADB_EXT_RESERVED, SADB_X_EXT_POLICY, SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST); } if (!n) return key_senderror(so, m, ENOBUFS); if (n->m_len < sizeof(*newmsg)) { n = m_pullup(n, sizeof(*newmsg)); if (!n) return key_senderror(so, m, ENOBUFS); } newmsg = mtod(n, struct sadb_msg *); newmsg->sadb_msg_errno = 0; newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len); off = 0; mpolicy = m_pulldown(n, PFKEY_ALIGN8(sizeof(struct sadb_msg)), sizeof(*xpl), &off); if (mpolicy == NULL) { /* n is already freed */ return key_senderror(so, m, ENOBUFS); } xpl = (struct sadb_x_policy *)(mtod(mpolicy, caddr_t) + off); if (xpl->sadb_x_policy_exttype != SADB_X_EXT_POLICY) { m_freem(n); return key_senderror(so, m, EINVAL); } xpl->sadb_x_policy_id = newsp->id; m_freem(m); return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); } } /* * SADB_SPDDELETE processing * receive * * from the user(?), and set SADB_SASTATE_DEAD, * and send, * * to the ikmpd. * policy(*) including the direction of the policy. * * m will always be freed. */ static int key_spddelete(so, m, mhp) struct socket *so; struct mbuf *m; const struct sadb_msghdr *mhp; { struct sadb_address *src0, *dst0; struct sadb_x_policy *xpl0; struct secpolicyindex spidx; struct secpolicy *sp; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_spddelete: NULL pointer is passed."); if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL || mhp->ext[SADB_EXT_ADDRESS_DST] == NULL || mhp->ext[SADB_X_EXT_POLICY] == NULL) { ipseclog((LOG_DEBUG, "key_spddelete: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } if (mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) || mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address) || mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) { ipseclog((LOG_DEBUG, "key_spddelete: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC]; dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST]; xpl0 = (struct sadb_x_policy *)mhp->ext[SADB_X_EXT_POLICY]; /* make secindex */ /* XXX boundary check against sa_len */ KEY_SETSECSPIDX(src0 + 1, dst0 + 1, src0->sadb_address_prefixlen, dst0->sadb_address_prefixlen, src0->sadb_address_proto, &spidx); /* checking the direciton. */ switch (xpl0->sadb_x_policy_dir) { case IPSEC_DIR_INBOUND: case IPSEC_DIR_OUTBOUND: break; default: ipseclog((LOG_DEBUG, "key_spddelete: Invalid SP direction.\n")); return key_senderror(so, m, EINVAL); } /* Is there SP in SPD ? */ if ((sp = key_getsp(&spidx, xpl0->sadb_x_policy_dir)) == NULL) { ipseclog((LOG_DEBUG, "key_spddelete: no SP found.\n")); return key_senderror(so, m, EINVAL); } if (sp->persist) { ipseclog((LOG_DEBUG, "key_spddelete2: attempt to remove persistent SP:%u.\n", sp->id)); key_freesp(sp); /* ref gained by key_getsp */ return key_senderror(so, m, EPERM); } /* save policy id to be returned. */ xpl0->sadb_x_policy_id = sp->id; key_sp_dead(sp); key_freesp(sp); /* ref gained by key_getsp */ key_sp_unlink(sp); sp = NULL; /* invalidate all cached SPD pointers on pcb */ ipsec_invalpcbcacheall(); { struct mbuf *n; struct sadb_msg *newmsg; /* create new sadb_msg to reply. */ n = key_gather_mbuf(m, mhp, 1, 4, SADB_EXT_RESERVED, SADB_X_EXT_POLICY, SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST); if (!n) return key_senderror(so, m, ENOBUFS); newmsg = mtod(n, struct sadb_msg *); newmsg->sadb_msg_errno = 0; newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len); m_freem(m); return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); } } /* * SADB_SPDDELETE2 processing * receive * * from the user(?), and set SADB_SASTATE_DEAD, * and send, * * to the ikmpd. * policy(*) including the policy id. * * m will always be freed. */ static int key_spddelete2(so, m, mhp) struct socket *so; struct mbuf *m; const struct sadb_msghdr *mhp; { u_int32_t id; struct secpolicy *sp; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_spddelete2: NULL pointer is passed."); if (mhp->ext[SADB_X_EXT_POLICY] == NULL || mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) { ipseclog((LOG_DEBUG, "key_spddelete2: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } id = ((struct sadb_x_policy *)mhp->ext[SADB_X_EXT_POLICY])->sadb_x_policy_id; /* Is there SP in SPD ? */ if ((sp = key_getspbyid(id)) == NULL) { ipseclog((LOG_DEBUG, "key_spddelete2: no SP found id:%u.\n", id)); return key_senderror(so, m, EINVAL); } if (sp->persist) { ipseclog((LOG_DEBUG, "key_spddelete2: attempt to remove persistent SP:%u.\n", id)); key_freesp(sp); /* ref gained by key_getspbyid */ return key_senderror(so, m, EPERM); } key_sp_dead(sp); key_freesp(sp); /* ref gained by key_getspbyid */ key_sp_unlink(sp); sp = NULL; /* invalidate all cached SPD pointers on pcb */ ipsec_invalpcbcacheall(); { struct mbuf *n, *nn; struct sadb_msg *newmsg; int off, len; /* create new sadb_msg to reply. */ len = PFKEY_ALIGN8(sizeof(struct sadb_msg)); if (len > MCLBYTES) return key_senderror(so, m, ENOBUFS); MGETHDR(n, M_DONTWAIT, MT_DATA); if (n && len > MHLEN) { MCLGET(n, M_DONTWAIT); if ((n->m_flags & M_EXT) == 0) { m_freem(n); n = NULL; } } if (!n) return key_senderror(so, m, ENOBUFS); n->m_len = len; n->m_next = NULL; off = 0; m_copydata(m, 0, sizeof(struct sadb_msg), mtod(n, caddr_t) + off); off += PFKEY_ALIGN8(sizeof(struct sadb_msg)); #ifdef DIAGNOSTIC if (off != len) panic("length inconsistency in key_spddelete2"); #endif n->m_next = m_copym(m, mhp->extoff[SADB_X_EXT_POLICY], mhp->extlen[SADB_X_EXT_POLICY], M_DONTWAIT); if (!n->m_next) { m_freem(n); return key_senderror(so, m, ENOBUFS); } n->m_pkthdr.len = 0; for (nn = n; nn; nn = nn->m_next) n->m_pkthdr.len += nn->m_len; newmsg = mtod(n, struct sadb_msg *); newmsg->sadb_msg_errno = 0; newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len); m_freem(m); return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); } } /* * SADB_X_SPDGET processing * receive * * from the user(?), * and send, * * to the ikmpd. * policy(*) including direction of policy. * * m will always be freed. */ static int key_spdget(so, m, mhp) struct socket *so; struct mbuf *m; const struct sadb_msghdr *mhp; { u_int32_t id; struct secpolicy *sp; struct mbuf *n; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_spdget: NULL pointer is passed."); if (mhp->ext[SADB_X_EXT_POLICY] == NULL || mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) { ipseclog((LOG_DEBUG, "key_spdget: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } id = ((struct sadb_x_policy *)mhp->ext[SADB_X_EXT_POLICY])->sadb_x_policy_id; /* Is there SP in SPD ? */ if ((sp = key_getspbyid(id)) == NULL) { ipseclog((LOG_DEBUG, "key_spdget: no SP found id:%u.\n", id)); return key_senderror(so, m, ENOENT); } n = key_setdumpsp(sp, SADB_X_SPDGET, 0, mhp->msg->sadb_msg_pid); key_freesp(sp); /* ref gained by key_getspbyid */ if (n != NULL) { m_freem(m); return key_sendup_mbuf(so, n, KEY_SENDUP_ONE); } else return key_senderror(so, m, ENOBUFS); } /* * SADB_X_SPDACQUIRE processing. * Acquire policy and SA(s) for a *OUTBOUND* packet. * send * * to KMD, and expect to receive * with SADB_X_SPDACQUIRE if error occured, * or * * with SADB_X_SPDUPDATE from KMD by PF_KEY. * policy(*) is without policy requests. * * 0 : succeed * others: error number */ int key_spdacquire(sp) struct secpolicy *sp; { struct mbuf *result = NULL, *m; #ifndef IPSEC_NONBLOCK_ACQUIRE struct secspacq *newspacq; #endif int error = -1; /* sanity check */ if (sp == NULL) panic("key_spdacquire: NULL pointer is passed."); if (sp->req != NULL) panic("key_spdacquire: called but there is request."); if (sp->policy != IPSEC_POLICY_IPSEC) panic("key_spdacquire: policy mismathed. IPsec is expected."); if (!sp->spidx) { error = EOPNOTSUPP; goto fail; } #ifndef IPSEC_NONBLOCK_ACQUIRE /* get an entry to check whether sent message or not. */ if ((newspacq = key_getspacq(sp->spidx)) != NULL) { if (key_blockacq_count < newspacq->count) { /* reset counter and do send message. */ newspacq->count = 0; } else { /* increment counter and do nothing. */ newspacq->count++; return 0; } } else { /* make new entry for blocking to send SADB_ACQUIRE. */ if ((newspacq = key_newspacq(sp->spidx)) == NULL) return ENOBUFS; /* add to acqtree */ LIST_INSERT_HEAD(&spacqtree, newspacq, chain); } #endif /* create new sadb_msg to reply. */ m = key_setsadbmsg(SADB_X_SPDACQUIRE, 0, 0, 0, 0, 0); if (!m) { error = ENOBUFS; goto fail; } result = m; /* set sadb_x_policy */ if (sp) { m = key_setsadbxpolicy(sp->policy, sp->dir, sp->id); if (!m) { error = ENOBUFS; goto fail; } m_cat(result, m); } result->m_pkthdr.len = 0; for (m = result; m; m = m->m_next) result->m_pkthdr.len += m->m_len; mtod(result, struct sadb_msg *)->sadb_msg_len = PFKEY_UNIT64(result->m_pkthdr.len); return key_sendup_mbuf(NULL, result, KEY_SENDUP_REGISTERED); fail: if (result) m_freem(result); return error; } /* * SADB_SPDFLUSH processing * receive * * from the user, and free all entries in secpctree. * and send, * * to the user. * NOTE: what to do is only marking SADB_SASTATE_DEAD. * * m will always be freed. */ static int key_spdflush(so, m, mhp) struct socket *so; struct mbuf *m; const struct sadb_msghdr *mhp; { struct sadb_msg *newmsg; struct secpolicy *sp, *nextsp; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_spdflush: NULL pointer is passed."); if (m->m_len != PFKEY_ALIGN8(sizeof(struct sadb_msg))) return key_senderror(so, m, EINVAL); for (sp = TAILQ_FIRST(&sptailq); sp; sp = nextsp) { nextsp = TAILQ_NEXT(sp, tailq); if (sp->persist) continue; if (sp->state == IPSEC_SPSTATE_DEAD) continue; key_sp_dead(sp); key_sp_unlink(sp); sp = NULL; } /* invalidate all cached SPD pointers on pcb */ ipsec_invalpcbcacheall(); if (sizeof(struct sadb_msg) > m->m_len + M_TRAILINGSPACE(m)) { ipseclog((LOG_DEBUG, "key_spdflush: No more memory.\n")); return key_senderror(so, m, ENOBUFS); } if (m->m_next) m_freem(m->m_next); m->m_next = NULL; m->m_pkthdr.len = m->m_len = PFKEY_ALIGN8(sizeof(struct sadb_msg)); newmsg = mtod(m, struct sadb_msg *); newmsg->sadb_msg_errno = 0; newmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len); return key_sendup_mbuf(so, m, KEY_SENDUP_ALL); } /* * SADB_SPDDUMP processing * receive * * from the user, and dump all SP leaves * and send, * ..... * to the ikmpd. * * m will always be freed. */ static int key_spddump(so, m, mhp) struct socket *so; struct mbuf *m; const struct sadb_msghdr *mhp; { struct secpolicy *sp; int cnt; u_int dir; struct mbuf *n; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_spddump: NULL pointer is passed."); /* search SPD entry and get buffer size. */ cnt = 0; for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { LIST_FOREACH(sp, &sptree[dir], chain) { cnt++; } } if (cnt == 0) return key_senderror(so, m, ENOENT); for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { LIST_FOREACH(sp, &sptree[dir], chain) { --cnt; n = key_setdumpsp(sp, SADB_X_SPDDUMP, cnt, mhp->msg->sadb_msg_pid); if (n) key_sendup_mbuf(so, n, KEY_SENDUP_ONE); } } m_freem(m); return 0; } static struct mbuf * key_setdumpsp(sp, type, seq, pid) struct secpolicy *sp; u_int8_t type; u_int32_t seq, pid; { struct mbuf *result = NULL, *m; m = key_setsadbmsg(type, 0, SADB_SATYPE_UNSPEC, seq, pid, sp->refcnt); if (!m) goto fail; result = m; if (sp->spidx) { m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC, (struct sockaddr *)&sp->spidx->src, sp->spidx->prefs, sp->spidx->ul_proto); if (!m) goto fail; m_cat(result, m); m = key_setsadbaddr(SADB_EXT_ADDRESS_DST, (struct sockaddr *)&sp->spidx->dst, sp->spidx->prefd, sp->spidx->ul_proto); if (!m) goto fail; m_cat(result, m); } m = key_sp2msg(sp); if (!m) goto fail; m_cat(result, m); m = key_setsadblifetime(SADB_EXT_LIFETIME_CURRENT, 0, 0, (u_int64_t)sp->created, (u_int64_t)sp->lastused); if (!m) goto fail; m_cat(result, m); m = key_setsadblifetime(SADB_EXT_LIFETIME_HARD, 0, 0, (u_int64_t)sp->lifetime, (u_int64_t)sp->validtime); if (!m) goto fail; m_cat(result, m); if ((result->m_flags & M_PKTHDR) == 0) goto fail; if (result->m_len < sizeof(struct sadb_msg)) { result = m_pullup(result, sizeof(struct sadb_msg)); if (result == NULL) goto fail; } result->m_pkthdr.len = 0; for (m = result; m; m = m->m_next) result->m_pkthdr.len += m->m_len; mtod(result, struct sadb_msg *)->sadb_msg_len = PFKEY_UNIT64(result->m_pkthdr.len); return result; fail: m_freem(result); return NULL; } /* * get PFKEY message length for security policy and request. */ static u_int key_getspreqmsglen(sp) struct secpolicy *sp; { u_int tlen; tlen = sizeof(struct sadb_x_policy); /* if is the policy for ipsec ? */ if (sp->policy != IPSEC_POLICY_IPSEC) return tlen; /* get length of ipsec requests */ { struct ipsecrequest *isr; int len; for (isr = sp->req; isr != NULL; isr = isr->next) { len = sizeof(struct sadb_x_ipsecrequest) + isr->saidx.src.ss_len + isr->saidx.dst.ss_len; tlen += PFKEY_ALIGN8(len); } } return tlen; } /* * SADB_X_SPDEXPIRE processing * send * * to KMD by PF_KEY. * * OUT: 0 : succeed * others : error number */ static int key_spdexpire(sp) struct secpolicy *sp; { int s; struct mbuf *result = NULL, *m; int len; int error = -1; struct sadb_lifetime *lt; /* XXX: Why do we lock ? */ s = splnet(); /*called from softclock()*/ /* sanity check */ if (sp == NULL) panic("key_spdexpire: NULL pointer is passed."); /* set msg header */ m = key_setsadbmsg(SADB_X_SPDEXPIRE, 0, 0, 0, 0, 0); if (!m) { error = ENOBUFS; goto fail; } result = m; /* create lifetime extension (current and hard) */ len = PFKEY_ALIGN8(sizeof(*lt)) * 2; m = key_alloc_mbuf(len); if (!m || m->m_next) { /*XXX*/ if (m) m_freem(m); error = ENOBUFS; goto fail; } bzero(mtod(m, caddr_t), len); lt = mtod(m, struct sadb_lifetime *); lt->sadb_lifetime_len = PFKEY_UNIT64(sizeof(struct sadb_lifetime)); lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT; lt->sadb_lifetime_allocations = 0; lt->sadb_lifetime_bytes = 0; lt->sadb_lifetime_addtime = sp->created; lt->sadb_lifetime_usetime = sp->lastused; lt = (struct sadb_lifetime *)(mtod(m, caddr_t) + len / 2); lt->sadb_lifetime_len = PFKEY_UNIT64(sizeof(struct sadb_lifetime)); lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; lt->sadb_lifetime_allocations = 0; lt->sadb_lifetime_bytes = 0; lt->sadb_lifetime_addtime = sp->lifetime; lt->sadb_lifetime_usetime = sp->validtime; m_cat(result, m); /* set sadb_address for source */ if (sp->spidx) { m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC, (struct sockaddr *)&sp->spidx->src, sp->spidx->prefs, sp->spidx->ul_proto); if (!m) { error = ENOBUFS; goto fail; } m_cat(result, m); /* set sadb_address for destination */ m = key_setsadbaddr(SADB_EXT_ADDRESS_DST, (struct sockaddr *)&sp->spidx->dst, sp->spidx->prefd, sp->spidx->ul_proto); if (!m) { error = ENOBUFS; goto fail; } m_cat(result, m); } /* set secpolicy */ m = key_sp2msg(sp); if (!m) { error = ENOBUFS; goto fail; } m_cat(result, m); if ((result->m_flags & M_PKTHDR) == 0) { error = EINVAL; goto fail; } if (result->m_len < sizeof(struct sadb_msg)) { result = m_pullup(result, sizeof(struct sadb_msg)); if (result == NULL) { error = ENOBUFS; goto fail; } } result->m_pkthdr.len = 0; for (m = result; m; m = m->m_next) result->m_pkthdr.len += m->m_len; mtod(result, struct sadb_msg *)->sadb_msg_len = PFKEY_UNIT64(result->m_pkthdr.len); splx(s); return key_sendup_mbuf(NULL, result, KEY_SENDUP_REGISTERED); fail: if (result) m_freem(result); splx(s); return error; } /* %%% SAD management */ /* * allocating a memory for new SA head, and copy from the values of mhp. * OUT: NULL : failure due to the lack of memory. * others : pointer to new SA head. */ static struct secashead * key_newsah(saidx) struct secasindex *saidx; { struct secashead *newsah; /* sanity check */ if (saidx == NULL) panic("key_newsaidx: NULL pointer is passed."); newsah = keydb_newsecashead(); if (newsah == NULL) return NULL; bcopy(saidx, &newsah->saidx, sizeof(newsah->saidx)); /* add to saidxtree */ newsah->state = SADB_SASTATE_MATURE; LIST_INSERT_HEAD(&sahtree, newsah, chain); return (newsah); } /* * delete SA index and all SA registerd. */ static void key_delsah(sah) struct secashead *sah; { struct secasvar *sav, *nextsav; u_int stateidx, state; int s; int zombie = 0; /* sanity check */ if (sah == NULL) panic("key_delsah: NULL pointer is passed."); s = splnet(); /*called from softclock()*/ /* searching all SA registerd in the secindex. */ for (stateidx = 0; stateidx < _ARRAYLEN(saorder_state_any); stateidx++) { state = saorder_state_any[stateidx]; for (sav = LIST_FIRST(&sah->savtree[state]); sav != NULL; sav = nextsav) { nextsav = LIST_NEXT(sav, chain); if (sav->refcnt > 0) { /* give up to delete this sa */ zombie++; continue; } /* sanity check */ KEY_CHKSASTATE(state, sav->state, "key_delsah"); /* remove back pointer */ sav->sah = NULL; key_freesav(sav); sav = NULL; } } /* delete sah only if there's no sav. */ if (zombie) { splx(s); return; } if (sah->sa_route.ro_rt) { RTFREE(sah->sa_route.ro_rt); sah->sa_route.ro_rt = (struct rtentry *)NULL; } /* remove from tree of SA index */ if (__LIST_CHAINED(sah)) LIST_REMOVE(sah, chain); KFREE(sah); splx(s); return; } /* * allocating a new SA with LARVAL state. key_add() and key_getspi() call, * and copy the values of mhp into new buffer. * When SAD message type is GETSPI: * to set sequence number from acq_seq++, * to set zero to SPI. * not to call key_setsava(). * OUT: NULL : fail * others : pointer to new secasvar. * * does not modify mbuf. does not free mbuf on error. */ static struct secasvar * key_newsav(m, mhp, sah, errp) struct mbuf *m; const struct sadb_msghdr *mhp; struct secashead *sah; int *errp; { struct secasvar *newsav; const struct sadb_sa *xsa; /* sanity check */ if (m == NULL || mhp == NULL || mhp->msg == NULL || sah == NULL) panic("key_newsa: NULL pointer is passed."); newsav = keydb_newsecasvar(); if (newsav == NULL) { ipseclog((LOG_DEBUG, "key_newsa: No more memory.\n")); *errp = ENOBUFS; return NULL; } switch (mhp->msg->sadb_msg_type) { case SADB_GETSPI: key_setspi(newsav, 0); #ifdef IPSEC_DOSEQCHECK /* sync sequence number */ if (mhp->msg->sadb_msg_seq == 0) newsav->seq = (acq_seq = (acq_seq == ~0 ? 1 : ++acq_seq)); else #endif newsav->seq = mhp->msg->sadb_msg_seq; break; case SADB_ADD: /* sanity check */ if (mhp->ext[SADB_EXT_SA] == NULL) { KFREE(newsav); ipseclog((LOG_DEBUG, "key_newsa: invalid message is passed.\n")); *errp = EINVAL; return NULL; } xsa = (const struct sadb_sa *)mhp->ext[SADB_EXT_SA]; key_setspi(newsav, xsa->sadb_sa_spi); newsav->seq = mhp->msg->sadb_msg_seq; break; default: KFREE(newsav); *errp = EINVAL; return NULL; } /* copy sav values */ if (mhp->msg->sadb_msg_type != SADB_GETSPI) { *errp = key_setsaval(newsav, m, mhp); if (*errp) { KFREE(newsav); return NULL; } } /* reset created */ newsav->created = time_second; newsav->pid = mhp->msg->sadb_msg_pid; /* add to satree */ newsav->sah = sah; newsav->refcnt = 1; newsav->state = SADB_SASTATE_LARVAL; LIST_INSERT_TAIL(&sah->savtree[SADB_SASTATE_LARVAL], newsav, secasvar, chain); return newsav; } /* * search SAD. * OUT: * NULL : not found * others : found, pointer to a SA. */ static struct secashead * key_getsah(saidx) struct secasindex *saidx; { struct secashead *sah; LIST_FOREACH(sah, &sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; if (key_cmpsaidx(&sah->saidx, saidx, CMP_MODE_REQID)) return sah; } return NULL; } /* * check not to be duplicated SPI. * NOTE: this function is too slow due to searching all SAD. * OUT: * NULL : not found * others : found, pointer to a SA. */ static struct secasvar * key_checkspidup(saidx, spi) struct secasindex *saidx; u_int32_t spi; { struct secasvar *sav; u_int stateidx, state; /* check address family */ if (saidx->src.ss_family != saidx->dst.ss_family) { ipseclog((LOG_DEBUG, "key_checkspidup: address family mismatched.\n")); return NULL; } /* check all SAD */ LIST_FOREACH(sav, &spihash[SPIHASH(spi)], spihash) { if (sav->spi != spi) continue; for (stateidx = 0; stateidx < _ARRAYLEN(saorder_state_alive); stateidx++) { state = saorder_state_alive[stateidx]; if (sav->state == state && key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst)) return sav; } } return NULL; } static void key_setspi(sav, spi) struct secasvar *sav; u_int32_t spi; { int s; s = splnet(); sav->spi = spi; if (sav->spihash.le_prev || sav->spihash.le_next) LIST_REMOVE(sav, spihash); LIST_INSERT_HEAD(&spihash[SPIHASH(spi)], sav, spihash); splx(s); } /* * search SAD litmited alive SA, protocol, SPI. * OUT: * NULL : not found * others : found, pointer to a SA. */ static struct secasvar * key_getsavbyspi(sah, spi) struct secashead *sah; u_int32_t spi; { struct secasvar *sav, *match; u_int stateidx, state, matchidx; match = NULL; matchidx = _ARRAYLEN(saorder_state_alive); LIST_FOREACH(sav, &spihash[SPIHASH(spi)], spihash) { if (sav->spi != spi) continue; if (sav->sah != sah) continue; for (stateidx = 0; stateidx < matchidx; stateidx++) { state = saorder_state_alive[stateidx]; if (sav->state == state) { match = sav; matchidx = stateidx; break; } } } return match; } /* * copy SA values from PF_KEY message except *SPI, SEQ, PID, STATE and TYPE*. * You must update these if need. * OUT: 0: success. * !0: failure. * * does not modify mbuf. does not free mbuf on error. */ static int key_setsaval(sav, m, mhp) struct secasvar *sav; struct mbuf *m; const struct sadb_msghdr *mhp; { #ifdef IPSEC_ESP const struct esp_algorithm *algo; #endif int error = 0; /* sanity check */ if (m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_setsaval: NULL pointer is passed."); /* initialization */ sav->replay = NULL; sav->key_auth = NULL; sav->key_enc = NULL; sav->sched = NULL; sav->schedlen = 0; sav->iv = NULL; sav->lft_c = NULL; sav->lft_h = NULL; sav->lft_s = NULL; /* SA */ if (mhp->ext[SADB_EXT_SA] != NULL) { const struct sadb_sa *sa0; sa0 = (const struct sadb_sa *)mhp->ext[SADB_EXT_SA]; if (mhp->extlen[SADB_EXT_SA] < sizeof(*sa0)) { error = EINVAL; goto fail; } sav->alg_auth = sa0->sadb_sa_auth; sav->alg_enc = sa0->sadb_sa_encrypt; sav->flags = sa0->sadb_sa_flags; /* replay window */ if ((sa0->sadb_sa_flags & SADB_X_EXT_OLD) == 0) { sav->replay = keydb_newsecreplay(sa0->sadb_sa_replay); if (sav->replay == NULL) { ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n")); error = ENOBUFS; goto fail; } } } /* Authentication keys */ if (mhp->ext[SADB_EXT_KEY_AUTH] != NULL) { const struct sadb_key *key0; int len; key0 = (const struct sadb_key *)mhp->ext[SADB_EXT_KEY_AUTH]; len = mhp->extlen[SADB_EXT_KEY_AUTH]; error = 0; if (len < sizeof(*key0)) { error = EINVAL; goto fail; } switch (mhp->msg->sadb_msg_satype) { case SADB_SATYPE_AH: case SADB_SATYPE_ESP: case SADB_X_SATYPE_TCPSIGNATURE: if (len == PFKEY_ALIGN8(sizeof(struct sadb_key)) && sav->alg_auth != SADB_X_AALG_NULL) error = EINVAL; break; case SADB_X_SATYPE_IPCOMP: default: error = EINVAL; break; } if (error) { ipseclog((LOG_DEBUG, "key_setsaval: invalid key_auth values.\n")); goto fail; } sav->key_auth = (struct sadb_key *)key_newbuf(key0, len); if (sav->key_auth == NULL) { ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n")); error = ENOBUFS; goto fail; } } /* Encryption key */ if (mhp->ext[SADB_EXT_KEY_ENCRYPT] != NULL) { const struct sadb_key *key0; int len; key0 = (const struct sadb_key *)mhp->ext[SADB_EXT_KEY_ENCRYPT]; len = mhp->extlen[SADB_EXT_KEY_ENCRYPT]; error = 0; if (len < sizeof(*key0)) { error = EINVAL; goto fail; } switch (mhp->msg->sadb_msg_satype) { case SADB_SATYPE_ESP: if (len == PFKEY_ALIGN8(sizeof(struct sadb_key)) && sav->alg_enc != SADB_EALG_NULL) { error = EINVAL; break; } sav->key_enc = (struct sadb_key *)key_newbuf(key0, len); if (sav->key_enc == NULL) { ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n")); error = ENOBUFS; goto fail; } break; case SADB_X_SATYPE_IPCOMP: if (len != PFKEY_ALIGN8(sizeof(struct sadb_key))) error = EINVAL; sav->key_enc = NULL; /*just in case*/ break; case SADB_SATYPE_AH: case SADB_X_SATYPE_TCPSIGNATURE: default: error = EINVAL; break; } if (error) { ipseclog((LOG_DEBUG, "key_setsatval: invalid key_enc value.\n")); goto fail; } } /* set iv */ sav->ivlen = 0; switch (mhp->msg->sadb_msg_satype) { case SADB_SATYPE_ESP: #ifdef IPSEC_ESP algo = esp_algorithm_lookup(sav->alg_enc); if (algo && algo->ivlen) sav->ivlen = (*algo->ivlen)(algo, sav); if (sav->ivlen == 0) break; KMALLOC(sav->iv, caddr_t, sav->ivlen); if (sav->iv == 0) { ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n")); error = ENOBUFS; goto fail; } /* initialize */ key_randomfill(sav->iv, sav->ivlen); #endif break; case SADB_SATYPE_AH: case SADB_X_SATYPE_IPCOMP: case SADB_X_SATYPE_TCPSIGNATURE: break; default: ipseclog((LOG_DEBUG, "key_setsaval: invalid SA type.\n")); error = EINVAL; goto fail; } /* reset created */ sav->created = time_second; /* make lifetime for CURRENT */ KMALLOC(sav->lft_c, struct sadb_lifetime *, sizeof(struct sadb_lifetime)); if (sav->lft_c == NULL) { ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n")); error = ENOBUFS; goto fail; } sav->lft_c->sadb_lifetime_len = PFKEY_UNIT64(sizeof(struct sadb_lifetime)); sav->lft_c->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT; sav->lft_c->sadb_lifetime_allocations = 0; sav->lft_c->sadb_lifetime_bytes = 0; sav->lft_c->sadb_lifetime_addtime = time_second; sav->lft_c->sadb_lifetime_usetime = 0; /* lifetimes for HARD and SOFT */ { const struct sadb_lifetime *lft0; lft0 = (struct sadb_lifetime *)mhp->ext[SADB_EXT_LIFETIME_HARD]; if (lft0 != NULL) { if (mhp->extlen[SADB_EXT_LIFETIME_HARD] < sizeof(*lft0)) { error = EINVAL; goto fail; } sav->lft_h = (struct sadb_lifetime *)key_newbuf(lft0, sizeof(*lft0)); if (sav->lft_h == NULL) { ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n")); error = ENOBUFS; goto fail; } /* we no longer support byte lifetime */ if (sav->lft_h->sadb_lifetime_bytes) { error = EINVAL; goto fail; } /* initialize? */ } lft0 = (struct sadb_lifetime *)mhp->ext[SADB_EXT_LIFETIME_SOFT]; if (lft0 != NULL) { if (mhp->extlen[SADB_EXT_LIFETIME_SOFT] < sizeof(*lft0)) { error = EINVAL; goto fail; } sav->lft_s = (struct sadb_lifetime *)key_newbuf(lft0, sizeof(*lft0)); if (sav->lft_s == NULL) { ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n")); error = ENOBUFS; goto fail; } /* we no longer support byte lifetime */ if (sav->lft_s->sadb_lifetime_bytes) { error = EINVAL; goto fail; } /* initialize? */ } } return 0; fail: /* initialization */ if (sav->replay != NULL) { keydb_delsecreplay(sav->replay); sav->replay = NULL; } if (sav->key_auth != NULL) { bzero(_KEYBUF(sav->key_auth), _KEYLEN(sav->key_auth)); KFREE(sav->key_auth); sav->key_auth = NULL; } if (sav->key_enc != NULL) { bzero(_KEYBUF(sav->key_enc), _KEYLEN(sav->key_enc)); KFREE(sav->key_enc); sav->key_enc = NULL; } if (sav->sched) { bzero(sav->sched, sav->schedlen); KFREE(sav->sched); sav->sched = NULL; } if (sav->iv != NULL) { KFREE(sav->iv); sav->iv = NULL; } if (sav->lft_c != NULL) { KFREE(sav->lft_c); sav->lft_c = NULL; } if (sav->lft_h != NULL) { KFREE(sav->lft_h); sav->lft_h = NULL; } if (sav->lft_s != NULL) { KFREE(sav->lft_s); sav->lft_s = NULL; } return error; } /* * validation with a secasvar entry, and set SADB_SATYPE_MATURE. * OUT: 0: valid * other: errno */ static int key_mature(sav) struct secasvar *sav; { int mature; int checkmask = 0; /* 2^0: ealg 2^1: aalg 2^2: calg */ int mustmask = 0; /* 2^0: ealg 2^1: aalg 2^2: calg */ mature = 0; /* check SPI value */ switch (sav->sah->saidx.proto) { case IPPROTO_ESP: case IPPROTO_AH: if (ntohl(sav->spi) >= 0 && ntohl(sav->spi) <= 255) { ipseclog((LOG_DEBUG, "key_mature: illegal range of SPI %u.\n", (u_int32_t)ntohl(sav->spi))); return EINVAL; } break; } /* check satype */ switch (sav->sah->saidx.proto) { case IPPROTO_ESP: /* check flags */ if ((sav->flags & SADB_X_EXT_OLD) && (sav->flags & SADB_X_EXT_DERIV)) { ipseclog((LOG_DEBUG, "key_mature: " "invalid flag (derived) given to old-esp.\n")); return EINVAL; } if (sav->alg_auth == SADB_AALG_NONE) checkmask = 1; else checkmask = 3; mustmask = 1; break; case IPPROTO_AH: /* check flags */ if (sav->flags & SADB_X_EXT_DERIV) { ipseclog((LOG_DEBUG, "key_mature: " "invalid flag (derived) given to AH SA.\n")); return EINVAL; } if (sav->alg_enc != SADB_EALG_NONE) { ipseclog((LOG_DEBUG, "key_mature: " "protocol and algorithm mismated.\n")); return (EINVAL); } checkmask = 2; mustmask = 2; break; case IPPROTO_IPCOMP: if (sav->alg_auth != SADB_AALG_NONE) { ipseclog((LOG_DEBUG, "key_mature: " "protocol and algorithm mismated.\n")); return (EINVAL); } if ((sav->flags & SADB_X_EXT_RAWCPI) == 0 && ntohl(sav->spi) >= 0x10000) { ipseclog((LOG_DEBUG, "key_mature: invalid cpi for IPComp.\n")); return (EINVAL); } checkmask = 4; mustmask = 4; break; case IPPROTO_TCP: if (sav->alg_auth != SADB_X_AALG_TCP_MD5) { ipseclog((LOG_DEBUG, "key_mature: unsupported authentication algorithm %u\n", sav->alg_auth)); return (EINVAL); } if (sav->alg_enc != SADB_EALG_NONE) { ipseclog((LOG_DEBUG, "%s: protocol and algorithm " "mismated.\n", __func__)); return(EINVAL); } if (sav->spi != htonl(0x1000)) { ipseclog((LOG_DEBUG, "key_mature: SPI must be TCP_SIG_SPI (0x1000)\n")); return (EINVAL); } checkmask = 2; mustmask = 2; break; default: ipseclog((LOG_DEBUG, "key_mature: Invalid satype.\n")); return EPROTONOSUPPORT; } /* check authentication algorithm */ if ((checkmask & 2) != 0) { const struct ah_algorithm *algo; int keylen; algo = ah_algorithm_lookup(sav->alg_auth); if (!algo) { ipseclog((LOG_DEBUG, "key_mature: " "unknown authentication algorithm.\n")); return EINVAL; } /* algorithm-dependent check */ if (sav->key_auth) keylen = sav->key_auth->sadb_key_bits; else keylen = 0; if (keylen < algo->keymin || algo->keymax < keylen) { ipseclog((LOG_DEBUG, "key_mature: invalid AH key length %d " "(%d-%d allowed)\n", keylen, algo->keymin, algo->keymax)); return EINVAL; } if (algo->mature) { if ((*algo->mature)(sav)) { /* message generated in per-algorithm function*/ return EINVAL; } else mature = SADB_SATYPE_AH; } if ((mustmask & 2) != 0 && mature != SADB_SATYPE_AH) { ipseclog((LOG_DEBUG, "key_mature: no satisfy algorithm for AH\n")); return EINVAL; } } /* check encryption algorithm */ if ((checkmask & 1) != 0) { #ifdef IPSEC_ESP const struct esp_algorithm *algo; int keylen; algo = esp_algorithm_lookup(sav->alg_enc); if (!algo) { ipseclog((LOG_DEBUG, "key_mature: unknown encryption algorithm.\n")); return EINVAL; } /* algorithm-dependent check */ if (sav->key_enc) keylen = sav->key_enc->sadb_key_bits; else keylen = 0; if (keylen < algo->keymin || algo->keymax < keylen) { ipseclog((LOG_DEBUG, "key_mature: invalid ESP key length %d " "(%d-%d allowed)\n", keylen, algo->keymin, algo->keymax)); return EINVAL; } if (algo->mature) { if ((*algo->mature)(sav)) { /* message generated in per-algorithm function*/ return EINVAL; } else mature = SADB_SATYPE_ESP; } if ((mustmask & 1) != 0 && mature != SADB_SATYPE_ESP) { ipseclog((LOG_DEBUG, "key_mature: no satisfy algorithm for ESP\n")); return EINVAL; } #else /*IPSEC_ESP*/ ipseclog((LOG_DEBUG, "key_mature: ESP not supported in this configuration\n")); return EINVAL; #endif } /* check compression algorithm */ if ((checkmask & 4) != 0) { const struct ipcomp_algorithm *algo; /* algorithm-dependent check */ algo = ipcomp_algorithm_lookup(sav->alg_enc); if (!algo) { ipseclog((LOG_DEBUG, "key_mature: unknown compression algorithm.\n")); return EINVAL; } } key_sa_chgstate(sav, SADB_SASTATE_MATURE); return 0; } /* * subroutine for SADB_GET and SADB_DUMP. */ static struct mbuf * key_setdumpsa(sav, type, satype, seq, pid) struct secasvar *sav; u_int8_t type, satype; u_int32_t seq, pid; { struct mbuf *result = NULL, *tres = NULL, *m; int l = 0; int i; void *p; int dumporder[] = { SADB_EXT_SA, SADB_X_EXT_SA2, SADB_EXT_LIFETIME_HARD, SADB_EXT_LIFETIME_SOFT, SADB_EXT_LIFETIME_CURRENT, SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST, SADB_EXT_ADDRESS_PROXY, SADB_EXT_KEY_AUTH, SADB_EXT_KEY_ENCRYPT, SADB_EXT_IDENTITY_SRC, SADB_EXT_IDENTITY_DST, SADB_EXT_SENSITIVITY, }; m = key_setsadbmsg(type, 0, satype, seq, pid, sav->refcnt); if (m == NULL) goto fail; result = m; for (i = sizeof(dumporder)/sizeof(dumporder[0]) - 1; i >= 0; i--) { m = NULL; p = NULL; switch (dumporder[i]) { case SADB_EXT_SA: m = key_setsadbsa(sav); if (!m) goto fail; break; case SADB_X_EXT_SA2: m = key_setsadbxsa2(sav->sah->saidx.mode, sav->replay ? (sav->replay->count & 0xffffffff) : 0, sav->sah->saidx.reqid); if (!m) goto fail; break; case SADB_EXT_ADDRESS_SRC: m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC, (struct sockaddr *)&sav->sah->saidx.src, FULLMASK, IPSEC_ULPROTO_ANY); if (!m) goto fail; break; case SADB_EXT_ADDRESS_DST: m = key_setsadbaddr(SADB_EXT_ADDRESS_DST, (struct sockaddr *)&sav->sah->saidx.dst, FULLMASK, IPSEC_ULPROTO_ANY); if (!m) goto fail; break; case SADB_EXT_KEY_AUTH: if (!sav->key_auth) continue; l = PFKEY_UNUNIT64(sav->key_auth->sadb_key_len); p = sav->key_auth; break; case SADB_EXT_KEY_ENCRYPT: if (!sav->key_enc) continue; l = PFKEY_UNUNIT64(sav->key_enc->sadb_key_len); p = sav->key_enc; break; case SADB_EXT_LIFETIME_CURRENT: if (!sav->lft_c) continue; l = PFKEY_UNUNIT64(((struct sadb_ext *)sav->lft_c)->sadb_ext_len); p = sav->lft_c; break; case SADB_EXT_LIFETIME_HARD: if (!sav->lft_h) continue; l = PFKEY_UNUNIT64(((struct sadb_ext *)sav->lft_h)->sadb_ext_len); p = sav->lft_h; break; case SADB_EXT_LIFETIME_SOFT: if (!sav->lft_s) continue; l = PFKEY_UNUNIT64(((struct sadb_ext *)sav->lft_s)->sadb_ext_len); p = sav->lft_s; break; case SADB_EXT_ADDRESS_PROXY: case SADB_EXT_IDENTITY_SRC: case SADB_EXT_IDENTITY_DST: /* XXX: should we brought from SPD ? */ case SADB_EXT_SENSITIVITY: default: continue; } if ((!m && !p) || (m && p)) goto fail; if (p && tres) { M_PREPEND(tres, l, M_DONTWAIT); if (!tres) goto fail; bcopy(p, mtod(tres, caddr_t), l); continue; } if (p) { m = key_alloc_mbuf(l); if (!m) goto fail; m_copyback(m, 0, l, p); } if (tres) m_cat(m, tres); tres = m; } m_cat(result, tres); if (result->m_len < sizeof(struct sadb_msg)) { result = m_pullup(result, sizeof(struct sadb_msg)); if (result == NULL) goto fail; } result->m_pkthdr.len = 0; for (m = result; m; m = m->m_next) result->m_pkthdr.len += m->m_len; mtod(result, struct sadb_msg *)->sadb_msg_len = PFKEY_UNIT64(result->m_pkthdr.len); return result; fail: m_freem(result); m_freem(tres); return NULL; } /* * set data into sadb_msg. */ static struct mbuf * key_setsadbmsg(type, tlen, satype, seq, pid, reserved) u_int8_t type, satype; u_int16_t tlen; u_int32_t seq; pid_t pid; u_int16_t reserved; { struct mbuf *m; struct sadb_msg *p; int len; len = PFKEY_ALIGN8(sizeof(struct sadb_msg)); if (len > MCLBYTES) return NULL; MGETHDR(m, M_DONTWAIT, MT_DATA); if (m && len > MHLEN) { MCLGET(m, M_DONTWAIT); if ((m->m_flags & M_EXT) == 0) { m_freem(m); m = NULL; } } if (!m) return NULL; m->m_pkthdr.len = m->m_len = len; m->m_next = NULL; p = mtod(m, struct sadb_msg *); bzero(p, len); p->sadb_msg_version = PF_KEY_V2; p->sadb_msg_type = type; p->sadb_msg_errno = 0; p->sadb_msg_satype = satype; p->sadb_msg_len = PFKEY_UNIT64(tlen); p->sadb_msg_reserved = reserved; p->sadb_msg_seq = seq; p->sadb_msg_pid = (u_int32_t)pid; return m; } /* * copy secasvar data into sadb_address. */ static struct mbuf * key_setsadbsa(sav) struct secasvar *sav; { struct mbuf *m; struct sadb_sa *p; int len; len = PFKEY_ALIGN8(sizeof(struct sadb_sa)); m = key_alloc_mbuf(len); if (!m || m->m_next) { /*XXX*/ if (m) m_freem(m); return NULL; } p = mtod(m, struct sadb_sa *); bzero(p, len); p->sadb_sa_len = PFKEY_UNIT64(len); p->sadb_sa_exttype = SADB_EXT_SA; p->sadb_sa_spi = sav->spi; p->sadb_sa_replay = (sav->replay != NULL ? sav->replay->wsize : 0); p->sadb_sa_state = sav->state; p->sadb_sa_auth = sav->alg_auth; p->sadb_sa_encrypt = sav->alg_enc; p->sadb_sa_flags = sav->flags; return m; } /* * set data into sadb_address. */ static struct mbuf * key_setsadbaddr(exttype, saddr, prefixlen, ul_proto) u_int16_t exttype; struct sockaddr *saddr; u_int8_t prefixlen; u_int16_t ul_proto; { struct mbuf *m; struct sadb_address *p; size_t len; len = PFKEY_ALIGN8(sizeof(struct sadb_address)) + PFKEY_ALIGN8(saddr->sa_len); m = key_alloc_mbuf(len); if (!m || m->m_next) { /*XXX*/ if (m) m_freem(m); return NULL; } p = mtod(m, struct sadb_address *); bzero(p, len); p->sadb_address_len = PFKEY_UNIT64(len); p->sadb_address_exttype = exttype; p->sadb_address_proto = ul_proto; if (prefixlen == FULLMASK) { switch (saddr->sa_family) { case AF_INET: prefixlen = sizeof(struct in_addr) << 3; break; case AF_INET6: prefixlen = sizeof(struct in6_addr) << 3; break; default: ; /*XXX*/ } } p->sadb_address_prefixlen = prefixlen; p->sadb_address_reserved = 0; bcopy(saddr, mtod(m, caddr_t) + PFKEY_ALIGN8(sizeof(struct sadb_address)), saddr->sa_len); return m; } #if 0 /* * set data into sadb_ident. */ static struct mbuf * key_setsadbident(exttype, idtype, string, stringlen, id) u_int16_t exttype, idtype; caddr_t string; int stringlen; u_int64_t id; { struct mbuf *m; struct sadb_ident *p; size_t len; len = PFKEY_ALIGN8(sizeof(struct sadb_ident)) + PFKEY_ALIGN8(stringlen); m = key_alloc_mbuf(len); if (!m || m->m_next) { /*XXX*/ if (m) m_freem(m); return NULL; } p = mtod(m, struct sadb_ident *); bzero(p, len); p->sadb_ident_len = PFKEY_UNIT64(len); p->sadb_ident_exttype = exttype; p->sadb_ident_type = idtype; p->sadb_ident_reserved = 0; p->sadb_ident_id = id; bcopy(string, mtod(m, caddr_t) + PFKEY_ALIGN8(sizeof(struct sadb_ident)), stringlen); return m; } #endif /* * set data into sadb_x_sa2. */ static struct mbuf * key_setsadbxsa2(mode, seq, reqid) u_int8_t mode; u_int32_t seq, reqid; { struct mbuf *m; struct sadb_x_sa2 *p; size_t len; len = PFKEY_ALIGN8(sizeof(struct sadb_x_sa2)); m = key_alloc_mbuf(len); if (!m || m->m_next) { /*XXX*/ if (m) m_freem(m); return NULL; } p = mtod(m, struct sadb_x_sa2 *); bzero(p, len); p->sadb_x_sa2_len = PFKEY_UNIT64(len); p->sadb_x_sa2_exttype = SADB_X_EXT_SA2; p->sadb_x_sa2_mode = mode; p->sadb_x_sa2_reserved1 = 0; p->sadb_x_sa2_reserved2 = 0; p->sadb_x_sa2_sequence = seq; p->sadb_x_sa2_reqid = reqid; return m; } /* * set data into sadb_lifetime */ static struct mbuf * key_setsadblifetime(type, alloc, bytes, addtime, usetime) u_int16_t type; u_int32_t alloc; u_int64_t bytes, addtime, usetime; { struct mbuf *m; struct sadb_lifetime *p; size_t len; len = PFKEY_ALIGN8(sizeof(struct sadb_lifetime)); m = key_alloc_mbuf(len); if (!m || m->m_next) { /*XXX*/ if (m) m_freem(m); return NULL; } p = mtod(m, struct sadb_lifetime *); bzero(p, len); p->sadb_lifetime_len = PFKEY_UNIT64(len); p->sadb_lifetime_exttype = type; p->sadb_lifetime_allocations = alloc; p->sadb_lifetime_bytes = bytes; p->sadb_lifetime_addtime = addtime; p->sadb_lifetime_usetime = usetime; return m; } /* * set data into sadb_x_policy */ static struct mbuf * key_setsadbxpolicy(type, dir, id) u_int16_t type; u_int8_t dir; u_int32_t id; { struct mbuf *m; struct sadb_x_policy *p; size_t len; len = PFKEY_ALIGN8(sizeof(struct sadb_x_policy)); m = key_alloc_mbuf(len); if (!m || m->m_next) { /*XXX*/ if (m) m_freem(m); return NULL; } p = mtod(m, struct sadb_x_policy *); bzero(p, len); p->sadb_x_policy_len = PFKEY_UNIT64(len); p->sadb_x_policy_exttype = SADB_X_EXT_POLICY; p->sadb_x_policy_type = type; p->sadb_x_policy_dir = dir; p->sadb_x_policy_id = id; return m; } /* %%% utilities */ /* * copy a buffer into the new buffer allocated. */ static void * key_newbuf(src, len) const void *src; u_int len; { caddr_t new; KMALLOC(new, caddr_t, len); if (new == NULL) { ipseclog((LOG_DEBUG, "key_newbuf: No more memory.\n")); return NULL; } bcopy(src, new, len); return new; } /* compare my own address * OUT: 1: true, i.e. my address. * 0: false */ static int key_ismyaddr(sa) struct sockaddr *sa; { #ifdef INET struct sockaddr_in *sin; struct in_ifaddr *ia; #endif /* sanity check */ if (sa == NULL) panic("key_ismyaddr: NULL pointer is passed."); switch (sa->sa_family) { #ifdef INET case AF_INET: sin = (struct sockaddr_in *)sa; for (ia = in_ifaddrhead.tqh_first; ia; ia = ia->ia_link.tqe_next) { if (sin->sin_family == ia->ia_addr.sin_family && sin->sin_len == ia->ia_addr.sin_len && sin->sin_addr.s_addr == ia->ia_addr.sin_addr.s_addr) { return 1; } } break; #endif #ifdef INET6 case AF_INET6: return key_ismyaddr6((struct sockaddr_in6 *)sa); #endif } return 0; } #ifdef INET6 /* * compare my own address for IPv6. * 1: ours * 0: other * NOTE: derived ip6_input() in KAME. This is necessary to modify more. */ #include static int key_ismyaddr6(sin6) struct sockaddr_in6 *sin6; { struct in6_ifaddr *ia; struct in6_multi *in6m; for (ia = in6_ifaddr; ia; ia = ia->ia_next) { if (key_sockaddrcmp((struct sockaddr *)&sin6, (struct sockaddr *)&ia->ia_addr, 0) == 0) return 1; /* * XXX Multicast * XXX why do we care about multlicast here while we don't care * about IPv4 multicast?? */ in6m = NULL; IN6_LOOKUP_MULTI(sin6->sin6_addr, ia->ia_ifp, in6m); if (in6m) return 1; } /* loopback, just for safety */ if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)) return 1; return 0; } #endif /*INET6*/ /* * compare two secasindex structure. * flag can specify to compare 2 saidxes. * compare two secasindex structure without both mode and reqid. * don't compare port. * IN: * saidx0: source, it can be in SAD. * saidx1: object. * OUT: * 1 : equal * 0 : not equal */ static int key_cmpsaidx(saidx0, saidx1, flag) struct secasindex *saidx0, *saidx1; int flag; { /* sanity */ if (saidx0 == NULL && saidx1 == NULL) return 1; if (saidx0 == NULL || saidx1 == NULL) return 0; if (saidx0->proto != saidx1->proto) return 0; if (flag == CMP_EXACTLY) { if (saidx0->mode != saidx1->mode) return 0; if (saidx0->reqid != saidx1->reqid) return 0; if (bcmp(&saidx0->src, &saidx1->src, saidx0->src.ss_len) != 0 || bcmp(&saidx0->dst, &saidx1->dst, saidx0->dst.ss_len) != 0) return 0; } else { /* CMP_MODE_REQID, CMP_HEAD */ if (flag == CMP_MODE_REQID) { /* * If reqid of SPD is non-zero, unique SA is required. * The result must be of same reqid in this case. */ if (saidx1->reqid != 0 && saidx0->reqid != saidx1->reqid) return 0; } if (flag == CMP_MODE_REQID) { if (saidx0->mode != IPSEC_MODE_ANY && saidx0->mode != saidx1->mode) return 0; } if (key_sockaddrcmp((struct sockaddr *)&saidx0->src, (struct sockaddr *)&saidx1->src, 0) != 0) { return 0; } if (key_sockaddrcmp((struct sockaddr *)&saidx0->dst, (struct sockaddr *)&saidx1->dst, 0) != 0) { return 0; } } return 1; } /* * compare two secindex structure exactly. * IN: * spidx0: source, it is often in SPD. * spidx1: object, it is often from PFKEY message. * OUT: * 1 : equal * 0 : not equal */ int key_cmpspidx_exactly(spidx0, spidx1) struct secpolicyindex *spidx0, *spidx1; { /* sanity */ if (spidx0 == NULL && spidx1 == NULL) return 1; if (spidx0 == NULL || spidx1 == NULL) return 0; if (spidx0->prefs != spidx1->prefs || spidx0->prefd != spidx1->prefd || spidx0->ul_proto != spidx1->ul_proto) return 0; if (key_sockaddrcmp((struct sockaddr *)&spidx0->src, (struct sockaddr *)&spidx1->src, 1) != 0) { return 0; } if (key_sockaddrcmp((struct sockaddr *)&spidx0->dst, (struct sockaddr *)&spidx1->dst, 1) != 0) { return 0; } return 1; } /* * compare two secindex structure with mask. * IN: * spidx0: source, it is often in SPD. * spidx1: object, it is often from IP header. * OUT: * 1 : equal * 0 : not equal */ int key_cmpspidx_withmask(spidx0, spidx1) struct secpolicyindex *spidx0, *spidx1; { /* sanity */ if (spidx0 == NULL && spidx1 == NULL) return 1; if (spidx0 == NULL || spidx1 == NULL) return 0; if (spidx0->src.ss_family != spidx1->src.ss_family || spidx0->dst.ss_family != spidx1->dst.ss_family || spidx0->src.ss_len != spidx1->src.ss_len || spidx0->dst.ss_len != spidx1->dst.ss_len) return 0; /* if spidx.ul_proto == IPSEC_ULPROTO_ANY, ignore. */ if (spidx0->ul_proto != (u_int16_t)IPSEC_ULPROTO_ANY && spidx0->ul_proto != spidx1->ul_proto) return 0; switch (spidx0->src.ss_family) { case AF_INET: if (satosin(&spidx0->src)->sin_port != IPSEC_PORT_ANY && satosin(&spidx0->src)->sin_port != satosin(&spidx1->src)->sin_port) return 0; if (!key_bbcmp((caddr_t)&satosin(&spidx0->src)->sin_addr, (caddr_t)&satosin(&spidx1->src)->sin_addr, spidx0->prefs)) return 0; break; case AF_INET6: if (satosin6(&spidx0->src)->sin6_port != IPSEC_PORT_ANY && satosin6(&spidx0->src)->sin6_port != satosin6(&spidx1->src)->sin6_port) return 0; /* * scope_id check. if sin6_scope_id is 0, we regard it * as a wildcard scope, which matches any scope zone ID. */ if (satosin6(&spidx0->src)->sin6_scope_id && satosin6(&spidx1->src)->sin6_scope_id && satosin6(&spidx0->src)->sin6_scope_id != satosin6(&spidx1->src)->sin6_scope_id) return 0; if (!key_bbcmp((caddr_t)&satosin6(&spidx0->src)->sin6_addr, (caddr_t)&satosin6(&spidx1->src)->sin6_addr, spidx0->prefs)) return 0; break; default: /* XXX */ if (bcmp(&spidx0->src, &spidx1->src, spidx0->src.ss_len) != 0) return 0; break; } switch (spidx0->dst.ss_family) { case AF_INET: if (satosin(&spidx0->dst)->sin_port != IPSEC_PORT_ANY && satosin(&spidx0->dst)->sin_port != satosin(&spidx1->dst)->sin_port) return 0; if (!key_bbcmp((caddr_t)&satosin(&spidx0->dst)->sin_addr, (caddr_t)&satosin(&spidx1->dst)->sin_addr, spidx0->prefd)) return 0; break; case AF_INET6: if (satosin6(&spidx0->dst)->sin6_port != IPSEC_PORT_ANY && satosin6(&spidx0->dst)->sin6_port != satosin6(&spidx1->dst)->sin6_port) return 0; /* * scope_id check. if sin6_scope_id is 0, we regard it * as a wildcard scope, which matches any scope zone ID. */ if (satosin6(&spidx0->src)->sin6_scope_id && satosin6(&spidx1->src)->sin6_scope_id && satosin6(&spidx0->dst)->sin6_scope_id != satosin6(&spidx1->dst)->sin6_scope_id) return 0; if (!key_bbcmp((caddr_t)&satosin6(&spidx0->dst)->sin6_addr, (caddr_t)&satosin6(&spidx1->dst)->sin6_addr, spidx0->prefd)) return 0; break; default: /* XXX */ if (bcmp(&spidx0->dst, &spidx1->dst, spidx0->dst.ss_len) != 0) return 0; break; } /* XXX Do we check other field ? e.g. flowinfo */ return 1; } /* returns 0 on match */ static int key_sockaddrcmp(sa1, sa2, port) struct sockaddr *sa1; struct sockaddr *sa2; int port; { if (sa1->sa_family != sa2->sa_family || sa1->sa_len != sa2->sa_len) return 1; switch (sa1->sa_family) { case AF_INET: if (sa1->sa_len != sizeof(struct sockaddr_in)) return 1; if (satosin(sa1)->sin_addr.s_addr != satosin(sa2)->sin_addr.s_addr) { return 1; } if (port && satosin(sa1)->sin_port != satosin(sa2)->sin_port) return 1; break; case AF_INET6: if (sa1->sa_len != sizeof(struct sockaddr_in6)) return 1; /*EINVAL*/ if (satosin6(sa1)->sin6_scope_id != satosin6(sa2)->sin6_scope_id) { return 1; } if (!IN6_ARE_ADDR_EQUAL(&satosin6(sa1)->sin6_addr, &satosin6(sa2)->sin6_addr)) { return 1; } if (port && satosin6(sa1)->sin6_port != satosin6(sa2)->sin6_port) { return 1; } break; default: if (bcmp(sa1, sa2, sa1->sa_len) != 0) return 1; break; } return 0; } /* * compare two buffers with mask. * IN: * addr1: source * addr2: object * bits: Number of bits to compare * OUT: * 1 : equal * 0 : not equal */ static int key_bbcmp(p1, p2, bits) caddr_t p1, p2; u_int bits; { u_int8_t mask; /* XXX: This could be considerably faster if we compare a word * at a time, but it is complicated on LSB Endian machines */ /* Handle null pointers */ if (p1 == NULL || p2 == NULL) return (p1 == p2); while (bits >= 8) { if (*p1++ != *p2++) return 0; bits -= 8; } if (bits > 0) { mask = ~((1<<(8-bits))-1); if ((*p1 & mask) != (*p2 & mask)) return 0; } return 1; /* Match! */ } /* * time handler. * scanning SPD and SAD to check status for each entries, * and do to remove or to expire. * XXX: year 2038 problem may remain. */ void key_timehandler(arg) void *arg; { u_int dir; int s; struct timeval tv; microtime(&tv); s = splnet(); /*called from softclock()*/ /* SPD */ { struct secpolicy *sp, *nextsp; for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { for (sp = LIST_FIRST(&sptree[dir]); sp != NULL; sp = nextsp) { nextsp = LIST_NEXT(sp, chain); if (sp->state == IPSEC_SPSTATE_DEAD) { key_sp_unlink(sp); /*XXX*/ sp = NULL; continue; } if (sp->lifetime == 0 && sp->validtime == 0) continue; /* the deletion will occur next time */ if ((sp->lifetime && tv.tv_sec - sp->created > sp->lifetime) || (sp->validtime && tv.tv_sec - sp->lastused > sp->validtime)) { key_sp_dead(sp); key_spdexpire(sp); continue; } } } /* invalidate all cached SPD pointers on pcb */ ipsec_invalpcbcacheall(); } /* SAD */ { struct secashead *sah, *nextsah; struct secasvar *sav, *nextsav; for (sah = LIST_FIRST(&sahtree); sah != NULL; sah = nextsah) { nextsah = LIST_NEXT(sah, chain); /* if sah has been dead, then delete it and process next sah. */ if (sah->state == SADB_SASTATE_DEAD) { key_delsah(sah); continue; } /* if LARVAL entry doesn't become MATURE, delete it. */ for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_LARVAL]); sav != NULL; sav = nextsav) { nextsav = LIST_NEXT(sav, chain); if (tv.tv_sec - sav->created > key_larval_lifetime) { key_freesav(sav); } } /* * check MATURE entry to start to send expire message * whether or not. */ for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_MATURE]); sav != NULL; sav = nextsav) { nextsav = LIST_NEXT(sav, chain); /* we don't need to check. */ if (sav->lft_s == NULL) continue; /* sanity check */ if (sav->lft_c == NULL) { ipseclog((LOG_DEBUG, "key_timehandler: " "There is no CURRENT time, why?\n")); continue; } /* check SOFT lifetime */ if (sav->lft_s->sadb_lifetime_addtime != 0 && tv.tv_sec - sav->created > sav->lft_s->sadb_lifetime_addtime) { /* * check the SA if it has been used. * when it hasn't been used, delete it. * i don't think such SA will be used. */ if (sav->lft_c->sadb_lifetime_usetime == 0) { key_sa_chgstate(sav, SADB_SASTATE_DEAD); key_freesav(sav); sav = NULL; } else { key_sa_chgstate(sav, SADB_SASTATE_DYING); /* * XXX If we keep to send expire * message in the status of * DYING. Do remove below code. */ key_expire(sav); } } /* check SOFT lifetime by bytes */ /* * XXX I don't know the way to delete this SA * when new SA is installed. Caution when it's * installed too big lifetime by time. */ else if (sav->lft_s->sadb_lifetime_bytes != 0 && sav->lft_s->sadb_lifetime_bytes < sav->lft_c->sadb_lifetime_bytes) { key_sa_chgstate(sav, SADB_SASTATE_DYING); /* * XXX If we keep to send expire * message in the status of * DYING. Do remove below code. */ key_expire(sav); } } /* check DYING entry to change status to DEAD. */ for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_DYING]); sav != NULL; sav = nextsav) { nextsav = LIST_NEXT(sav, chain); /* we don't need to check. */ if (sav->lft_h == NULL) continue; /* sanity check */ if (sav->lft_c == NULL) { ipseclog((LOG_DEBUG, "key_timehandler: " "There is no CURRENT time, why?\n")); continue; } if (sav->lft_h->sadb_lifetime_addtime != 0 && tv.tv_sec - sav->created > sav->lft_h->sadb_lifetime_addtime) { key_sa_chgstate(sav, SADB_SASTATE_DEAD); key_freesav(sav); sav = NULL; } #if 0 /* XXX Should we keep to send expire message until HARD lifetime ? */ else if (sav->lft_s != NULL && sav->lft_s->sadb_lifetime_addtime != 0 && tv.tv_sec - sav->created > sav->lft_s->sadb_lifetime_addtime) { /* * XXX: should be checked to be * installed the valid SA. */ /* * If there is no SA then sending * expire message. */ key_expire(sav); } #endif /* check HARD lifetime by bytes */ else if (sav->lft_h->sadb_lifetime_bytes != 0 && sav->lft_h->sadb_lifetime_bytes < sav->lft_c->sadb_lifetime_bytes) { key_sa_chgstate(sav, SADB_SASTATE_DEAD); key_freesav(sav); sav = NULL; } } /* delete entry in DEAD */ for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_DEAD]); sav != NULL; sav = nextsav) { nextsav = LIST_NEXT(sav, chain); /* sanity check */ if (sav->state != SADB_SASTATE_DEAD) { ipseclog((LOG_DEBUG, "key_timehandler: " "invalid sav->state " "(queue: %u SA: %u): " "kill it anyway\n", SADB_SASTATE_DEAD, sav->state)); } /* * do not call key_freesav() here. * sav should already be freed, and sav->refcnt * shows other references to sav * (such as from SPD). */ } } } #ifndef IPSEC_NONBLOCK_ACQUIRE /* ACQ tree */ { struct secacq *acq, *nextacq; for (acq = LIST_FIRST(&acqtree); acq != NULL; acq = nextacq) { nextacq = LIST_NEXT(acq, chain); if (tv.tv_sec - acq->created > key_blockacq_lifetime && __LIST_CHAINED(acq)) { LIST_REMOVE(acq, chain); KFREE(acq); } } } #endif /* SP ACQ tree */ { struct secspacq *acq, *nextacq; for (acq = LIST_FIRST(&spacqtree); acq != NULL; acq = nextacq) { nextacq = LIST_NEXT(acq, chain); if (tv.tv_sec - acq->created > key_blockacq_lifetime && __LIST_CHAINED(acq)) { LIST_REMOVE(acq, chain); KFREE(acq); } } } /* * should set timeout based on the most closest timer expiration. * we don't bother to do that yet. */ callout_reset(&key_timehandler_ch, hz, key_timehandler, (void *)0); splx(s); return; } static u_long key_random() { u_long value; key_randomfill(&value, sizeof(value)); return value; } void key_randomfill(p, l) void *p; size_t l; { size_t n; u_long v; static int warn = 1; n = 0; n = (size_t)read_random(p, (u_int)l); /* last resort */ while (n < l) { v = random(); bcopy(&v, (u_int8_t *)p + n, l - n < sizeof(v) ? l - n : sizeof(v)); n += sizeof(v); if (warn) { printf("WARNING: pseudo-random number generator " "used for IPsec processing\n"); warn = 0; } } } /* * map SADB_SATYPE_* to IPPROTO_*. * if satype == SADB_SATYPE then satype is mapped to ~0. * OUT: * 0: invalid satype. */ static u_int16_t key_satype2proto(satype) u_int8_t satype; { switch (satype) { case SADB_SATYPE_UNSPEC: return IPSEC_PROTO_ANY; case SADB_SATYPE_AH: return IPPROTO_AH; case SADB_SATYPE_ESP: return IPPROTO_ESP; case SADB_X_SATYPE_IPCOMP: return IPPROTO_IPCOMP; case SADB_X_SATYPE_TCPSIGNATURE: return IPPROTO_TCP; default: return 0; } /* NOTREACHED */ } /* * map IPPROTO_* to SADB_SATYPE_* * OUT: * 0: invalid protocol type. */ static u_int8_t key_proto2satype(proto) u_int16_t proto; { switch (proto) { case IPPROTO_AH: return SADB_SATYPE_AH; case IPPROTO_ESP: return SADB_SATYPE_ESP; case IPPROTO_IPCOMP: return SADB_X_SATYPE_IPCOMP; case IPPROTO_TCP: return SADB_X_SATYPE_TCPSIGNATURE; default: return 0; } /* NOTREACHED */ } /* %%% PF_KEY */ /* * SADB_GETSPI processing is to receive * * from the IKMPd, to assign a unique spi value, to hang on the INBOUND * tree with the status of LARVAL, and send * * to the IKMPd. * * IN: mhp: pointer to the pointer to each header. * OUT: NULL if fail. * other if success, return pointer to the message to send. */ static int key_getspi(so, m, mhp) struct socket *so; struct mbuf *m; const struct sadb_msghdr *mhp; { struct sadb_address *src0, *dst0; struct secasindex saidx; struct secashead *newsah; struct secasvar *newsav; u_int8_t proto; u_int32_t spi; u_int8_t mode; u_int32_t reqid; int error; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_getspi: NULL pointer is passed."); if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL || mhp->ext[SADB_EXT_ADDRESS_DST] == NULL) { ipseclog((LOG_DEBUG, "key_getspi: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } if (mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) || mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) { ipseclog((LOG_DEBUG, "key_getspi: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } if (mhp->ext[SADB_X_EXT_SA2] != NULL) { mode = ((struct sadb_x_sa2 *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_mode; reqid = ((struct sadb_x_sa2 *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_reqid; } else { mode = IPSEC_MODE_ANY; reqid = 0; } src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]); dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]); /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { ipseclog((LOG_DEBUG, "key_getspi: invalid satype is passed.\n")); return key_senderror(so, m, EINVAL); } /* make sure if port number is zero. */ switch (((struct sockaddr *)(src0 + 1))->sa_family) { case AF_INET: if (((struct sockaddr *)(src0 + 1))->sa_len != sizeof(struct sockaddr_in)) return key_senderror(so, m, EINVAL); ((struct sockaddr_in *)(src0 + 1))->sin_port = 0; break; case AF_INET6: if (((struct sockaddr *)(src0 + 1))->sa_len != sizeof(struct sockaddr_in6)) return key_senderror(so, m, EINVAL); ((struct sockaddr_in6 *)(src0 + 1))->sin6_port = 0; break; default: ; /*???*/ } switch (((struct sockaddr *)(dst0 + 1))->sa_family) { case AF_INET: if (((struct sockaddr *)(dst0 + 1))->sa_len != sizeof(struct sockaddr_in)) return key_senderror(so, m, EINVAL); ((struct sockaddr_in *)(dst0 + 1))->sin_port = 0; break; case AF_INET6: if (((struct sockaddr *)(dst0 + 1))->sa_len != sizeof(struct sockaddr_in6)) return key_senderror(so, m, EINVAL); ((struct sockaddr_in6 *)(dst0 + 1))->sin6_port = 0; break; default: ; /*???*/ } /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); /* SPI allocation */ spi = key_do_getnewspi((struct sadb_spirange *)mhp->ext[SADB_EXT_SPIRANGE], &saidx); if (spi == 0) return key_senderror(so, m, EINVAL); /* get a SA index */ if ((newsah = key_getsah(&saidx)) == NULL) { /* create a new SA index */ if ((newsah = key_newsah(&saidx)) == NULL) { ipseclog((LOG_DEBUG, "key_getspi: No more memory.\n")); return key_senderror(so, m, ENOBUFS); } } /* get a new SA */ /* XXX rewrite */ newsav = key_newsav(m, mhp, newsah, &error); if (newsav == NULL) { /* XXX don't free new SA index allocated in above. */ return key_senderror(so, m, error); } /* set spi */ key_setspi(newsav, htonl(spi)); #ifndef IPSEC_NONBLOCK_ACQUIRE /* delete the entry in acqtree */ if (mhp->msg->sadb_msg_seq != 0) { struct secacq *acq; if ((acq = key_getacqbyseq(mhp->msg->sadb_msg_seq)) != NULL) { /* reset counter in order to deletion by timehandler. */ acq->created = time_second; acq->count = 0; } } #endif { struct mbuf *n, *nn; struct sadb_sa *m_sa; struct sadb_msg *newmsg; int off, len; /* create new sadb_msg to reply. */ len = PFKEY_ALIGN8(sizeof(struct sadb_msg)) + PFKEY_ALIGN8(sizeof(struct sadb_sa)); if (len > MCLBYTES) return key_senderror(so, m, ENOBUFS); MGETHDR(n, M_DONTWAIT, MT_DATA); if (len > MHLEN) { MCLGET(n, M_DONTWAIT); if ((n->m_flags & M_EXT) == 0) { m_freem(n); n = NULL; } } if (!n) return key_senderror(so, m, ENOBUFS); n->m_len = len; n->m_next = NULL; off = 0; m_copydata(m, 0, sizeof(struct sadb_msg), mtod(n, caddr_t) + off); off += PFKEY_ALIGN8(sizeof(struct sadb_msg)); m_sa = (struct sadb_sa *)(mtod(n, caddr_t) + off); m_sa->sadb_sa_len = PFKEY_UNIT64(sizeof(struct sadb_sa)); m_sa->sadb_sa_exttype = SADB_EXT_SA; m_sa->sadb_sa_spi = htonl(spi); off += PFKEY_ALIGN8(sizeof(struct sadb_sa)); #ifdef DIAGNOSTIC if (off != len) panic("length inconsistency in key_getspi"); #endif n->m_next = key_gather_mbuf(m, mhp, 0, 2, SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST); if (!n->m_next) { m_freem(n); return key_senderror(so, m, ENOBUFS); } if (n->m_len < sizeof(struct sadb_msg)) { n = m_pullup(n, sizeof(struct sadb_msg)); if (n == NULL) return key_sendup_mbuf(so, m, KEY_SENDUP_ONE); } n->m_pkthdr.len = 0; for (nn = n; nn; nn = nn->m_next) n->m_pkthdr.len += nn->m_len; newmsg = mtod(n, struct sadb_msg *); newmsg->sadb_msg_seq = newsav->seq; newmsg->sadb_msg_errno = 0; newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len); m_freem(m); return key_sendup_mbuf(so, n, KEY_SENDUP_ONE); } } /* * allocating new SPI * called by key_getspi(). * OUT: * 0: failure. * others: success. */ static u_int32_t key_do_getnewspi(spirange, saidx) struct sadb_spirange *spirange; struct secasindex *saidx; { u_int32_t newspi; u_int32_t min, max; int count = key_spi_trycnt; /* set spi range to allocate */ if (spirange != NULL) { min = spirange->sadb_spirange_min; max = spirange->sadb_spirange_max; } else { min = key_spi_minval; max = key_spi_maxval; } /* IPCOMP needs 2-byte SPI */ if (saidx->proto == IPPROTO_IPCOMP) { u_int32_t t; if (min >= 0x10000) min = 0xffff; if (max >= 0x10000) max = 0xffff; if (min > max) { t = min; min = max; max = t; } } if (min == max) { if (key_checkspidup(saidx, min) != NULL) { ipseclog((LOG_DEBUG, "key_do_getnewspi: SPI %u exists already.\n", min)); return 0; } count--; /* taking one cost. */ newspi = min; } else { /* init SPI */ newspi = 0; /* when requesting to allocate spi ranged */ while (count--) { /* generate pseudo-random SPI value ranged. */ newspi = min + (key_random() % (max - min + 1)); if (key_checkspidup(saidx, newspi) == NULL) break; } if (count == 0 || newspi == 0) { ipseclog((LOG_DEBUG, "key_do_getnewspi: to allocate spi is failed.\n")); return 0; } } /* statistics */ keystat.getspi_count = (keystat.getspi_count + key_spi_trycnt - count) / 2; return newspi; } /* * SADB_UPDATE processing * receive * * from the ikmpd, and update a secasvar entry whose status is SADB_SASTATE_LARVAL. * and send * * to the ikmpd. * * m will always be freed. */ static int key_update(so, m, mhp) struct socket *so; struct mbuf *m; const struct sadb_msghdr *mhp; { struct sadb_sa *sa0; struct sadb_address *src0, *dst0; struct secasindex saidx; struct secashead *sah; struct secasvar *sav; u_int16_t proto; u_int8_t mode; u_int32_t reqid; int error; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_update: NULL pointer is passed."); /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { ipseclog((LOG_DEBUG, "key_update: invalid satype is passed.\n")); return key_senderror(so, m, EINVAL); } if (mhp->ext[SADB_EXT_SA] == NULL || mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL || mhp->ext[SADB_EXT_ADDRESS_DST] == NULL || (mhp->msg->sadb_msg_satype == SADB_SATYPE_ESP && mhp->ext[SADB_EXT_KEY_ENCRYPT] == NULL) || (mhp->msg->sadb_msg_satype == SADB_SATYPE_AH && mhp->ext[SADB_EXT_KEY_AUTH] == NULL) || (mhp->ext[SADB_EXT_LIFETIME_HARD] != NULL && mhp->ext[SADB_EXT_LIFETIME_SOFT] == NULL) || (mhp->ext[SADB_EXT_LIFETIME_HARD] == NULL && mhp->ext[SADB_EXT_LIFETIME_SOFT] != NULL)) { ipseclog((LOG_DEBUG, "key_update: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa) || mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) || mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) { ipseclog((LOG_DEBUG, "key_update: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } if (mhp->ext[SADB_X_EXT_SA2] != NULL) { mode = ((struct sadb_x_sa2 *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_mode; reqid = ((struct sadb_x_sa2 *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_reqid; } else { mode = IPSEC_MODE_ANY; reqid = 0; } /* XXX boundary checking for other extensions */ sa0 = (struct sadb_sa *)mhp->ext[SADB_EXT_SA]; src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]); dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]); /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); /* get a SA header */ if ((sah = key_getsah(&saidx)) == NULL) { ipseclog((LOG_DEBUG, "key_update: no SA index found.\n")); return key_senderror(so, m, ENOENT); } /* set spidx if there */ /* XXX rewrite */ error = key_setident(sah, m, mhp); if (error) return key_senderror(so, m, error); /* find a SA with sequence number. */ #ifdef IPSEC_DOSEQCHECK if (mhp->msg->sadb_msg_seq != 0 && (sav = key_getsavbyseq(sah, mhp->msg->sadb_msg_seq)) == NULL) { ipseclog((LOG_DEBUG, "key_update: no larval SA with sequence %u exists.\n", mhp->msg->sadb_msg_seq)); return key_senderror(so, m, ENOENT); } #else if ((sav = key_getsavbyspi(sah, sa0->sadb_sa_spi)) == NULL) { ipseclog((LOG_DEBUG, "key_update: no such a SA found (spi:%u)\n", (u_int32_t)ntohl(sa0->sadb_sa_spi))); return key_senderror(so, m, EINVAL); } #endif /* validity check */ if (sav->sah->saidx.proto != proto) { ipseclog((LOG_DEBUG, "key_update: protocol mismatched (DB=%u param=%u)\n", sav->sah->saidx.proto, proto)); return key_senderror(so, m, EINVAL); } #ifdef IPSEC_DOSEQCHECK if (sav->spi != sa0->sadb_sa_spi) { ipseclog((LOG_DEBUG, "key_update: SPI mismatched (DB:%u param:%u)\n", (u_int32_t)ntohl(sav->spi), (u_int32_t)ntohl(sa0->sadb_sa_spi))); return key_senderror(so, m, EINVAL); } #endif if (sav->pid != mhp->msg->sadb_msg_pid) { ipseclog((LOG_DEBUG, "key_update: pid mismatched (DB:%u param:%u)\n", sav->pid, mhp->msg->sadb_msg_pid)); return key_senderror(so, m, EINVAL); } /* copy sav values */ error = key_setsaval(sav, m, mhp); if (error) { key_freesav(sav); return key_senderror(so, m, error); } /* check SA values to be mature. */ if ((error = key_mature(sav)) != 0) { key_freesav(sav); return key_senderror(so, m, error); } { struct mbuf *n; /* set msg buf from mhp */ n = key_getmsgbuf_x1(m, mhp); if (n == NULL) { ipseclog((LOG_DEBUG, "key_update: No more memory.\n")); return key_senderror(so, m, ENOBUFS); } m_freem(m); return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); } } /* * search SAD with sequence for a SA which state is SADB_SASTATE_LARVAL. * only called by key_update(). * OUT: * NULL : not found * others : found, pointer to a SA. */ #ifdef IPSEC_DOSEQCHECK static struct secasvar * key_getsavbyseq(sah, seq) struct secashead *sah; u_int32_t seq; { struct secasvar *sav; u_int state; state = SADB_SASTATE_LARVAL; /* search SAD with sequence number ? */ LIST_FOREACH(sav, &sah->savtree[state], chain) { KEY_CHKSASTATE(state, sav->state, "key_getsabyseq"); if (sav->seq == seq) { sav->refcnt++; KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP key_getsavbyseq cause " "refcnt++:%d SA:%p\n", sav->refcnt, sav)); return sav; } } return NULL; } #endif /* * SADB_ADD processing * add an entry to SA database, when received * * from the ikmpd, * and send * * to the ikmpd. * * IGNORE identity and sensitivity messages. * * m will always be freed. */ static int key_add(so, m, mhp) struct socket *so; struct mbuf *m; const struct sadb_msghdr *mhp; { struct sadb_sa *sa0; struct sadb_address *src0, *dst0; struct secasindex saidx; struct secashead *newsah; struct secasvar *newsav; u_int16_t proto; u_int8_t mode; u_int32_t reqid; int error; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_add: NULL pointer is passed."); /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { ipseclog((LOG_DEBUG, "key_add: invalid satype is passed.\n")); return key_senderror(so, m, EINVAL); } if (mhp->ext[SADB_EXT_SA] == NULL || mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL || mhp->ext[SADB_EXT_ADDRESS_DST] == NULL || (mhp->msg->sadb_msg_satype == SADB_SATYPE_ESP && mhp->ext[SADB_EXT_KEY_ENCRYPT] == NULL) || (mhp->msg->sadb_msg_satype == SADB_SATYPE_AH && mhp->ext[SADB_EXT_KEY_AUTH] == NULL) || (mhp->ext[SADB_EXT_LIFETIME_HARD] != NULL && mhp->ext[SADB_EXT_LIFETIME_SOFT] == NULL) || (mhp->ext[SADB_EXT_LIFETIME_HARD] == NULL && mhp->ext[SADB_EXT_LIFETIME_SOFT] != NULL)) { ipseclog((LOG_DEBUG, "key_add: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa) || mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) || mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) { /* XXX need more */ ipseclog((LOG_DEBUG, "key_add: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } if (mhp->ext[SADB_X_EXT_SA2] != NULL) { mode = ((struct sadb_x_sa2 *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_mode; reqid = ((struct sadb_x_sa2 *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_reqid; } else { mode = IPSEC_MODE_ANY; reqid = 0; } sa0 = (struct sadb_sa *)mhp->ext[SADB_EXT_SA]; src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC]; dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST]; /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); /* get a SA header */ if ((newsah = key_getsah(&saidx)) == NULL) { /* create a new SA header */ if ((newsah = key_newsah(&saidx)) == NULL) { ipseclog((LOG_DEBUG, "key_add: No more memory.\n")); return key_senderror(so, m, ENOBUFS); } } /* set spidx if there */ /* XXX rewrite */ error = key_setident(newsah, m, mhp); if (error) { return key_senderror(so, m, error); } /* create new SA entry. */ /* We can create new SA only if SPI is differenct. */ if (key_getsavbyspi(newsah, sa0->sadb_sa_spi)) { ipseclog((LOG_DEBUG, "key_add: SA already exists.\n")); return key_senderror(so, m, EEXIST); } newsav = key_newsav(m, mhp, newsah, &error); if (newsav == NULL) { return key_senderror(so, m, error); } /* check SA values to be mature. */ if ((error = key_mature(newsav)) != 0) { key_freesav(newsav); return key_senderror(so, m, error); } /* * don't call key_freesav() here, as we would like to keep the SA * in the database on success. */ { struct mbuf *n; /* set msg buf from mhp */ n = key_getmsgbuf_x1(m, mhp); if (n == NULL) { ipseclog((LOG_DEBUG, "key_update: No more memory.\n")); return key_senderror(so, m, ENOBUFS); } m_freem(m); return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); } } /* m is retained */ static int key_setident(sah, m, mhp) struct secashead *sah; struct mbuf *m; const struct sadb_msghdr *mhp; { const struct sadb_ident *idsrc, *iddst; int idsrclen, iddstlen; /* sanity check */ if (sah == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_setident: NULL pointer is passed."); /* don't make buffer if not there */ if (mhp->ext[SADB_EXT_IDENTITY_SRC] == NULL && mhp->ext[SADB_EXT_IDENTITY_DST] == NULL) { sah->idents = NULL; sah->identd = NULL; return 0; } if (mhp->ext[SADB_EXT_IDENTITY_SRC] == NULL || mhp->ext[SADB_EXT_IDENTITY_DST] == NULL) { ipseclog((LOG_DEBUG, "key_setident: invalid identity.\n")); return EINVAL; } idsrc = (const struct sadb_ident *)mhp->ext[SADB_EXT_IDENTITY_SRC]; iddst = (const struct sadb_ident *)mhp->ext[SADB_EXT_IDENTITY_DST]; idsrclen = mhp->extlen[SADB_EXT_IDENTITY_SRC]; iddstlen = mhp->extlen[SADB_EXT_IDENTITY_DST]; /* validity check */ if (idsrc->sadb_ident_type != iddst->sadb_ident_type) { ipseclog((LOG_DEBUG, "key_setident: ident type mismatch.\n")); return EINVAL; } switch (idsrc->sadb_ident_type) { case SADB_IDENTTYPE_PREFIX: case SADB_IDENTTYPE_FQDN: case SADB_IDENTTYPE_USERFQDN: default: /* XXX do nothing */ sah->idents = NULL; sah->identd = NULL; return 0; } /* make structure */ KMALLOC(sah->idents, struct sadb_ident *, idsrclen); if (sah->idents == NULL) { ipseclog((LOG_DEBUG, "key_setident: No more memory.\n")); return ENOBUFS; } KMALLOC(sah->identd, struct sadb_ident *, iddstlen); if (sah->identd == NULL) { KFREE(sah->idents); sah->idents = NULL; ipseclog((LOG_DEBUG, "key_setident: No more memory.\n")); return ENOBUFS; } bcopy(idsrc, sah->idents, idsrclen); bcopy(iddst, sah->identd, iddstlen); return 0; } /* * m will not be freed on return. * it is caller's responsibility to free the result. */ static struct mbuf * key_getmsgbuf_x1(m, mhp) struct mbuf *m; const struct sadb_msghdr *mhp; { struct mbuf *n; /* sanity check */ if (m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_getmsgbuf_x1: NULL pointer is passed."); /* create new sadb_msg to reply. */ n = key_gather_mbuf(m, mhp, 1, 9, SADB_EXT_RESERVED, SADB_EXT_SA, SADB_X_EXT_SA2, SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST, SADB_EXT_LIFETIME_HARD, SADB_EXT_LIFETIME_SOFT, SADB_EXT_IDENTITY_SRC, SADB_EXT_IDENTITY_DST); if (!n) return NULL; if (n->m_len < sizeof(struct sadb_msg)) { n = m_pullup(n, sizeof(struct sadb_msg)); if (n == NULL) return NULL; } mtod(n, struct sadb_msg *)->sadb_msg_errno = 0; mtod(n, struct sadb_msg *)->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len); return n; } static int key_delete_all(struct socket *, struct mbuf *, const struct sadb_msghdr *, u_int16_t); /* * SADB_DELETE processing * receive * * from the ikmpd, and set SADB_SASTATE_DEAD, * and send, * * to the ikmpd. * * m will always be freed. */ static int key_delete(so, m, mhp) struct socket *so; struct mbuf *m; const struct sadb_msghdr *mhp; { struct sadb_sa *sa0; struct sadb_address *src0, *dst0; struct secasindex saidx; struct secashead *sah; struct secasvar *sav = NULL; u_int16_t proto; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_delete: NULL pointer is passed."); /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { ipseclog((LOG_DEBUG, "key_delete: invalid satype is passed.\n")); return key_senderror(so, m, EINVAL); } if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL || mhp->ext[SADB_EXT_ADDRESS_DST] == NULL) { ipseclog((LOG_DEBUG, "key_delete: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } if (mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) || mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) { ipseclog((LOG_DEBUG, "key_delete: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } if (mhp->ext[SADB_EXT_SA] == NULL) { /* * Caller wants us to delete all non-LARVAL SAs * that match the src/dst. This is used during * IKE INITIAL-CONTACT. */ ipseclog((LOG_DEBUG, "key_delete: doing delete all.\n")); return key_delete_all(so, m, mhp, proto); } else if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa)) { ipseclog((LOG_DEBUG, "key_delete: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } sa0 = (struct sadb_sa *)mhp->ext[SADB_EXT_SA]; src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]); dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]); /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); /* get a SA header */ LIST_FOREACH(sah, &sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; if (key_cmpsaidx(&sah->saidx, &saidx, CMP_HEAD) == 0) continue; /* get a SA with SPI. */ sav = key_getsavbyspi(sah, sa0->sadb_sa_spi); if (sav) break; } if (sah == NULL) { ipseclog((LOG_DEBUG, "key_delete: no SA found.\n")); return key_senderror(so, m, ENOENT); } key_sa_chgstate(sav, SADB_SASTATE_DEAD); key_freesav(sav); sav = NULL; { struct mbuf *n; struct sadb_msg *newmsg; /* create new sadb_msg to reply. */ n = key_gather_mbuf(m, mhp, 1, 4, SADB_EXT_RESERVED, SADB_EXT_SA, SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST); if (!n) return key_senderror(so, m, ENOBUFS); if (n->m_len < sizeof(struct sadb_msg)) { n = m_pullup(n, sizeof(struct sadb_msg)); if (n == NULL) return key_senderror(so, m, ENOBUFS); } newmsg = mtod(n, struct sadb_msg *); newmsg->sadb_msg_errno = 0; newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len); m_freem(m); return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); } } /* * delete all SAs for src/dst. Called from key_delete(). */ static int key_delete_all(so, m, mhp, proto) struct socket *so; struct mbuf *m; const struct sadb_msghdr *mhp; u_int16_t proto; { struct sadb_address *src0, *dst0; struct secasindex saidx; struct secashead *sah; struct secasvar *sav, *nextsav; u_int stateidx, state; src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]); dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]); /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); LIST_FOREACH(sah, &sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; if (key_cmpsaidx(&sah->saidx, &saidx, CMP_HEAD) == 0) continue; /* Delete all non-LARVAL SAs. */ for (stateidx = 0; stateidx < _ARRAYLEN(saorder_state_alive); stateidx++) { state = saorder_state_alive[stateidx]; if (state == SADB_SASTATE_LARVAL) continue; for (sav = LIST_FIRST(&sah->savtree[state]); sav != NULL; sav = nextsav) { nextsav = LIST_NEXT(sav, chain); /* sanity check */ if (sav->state != state) { ipseclog((LOG_DEBUG, "key_delete_all: " "invalid sav->state " "(queue: %u SA: %u)\n", state, sav->state)); continue; } key_sa_chgstate(sav, SADB_SASTATE_DEAD); key_freesav(sav); } } } { struct mbuf *n; struct sadb_msg *newmsg; /* create new sadb_msg to reply. */ n = key_gather_mbuf(m, mhp, 1, 3, SADB_EXT_RESERVED, SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST); if (!n) return key_senderror(so, m, ENOBUFS); if (n->m_len < sizeof(struct sadb_msg)) { n = m_pullup(n, sizeof(struct sadb_msg)); if (n == NULL) return key_senderror(so, m, ENOBUFS); } newmsg = mtod(n, struct sadb_msg *); newmsg->sadb_msg_errno = 0; newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len); m_freem(m); return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); } } /* * SADB_GET processing * receive * * from the ikmpd, and get a SP and a SA to respond, * and send, * * to the ikmpd. * * m will always be freed. */ static int key_get(so, m, mhp) struct socket *so; struct mbuf *m; const struct sadb_msghdr *mhp; { struct sadb_sa *sa0; struct sadb_address *src0, *dst0; struct secasindex saidx; struct secashead *sah; struct secasvar *sav = NULL; u_int16_t proto; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_get: NULL pointer is passed."); /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { ipseclog((LOG_DEBUG, "key_get: invalid satype is passed.\n")); return key_senderror(so, m, EINVAL); } if (mhp->ext[SADB_EXT_SA] == NULL || mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL || mhp->ext[SADB_EXT_ADDRESS_DST] == NULL) { ipseclog((LOG_DEBUG, "key_get: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa) || mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) || mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) { ipseclog((LOG_DEBUG, "key_get: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } sa0 = (struct sadb_sa *)mhp->ext[SADB_EXT_SA]; src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC]; dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST]; /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); /* get a SA header */ LIST_FOREACH(sah, &sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; if (key_cmpsaidx(&sah->saidx, &saidx, CMP_HEAD) == 0) continue; /* get a SA with SPI. */ sav = key_getsavbyspi(sah, sa0->sadb_sa_spi); if (sav) break; } if (sah == NULL) { ipseclog((LOG_DEBUG, "key_get: no SA found.\n")); return key_senderror(so, m, ENOENT); } { struct mbuf *n; u_int8_t satype; /* map proto to satype */ if ((satype = key_proto2satype(sah->saidx.proto)) == 0) { ipseclog((LOG_DEBUG, "key_get: there was invalid proto in SAD.\n")); return key_senderror(so, m, EINVAL); } /* create new sadb_msg to reply. */ n = key_setdumpsa(sav, SADB_GET, satype, mhp->msg->sadb_msg_seq, mhp->msg->sadb_msg_pid); if (!n) return key_senderror(so, m, ENOBUFS); m_freem(m); return key_sendup_mbuf(so, n, KEY_SENDUP_ONE); } } /* XXX make it sysctl-configurable? */ static void key_getcomb_setlifetime(comb) struct sadb_comb *comb; { comb->sadb_comb_soft_allocations = 1; comb->sadb_comb_hard_allocations = 1; comb->sadb_comb_soft_bytes = 0; comb->sadb_comb_hard_bytes = 0; comb->sadb_comb_hard_addtime = 86400; /* 1 day */ comb->sadb_comb_soft_addtime = comb->sadb_comb_hard_addtime * 80 / 100; comb->sadb_comb_hard_usetime = 28800; /* 8 hours */ comb->sadb_comb_soft_usetime = comb->sadb_comb_hard_usetime * 80 / 100; } #ifdef IPSEC_ESP /* * XXX reorder combinations by preference * XXX no idea if the user wants ESP authentication or not */ static struct mbuf * key_getcomb_esp() { struct sadb_comb *comb; const struct esp_algorithm *algo; struct mbuf *result = NULL, *m, *n; int encmin; int i, off, o; int totlen; const int l = PFKEY_ALIGN8(sizeof(struct sadb_comb)); m = NULL; for (i = 1; i <= SADB_EALG_MAX; i++) { algo = esp_algorithm_lookup(i); if (!algo) continue; if (algo->keymax < ipsec_esp_keymin) continue; if (algo->keymin < ipsec_esp_keymin) encmin = ipsec_esp_keymin; else encmin = algo->keymin; if (ipsec_esp_auth) m = key_getcomb_ah(); else { #ifdef DIAGNOSTIC if (l > MLEN) panic("assumption failed in key_getcomb_esp"); #endif MGET(m, M_DONTWAIT, MT_DATA); if (m) { M_ALIGN(m, l); m->m_len = l; m->m_next = NULL; bzero(mtod(m, caddr_t), m->m_len); } } if (!m) goto fail; totlen = 0; for (n = m; n; n = n->m_next) totlen += n->m_len; #ifdef DIAGNOSTIC if (totlen % l) panic("assumption failed in key_getcomb_esp"); #endif for (off = 0; off < totlen; off += l) { n = m_pulldown(m, off, l, &o); if (!n) { /* m is already freed */ goto fail; } comb = (struct sadb_comb *)(mtod(n, caddr_t) + o); bzero(comb, sizeof(*comb)); key_getcomb_setlifetime(comb); comb->sadb_comb_encrypt = i; comb->sadb_comb_encrypt_minbits = encmin; comb->sadb_comb_encrypt_maxbits = algo->keymax; } if (!result) result = m; else m_cat(result, m); } return result; fail: if (result) m_freem(result); return NULL; } #endif /* * XXX reorder combinations by preference */ static struct mbuf * key_getcomb_ah() { struct sadb_comb *comb; const struct ah_algorithm *algo; struct mbuf *m; int min; int i; const int l = PFKEY_ALIGN8(sizeof(struct sadb_comb)); m = NULL; for (i = 1; i <= SADB_AALG_MAX; i++) { #if 1 /* we prefer HMAC algorithms, not old algorithms */ if (i != SADB_AALG_SHA1HMAC && i != SADB_AALG_MD5HMAC) continue; #endif algo = ah_algorithm_lookup(i); if (!algo) continue; if (algo->keymax < ipsec_ah_keymin) continue; if (algo->keymin < ipsec_ah_keymin) min = ipsec_ah_keymin; else min = algo->keymin; if (!m) { #ifdef DIAGNOSTIC if (l > MLEN) panic("assumption failed in key_getcomb_ah"); #endif MGET(m, M_DONTWAIT, MT_DATA); if (m) { M_ALIGN(m, l); m->m_len = l; m->m_next = NULL; } } else M_PREPEND(m, l, M_DONTWAIT); if (!m) return NULL; comb = mtod(m, struct sadb_comb *); bzero(comb, sizeof(*comb)); key_getcomb_setlifetime(comb); comb->sadb_comb_auth = i; comb->sadb_comb_auth_minbits = min; comb->sadb_comb_auth_maxbits = algo->keymax; } return m; } /* * not really an official behavior. discussed in pf_key@inner.net in Sep2000. * XXX reorder combinations by preference */ static struct mbuf * key_getcomb_ipcomp() { struct sadb_comb *comb; const struct ipcomp_algorithm *algo; struct mbuf *m; int i; const int l = PFKEY_ALIGN8(sizeof(struct sadb_comb)); m = NULL; for (i = 1; i <= SADB_X_CALG_MAX; i++) { algo = ipcomp_algorithm_lookup(i); if (!algo) continue; if (!m) { #ifdef DIAGNOSTIC if (l > MLEN) panic("assumption failed in key_getcomb_ipcomp"); #endif MGET(m, M_DONTWAIT, MT_DATA); if (m) { M_ALIGN(m, l); m->m_len = l; m->m_next = NULL; } } else M_PREPEND(m, l, M_DONTWAIT); if (!m) return NULL; comb = mtod(m, struct sadb_comb *); bzero(comb, sizeof(*comb)); key_getcomb_setlifetime(comb); comb->sadb_comb_encrypt = i; /* what should we set into sadb_comb_*_{min,max}bits? */ } return m; } /* * XXX no way to pass mode (transport/tunnel) to userland * XXX replay checking? * XXX sysctl interface to ipsec_{ah,esp}_keymin */ static struct mbuf * key_getprop(saidx) const struct secasindex *saidx; { struct sadb_prop *prop; struct mbuf *m, *n; const int l = PFKEY_ALIGN8(sizeof(struct sadb_prop)); int totlen; switch (saidx->proto) { #ifdef IPSEC_ESP case IPPROTO_ESP: m = key_getcomb_esp(); break; #endif case IPPROTO_AH: m = key_getcomb_ah(); break; case IPPROTO_IPCOMP: m = key_getcomb_ipcomp(); break; default: return NULL; } if (!m) return NULL; M_PREPEND(m, l, M_DONTWAIT); if (!m) return NULL; totlen = 0; for (n = m; n; n = n->m_next) totlen += n->m_len; prop = mtod(m, struct sadb_prop *); bzero(prop, sizeof(*prop)); prop->sadb_prop_len = PFKEY_UNIT64(totlen); prop->sadb_prop_exttype = SADB_EXT_PROPOSAL; prop->sadb_prop_replay = 32; /* XXX */ return m; } /* * SADB_ACQUIRE processing called by key_checkrequest() and key_acquire2(). * send * * to KMD, and expect to receive * with SADB_ACQUIRE if error occured, * or * with SADB_GETSPI * from KMD by PF_KEY. * * XXX x_policy is outside of RFC2367 (KAME extension). * XXX sensitivity is not supported. * XXX for ipcomp, RFC2367 does not define how to fill in proposal. * see comment for key_getcomb_ipcomp(). * * OUT: * 0 : succeed * others: error number */ static int key_acquire(saidx, sp) struct secasindex *saidx; struct secpolicy *sp; { struct mbuf *result = NULL, *m; #ifndef IPSEC_NONBLOCK_ACQUIRE struct secacq *newacq; #endif u_int8_t satype; int error = -1; u_int32_t seq; /* sanity check */ if (saidx == NULL) panic("key_acquire: NULL pointer is passed."); if ((satype = key_proto2satype(saidx->proto)) == 0) panic("key_acquire: invalid proto is passed."); #ifndef IPSEC_NONBLOCK_ACQUIRE /* * We never do anything about acquirng SA. There is anather * solution that kernel blocks to send SADB_ACQUIRE message until * getting something message from IKEd. In later case, to be * managed with ACQUIRING list. */ /* get an entry to check whether sending message or not. */ if ((newacq = key_getacq(saidx)) != NULL) { if (key_blockacq_count < newacq->count) { /* reset counter and do send message. */ newacq->count = 0; } else { /* increment counter and do nothing. */ newacq->count++; return 0; } } else { /* make new entry for blocking to send SADB_ACQUIRE. */ if ((newacq = key_newacq(saidx)) == NULL) return ENOBUFS; /* add to acqtree */ LIST_INSERT_HEAD(&acqtree, newacq, chain); } #endif #ifndef IPSEC_NONBLOCK_ACQUIRE seq = newacq->seq; #else seq = (acq_seq = (acq_seq == ~0 ? 1 : ++acq_seq)); #endif m = key_setsadbmsg(SADB_ACQUIRE, 0, satype, seq, 0, 0); if (!m) { error = ENOBUFS; goto fail; } result = m; /* set sadb_address for saidx's. */ m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC, (struct sockaddr *)&saidx->src, FULLMASK, IPSEC_ULPROTO_ANY); if (!m) { error = ENOBUFS; goto fail; } m_cat(result, m); m = key_setsadbaddr(SADB_EXT_ADDRESS_DST, (struct sockaddr *)&saidx->dst, FULLMASK, IPSEC_ULPROTO_ANY); if (!m) { error = ENOBUFS; goto fail; } m_cat(result, m); /* XXX proxy address (optional) */ /* set sadb_x_policy */ if (sp) { m = key_setsadbxpolicy(sp->policy, sp->dir, sp->id); if (!m) { error = ENOBUFS; goto fail; } m_cat(result, m); } /* XXX identity (optional) */ #if 0 if (idexttype && fqdn) { /* create identity extension (FQDN) */ struct sadb_ident *id; int fqdnlen; fqdnlen = strlen(fqdn) + 1; /* +1 for terminating-NUL */ id = (struct sadb_ident *)p; bzero(id, sizeof(*id) + PFKEY_ALIGN8(fqdnlen)); id->sadb_ident_len = PFKEY_UNIT64(sizeof(*id) + PFKEY_ALIGN8(fqdnlen)); id->sadb_ident_exttype = idexttype; id->sadb_ident_type = SADB_IDENTTYPE_FQDN; bcopy(fqdn, id + 1, fqdnlen); p += sizeof(struct sadb_ident) + PFKEY_ALIGN8(fqdnlen); } if (idexttype) { /* create identity extension (USERFQDN) */ struct sadb_ident *id; int userfqdnlen; if (userfqdn) { /* +1 for terminating-NUL */ userfqdnlen = strlen(userfqdn) + 1; } else userfqdnlen = 0; id = (struct sadb_ident *)p; bzero(id, sizeof(*id) + PFKEY_ALIGN8(userfqdnlen)); id->sadb_ident_len = PFKEY_UNIT64(sizeof(*id) + PFKEY_ALIGN8(userfqdnlen)); id->sadb_ident_exttype = idexttype; id->sadb_ident_type = SADB_IDENTTYPE_USERFQDN; /* XXX is it correct? */ if (curproc && curproc->p_cred) id->sadb_ident_id = curproc->p_cred->p_ruid; if (userfqdn && userfqdnlen) bcopy(userfqdn, id + 1, userfqdnlen); p += sizeof(struct sadb_ident) + PFKEY_ALIGN8(userfqdnlen); } #endif /* XXX sensitivity (optional) */ /* create proposal/combination extension */ m = key_getprop(saidx); #if 0 /* * spec conformant: always attach proposal/combination extension, * the problem is that we have no way to attach it for ipcomp, * due to the way sadb_comb is declared in RFC2367. */ if (!m) { error = ENOBUFS; goto fail; } m_cat(result, m); #else /* * outside of spec; make proposal/combination extension optional. */ if (m) m_cat(result, m); #endif if ((result->m_flags & M_PKTHDR) == 0) { error = EINVAL; goto fail; } if (result->m_len < sizeof(struct sadb_msg)) { result = m_pullup(result, sizeof(struct sadb_msg)); if (result == NULL) { error = ENOBUFS; goto fail; } } result->m_pkthdr.len = 0; for (m = result; m; m = m->m_next) result->m_pkthdr.len += m->m_len; mtod(result, struct sadb_msg *)->sadb_msg_len = PFKEY_UNIT64(result->m_pkthdr.len); return key_sendup_mbuf(NULL, result, KEY_SENDUP_REGISTERED); fail: if (result) m_freem(result); return error; } #ifndef IPSEC_NONBLOCK_ACQUIRE static struct secacq * key_newacq(saidx) struct secasindex *saidx; { struct secacq *newacq; /* get new entry */ KMALLOC(newacq, struct secacq *, sizeof(struct secacq)); if (newacq == NULL) { ipseclog((LOG_DEBUG, "key_newacq: No more memory.\n")); return NULL; } bzero(newacq, sizeof(*newacq)); /* copy secindex */ bcopy(saidx, &newacq->saidx, sizeof(newacq->saidx)); newacq->seq = (acq_seq == ~0 ? 1 : ++acq_seq); newacq->created = time_second; newacq->count = 0; return newacq; } static struct secacq * key_getacq(saidx) struct secasindex *saidx; { struct secacq *acq; LIST_FOREACH(acq, &acqtree, chain) { if (key_cmpsaidx(saidx, &acq->saidx, CMP_EXACTLY)) return acq; } return NULL; } static struct secacq * key_getacqbyseq(seq) u_int32_t seq; { struct secacq *acq; LIST_FOREACH(acq, &acqtree, chain) { if (acq->seq == seq) return acq; } return NULL; } #endif static struct secspacq * key_newspacq(spidx) struct secpolicyindex *spidx; { struct secspacq *acq; if (!spidx) return NULL; /* get new entry */ KMALLOC(acq, struct secspacq *, sizeof(struct secspacq)); if (acq == NULL) { ipseclog((LOG_DEBUG, "key_newspacq: No more memory.\n")); return NULL; } bzero(acq, sizeof(*acq)); /* copy secindex */ bcopy(spidx, &acq->spidx, sizeof(acq->spidx)); acq->created = time_second; acq->count = 1; return acq; } static struct secspacq * key_getspacq(spidx) struct secpolicyindex *spidx; { struct secspacq *acq; if (!spidx) return NULL; LIST_FOREACH(acq, &spacqtree, chain) { if (key_cmpspidx_exactly(spidx, &acq->spidx)) return acq; } return NULL; } /* * SADB_ACQUIRE processing, * in first situation, is receiving * * from the ikmpd, and clear sequence of its secasvar entry. * * In second situation, is receiving * * from a user land process, and return * * to the socket. * * m will always be freed. */ static int key_acquire2(so, m, mhp) struct socket *so; struct mbuf *m; const struct sadb_msghdr *mhp; { struct sadb_address *src0, *dst0; struct secasindex saidx; struct secashead *sah; u_int16_t proto; int error; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_acquire2: NULL pointer is passed."); /* * Error message from KMd. * We assume that if error was occured in IKEd, the length of PFKEY * message is equal to the size of sadb_msg structure. * We do not raise error even if error occured in this function. */ if (mhp->msg->sadb_msg_len == PFKEY_UNIT64(sizeof(struct sadb_msg))) { #ifndef IPSEC_NONBLOCK_ACQUIRE struct secacq *acq; /* check sequence number */ if (mhp->msg->sadb_msg_seq == 0) { ipseclog((LOG_DEBUG, "key_acquire2: must specify sequence number.\n")); m_freem(m); return 0; } if ((acq = key_getacqbyseq(mhp->msg->sadb_msg_seq)) == NULL) { /* * the specified larval SA is already gone, or we got * a bogus sequence number. we can silently ignore it. */ m_freem(m); return 0; } /* reset acq counter in order to deletion by timehander. */ acq->created = time_second; acq->count = 0; #endif m_freem(m); return 0; } /* * This message is from user land. */ /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { ipseclog((LOG_DEBUG, "key_acquire2: invalid satype is passed.\n")); return key_senderror(so, m, EINVAL); } if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL || mhp->ext[SADB_EXT_ADDRESS_DST] == NULL || mhp->ext[SADB_EXT_PROPOSAL] == NULL) { /* error */ ipseclog((LOG_DEBUG, "key_acquire2: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } if (mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) || mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address) || mhp->extlen[SADB_EXT_PROPOSAL] < sizeof(struct sadb_prop)) { /* error */ ipseclog((LOG_DEBUG, "key_acquire2: invalid message is passed.\n")); return key_senderror(so, m, EINVAL); } src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC]; dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST]; /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); /* get a SA index */ LIST_FOREACH(sah, &sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; if (key_cmpsaidx(&sah->saidx, &saidx, CMP_MODE_REQID)) break; } if (sah != NULL) { ipseclog((LOG_DEBUG, "key_acquire2: a SA exists already.\n")); return key_senderror(so, m, EEXIST); } error = key_acquire(&saidx, NULL); if (error != 0) { ipseclog((LOG_DEBUG, "key_acquire2: error %d returned " "from key_acquire.\n", mhp->msg->sadb_msg_errno)); return key_senderror(so, m, error); } return key_sendup_mbuf(so, m, KEY_SENDUP_REGISTERED); } /* * SADB_REGISTER processing. * If SATYPE_UNSPEC has been passed as satype, only return sabd_supported. * receive * * from the ikmpd, and register a socket to send PF_KEY messages, * and send * * to KMD by PF_KEY. * If socket is detached, must free from regnode. * * m will always be freed. */ static int key_register(so, m, mhp) struct socket *so; struct mbuf *m; const struct sadb_msghdr *mhp; { struct secreg *reg, *newreg = 0; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_register: NULL pointer is passed."); /* check for invalid register message */ if (mhp->msg->sadb_msg_satype >= sizeof(regtree)/sizeof(regtree[0])) return key_senderror(so, m, EINVAL); /* When SATYPE_UNSPEC is specified, only return sabd_supported. */ if (mhp->msg->sadb_msg_satype == SADB_SATYPE_UNSPEC) goto setmsg; /* check whether existing or not */ LIST_FOREACH(reg, ®tree[mhp->msg->sadb_msg_satype], chain) { if (reg->so == so) { ipseclog((LOG_DEBUG, "key_register: socket exists already.\n")); return key_senderror(so, m, EEXIST); } } /* create regnode */ KMALLOC(newreg, struct secreg *, sizeof(*newreg)); if (newreg == NULL) { ipseclog((LOG_DEBUG, "key_register: No more memory.\n")); return key_senderror(so, m, ENOBUFS); } bzero((caddr_t)newreg, sizeof(*newreg)); newreg->so = so; ((struct keycb *)sotorawcb(so))->kp_registered++; /* add regnode to regtree. */ LIST_INSERT_HEAD(®tree[mhp->msg->sadb_msg_satype], newreg, chain); setmsg: { struct mbuf *n; struct sadb_msg *newmsg; struct sadb_supported *sup; u_int len, alen, elen; int off; int i; struct sadb_alg *alg; /* create new sadb_msg to reply. */ alen = 0; for (i = 1; i <= SADB_AALG_MAX; i++) { if (ah_algorithm_lookup(i)) alen += sizeof(struct sadb_alg); } if (alen) alen += sizeof(struct sadb_supported); elen = 0; #ifdef IPSEC_ESP for (i = 1; i <= SADB_EALG_MAX; i++) { if (esp_algorithm_lookup(i)) elen += sizeof(struct sadb_alg); } if (elen) elen += sizeof(struct sadb_supported); #endif len = sizeof(struct sadb_msg) + alen + elen; if (len > MCLBYTES) return key_senderror(so, m, ENOBUFS); MGETHDR(n, M_DONTWAIT, MT_DATA); if (len > MHLEN) { MCLGET(n, M_DONTWAIT); if ((n->m_flags & M_EXT) == 0) { m_freem(n); n = NULL; } } if (!n) return key_senderror(so, m, ENOBUFS); n->m_pkthdr.len = n->m_len = len; n->m_next = NULL; off = 0; m_copydata(m, 0, sizeof(struct sadb_msg), mtod(n, caddr_t) + off); newmsg = mtod(n, struct sadb_msg *); newmsg->sadb_msg_errno = 0; newmsg->sadb_msg_len = PFKEY_UNIT64(len); off += PFKEY_ALIGN8(sizeof(struct sadb_msg)); /* for authentication algorithm */ if (alen) { sup = (struct sadb_supported *)(mtod(n, caddr_t) + off); sup->sadb_supported_len = PFKEY_UNIT64(alen); sup->sadb_supported_exttype = SADB_EXT_SUPPORTED_AUTH; off += PFKEY_ALIGN8(sizeof(*sup)); for (i = 1; i <= SADB_AALG_MAX; i++) { const struct ah_algorithm *aalgo; aalgo = ah_algorithm_lookup(i); if (!aalgo) continue; alg = (struct sadb_alg *)(mtod(n, caddr_t) + off); alg->sadb_alg_id = i; alg->sadb_alg_ivlen = 0; alg->sadb_alg_minbits = aalgo->keymin; alg->sadb_alg_maxbits = aalgo->keymax; off += PFKEY_ALIGN8(sizeof(*alg)); } } #ifdef IPSEC_ESP /* for encryption algorithm */ if (elen) { sup = (struct sadb_supported *)(mtod(n, caddr_t) + off); sup->sadb_supported_len = PFKEY_UNIT64(elen); sup->sadb_supported_exttype = SADB_EXT_SUPPORTED_ENCRYPT; off += PFKEY_ALIGN8(sizeof(*sup)); for (i = 1; i <= SADB_EALG_MAX; i++) { const struct esp_algorithm *ealgo; ealgo = esp_algorithm_lookup(i); if (!ealgo) continue; alg = (struct sadb_alg *)(mtod(n, caddr_t) + off); alg->sadb_alg_id = i; if (ealgo && ealgo->ivlen) { /* * give NULL to get the value preferred by * algorithm XXX SADB_X_EXT_DERIV ? */ alg->sadb_alg_ivlen = (*ealgo->ivlen)(ealgo, NULL); } else alg->sadb_alg_ivlen = 0; alg->sadb_alg_minbits = ealgo->keymin; alg->sadb_alg_maxbits = ealgo->keymax; off += PFKEY_ALIGN8(sizeof(struct sadb_alg)); } } #endif #ifdef DIGAGNOSTIC if (off != len) panic("length assumption failed in key_register"); #endif m_freem(m); return key_sendup_mbuf(so, n, KEY_SENDUP_REGISTERED); } } /* * free secreg entry registered. * XXX: I want to do free a socket marked done SADB_RESIGER to socket. */ void key_freereg(so) struct socket *so; { struct secreg *reg; int i; /* sanity check */ if (so == NULL) panic("key_freereg: NULL pointer is passed."); /* * check whether existing or not. * check all type of SA, because there is a potential that * one socket is registered to multiple type of SA. */ for (i = 0; i <= SADB_SATYPE_MAX; i++) { LIST_FOREACH(reg, ®tree[i], chain) { if (reg->so == so && __LIST_CHAINED(reg)) { LIST_REMOVE(reg, chain); KFREE(reg); break; } } } return; } /* * SADB_EXPIRE processing * send * * to KMD by PF_KEY. * NOTE: We send only soft lifetime extension. * * OUT: 0 : succeed * others : error number */ static int key_expire(sav) struct secasvar *sav; { int s; int satype; struct mbuf *result = NULL, *m; int len; int error = -1; struct sadb_lifetime *lt; /* XXX: Why do we lock ? */ s = splnet(); /*called from softclock()*/ /* sanity check */ if (sav == NULL) panic("key_expire: NULL pointer is passed."); if (sav->sah == NULL) panic("key_expire: Why was SA index in SA NULL."); if ((satype = key_proto2satype(sav->sah->saidx.proto)) == 0) panic("key_expire: invalid proto is passed."); /* set msg header */ m = key_setsadbmsg(SADB_EXPIRE, 0, satype, sav->seq, 0, sav->refcnt); if (!m) { error = ENOBUFS; goto fail; } result = m; /* create SA extension */ m = key_setsadbsa(sav); if (!m) { error = ENOBUFS; goto fail; } m_cat(result, m); /* create SA extension */ m = key_setsadbxsa2(sav->sah->saidx.mode, sav->replay ? (sav->replay->count & 0xffffffff) : 0, sav->sah->saidx.reqid); if (!m) { error = ENOBUFS; goto fail; } m_cat(result, m); /* create lifetime extension (current and soft) */ len = PFKEY_ALIGN8(sizeof(*lt)) * 2; m = key_alloc_mbuf(len); if (!m || m->m_next) { /*XXX*/ if (m) m_freem(m); error = ENOBUFS; goto fail; } bzero(mtod(m, caddr_t), len); lt = mtod(m, struct sadb_lifetime *); lt->sadb_lifetime_len = PFKEY_UNIT64(sizeof(struct sadb_lifetime)); lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT; lt->sadb_lifetime_allocations = sav->lft_c->sadb_lifetime_allocations; lt->sadb_lifetime_bytes = sav->lft_c->sadb_lifetime_bytes; lt->sadb_lifetime_addtime = sav->lft_c->sadb_lifetime_addtime; lt->sadb_lifetime_usetime = sav->lft_c->sadb_lifetime_usetime; lt = (struct sadb_lifetime *)(mtod(m, caddr_t) + len / 2); bcopy(sav->lft_s, lt, sizeof(*lt)); m_cat(result, m); /* set sadb_address for source */ m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC, (struct sockaddr *)&sav->sah->saidx.src, FULLMASK, IPSEC_ULPROTO_ANY); if (!m) { error = ENOBUFS; goto fail; } m_cat(result, m); /* set sadb_address for destination */ m = key_setsadbaddr(SADB_EXT_ADDRESS_DST, (struct sockaddr *)&sav->sah->saidx.dst, FULLMASK, IPSEC_ULPROTO_ANY); if (!m) { error = ENOBUFS; goto fail; } m_cat(result, m); if ((result->m_flags & M_PKTHDR) == 0) { error = EINVAL; goto fail; } if (result->m_len < sizeof(struct sadb_msg)) { result = m_pullup(result, sizeof(struct sadb_msg)); if (result == NULL) { error = ENOBUFS; goto fail; } } result->m_pkthdr.len = 0; for (m = result; m; m = m->m_next) result->m_pkthdr.len += m->m_len; mtod(result, struct sadb_msg *)->sadb_msg_len = PFKEY_UNIT64(result->m_pkthdr.len); splx(s); return key_sendup_mbuf(NULL, result, KEY_SENDUP_REGISTERED); fail: if (result) m_freem(result); splx(s); return error; } /* * SADB_FLUSH processing * receive * * from the ikmpd, and free all entries in secastree. * and send, * * to the ikmpd. * NOTE: to do is only marking SADB_SASTATE_DEAD. * * m will always be freed. */ static int key_flush(so, m, mhp) struct socket *so; struct mbuf *m; const struct sadb_msghdr *mhp; { struct sadb_msg *newmsg; struct secashead *sah, *nextsah; struct secasvar *sav, *nextsav; u_int16_t proto; u_int8_t state; u_int stateidx; /* sanity check */ if (so == NULL || mhp == NULL || mhp->msg == NULL) panic("key_flush: NULL pointer is passed."); /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { ipseclog((LOG_DEBUG, "key_flush: invalid satype is passed.\n")); return key_senderror(so, m, EINVAL); } /* no SATYPE specified, i.e. flushing all SA. */ for (sah = LIST_FIRST(&sahtree); sah != NULL; sah = nextsah) { nextsah = LIST_NEXT(sah, chain); if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC && proto != sah->saidx.proto) continue; for (stateidx = 0; stateidx < _ARRAYLEN(saorder_state_alive); stateidx++) { state = saorder_state_any[stateidx]; for (sav = LIST_FIRST(&sah->savtree[state]); sav != NULL; sav = nextsav) { nextsav = LIST_NEXT(sav, chain); key_sa_chgstate(sav, SADB_SASTATE_DEAD); key_freesav(sav); } } sah->state = SADB_SASTATE_DEAD; } if (m->m_len < sizeof(struct sadb_msg) || sizeof(struct sadb_msg) > m->m_len + M_TRAILINGSPACE(m)) { ipseclog((LOG_DEBUG, "key_flush: No more memory.\n")); return key_senderror(so, m, ENOBUFS); } if (m->m_next) m_freem(m->m_next); m->m_next = NULL; m->m_pkthdr.len = m->m_len = sizeof(struct sadb_msg); newmsg = mtod(m, struct sadb_msg *); newmsg->sadb_msg_errno = 0; newmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len); return key_sendup_mbuf(so, m, KEY_SENDUP_ALL); } /* * SADB_DUMP processing * dump all entries including status of DEAD in SAD. * receive * * from the ikmpd, and dump all secasvar leaves * and send, * ..... * to the ikmpd. * * m will always be freed. */ static int key_dump(so, m, mhp) struct socket *so; struct mbuf *m; const struct sadb_msghdr *mhp; { struct secashead *sah; struct secasvar *sav; u_int16_t proto; u_int stateidx; u_int8_t satype; u_int8_t state; int cnt; struct mbuf *n; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_dump: NULL pointer is passed."); /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { ipseclog((LOG_DEBUG, "key_dump: invalid satype is passed.\n")); return key_senderror(so, m, EINVAL); } /* count sav entries to be sent to the userland. */ cnt = 0; LIST_FOREACH(sah, &sahtree, chain) { if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC && proto != sah->saidx.proto) continue; for (stateidx = 0; stateidx < _ARRAYLEN(saorder_state_any); stateidx++) { state = saorder_state_any[stateidx]; LIST_FOREACH(sav, &sah->savtree[state], chain) { cnt++; } } } if (cnt == 0) return key_senderror(so, m, ENOENT); /* send this to the userland, one at a time. */ LIST_FOREACH(sah, &sahtree, chain) { if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC && proto != sah->saidx.proto) continue; /* map proto to satype */ if ((satype = key_proto2satype(sah->saidx.proto)) == 0) { ipseclog((LOG_DEBUG, "key_dump: there was invalid proto in SAD.\n")); return key_senderror(so, m, EINVAL); } for (stateidx = 0; stateidx < _ARRAYLEN(saorder_state_any); stateidx++) { state = saorder_state_any[stateidx]; LIST_FOREACH(sav, &sah->savtree[state], chain) { n = key_setdumpsa(sav, SADB_DUMP, satype, --cnt, mhp->msg->sadb_msg_pid); if (!n) return key_senderror(so, m, ENOBUFS); key_sendup_mbuf(so, n, KEY_SENDUP_ONE); } } } m_freem(m); return 0; } /* * SADB_X_PROMISC processing * * m will always be freed. */ static int key_promisc(so, m, mhp) struct socket *so; struct mbuf *m; const struct sadb_msghdr *mhp; { int olen; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_promisc: NULL pointer is passed."); olen = PFKEY_UNUNIT64(mhp->msg->sadb_msg_len); if (olen < sizeof(struct sadb_msg)) { #if 1 return key_senderror(so, m, EINVAL); #else m_freem(m); return 0; #endif } else if (olen == sizeof(struct sadb_msg)) { /* enable/disable promisc mode */ struct keycb *kp; if ((kp = (struct keycb *)sotorawcb(so)) == NULL) return key_senderror(so, m, EINVAL); mhp->msg->sadb_msg_errno = 0; switch (mhp->msg->sadb_msg_satype) { case 0: case 1: kp->kp_promisc = mhp->msg->sadb_msg_satype; break; default: return key_senderror(so, m, EINVAL); } /* send the original message back to everyone */ mhp->msg->sadb_msg_errno = 0; return key_sendup_mbuf(so, m, KEY_SENDUP_ALL); } else { /* send packet as is */ m_adj(m, PFKEY_ALIGN8(sizeof(struct sadb_msg))); /* TODO: if sadb_msg_seq is specified, send to specific pid */ return key_sendup_mbuf(so, m, KEY_SENDUP_ALL); } } static int (*key_typesw[])(struct socket *, struct mbuf *, const struct sadb_msghdr *) = { NULL, /* SADB_RESERVED */ key_getspi, /* SADB_GETSPI */ key_update, /* SADB_UPDATE */ key_add, /* SADB_ADD */ key_delete, /* SADB_DELETE */ key_get, /* SADB_GET */ key_acquire2, /* SADB_ACQUIRE */ key_register, /* SADB_REGISTER */ NULL, /* SADB_EXPIRE */ key_flush, /* SADB_FLUSH */ key_dump, /* SADB_DUMP */ key_promisc, /* SADB_X_PROMISC */ NULL, /* SADB_X_PCHANGE */ key_spdadd, /* SADB_X_SPDUPDATE */ key_spdadd, /* SADB_X_SPDADD */ key_spddelete, /* SADB_X_SPDDELETE */ key_spdget, /* SADB_X_SPDGET */ NULL, /* SADB_X_SPDACQUIRE */ key_spddump, /* SADB_X_SPDDUMP */ key_spdflush, /* SADB_X_SPDFLUSH */ key_spdadd, /* SADB_X_SPDSETIDX */ NULL, /* SADB_X_SPDEXPIRE */ key_spddelete2, /* SADB_X_SPDDELETE2 */ }; /* * parse sadb_msg buffer to process PFKEYv2, * and create a data to response if needed. * I think to be dealed with mbuf directly. * IN: * msgp : pointer to pointer to a received buffer pulluped. * This is rewrited to response. * so : pointer to socket. * OUT: * length for buffer to send to user process. */ int key_parse(m, so) struct mbuf *m; struct socket *so; { struct sadb_msg *msg; struct sadb_msghdr mh; u_int orglen; int error; int target; /* sanity check */ if (m == NULL || so == NULL) panic("key_parse: NULL pointer is passed."); #if 0 /*kdebug_sadb assumes msg in linear buffer*/ KEYDEBUG(KEYDEBUG_KEY_DUMP, ipseclog((LOG_DEBUG, "key_parse: passed sadb_msg\n")); kdebug_sadb(msg)); #endif if (m->m_len < sizeof(struct sadb_msg)) { m = m_pullup(m, sizeof(struct sadb_msg)); if (!m) return ENOBUFS; } msg = mtod(m, struct sadb_msg *); orglen = PFKEY_UNUNIT64(msg->sadb_msg_len); target = KEY_SENDUP_ONE; if ((m->m_flags & M_PKTHDR) == 0 || m->m_pkthdr.len != m->m_pkthdr.len) { ipseclog((LOG_DEBUG, "key_parse: invalid message length.\n")); pfkeystat.out_invlen++; error = EINVAL; goto senderror; } if (msg->sadb_msg_version != PF_KEY_V2) { ipseclog((LOG_DEBUG, "key_parse: PF_KEY version %u is mismatched.\n", msg->sadb_msg_version)); pfkeystat.out_invver++; error = EINVAL; goto senderror; } if (msg->sadb_msg_type > SADB_MAX) { ipseclog((LOG_DEBUG, "key_parse: invalid type %u is passed.\n", msg->sadb_msg_type)); pfkeystat.out_invmsgtype++; error = EINVAL; goto senderror; } /* for old-fashioned code - should be nuked */ if (m->m_pkthdr.len > MCLBYTES) { m_freem(m); return ENOBUFS; } if (m->m_next) { struct mbuf *n; MGETHDR(n, M_DONTWAIT, MT_DATA); if (n && m->m_pkthdr.len > MHLEN) { MCLGET(n, M_DONTWAIT); if ((n->m_flags & M_EXT) == 0) { m_free(n); n = NULL; } } if (!n) { m_freem(m); return ENOBUFS; } m_copydata(m, 0, m->m_pkthdr.len, mtod(n, caddr_t)); n->m_pkthdr.len = n->m_len = m->m_pkthdr.len; n->m_next = NULL; m_freem(m); m = n; } /* align the mbuf chain so that extensions are in contiguous region. */ error = key_align(m, &mh); if (error) return error; msg = mh.msg; /* check SA type */ switch (msg->sadb_msg_satype) { case SADB_SATYPE_UNSPEC: switch (msg->sadb_msg_type) { case SADB_GETSPI: case SADB_UPDATE: case SADB_ADD: case SADB_DELETE: case SADB_GET: case SADB_ACQUIRE: case SADB_EXPIRE: ipseclog((LOG_DEBUG, "key_parse: must specify satype " "when msg type=%u.\n", msg->sadb_msg_type)); pfkeystat.out_invsatype++; error = EINVAL; goto senderror; } break; case SADB_SATYPE_AH: case SADB_SATYPE_ESP: case SADB_X_SATYPE_IPCOMP: case SADB_X_SATYPE_TCPSIGNATURE: switch (msg->sadb_msg_type) { case SADB_X_SPDADD: case SADB_X_SPDDELETE: case SADB_X_SPDGET: case SADB_X_SPDDUMP: case SADB_X_SPDFLUSH: case SADB_X_SPDSETIDX: case SADB_X_SPDUPDATE: case SADB_X_SPDDELETE2: ipseclog((LOG_DEBUG, "key_parse: illegal satype=%u\n", msg->sadb_msg_type)); pfkeystat.out_invsatype++; error = EINVAL; goto senderror; } break; case SADB_SATYPE_RSVP: case SADB_SATYPE_OSPFV2: case SADB_SATYPE_RIPV2: case SADB_SATYPE_MIP: ipseclog((LOG_DEBUG, "key_parse: type %u isn't supported.\n", msg->sadb_msg_satype)); pfkeystat.out_invsatype++; error = EOPNOTSUPP; goto senderror; case 1: /* XXX: What does it do? */ if (msg->sadb_msg_type == SADB_X_PROMISC) break; /*FALLTHROUGH*/ default: ipseclog((LOG_DEBUG, "key_parse: invalid type %u is passed.\n", msg->sadb_msg_satype)); pfkeystat.out_invsatype++; error = EINVAL; goto senderror; } /* check field of upper layer protocol and address family */ if (mh.ext[SADB_EXT_ADDRESS_SRC] != NULL && mh.ext[SADB_EXT_ADDRESS_DST] != NULL) { struct sadb_address *src0, *dst0; u_int plen; src0 = (struct sadb_address *)(mh.ext[SADB_EXT_ADDRESS_SRC]); dst0 = (struct sadb_address *)(mh.ext[SADB_EXT_ADDRESS_DST]); /* check upper layer protocol */ if (src0->sadb_address_proto != dst0->sadb_address_proto) { ipseclog((LOG_DEBUG, "key_parse: upper layer protocol mismatched.\n")); pfkeystat.out_invaddr++; error = EINVAL; goto senderror; } /* check family */ if (PFKEY_ADDR_SADDR(src0)->sa_family != PFKEY_ADDR_SADDR(dst0)->sa_family) { ipseclog((LOG_DEBUG, "key_parse: address family mismatched.\n")); pfkeystat.out_invaddr++; error = EINVAL; goto senderror; } if (PFKEY_ADDR_SADDR(src0)->sa_len != PFKEY_ADDR_SADDR(dst0)->sa_len) { ipseclog((LOG_DEBUG, "key_parse: address struct size mismatched.\n")); pfkeystat.out_invaddr++; error = EINVAL; goto senderror; } switch (PFKEY_ADDR_SADDR(src0)->sa_family) { case AF_INET: if (PFKEY_ADDR_SADDR(src0)->sa_len != sizeof(struct sockaddr_in)) { pfkeystat.out_invaddr++; error = EINVAL; goto senderror; } break; case AF_INET6: if (PFKEY_ADDR_SADDR(src0)->sa_len != sizeof(struct sockaddr_in6)) { pfkeystat.out_invaddr++; error = EINVAL; goto senderror; } break; default: ipseclog((LOG_DEBUG, "key_parse: unsupported address family.\n")); pfkeystat.out_invaddr++; error = EAFNOSUPPORT; goto senderror; } switch (PFKEY_ADDR_SADDR(src0)->sa_family) { case AF_INET: plen = sizeof(struct in_addr) << 3; break; case AF_INET6: plen = sizeof(struct in6_addr) << 3; break; default: plen = 0; /*fool gcc*/ break; } /* check max prefix length */ if (src0->sadb_address_prefixlen > plen || dst0->sadb_address_prefixlen > plen) { ipseclog((LOG_DEBUG, "key_parse: illegal prefixlen.\n")); pfkeystat.out_invaddr++; error = EINVAL; goto senderror; } /* * prefixlen == 0 is valid because there can be a case when * all addresses are matched. */ } if (msg->sadb_msg_type >= sizeof(key_typesw)/sizeof(key_typesw[0]) || key_typesw[msg->sadb_msg_type] == NULL) { pfkeystat.out_invmsgtype++; error = EINVAL; goto senderror; } return (*key_typesw[msg->sadb_msg_type])(so, m, &mh); senderror: msg->sadb_msg_errno = error; return key_sendup_mbuf(so, m, target); } static int key_senderror(so, m, code) struct socket *so; struct mbuf *m; int code; { struct sadb_msg *msg; if (m->m_len < sizeof(struct sadb_msg)) panic("invalid mbuf passed to key_senderror"); msg = mtod(m, struct sadb_msg *); msg->sadb_msg_errno = code; return key_sendup_mbuf(so, m, KEY_SENDUP_ONE); } /* * set the pointer to each header into message buffer. * m will be freed on error. * XXX larger-than-MCLBYTES extension? */ static int key_align(m, mhp) struct mbuf *m; struct sadb_msghdr *mhp; { struct mbuf *n; struct sadb_ext *ext; size_t off, end; int extlen; int toff; /* sanity check */ if (m == NULL || mhp == NULL) panic("key_align: NULL pointer is passed."); if (m->m_len < sizeof(struct sadb_msg)) panic("invalid mbuf passed to key_align"); /* initialize */ bzero(mhp, sizeof(*mhp)); mhp->msg = mtod(m, struct sadb_msg *); mhp->ext[0] = (struct sadb_ext *)mhp->msg; /*XXX backward compat */ end = PFKEY_UNUNIT64(mhp->msg->sadb_msg_len); extlen = end; /*just in case extlen is not updated*/ for (off = sizeof(struct sadb_msg); off < end; off += extlen) { n = m_pulldown(m, off, sizeof(struct sadb_ext), &toff); if (!n) { /* m is already freed */ return ENOBUFS; } ext = (struct sadb_ext *)(mtod(n, caddr_t) + toff); /* set pointer */ switch (ext->sadb_ext_type) { case SADB_EXT_SA: case SADB_EXT_ADDRESS_SRC: case SADB_EXT_ADDRESS_DST: case SADB_EXT_ADDRESS_PROXY: case SADB_EXT_LIFETIME_CURRENT: case SADB_EXT_LIFETIME_HARD: case SADB_EXT_LIFETIME_SOFT: case SADB_EXT_KEY_AUTH: case SADB_EXT_KEY_ENCRYPT: case SADB_EXT_IDENTITY_SRC: case SADB_EXT_IDENTITY_DST: case SADB_EXT_SENSITIVITY: case SADB_EXT_PROPOSAL: case SADB_EXT_SUPPORTED_AUTH: case SADB_EXT_SUPPORTED_ENCRYPT: case SADB_EXT_SPIRANGE: case SADB_X_EXT_POLICY: case SADB_X_EXT_SA2: /* duplicate check */ /* * XXX Are there duplication payloads of either * KEY_AUTH or KEY_ENCRYPT ? */ if (mhp->ext[ext->sadb_ext_type] != NULL) { ipseclog((LOG_DEBUG, "key_align: duplicate ext_type %u " "is passed.\n", ext->sadb_ext_type)); m_freem(m); pfkeystat.out_dupext++; return EINVAL; } break; default: ipseclog((LOG_DEBUG, "key_align: invalid ext_type %u is passed.\n", ext->sadb_ext_type)); m_freem(m); pfkeystat.out_invexttype++; return EINVAL; } extlen = PFKEY_UNUNIT64(ext->sadb_ext_len); if (key_validate_ext(ext, extlen)) { m_freem(m); pfkeystat.out_invlen++; return EINVAL; } n = m_pulldown(m, off, extlen, &toff); if (!n) { /* m is already freed */ return ENOBUFS; } ext = (struct sadb_ext *)(mtod(n, caddr_t) + toff); mhp->ext[ext->sadb_ext_type] = ext; mhp->extoff[ext->sadb_ext_type] = off; mhp->extlen[ext->sadb_ext_type] = extlen; } if (off != end) { m_freem(m); pfkeystat.out_invlen++; return EINVAL; } return 0; } static int key_validate_ext(ext, len) struct sadb_ext *ext; int len; { struct sockaddr *sa; enum { NONE, ADDR } checktype = NONE; int baselen = 0; const int sal = offsetof(struct sockaddr, sa_len) + sizeof(sa->sa_len); if (len != PFKEY_UNUNIT64(ext->sadb_ext_len)) return EINVAL; /* if it does not match minimum/maximum length, bail */ if (ext->sadb_ext_type >= sizeof(minsize) / sizeof(minsize[0]) || ext->sadb_ext_type >= sizeof(maxsize) / sizeof(maxsize[0])) return EINVAL; if (!minsize[ext->sadb_ext_type] || len < minsize[ext->sadb_ext_type]) return EINVAL; if (maxsize[ext->sadb_ext_type] && len > maxsize[ext->sadb_ext_type]) return EINVAL; /* more checks based on sadb_ext_type XXX need more */ switch (ext->sadb_ext_type) { case SADB_EXT_ADDRESS_SRC: case SADB_EXT_ADDRESS_DST: case SADB_EXT_ADDRESS_PROXY: baselen = PFKEY_ALIGN8(sizeof(struct sadb_address)); checktype = ADDR; break; case SADB_EXT_IDENTITY_SRC: case SADB_EXT_IDENTITY_DST: if (((struct sadb_ident *)ext)->sadb_ident_type == SADB_X_IDENTTYPE_ADDR) { baselen = PFKEY_ALIGN8(sizeof(struct sadb_ident)); checktype = ADDR; } else checktype = NONE; break; default: checktype = NONE; break; } switch (checktype) { case NONE: break; case ADDR: sa = (struct sockaddr *)((caddr_t)ext + baselen); if (len < baselen + sal) return EINVAL; if (baselen + PFKEY_ALIGN8(sa->sa_len) != len) return EINVAL; break; } return 0; } void key_init() { int i; bzero((caddr_t)&key_cb, sizeof(key_cb)); callout_init(&key_timehandler_ch, 0); for (i = 0; i < IPSEC_DIR_MAX; i++) LIST_INIT(&sptree[i]); LIST_INIT(&sahtree); for (i = 0; i <= SADB_SATYPE_MAX; i++) LIST_INIT(®tree[i]); for (i = 0; i < SPIHASHSIZE; i++) LIST_INIT(&spihash[i]); #ifndef IPSEC_NONBLOCK_ACQUIRE LIST_INIT(&acqtree); #endif LIST_INIT(&spacqtree); TAILQ_INIT(&satailq); TAILQ_INIT(&sptailq); /* system default */ #ifdef INET ip4_def_policy = key_newsp(0); if (!ip4_def_policy) panic("could not initialize IPv4 default security policy"); ip4_def_policy->state = IPSEC_SPSTATE_ALIVE; ip4_def_policy->policy = IPSEC_POLICY_NONE; ip4_def_policy->dir = IPSEC_DIR_ANY; ip4_def_policy->readonly = 1; ip4_def_policy->persist = 1; #endif #ifdef INET6 ip6_def_policy = key_newsp(0); if (!ip6_def_policy) panic("could not initialize IPv6 default security policy"); ip6_def_policy->state = IPSEC_SPSTATE_ALIVE; ip6_def_policy->policy = IPSEC_POLICY_NONE; ip6_def_policy->dir = IPSEC_DIR_ANY; ip6_def_policy->readonly = 1; ip6_def_policy->persist = 1; #endif callout_reset(&key_timehandler_ch, hz, key_timehandler, (void *)0); /* initialize key statistics */ keystat.getspi_count = 1; printf("IPsec: Initialized Security Association Processing.\n"); return; } /* * XXX: maybe This function is called after INBOUND IPsec processing. * * Special check for tunnel-mode packets. * We must make some checks for consistency between inner and outer IP header. * * xxx more checks to be provided */ int key_checktunnelsanity(sav, family, src, dst) struct secasvar *sav; u_int family; caddr_t src; caddr_t dst; { /* sanity check */ if (sav->sah == NULL) panic("sav->sah == NULL at key_checktunnelsanity"); /* XXX: check inner IP header */ return 1; } #if 0 /* * Get FQDN for the host. * If the administrator configured hostname (by hostname(1)) without * domain name, returns nothing. */ static const char * key_getfqdn() { int i; int hasdot; static char fqdn[MAXHOSTNAMELEN + 1]; int hostnamelen = strlen(hostname); if (!hostnamelen) return NULL; /* check if it comes with domain name. */ hasdot = 0; for (i = 0; i < hostnamelen; i++) { if (hostname[i] == '.') hasdot++; } if (!hasdot) return NULL; /* NOTE: hostname may not be NUL-terminated. */ bzero(fqdn, sizeof(fqdn)); bcopy(hostname, fqdn, hostnamelen); fqdn[hostnamelen] = '\0'; return fqdn; } /* * get username@FQDN for the host/user. */ static const char * key_getuserfqdn() { const char *host; static char userfqdn[MAXHOSTNAMELEN + MAXLOGNAME + 2]; struct proc *p = curproc; char *q; PROC_LOCK(p); if (!p || !p->p_pgrp || !p->p_pgrp->pg_session) { PROC_UNLOCK(p); return NULL; } if (!(host = key_getfqdn())) { PROC_UNLOCK(p); return NULL; } /* NOTE: s_login may not be-NUL terminated. */ bzero(userfqdn, sizeof(userfqdn)); SESS_LOCK(p->p_session); bcopy(p->p_pgrp->pg_session->s_login, userfqdn, MAXLOGNAME); SESS_UNLOCK(p->p_session); PROC_UNLOCK(p); userfqdn[MAXLOGNAME] = '\0'; /* safeguard */ q = userfqdn + strlen(userfqdn); *q++ = '@'; bcopy(host, q, strlen(host)); q += strlen(host); *q++ = '\0'; return userfqdn; } #endif /* record data transfer on SA, and update timestamps */ void key_sa_recordxfer(sav, m) struct secasvar *sav; struct mbuf *m; { if (!sav) panic("key_sa_recordxfer called with sav == NULL"); if (!m) panic("key_sa_recordxfer called with m == NULL"); if (!sav->lft_c) return; /* * XXX Currently, there is a difference of bytes size * between inbound and outbound processing. */ sav->lft_c->sadb_lifetime_bytes += m->m_pkthdr.len; /* to check bytes lifetime is done in key_timehandler(). */ /* * We use the number of packets as the unit of * sadb_lifetime_allocations. We increment the variable * whenever {esp,ah}_{in,out}put is called. */ sav->lft_c->sadb_lifetime_allocations++; /* XXX check for expires? */ /* * NOTE: We record CURRENT sadb_lifetime_usetime by using wall clock, * in seconds. HARD and SOFT lifetime are measured by the time * difference (again in seconds) from sadb_lifetime_usetime. * * usetime * v expire expire * -----+-----+--------+---> t * <--------------> HARD * <-----> SOFT */ { sav->lft_c->sadb_lifetime_usetime = time_second; /* XXX check for expires? */ } return; } /* dumb version */ void key_sa_routechange(dst) struct sockaddr *dst; { struct secashead *sah; struct route *ro; LIST_FOREACH(sah, &sahtree, chain) { ro = &sah->sa_route; if (ro->ro_rt && dst->sa_len == ro->ro_dst.sa_len && bcmp(dst, &ro->ro_dst, dst->sa_len) == 0) { RTFREE(ro->ro_rt); ro->ro_rt = (struct rtentry *)NULL; } } return; } static void key_sa_chgstate(sav, state) struct secasvar *sav; u_int8_t state; { if (sav == NULL) panic("key_sa_chgstate called with sav == NULL"); if (sav->state == state) return; if (__LIST_CHAINED(sav)) LIST_REMOVE(sav, chain); sav->state = state; LIST_INSERT_HEAD(&sav->sah->savtree[state], sav, chain); } void key_sa_stir_iv(sav) struct secasvar *sav; { if (!sav->iv) panic("key_sa_stir_iv called with sav == NULL"); key_randomfill(sav->iv, sav->ivlen); } static void key_sp_dead(sp) struct secpolicy *sp; { /* mark the SP dead */ sp->state = IPSEC_SPSTATE_DEAD; } static void key_sp_unlink(sp) struct secpolicy *sp; { /* remove from SP index */ if (__LIST_CHAINED(sp)) { LIST_REMOVE(sp, chain); key_freesp(sp); } } /* XXX too much? */ static struct mbuf * key_alloc_mbuf(l) int l; { struct mbuf *m = NULL, *n; int len, t; len = l; while (len > 0) { MGET(n, M_DONTWAIT, MT_DATA); if (n && len > MLEN) MCLGET(n, M_DONTWAIT); if (!n) { m_freem(m); return NULL; } n->m_next = NULL; n->m_len = 0; n->m_len = M_TRAILINGSPACE(n); /* use the bottom of mbuf, hoping we can prepend afterwards */ if (n->m_len > len) { t = (n->m_len - len) & ~(sizeof(long) - 1); n->m_data += t; n->m_len = len; } len -= n->m_len; if (m) m_cat(m, n); else m = n; } return m; } --------------------------------------------------------------------------------------- after I have changed the original key.c, I run diff key.c.orig key.c to find the following ---------------------- the diff after patching is ----------------------------- 195a196,200 > sizeof(struct sadb_x_nat_t_type), /* SADB_X_EXT_NAT_T_TYPE */ > sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_SPORT */ > sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_DPORT */ > sizeof(struct sadb_address), /* SADB_X_EXT_NAT_T_OA */ > sizeof(struct sadb_x_nat_t_frag),/* SADB_X_EXT_NAT_T_FRAG */ 217a223,227 > sizeof(struct sadb_x_nat_t_type), /* SADB_X_EXT_NAT_T_TYPE */ > sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_SPORT */ > sizeof(struct sadb_x_nat_t_port), /* SADB_X_EXT_NAT_T_DPORT */ > 0, /* SADB_X_EXT_NAT_T_OA */ > sizeof(struct sadb_x_nat_t_frag), /* SADB_X_EXT_NAT_T_FRAG */ 385a396,399 > #ifdef IPSEC_NAT_T > static int key_nat_map(struct socket *, struct mbuf *, > const struct sadb_msghdr *); > #endif 407a422,428 > #ifdef IPSEC_NAT_T > static struct mbuf *key_setsadbxport __P((u_int16_t, u_int16_t)); > static struct mbuf *key_setsadbxtype __P((u_int16_t)); > #endif > static void key_porttosaddr __P((struct sockaddr *, u_int16_t)); > #define KEY_PORTTOSADDR(saddr, port) \ > key_porttosaddr((struct sockaddr *)(saddr), (port)) 929c950 < key_allocsa(family, src, dst, proto, spi) --- > key_allocsa(family, src, dst, proto, spi, sport, dport) 932a954 > u_int16_t sport, dport; 940a963 > int chkport = 0; 945a969,973 > #ifdef IPSEC_NAT_T > if ((sport != 0) && (dport != 0)) > chkport = 1; > #endif > 1034a1063,1065 > #ifdef IPSEC_NAT_T > sin.sin_port = sport; > #endif 1036c1067 < (struct sockaddr *)&sav->sah->saidx.dst, 0) != 0) --- > (struct sockaddr *)&sav->sah->saidx.src, chkport) != 0) 1050a1082,1084 > #ifdef IPSEC_NAT_T > sin6.sin6_port = sport; > #endif 1052c1086 < (struct sockaddr *)&sav->sah->saidx.dst, 0) != 0) --- > (struct sockaddr *)&sav->sah->saidx.src, chkport) != 0) 1879a1914 > #ifndef IPSEC_NAT_T 1922a1958 > #endif /* !IPSEC_NAT_T */ 2481a2518,2583 > #ifdef IPSEC_NAT_T > /* > * SADB_X_NAT_T_NEW_MAPPING > */ > static int > key_nat_map(so, m, mhp) > struct socket *so; > struct mbuf *m; > const struct sadb_msghdr *mhp; > { > struct sadb_x_nat_t_type *type; > struct sadb_x_nat_t_port *sport; > struct sadb_x_nat_t_port *dport; > struct sadb_address *addr; > struct sadb_x_nat_t_frag *frag; > > /* sanity check */ > if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) > panic("key_nat_map: NULL pointer is passed."); > > if (mhp->ext[SADB_X_EXT_NAT_T_TYPE] == NULL || > mhp->ext[SADB_X_EXT_NAT_T_SPORT] == NULL || > mhp->ext[SADB_X_EXT_NAT_T_DPORT] == NULL) { > ipseclog((LOG_DEBUG, "key_nat_map: invalid message.\n")); > return key_senderror(so, m, EINVAL); > } > if ((mhp->extlen[SADB_X_EXT_NAT_T_TYPE] < sizeof(*type)) || > (mhp->extlen[SADB_X_EXT_NAT_T_SPORT] < sizeof(*sport)) || > (mhp->extlen[SADB_X_EXT_NAT_T_DPORT] < sizeof(*dport))) { > ipseclog((LOG_DEBUG, "key_nat_map: invalid message.\n")); > return key_senderror(so, m, EINVAL); > } > > if ((mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) && > (mhp->extlen[SADB_X_EXT_NAT_T_OA] < sizeof(*addr))) { > ipseclog((LOG_DEBUG, "key_nat_map: invalid message\n")); > return key_senderror(so, m, EINVAL); > } > > if ((mhp->ext[SADB_X_EXT_NAT_T_FRAG] != NULL) && > (mhp->extlen[SADB_X_EXT_NAT_T_FRAG] < sizeof(*frag))) { > ipseclog((LOG_DEBUG, "key_nat_map: invalid message\n")); > return key_senderror(so, m, EINVAL); > } > > type = (struct sadb_x_nat_t_type *)mhp->ext[SADB_X_EXT_NAT_T_TYPE]; > sport = (struct sadb_x_nat_t_port *)mhp->ext[SADB_X_EXT_NAT_T_SPORT]; > dport = (struct sadb_x_nat_t_port *)mhp->ext[SADB_X_EXT_NAT_T_DPORT]; > addr = (struct sadb_address *)mhp->ext[SADB_X_EXT_NAT_T_OA]; > frag = (struct sadb_x_nat_t_frag *) mhp->ext[SADB_X_EXT_NAT_T_FRAG]; > > printf("sadb_nat_map: type %d, sport = %d, dport = %d\n", > type->sadb_x_nat_t_type_type, > sport->sadb_x_nat_t_port_port, > dport->sadb_x_nat_t_port_port); > > /* > * XXX handle that, it should also contain a SA, or anything > * that enable to update the SA information. > */ > > return 0; > } > #endif /* IPSEC_NAT_T */ > > 3031a3134,3137 > #ifdef IPSEC_NAT_T > sav->natt_type = 0; > sav->esp_frag = 0; > #endif 3497a3604,3608 > #ifdef IPSEC_NAT_T > SADB_X_EXT_NAT_T_TYPE, SADB_X_EXT_NAT_T_SPORT, > SADB_X_EXT_NAT_T_DPORT, SADB_X_EXT_NAT_T_OA, > SADB_X_EXT_NAT_T_FRAG, > #endif 3573a3685,3709 > #ifdef IPSEC_NAT_T > case SADB_X_EXT_NAT_T_TYPE: > if ((m = key_setsadbxtype(sav->natt_type)) == NULL) > goto fail; > break; > > case SADB_X_EXT_NAT_T_DPORT: > if ((m = key_setsadbxport(KEY_PORTFROMSADDR > (&sav->sah->saidx.dst), > SADB_X_EXT_NAT_T_DPORT)) == NULL) > goto fail; > break; > > case SADB_X_EXT_NAT_T_SPORT: > if ((m = key_setsadbxport(KEY_PORTFROMSADDR > (&sav->sah->saidx.src), > SADB_X_EXT_NAT_T_SPORT)) == NULL) > goto fail; > break; > > case SADB_X_EXT_NAT_T_OA: > case SADB_X_EXT_NAT_T_FRAG: > continue; > #endif > 3831a3968,4094 > #ifdef IPSEC_NAT_T > /* > * set a type in sadb_x_nat_t_type > */ > static struct mbuf * > key_setsadbxtype(type) > u_int16_t type; > { > struct mbuf *m; > size_t len; > struct sadb_x_nat_t_type *p; > > len = PFKEY_ALIGN8(sizeof(struct sadb_x_nat_t_type)); > > m = key_alloc_mbuf(len); > if (!m || m->m_next) { /*XXX*/ > if (m) > m_freem(m); > return NULL; > } > > p = mtod(m, struct sadb_x_nat_t_type *); > > bzero(p, len); > p->sadb_x_nat_t_type_len = PFKEY_UNIT64(len); > p->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE; > p->sadb_x_nat_t_type_type = type; > > return m; > } > /* > * set a port in sadb_x_nat_t_port. port is in network order > */ > static struct mbuf * > key_setsadbxport(port, type) > u_int16_t port; > u_int16_t type; > { > struct mbuf *m; > size_t len; > struct sadb_x_nat_t_port *p; > > len = PFKEY_ALIGN8(sizeof(struct sadb_x_nat_t_port)); > > m = key_alloc_mbuf(len); > if (!m || m->m_next) { /*XXX*/ > if (m) > m_freem(m); > return NULL; > } > > p = mtod(m, struct sadb_x_nat_t_port *); > > bzero(p, len); > p->sadb_x_nat_t_port_len = PFKEY_UNIT64(len); > p->sadb_x_nat_t_port_exttype = type; > p->sadb_x_nat_t_port_port = port; > > return m; > } > > /* > * Get port from sockaddr, port is in network order > */ > u_int16_t > key_portfromsaddr(saddr) > struct sockaddr *saddr; > { > u_int16_t port; > > switch (saddr->sa_family) { > case AF_INET: { > struct sockaddr_in *sin = (struct sockaddr_in *)saddr; > > port = sin->sin_port; > break; > } > #ifdef INET6 > case AF_INET6: { > struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)saddr; > > port = sin6->sin6_port; > break; > } > #endif > default: > printf("key_portfromsaddr: unexpected address family\n"); > port = 0; > break; > } > > return port; > } > #endif /* IPSEC_NAT_T */ > > /* > * Set port is struct sockaddr. port is in network order > */ > static void > key_porttosaddr(saddr, port) > struct sockaddr *saddr; > u_int16_t port; > { > switch (saddr->sa_family) { > case AF_INET: { > struct sockaddr_in *sin = (struct sockaddr_in *)saddr; > > sin->sin_port = port; > break; > } > #ifdef INET6 > case AF_INET6: { > struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)saddr; > > sin6->sin6_port = port; > break; > } > #endif > default: > printf("key_porttosaddr: unexpected address family %d\n", > saddr->sa_family); > break; > } > > return; > } > 4018a4282,4283 > int chkport = 0; > 4040a4306,4318 > #ifdef IPSEC_NAT_T > /* > * If NAT-T is enabled, check ports for tunnel mode. > * Don't do it for transport mode, as there is no > * port information available in the SP. > * XXX also don't check ports if they are set to zero in the SPD: > * This means we bave a non-generated SPD, which can't know UDP ports. > */ > if (saidx1->mode == IPSEC_MODE_TUNNEL && > satosin(&saidx1->src)->sin_port && > satosin(&saidx1->dst)->sin_port ) > chkport = 1; > #endif 4047a4326,4329 > #ifdef IPSEC_NAT_T > else > chkport = 1; > #endif 4056c4338 < (struct sockaddr *)&saidx1->src, 0) != 0) { --- > (struct sockaddr *)&saidx1->src, chkport) != 0) { 4060c4342 < (struct sockaddr *)&saidx1->dst, 0) != 0) { --- > (struct sockaddr *)&saidx1->dst, chkport) != 0) { 4708c4990 < /* make sure if port number is zero. */ --- > /* make sure if port number is zero if NAT-T support is NOT compiled. */ 4713a4996 > #ifndef IPSEC_NAT_T 4714a4998 > #endif 4719a5004 > #ifndef IPSEC_NAT_T 4720a5006 > #endif 4729a5016 > #ifndef IPSEC_NAT_T 4730a5018 > #endif 4735a5024 > #ifndef IPSEC_NAT_T 4736a5026 > #endif 4744a5035,5040 > /* If not using NAT-T, make sure port numbers are set to zero. */ > #ifndef IPSEC_NAT_T > KEY_PORTTOSADDR(&saidx.src, 0); > KEY_PORTTOSADDR(&saidx.dst, 0); > #endif > 4997a5294,5299 > /* If not using NAT-T, make sure if port number is zero. */ > #ifndef IPSEC_NAT_T > KEY_PORTTOSADDR(&saidx.src, 0); > KEY_PORTTOSADDR(&saidx.dst, 0); > #endif > 5063a5366,5427 > #ifdef IPSEC_NAT_T > /* > * Handle NAT-T info if present > */ > if (mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) > printf("update: NAT-T OA present\n"); > > if ((mhp->ext[SADB_X_EXT_NAT_T_TYPE] != NULL) && > (mhp->ext[SADB_X_EXT_NAT_T_SPORT] != NULL) && > (mhp->ext[SADB_X_EXT_NAT_T_DPORT] != NULL)) { > struct sadb_x_nat_t_type *type; > struct sadb_x_nat_t_port *sport; > struct sadb_x_nat_t_port *dport; > struct sadb_address *addr; > struct sadb_x_nat_t_frag *frag; > > if ((mhp->extlen[SADB_X_EXT_NAT_T_TYPE] < sizeof(*type)) || > (mhp->extlen[SADB_X_EXT_NAT_T_SPORT] < sizeof(*sport)) || > (mhp->extlen[SADB_X_EXT_NAT_T_DPORT] < sizeof(*dport))) { > ipseclog((LOG_DEBUG, "key_update: " > "invalid message.\n")); > return key_senderror(so, m, EINVAL); > } > > if ((mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) && > (mhp->extlen[SADB_X_EXT_NAT_T_OA] < sizeof(*addr))) { > ipseclog((LOG_DEBUG, "key_update: invalid message\n")); > return key_senderror(so, m, EINVAL); > } > > if ((mhp->ext[SADB_X_EXT_NAT_T_FRAG] != NULL) && > (mhp->extlen[SADB_X_EXT_NAT_T_FRAG] < sizeof(*frag))) { > ipseclog((LOG_DEBUG, "key_update: invalid message\n")); > return key_senderror(so, m, EINVAL); > } > > type = (struct sadb_x_nat_t_type *) > mhp->ext[SADB_X_EXT_NAT_T_TYPE]; > sport = (struct sadb_x_nat_t_port *) > mhp->ext[SADB_X_EXT_NAT_T_SPORT]; > dport = (struct sadb_x_nat_t_port *) > mhp->ext[SADB_X_EXT_NAT_T_DPORT]; > addr = (struct sadb_address *) > mhp->ext[SADB_X_EXT_NAT_T_OA]; > frag = (struct sadb_x_nat_t_frag *) > mhp->ext[SADB_X_EXT_NAT_T_FRAG]; > > if (type) > sav->natt_type = type->sadb_x_nat_t_type_type; > if (sport) > KEY_PORTTOSADDR(&sav->sah->saidx.src, > sport->sadb_x_nat_t_port_port); > if (dport) > KEY_PORTTOSADDR(&sav->sah->saidx.dst, > dport->sadb_x_nat_t_port_port); > if (frag) > sav->esp_frag = frag->sadb_x_nat_t_frag_fraglen; > else > sav->esp_frag = IP_MAXPACKET; > } > #endif /* IPSEC_NAT_T */ > 5192a5557,5561 > #ifndef IPSEC_NAT_T > KEY_PORTTOSADDR(&saidx.src, 0); > KEY_PORTTOSADDR(&saidx.dst, 0); > #endif > 5225a5595,5656 > #ifdef IPSEC_NAT_T > /* > * Handle NAT-T info if present > */ > if (mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) > printf("add: NAT-T OA present\n"); > > if ((mhp->ext[SADB_X_EXT_NAT_T_TYPE] != NULL) && > (mhp->ext[SADB_X_EXT_NAT_T_SPORT] != NULL) && > (mhp->ext[SADB_X_EXT_NAT_T_DPORT] != NULL)) { > struct sadb_x_nat_t_type *type; > struct sadb_x_nat_t_port *sport; > struct sadb_x_nat_t_port *dport; > struct sadb_address *addr; > struct sadb_x_nat_t_frag *frag; > > if ((mhp->extlen[SADB_X_EXT_NAT_T_TYPE] < sizeof(*type)) || > (mhp->extlen[SADB_X_EXT_NAT_T_SPORT] < sizeof(*sport)) || > (mhp->extlen[SADB_X_EXT_NAT_T_DPORT] < sizeof(*dport))) { > ipseclog((LOG_DEBUG, "key_add: " > "invalid message.\n")); > return key_senderror(so, m, EINVAL); > } > > if ((mhp->ext[SADB_X_EXT_NAT_T_OA] != NULL) && > (mhp->extlen[SADB_X_EXT_NAT_T_OA] < sizeof(*addr))) { > ipseclog((LOG_DEBUG, "key_add: invalid message\n")); > return key_senderror(so, m, EINVAL); > } > > if ((mhp->ext[SADB_X_EXT_NAT_T_FRAG] != NULL) && > (mhp->extlen[SADB_X_EXT_NAT_T_FRAG] < sizeof(*frag))) { > ipseclog((LOG_DEBUG, "key_update: invalid message\n")); > return key_senderror(so, m, EINVAL); > } > > type = (struct sadb_x_nat_t_type *) > mhp->ext[SADB_X_EXT_NAT_T_TYPE]; > sport = (struct sadb_x_nat_t_port *) > mhp->ext[SADB_X_EXT_NAT_T_SPORT]; > dport = (struct sadb_x_nat_t_port *) > mhp->ext[SADB_X_EXT_NAT_T_DPORT]; > addr = (struct sadb_address *) > mhp->ext[SADB_X_EXT_NAT_T_OA]; > frag = (struct sadb_x_nat_t_frag *) > mhp->ext[SADB_X_EXT_NAT_T_FRAG]; > > if (type) > newsav->natt_type = type->sadb_x_nat_t_type_type; > if (sport) > KEY_PORTTOSADDR(&newsav->sah->saidx.src, > sport->sadb_x_nat_t_port_port); > if (dport) > KEY_PORTTOSADDR(&newsav->sah->saidx.dst, > dport->sadb_x_nat_t_port_port); > if (frag) > newsav->esp_frag = frag->sadb_x_nat_t_frag_fraglen; > else > newsav->esp_frag = IP_MAXPACKET; > } > #endif > 5419a5851,5855 > #ifndef IPSEC_NAT_T > KEY_PORTTOSADDR(&saidx.src, 0); > KEY_PORTTOSADDR(&saidx.dst, 0); > #endif > 5486a5923,5927 > #ifndef IPSEC_NAT_T > KEY_PORTTOSADDR(&saidx.src, 0); > KEY_PORTTOSADDR(&saidx.dst, 0); > #endif > 5595a6037,6041 > #ifndef IPSEC_NAT_T > KEY_PORTTOSADDR(&saidx.src, 0); > KEY_PORTTOSADDR(&saidx.dst, 0); > #endif > 6275a6722,6726 > #ifndef IPSEC_NAT_T > KEY_PORTTOSADDR(&saidx.src, 0); > KEY_PORTTOSADDR(&saidx.dst, 0); > #endif > 6878a7330,7334 > #ifdef IPSEC_NAT_T > key_nat_map, /* SADB_X_NAT_T_NEW_MAPPING */ > #else > NULL, > #endif 7214a7671,7677 > #ifdef IPSEC_NAT_T > case SADB_X_EXT_NAT_T_TYPE: > case SADB_X_EXT_NAT_T_SPORT: > case SADB_X_EXT_NAT_T_DPORT: > case SADB_X_EXT_NAT_T_OA: > case SADB_X_EXT_NAT_T_FRAG: > #endif ------------------------------------------------------------------------- That is all. I am waiting for your reply -- thanks, Kamanashis Roy From owner-freebsd-net@FreeBSD.ORG Fri Sep 15 01:43:47 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 652E416A403 for ; Fri, 15 Sep 2006 01:43:47 +0000 (UTC) (envelope-from sullrich@gmail.com) Received: from ug-out-1314.google.com (ug-out-1314.google.com [66.249.92.168]) by mx1.FreeBSD.org (Postfix) with ESMTP id 671DD43D6D for ; Fri, 15 Sep 2006 01:43:39 +0000 (GMT) (envelope-from sullrich@gmail.com) Received: by ug-out-1314.google.com with SMTP id m2so153859uge for ; Thu, 14 Sep 2006 18:43:39 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=Kf8jrPXd0m/NYc5BXUUUsMnhdkT3sx57QFrROriCuFG6h8WtslouBLXVwnTM1JKr6ZEzjVJSEpUZzITCuj7KK9xCdOGf1F1ovnK+HtSO5xalODprP7aHKFEsVmEqhCgJV9lwqno46/5v/uSsTYlhobprwmMvYDQ4TTDKooSahMI= Received: by 10.67.100.17 with SMTP id c17mr5176089ugm; Thu, 14 Sep 2006 18:43:38 -0700 (PDT) Received: by 10.67.105.8 with HTTP; Thu, 14 Sep 2006 18:43:38 -0700 (PDT) Message-ID: Date: Thu, 14 Sep 2006 21:43:38 -0400 From: "Scott Ullrich" To: "Larry Baird" In-Reply-To: <20060914093034.A83805@gta.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <20060914093034.A83805@gta.com> Cc: freebsd-net@freebsd.org Subject: Re: FAST_IPSEC NAT-T support X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2006 01:43:47 -0000 On 9/14/06, Larry Baird wrote: > Please find attached two patches for adding FAST_IPSEC NAT-T support to > FreeBSD 6.x. The patch "freebsd6-fastipsec-natt.diff" is dependent > upon Yvan's IPSEC NAT-T patch "freebsd6-natt.diff" which can be found at > http://ipsec-tools.cvs.sourceforge.net/ipsec-tools/htdocs/. The second > patch "freebsd6-ipsec-fastipsec-natt.diff" is a cumulative patch > combining both patches together. This is great! It compiles on FreeBSD 6.1 when you include options IPSEC_NAT_T but when you fail to include this item "options IPSEC_NAT_T" in addition to including "options FAST_IPSEC" you end up with: cc -c -O -pipe -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual -fformat-extensions -std=c99 -g -nostdinc -I- -I. -I/usr/src/sys -I/usr/src/sys/contrib/altq -I/usr/src/sys/contrib/ipfilter -I/usr/src/sys/contrib/pf -I/usr/src/sys/contrib/dev/ath -I/usr/src/sys/contrib/dev/ath/freebsd -I/usr/src/sys/contrib/ngatm -I/usr/src/sys/dev/twa -D_KERNEL -DHAVE_KERNEL_OPTION_HEADERS -include opt_global.h -fno-common -finline-limit=8000 --param inline-unit-growth=100 --param large-function-growth=1000 -mno-align-long-strings -mpreferred-stack-boundary=2 -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -ffreestanding -Werror /usr/src/sys/netipsec/key.c /usr/src/sys/netipsec/key.c: In function `key_spdadd': /usr/src/sys/netipsec/key.c:1867: error: `isr' undeclared (first use in this function) /usr/src/sys/netipsec/key.c:1867: error: (Each undeclared identifier is reported only once /usr/src/sys/netipsec/key.c:1867: error: for each function it appears in.) *** Error code 1 Stop in /usr/obj/usr/src/sys/pfSense.6. *** Error code 1 Stop in /usr/src. *** Error code 1 Stop in /usr/src. Meanwhile I have a new version of pfSense out asking for testing. We seem to have a large base of users requesting this option so hopefully I can get some meaningful testing information for you soon. Thanks again! Scott From owner-freebsd-net@FreeBSD.ORG Fri Sep 15 04:22:19 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id CC20816A417; Fri, 15 Sep 2006 04:22:19 +0000 (UTC) (envelope-from bu7cher@yandex.ru) Received: from smtp1.yandex.ru (smtp1.yandex.ru [213.180.223.87]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7DE5243D5E; Fri, 15 Sep 2006 04:22:17 +0000 (GMT) (envelope-from bu7cher@yandex.ru) Received: from ns.kirov.so-cdu.ru ([81.18.142.225]:37132 "EHLO [127.0.0.1]" smtp-auth: "bu7cher" TLS-CIPHER: "DHE-RSA-AES256-SHA keybits 256/256 version TLSv1/SSLv3" TLS-PEER-CN1: ) by mail.yandex.ru with ESMTP id S2077741AbWIOEWJ (ORCPT + 2 others); Fri, 15 Sep 2006 08:22:09 +0400 X-Comment: RFC 2476 MSA function at smtp1.yandex.ru logged sender identity as: bu7cher Message-ID: <450A2A6E.3040408@yandex.ru> Date: Fri, 15 Sep 2006 08:22:06 +0400 From: "Andrey V. Elsukov" User-Agent: Mozilla Thunderbird 1.5 (FreeBSD/20051231) MIME-Version: 1.0 To: Marcelo Gardini do Amaral References: <2a41acea0608301145j7bbed961j33ce903a27d8963d@mail.gmail.com> <20060904130827.GE12975@registro.br> <20060911195521.GD63300@registro.br> <20060913182019.R50147@fledge.watson.org> <20060913182457.W50147@fledge.watson.org> <20060914175049.GH49126@registro.br> In-Reply-To: <20060914175049.GH49126@registro.br> Content-Type: text/plain; charset=KOI8-R; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-net@freebsd.org, Robert Watson , freebsd-stable@freebsd.org Subject: Re: DNS query performance X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2006 04:22:19 -0000 Marcelo Gardini do Amaral wrote: > With the 7.x kernel and no changes in src/sys/netinet/udp_usrreq.c I > tried different timecounters and I couldn't see any performance > difference. You have tested with a GENERIC kernel? You should remove all debugging kernel options before testing performance. -- WBR, Andrey V. Elsukov From owner-freebsd-net@FreeBSD.ORG Fri Sep 15 05:30:44 2006 Return-Path: X-Original-To: freebsd-net@FreeBSD.org Delivered-To: freebsd-net@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 33FD416A412 for ; Fri, 15 Sep 2006 05:30:44 +0000 (UTC) (envelope-from sivakumar.subramani@wipro.com) Received: from wip-ectls-mx1.wipro.com (wip-ectls-mx1.wipro.com [203.91.193.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id DEF7943D58 for ; Fri, 15 Sep 2006 05:30:42 +0000 (GMT) (envelope-from sivakumar.subramani@wipro.com) Received: from wip-ectls-mx1.wipro.com (localhost.localdomain [127.0.0.1]) by localhost (Postfix) with ESMTP id B9C55220219; Fri, 15 Sep 2006 11:00:48 +0530 (IST) Received: from blr-ec-bh02.wipro.com (blr-ec-bh02.wipro.com [10.201.50.92]) by wip-ectls-mx1.wipro.com (Postfix) with ESMTP id ADE85220078; Fri, 15 Sep 2006 11:00:48 +0530 (IST) Received: from blr-m3-msg.wipro.com ([10.114.50.99]) by blr-ec-bh02.wipro.com with Microsoft SMTPSVC(6.0.3790.1830); Fri, 15 Sep 2006 11:00:40 +0530 X-MimeOLE: Produced By Microsoft Exchange V6.5 Content-class: urn:content-classes:message MIME-Version: 1.0 Date: Fri, 15 Sep 2006 10:55:38 +0530 Message-ID: <956E7FA2615F3B4595FC5F22870A722108100C@blr-m3-msg.wipro.com> In-Reply-To: <20060914161309.GC9421@funkthat.com> X-MS-Has-Attach: X-MS-TNEF-Correlator: Thread-Topic: Reading a configuration file from a driver code during intialization. Thread-Index: AcbYF/+021bnu0ECTPGcBjTczt8mSgAbQW/Q From: To: X-OriginalArrivalTime: 15 Sep 2006 05:30:40.0671 (UTC) FILETIME=[150922F0:01C6D888] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Cc: freebsd-net@FreeBSD.org Subject: RE: Reading a configuration file from a driver code during intialization. X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2006 05:30:44 -0000 Hi Mark, =0D As I mentioned in the previous mail, the main issue is to read a Configuration parameter file from driver code. I am already using Sysctl variables as mentioned below, =0D Currently I have written a small kernel module that will create a sysctl variable and update with a default value. After loading this module, using shell scripts, I read the configuration file and get the user set values and update the sysctl variable in that value. Then I will load my driver where I read the sysctl variable to get the required values set by the user in the configuration file. =0D This is a round about way. Is there is any other way to read a configuration file from Driver code. =0D =0D Thanks, ~Siva -----Original Message----- From: John-Mark Gurney [mailto:gurney_j@resnet.uoregon.edu]=0D Sent: Thursday, September 14, 2006 9:43 PM To: SIVAKUMAR SUBRAMANI (WT01 - Computing Systems & Storage) Cc: freebsd-net@FreeBSD.org Subject: Re: Reading a configuration file from a driver code during intialization. =0D sivakumar.subramani@wipro.com wrote this message on Thu, Sep 14, 2006 at 12:16 +0530: > Is there is any other solution to the above problem? >=0D >=0D >=0D > Actually I am looking for some thing similar to Module loadable > parameters in the Linux Device Driver. =0D look at kenv... It lets you set arbitrary values and access them in the kernel... you can use the TUNABLE_* macros provided by sys/kernel.h to make accessing them easier... =0D If the variables need to change at run time, look at SYSCTL... =0D --=0D John-Mark Gurney Voice: +1 415 225 5579 =0D "All that I will do, has been done, All that I have, has not." The information contained in this electronic message and any attachments to= this message are intended for the exclusive use of the addressee(s) and= may contain proprietary, confidential or privileged information. If you= are not the intended recipient, you should not disseminate, distribute or= copy this e-mail. Please notify the sender immediately and destroy all= copies of this message and any attachments.=0D WARNING: Computer viruses can be transmitted via email. The recipient= should check this email and any attachments for the presence of viruses.= The company accepts no liability for any damage caused by any virus= transmitted by this email. =0D www.wipro.com From owner-freebsd-net@FreeBSD.ORG Fri Sep 15 06:39:26 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E0CFF16A403 for ; Fri, 15 Sep 2006 06:39:26 +0000 (UTC) (envelope-from vanhu@zeninc.net) Received: from leia.fdn.fr (ns0.fdn.org [80.67.169.12]) by mx1.FreeBSD.org (Postfix) with ESMTP id 50EDD43D45 for ; Fri, 15 Sep 2006 06:39:25 +0000 (GMT) (envelope-from vanhu@zeninc.net) Received: from smtp.zeninc.net (reverse-25.fdn.fr [80.67.176.25]) by leia.fdn.fr (8.13.3/8.13.3/FDN) with ESMTP id k8F6dNw4007532 for ; Fri, 15 Sep 2006 08:39:24 +0200 Received: by smtp.zeninc.net (smtpd, from userid 1000) id 382AA3F17; Fri, 15 Sep 2006 08:39:18 +0200 (CEST) Date: Fri, 15 Sep 2006 08:39:17 +0200 From: VANHULLEBUS Yvan To: freebsd-net@freebsd.org Message-ID: <20060915063917.GA12057@zen.inc> References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: All mail clients suck. This one just sucks less. Subject: Re: Where is IPSec NAT-T support? X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2006 06:39:27 -0000 On Fri, Sep 15, 2006 at 06:02:38AM +0600, Kamanashis Roy Shuva wrote: > Hi, > You have done a great jop. And I find this useful today. Problem is things > are not working fine. > I have compiled freebsd with the patch > MD5 (freebsd6-natt.diff) = 81d535363981b5e84be77cbf26918ccc > for natt support. But I have problems both before and after compilation. > Note, as I tried uname I find > ------------------------------------- > localhost# uname -v > FreeBSD 6.0-RELEASE #7: Thu Sep 14 19:28:39 GMT 2006 tapan@localhost > :/usr/obj/usr/src/sys/IPSEC > ------------------------------------- > Again I have the following line in my conf file for kernel > ------------------------------------- > options IPSEC > options IPSEC_ESP > options IPSEC_DEBUG > options IPSEC_NAT_T > ------------------------------------- > and I have not compiled with fast ipsec support > But there were two problems. > 1. I cannot compile the ipsec-tools with '--enable-natt=yes'. It checks > the presence of > natt support and it fals to find that. There in configure file I find a c > program Guess you didn't "make buildworld && make installworld", so you still have the non patched version of net/pfkeyv2.h in /usr/src. [....] > -------------------------------------- > 2. the patch failed for src/sys/netkey/key.c > and I have tried to do this manually , ?????? Could you give us the .rej ? Yvan. -- NETASQ http://www.netasq.com From owner-freebsd-net@FreeBSD.ORG Fri Sep 15 09:25:13 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1269116A403 for ; Fri, 15 Sep 2006 09:25:13 +0000 (UTC) (envelope-from bzeeb-lists@lists.zabbadoz.net) Received: from transport.cksoft.de (transport.cksoft.de [62.111.66.27]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6C37943D49 for ; Fri, 15 Sep 2006 09:25:11 +0000 (GMT) (envelope-from bzeeb-lists@lists.zabbadoz.net) Received: from transport.cksoft.de (localhost [127.0.0.1]) by transport.cksoft.de (Postfix) with ESMTP id F3C831FFF99; Fri, 15 Sep 2006 11:25:09 +0200 (CEST) Received: by transport.cksoft.de (Postfix, from userid 66) id 600491FFF7F; Fri, 15 Sep 2006 11:25:05 +0200 (CEST) Received: from maildrop.int.zabbadoz.net (maildrop.int.zabbadoz.net [10.111.66.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.int.zabbadoz.net (Postfix) with ESMTP id DBEB64448D6; Fri, 15 Sep 2006 09:24:03 +0000 (UTC) Date: Fri, 15 Sep 2006 09:24:03 +0000 (UTC) From: "Bjoern A. Zeeb" X-X-Sender: bz@maildrop.int.zabbadoz.net To: Larry Baird , VANHULLEBUS Yvan In-Reply-To: <20060914093034.A83805@gta.com> Message-ID: <20060915082519.T44392@maildrop.int.zabbadoz.net> References: <20060914093034.A83805@gta.com> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Virus-Scanned: by AMaViS cksoft-s20020300-20031204bz on transport.cksoft.de Cc: freebsd-net@freebsd.org Subject: Re: FAST_IPSEC NAT-T support X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2006 09:25:13 -0000 Hi, [just replying to a random mail of one of the various NAT-T threads at this point] I had started to review the code (to find some problems people had with the patch) and came up with the following so far. This work was done based on the old freebsd6-natt.diff which is no longer available:( but should equally apply to the new one. Here is what the patch[1] changes: - do not request more data to be collapsed into one contiguous data area of a mbuf than needed. sizeof(struct udphdr) is already included in off. - remove unused variable 'family' - the original patch did a m_dup() to get another writable copy (not only a reference) of the mbuf chain but did this after touching/changing data of the original mbuf. As it shouldn't matter in either case do it the right way and create the copy before moving data around so the original mbuf stays untouched. - After removing the UDP part correctly set the new ip_len. The value already is in hbo so arithmetics were wrong. The new value should not be needed by functions called (though they may change it too) but if we adjust it do it correctly. - NICs like bge(4) do support IP/TCP/UDP checksum offloading. That means once a natt packet hits udp_input a csum for the IP and UDP payload was already validated. UDP checksumming is generally optional so nobody really cares in case it's a) not requested and b) the NIC doesn't do it already. But in case the NIC does, the flags are set on the mbuf that the csum was/is correct. While this mbuf (or a 1:1 copy) is passed on to ESP handling and later for example TCP handlig the valid csum flags are still there but our paket has changed and of course the original checksum for the UDP natt part is no longer the same and valid for the TCP payload and thus the packet gets dropped. So clear the csum flags if set before handing the packet off to ESP processing. Now that it looks that finally all the bits and pieces are there for NAT-T support I'll continue the review as time permits. Greetings Bjoern References: [1] http://sources.zabbadoz.net/freebsd/ipv6/patches/natt-20060908-01-bz.diff -- Bjoern A. Zeeb bzeeb at Zabbadoz dot NeT From owner-freebsd-net@FreeBSD.ORG Fri Sep 15 09:30:26 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9049216A416 for ; Fri, 15 Sep 2006 09:30:26 +0000 (UTC) (envelope-from vanhu@zeninc.net) Received: from leia.fdn.fr (ns0.fdn.org [80.67.169.12]) by mx1.FreeBSD.org (Postfix) with ESMTP id CABB543D49 for ; Fri, 15 Sep 2006 09:30:25 +0000 (GMT) (envelope-from vanhu@zeninc.net) Received: from smtp.zeninc.net (reverse-25.fdn.fr [80.67.176.25]) by leia.fdn.fr (8.13.3/8.13.3/FDN) with ESMTP id k8F9UMxj006874; Fri, 15 Sep 2006 11:30:23 +0200 Received: by smtp.zeninc.net (smtpd, from userid 1000) id BD2133F17; Fri, 15 Sep 2006 11:30:17 +0200 (CEST) Date: Fri, 15 Sep 2006 11:30:17 +0200 From: VANHULLEBUS Yvan To: freebsd-net@freebsd.org Message-ID: <20060915093017.GA13878@zen.inc> References: <20060914093034.A83805@gta.com> <20060915082519.T44392@maildrop.int.zabbadoz.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20060915082519.T44392@maildrop.int.zabbadoz.net> User-Agent: All mail clients suck. This one just sucks less. Cc: "Bjoern A. Zeeb" , Larry Baird Subject: Re: FAST_IPSEC NAT-T support X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2006 09:30:26 -0000 On Fri, Sep 15, 2006 at 09:24:03AM +0000, Bjoern A. Zeeb wrote: > Hi, Hi. > [just replying to a random mail of one of the various NAT-T threads > at this point] > > I had started to review the code (to find some problems people had > with the patch) and came up with the following so far. This work > was done based on the old freebsd6-natt.diff which is no longer > available:( but should equally apply to the new one. There have been some changes between the patch you've worked on and the latest I released a few days ago, but most things will probably be trivial to port, I'll start to do that as soon as I'll have integrated/tested/commited (on ipsec-tools website) Larry's patch for FAST_IPSEC. Yvan. -- NETASQ http://www.netasq.com From owner-freebsd-net@FreeBSD.ORG Fri Sep 15 11:52:05 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 6317616A403 for ; Fri, 15 Sep 2006 11:52:05 +0000 (UTC) (envelope-from wjw@withagen.nl) Received: from freebee.digiware.nl (www.tegenbosch28.nl [217.21.251.97]) by mx1.FreeBSD.org (Postfix) with ESMTP id B471843D49 for ; Fri, 15 Sep 2006 11:52:04 +0000 (GMT) (envelope-from wjw@withagen.nl) Received: from [212.61.27.67] (opteron.digiware.nl [212.61.27.67]) by freebee.digiware.nl (Postfix) with ESMTP id 86D7D2AAA0; Fri, 15 Sep 2006 13:52:00 +0200 (CEST) Message-ID: <450A9421.6010400@withagen.nl> Date: Fri, 15 Sep 2006 13:53:05 +0200 From: Willem Jan Withagen User-Agent: Thunderbird 1.5.0.5 (Windows/20060719) MIME-Version: 1.0 To: Julian Elischer References: <4509592A.3040602@digiware.nl> <20060914134611.GW76403@catpipe.net> <20060914150902.GA17230@pit.databus.com> <45097364.1090905@withagen.nl> <4509C4BC.3090000@elischer.org> In-Reply-To: <4509C4BC.3090000@elischer.org> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: Barney Wolff , freebsd-net@freebsd.org, Willem Jan Withagen Subject: Re: blocking a string in a packet using ipfw X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2006 11:52:05 -0000 Julian Elischer wrote: >> Forgot to mention: 4.7-PRERELEASE :( > > > ugh... no tables > and 45000 lines will be bad. > > load an old PC with 6.2 > and seet it up as a bridge with 2 interfaces. > and use ipfw table to filter on the bridge > If I could have easy access to the box, that would be the sollution. But the box is in Amsterdam in a Colo, and currently the rack is fully loaded. And we're not allowed to leave stuff standing outside the rack. For now the storm generated by the virus has calmed, because the DNS address used was one that was easily changed without penalties of sites getting unavialable. So setting that to 127.0.0.1 solved quite a lot. It still took a few hours to actually pickup every where. Over that time I collected over 50.000 IP's which all ended up in IPFW. :) The box (PIII, 750 Mhz, 512Mb) started using a lot of system and interrupt time, but it survived it all. Only to find out that it got whacked this morning again but now in some phpbb's, where they uploaded something like 45.000 viagra/spam messages. :( But fortunately this convinced the customer that he really should upgrade both hardware and software. Something I've been asking for as long as I've set eyes on this server. Probably the hours now spent in repairing etc. could have better be invested in a new server. --WjW From owner-freebsd-net@FreeBSD.ORG Fri Sep 15 12:44:48 2006 Return-Path: X-Original-To: freebsd-net@FreeBSD.ORG Delivered-To: freebsd-net@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 8E2BE16A403 for ; Fri, 15 Sep 2006 12:44:48 +0000 (UTC) (envelope-from olli@lurza.secnetix.de) Received: from lurza.secnetix.de (lurza.secnetix.de [83.120.8.8]) by mx1.FreeBSD.org (Postfix) with ESMTP id CCEBD43D66 for ; Fri, 15 Sep 2006 12:44:39 +0000 (GMT) (envelope-from olli@lurza.secnetix.de) Received: from lurza.secnetix.de (pahevu@localhost [127.0.0.1]) by lurza.secnetix.de (8.13.4/8.13.4) with ESMTP id k8FCiVkK016727 for ; Fri, 15 Sep 2006 14:44:37 +0200 (CEST) (envelope-from oliver.fromme@secnetix.de) Received: (from olli@localhost) by lurza.secnetix.de (8.13.4/8.13.1/Submit) id k8FCiVqV016726; Fri, 15 Sep 2006 14:44:31 +0200 (CEST) (envelope-from olli) Date: Fri, 15 Sep 2006 14:44:31 +0200 (CEST) Message-Id: <200609151244.k8FCiVqV016726@lurza.secnetix.de> From: Oliver Fromme To: freebsd-net@FreeBSD.ORG In-Reply-To: <450A9421.6010400@withagen.nl> X-Newsgroups: list.freebsd-net User-Agent: tin/1.8.0-20051224 ("Ronay") (UNIX) (FreeBSD/4.11-STABLE (i386)) X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-2.1.2 (lurza.secnetix.de [127.0.0.1]); Fri, 15 Sep 2006 14:44:37 +0200 (CEST) Cc: Subject: Re: blocking a string in a packet using ipfw X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: freebsd-net@FreeBSD.ORG List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2006 12:44:48 -0000 Willem Jan Withagen wrote: > Julian Elischer wrote: > > > Forgot to mention: 4.7-PRERELEASE :( > > > > ugh... no tables > > and 45000 lines will be bad. Not necessarily ... > Over that time I collected over 50.000 IP's which all ended up > in IPFW. :) The box (PIII, 750 Mhz, 512Mb) started using a lot > of system and interrupt time, but it survived it all. I once wrote a small tool that took a bunch of IP addresses on stdin and converted it into IPFW "skipto" rules forming a binary tree. So, in the worst case, only 32 rules had to be checked for each packet, instead of 50,000. Of course, with IPFW2's table feature, that tool of mine became obsolete. Best regards Oliver -- Oliver Fromme, secnetix GmbH & Co. KG, Marktplatz 29, 85567 Grafing Dienstleistungen mit Schwerpunkt FreeBSD: http://www.secnetix.de/bsd Any opinions expressed in this message may be personal to the author and may not necessarily reflect the opinions of secnetix in any way. "I have stopped reading Stephen King novels. Now I just read C code instead." -- Richard A. O'Keefe From owner-freebsd-net@FreeBSD.ORG Fri Sep 15 13:14:32 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2DE3F16A403 for ; Fri, 15 Sep 2006 13:14:32 +0000 (UTC) (envelope-from lab@gta.com) Received: from gta.com (gta-edge-199-20.gta.com [199.120.225.20]) by mx1.FreeBSD.org (Postfix) with SMTP id 688D443D45 for ; Fri, 15 Sep 2006 13:14:31 +0000 (GMT) (envelope-from lab@gta.com) Received: (qmail 63933 invoked by uid 1000); 15 Sep 2006 13:14:30 -0000 Date: Fri, 15 Sep 2006 09:14:30 -0400 From: Larry Baird To: Scott Ullrich Message-ID: <20060915091430.A45488@gta.com> References: <20060914093034.A83805@gta.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="wac7ysb48OaltWcw" Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: ; from sullrich@gmail.com on Thu, Sep 14, 2006 at 09:43:38PM -0400 Cc: freebsd-net@freebsd.org Subject: Re: FAST_IPSEC NAT-T support X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2006 13:14:32 -0000 --wac7ysb48OaltWcw Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Thu, Sep 14, 2006 at 09:43:38PM -0400, Scott Ullrich wrote: > On 9/14/06, Larry Baird wrote: > > Please find attached two patches for adding FAST_IPSEC NAT-T support to > > FreeBSD 6.x. The patch "freebsd6-fastipsec-natt.diff" is dependent > > upon Yvan's IPSEC NAT-T patch "freebsd6-natt.diff" which can be found at > > http://ipsec-tools.cvs.sourceforge.net/ipsec-tools/htdocs/. The second > > patch "freebsd6-ipsec-fastipsec-natt.diff" is a cumulative patch > > combining both patches together. > > This is great! It compiles on FreeBSD 6.1 when you include options > IPSEC_NAT_T but when you fail to include this item "options > IPSEC_NAT_T" in addition to including "options FAST_IPSEC" you end up > with: > > cc -c -O -pipe -Wall -Wredundant-decls -Wnested-externs > -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Winline > -Wcast-qual -fformat-extensions -std=c99 -g -nostdinc -I- -I. > -I/usr/src/sys -I/usr/src/sys/contrib/altq > -I/usr/src/sys/contrib/ipfilter -I/usr/src/sys/contrib/pf > -I/usr/src/sys/contrib/dev/ath -I/usr/src/sys/contrib/dev/ath/freebsd > -I/usr/src/sys/contrib/ngatm -I/usr/src/sys/dev/twa -D_KERNEL > -DHAVE_KERNEL_OPTION_HEADERS -include opt_global.h -fno-common > -finline-limit=8000 --param inline-unit-growth=100 --param > large-function-growth=1000 -mno-align-long-strings > -mpreferred-stack-boundary=2 -mno-mmx -mno-3dnow -mno-sse -mno-sse2 > -ffreestanding -Werror /usr/src/sys/netipsec/key.c > /usr/src/sys/netipsec/key.c: In function `key_spdadd': > /usr/src/sys/netipsec/key.c:1867: error: `isr' undeclared (first use > in this function) > /usr/src/sys/netipsec/key.c:1867: error: (Each undeclared identifier > is reported only once > /usr/src/sys/netipsec/key.c:1867: error: for each function it appears in.) > *** Error code 1 > > Stop in /usr/obj/usr/src/sys/pfSense.6. > *** Error code 1 > > Stop in /usr/src. > *** Error code 1 > > Stop in /usr/src. > > Meanwhile I have a new version of pfSense out asking for testing. We > seem to have a large base of users requesting this option so hopefully > I can get some meaningful testing information for you soon. It looks like the problem code is not needed. I was so busy focusing on getting NAT-T working with FAST_IPSEC I didn't notice this part of the non NAT_T case in the IPSEC NAT_T patch. Remove the section starting with "#ifndef IPSEC_NAT_T" at line 1866. Or run the attached patch. I'll update the full patch shortly. Larry -- ------------------------------------------------------------------------ Larry Baird | http://www.gta.com Global Technology Associates, Inc. | Orlando, FL Email: lab@gta.com | TEL 407-380-0220, FAX 407-380-6080 --wac7ysb48OaltWcw Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="nokey.diff" Index: key.c =================================================================== --- key.c (revision 8199) +++ key.c (working copy) @@ -1876,52 +1876,6 @@ return key_senderror(so, m, error); } -#ifndef IPSEC_NAT_T - for (isr = newsp->req; isr; isr = isr->next) { - struct sockaddr *sa; - - /* - * port spec is not permitted for tunnel mode - */ - if (isr->saidx.mode == IPSEC_MODE_TUNNEL && src0 && dst0) { - sa = (struct sockaddr *)(src0 + 1); - switch (sa->sa_family) { - case AF_INET: - if (((struct sockaddr_in *)sa)->sin_port) { - keydb_delsecpolicy(newsp); - return key_senderror(so, m, EINVAL); - } - break; - case AF_INET6: - if (((struct sockaddr_in6 *)sa)->sin6_port) { - keydb_delsecpolicy(newsp); - return key_senderror(so, m, EINVAL); - } - break; - default: - break; - } - sa = (struct sockaddr *)(dst0 + 1); - switch (sa->sa_family) { - case AF_INET: - if (((struct sockaddr_in *)sa)->sin_port) { - keydb_delsecpolicy(newsp); - return key_senderror(so, m, EINVAL); - } - break; - case AF_INET6: - if (((struct sockaddr_in6 *)sa)->sin6_port) { - keydb_delsecpolicy(newsp); - return key_senderror(so, m, EINVAL); - } - break; - default: - break; - } - } - } -#endif /* !IPSEC_NAT_T */ - if ((newsp->id = key_getnewspid()) == 0) { _key_delsp(newsp); return key_senderror(so, m, ENOBUFS); --wac7ysb48OaltWcw-- From owner-freebsd-net@FreeBSD.ORG Fri Sep 15 14:17:33 2006 Return-Path: X-Original-To: freebsd-net@FreeBSD.org Delivered-To: freebsd-net@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9092416A51E for ; Fri, 15 Sep 2006 14:17:33 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from cell.sick.ru (cell.sick.ru [217.72.144.68]) by mx1.FreeBSD.org (Postfix) with ESMTP id F25F543DA4 for ; Fri, 15 Sep 2006 14:17:12 +0000 (GMT) (envelope-from glebius@FreeBSD.org) Received: from cell.sick.ru (glebius@localhost [127.0.0.1]) by cell.sick.ru (8.13.4/8.13.3) with ESMTP id k8FEHADW080732 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 15 Sep 2006 18:17:11 +0400 (MSD) (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by cell.sick.ru (8.13.4/8.13.1/Submit) id k8FEHAK5080731; Fri, 15 Sep 2006 18:17:10 +0400 (MSD) (envelope-from glebius@FreeBSD.org) X-Authentication-Warning: cell.sick.ru: glebius set sender to glebius@FreeBSD.org using -f Date: Fri, 15 Sep 2006 18:17:10 +0400 From: Gleb Smirnoff To: Slawek Zak Message-ID: <20060915141710.GR27667@FreeBSD.org> Mail-Followup-To: Gleb Smirnoff , Slawek Zak , freebsd-net@freebsd.org References: <787bbe1c0609130609l33fb29dawc465b7bcfb2f430e@mail.gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=koi8-r Content-Disposition: inline In-Reply-To: <787bbe1c0609130609l33fb29dawc465b7bcfb2f430e@mail.gmail.com> User-Agent: Mutt/1.5.6i Cc: freebsd-net@FreeBSD.org Subject: Re: Rapid link state changes on bge(4) interface X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2006 14:17:33 -0000 On Wed, Sep 13, 2006 at 03:09:56PM +0200, Slawek Zak wrote: S> I'm testing network failover on IBM BladeCenter running FreeBSD 6.1 S> STABLE for Sep 6th. S> S> I suspect a problem with link state change detection in bge code. When S> I disable internal port on chassis built-in ethernet switch, kernel S> floods syslog with messages about link state changes and coalescing S> them. Log snippet follows: S> S> Sep 13 14:58:28 w3-6 kernel: bge1: link state changed to DOWN S> Sep 13 14:58:28 w3-6 kernel: bge1: link state changed to UP S> Sep 13 14:58:29 w3-6 kernel: bge1: link state changed to DOWN S> Sep 13 14:58:29 w3-6 kernel: bge1: link state changed to UP S> Sep 13 14:58:29 w3-6 kernel: bge1: link state changed to DOWN S> Sep 13 14:58:29 w3-6 kernel: bge1: 4 link states coalesced S> Sep 13 14:58:29 w3-6 kernel: bge1: link state changed to DOWN S> Sep 13 14:58:29 w3-6 kernel: bge1: 11 link states coalesced S> Sep 13 14:58:29 w3-6 kernel: bge1: link state changed to UP S> Sep 13 14:58:30 w3-6 kernel: bge1: link state changed to DOWN S> Sep 13 14:58:30 w3-6 kernel: bge1: 3 link states coalesced S> Sep 13 14:58:30 w3-6 kernel: bge1: link state changed to UP S> Sep 13 14:58:30 w3-6 kernel: bge1: 7 link states coalesced S> Sep 13 14:58:30 w3-6 kernel: bge1: link state changed to DOWN S> Sep 13 14:58:30 w3-6 kernel: bge1: 4 link states coalesced S> Sep 13 14:58:30 w3-6 kernel: bge1: link state changed to DOWN S> Sep 13 14:58:30 w3-6 kernel: bge1: 2 link states coalesced S> S> As you can see, messages are generated in rapid succession and S> therefore any probing of link state change by ng_one2many for S> interface failover is meaningless. Ethernet switch doesn't register S> and log any interface state changes after disabling this port. LS20 S> blades use chipset 8850. My firmware is 3.38, full changelog, if it is S> of any help, is here: S> S> http://www-307.ibm.com/pc/support/site.wss/license.do?filename=pc_servers/brcm_fw_nic_12021_anyos_anycpu.chg S> S> Any ideas what might be wrong? Please try to add hw.bge.fake_autoneg=1 to /boot/loader.conf. May be this will help. -- Totus tuus, Glebius. GLEBIUS-RIPN GLEB-RIPE From owner-freebsd-net@FreeBSD.ORG Fri Sep 15 14:23:46 2006 Return-Path: X-Original-To: freebsd-net@FreeBSD.org Delivered-To: freebsd-net@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1397416A407; Fri, 15 Sep 2006 14:23:46 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from cell.sick.ru (cell.sick.ru [217.72.144.68]) by mx1.FreeBSD.org (Postfix) with ESMTP id 589BE43D95; Fri, 15 Sep 2006 14:23:32 +0000 (GMT) (envelope-from glebius@FreeBSD.org) Received: from cell.sick.ru (glebius@localhost [127.0.0.1]) by cell.sick.ru (8.13.4/8.13.3) with ESMTP id k8FENUcC080782 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 15 Sep 2006 18:23:31 +0400 (MSD) (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by cell.sick.ru (8.13.4/8.13.1/Submit) id k8FENU8l080781; Fri, 15 Sep 2006 18:23:30 +0400 (MSD) (envelope-from glebius@FreeBSD.org) X-Authentication-Warning: cell.sick.ru: glebius set sender to glebius@FreeBSD.org using -f Date: Fri, 15 Sep 2006 18:23:30 +0400 From: Gleb Smirnoff To: Jack Vogel Message-ID: <20060915142330.GS27667@FreeBSD.org> Mail-Followup-To: Gleb Smirnoff , Jack Vogel , freebsd-net , Prafulla Deuskar References: <2a41acea0609111402g68741d86ib185e9bb77908658@mail.gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=koi8-r Content-Disposition: inline In-Reply-To: <2a41acea0609111402g68741d86ib185e9bb77908658@mail.gmail.com> User-Agent: Mutt/1.5.6i Cc: freebsd-net , Prafulla Deuskar Subject: Re: Stale PCI ID X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2006 14:23:46 -0000 On Mon, Sep 11, 2006 at 02:02:58PM -0700, Jack Vogel wrote: J> In the last attempt to merge community CVS with Intel internal code I J> came across an issue I'd like to bring up. J> J> There is an ancient e1000 card, pci id 1000, an 82542, that we J> don't have in our source, yet community cvs still does. Support J> for this was removed from Linux long ago because the card did J> not even work. J> J> I just had our test group hunt up one of these and test, and sure J> enough, the driver recognizes it, but it does NOT pass traffic. J> J> Clearly no one is using these, at least not with STABLE :) and J> as Intel does not want to support this I would recommend removing J> the ID from the driver. J> J> Comments? It should be removed then. When merging the Intel versions of driver to FreeBSD, I've noticed that some PCI IDs disappeared from vendor driver. Since I couldn't obtain any comments from the release tarball, I decided to be on safe side and leave these PCI IDs in the driver untouched. Which exact one are you speaking about? The E1000_DEV_ID_82542, that is equal to 0x1000 is supported by em-6.1.4 vendor's driver. -- Totus tuus, Glebius. GLEBIUS-RIPN GLEB-RIPE From owner-freebsd-net@FreeBSD.ORG Fri Sep 15 14:51:22 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5FE6516A403; Fri, 15 Sep 2006 14:51:22 +0000 (UTC) (envelope-from marcelo@registro.br) Received: from clone.registro.br (clone.registro.br [200.160.2.4]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0357143D45; Fri, 15 Sep 2006 14:51:21 +0000 (GMT) (envelope-from marcelo@registro.br) Received: by clone.registro.br (Postfix, from userid 1014) id A45B52A580; Fri, 15 Sep 2006 11:51:20 -0300 (BRT) Date: Fri, 15 Sep 2006 11:51:20 -0300 From: Marcelo Gardini do Amaral To: "Andrey V. Elsukov" Message-ID: <20060915145120.GA93074@registro.br> References: <2a41acea0608301145j7bbed961j33ce903a27d8963d@mail.gmail.com> <20060904130827.GE12975@registro.br> <20060911195521.GD63300@registro.br> <20060913182019.R50147@fledge.watson.org> <20060913182457.W50147@fledge.watson.org> <20060914175049.GH49126@registro.br> <450A2A6E.3040408@yandex.ru> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <450A2A6E.3040408@yandex.ru> User-Agent: Mutt/1.4.2.1i Cc: freebsd-net@freebsd.org, Robert Watson , freebsd-stable@freebsd.org Subject: Re: DNS query performance X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2006 14:51:22 -0000 > You have tested with a GENERIC kernel? You should remove all > debugging kernel options before testing performance. Sure. Removing debug I got: Kernel UP Timecounter queries/s ----------- --------- TSC 16541 There is no difference. -- Att., Marcelo Gardini From owner-freebsd-net@FreeBSD.ORG Fri Sep 15 15:21:14 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id EE5EF16A40F for ; Fri, 15 Sep 2006 15:21:14 +0000 (UTC) (envelope-from prvs=julian=4062b6196@elischer.org) Received: from a50.ironport.com (a50.ironport.com [63.251.108.112]) by mx1.FreeBSD.org (Postfix) with ESMTP id 3D7D743D46 for ; Fri, 15 Sep 2006 15:21:14 +0000 (GMT) (envelope-from prvs=julian=4062b6196@elischer.org) Received: from unknown (HELO [192.168.2.6]) ([10.251.60.41]) by a50.ironport.com with ESMTP; 15 Sep 2006 08:21:13 -0700 Message-ID: <450AC4E9.7050302@elischer.org> Date: Fri, 15 Sep 2006 08:21:13 -0700 From: Julian Elischer User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.13) Gecko/20060414 X-Accept-Language: en-us, en MIME-Version: 1.0 To: freebsd-net@freebsd.org References: <200609151244.k8FCiVqV016726@lurza.secnetix.de> In-Reply-To: <200609151244.k8FCiVqV016726@lurza.secnetix.de> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: blocking a string in a packet using ipfw X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2006 15:21:15 -0000 Oliver Fromme wrote: >Willem Jan Withagen wrote: > > Julian Elischer wrote: > > > > Forgot to mention: 4.7-PRERELEASE :( > > > > > > ugh... no tables > > > and 45000 lines will be bad. > >Not necessarily ... > > > Over that time I collected over 50.000 IP's which all ended up > > in IPFW. :) The box (PIII, 750 Mhz, 512Mb) started using a lot > > of system and interrupt time, but it survived it all. > >I once wrote a small tool that took a bunch of IP addresses >on stdin and converted it into IPFW "skipto" rules forming >a binary tree. So, in the worst case, only 32 rules had to >be checked for each packet, instead of 50,000. > > > yes I've done that too but tables are such an improvement. I back ported tabled from 4.10 to 4.8 for ironport last year and it wasn't any problem.. just copied back the relevant files and compiled with ipfw2. it would probably work for 4.7 too. >Of course, with IPFW2's table feature, that tool of mine >became obsolete. > >Best regards > Oliver > > > From owner-freebsd-net@FreeBSD.ORG Fri Sep 15 16:08:01 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2947916A403 for ; Fri, 15 Sep 2006 16:08:01 +0000 (UTC) (envelope-from sullrich@gmail.com) Received: from ug-out-1314.google.com (ug-out-1314.google.com [66.249.92.175]) by mx1.FreeBSD.org (Postfix) with ESMTP id 3892343D45 for ; Fri, 15 Sep 2006 16:08:00 +0000 (GMT) (envelope-from sullrich@gmail.com) Received: by ug-out-1314.google.com with SMTP id m2so198949uge for ; Fri, 15 Sep 2006 09:07:59 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=pqdzMWL9lHxK09ZKVYaEqGuoT4X8YqeavRtwy2ODDGGJhQO5IGSOBYn/qQLC5UZC1EOW7Tojqyn1s42kkMtyLkJ5QJyWTs8DvT55w8F8zlwW6bJcZKQDwczs27kI0ICepuJwuY9fNuJ9QoH1z20mDyln75sJUh40L7JUsTpkc7w= Received: by 10.67.119.5 with SMTP id w5mr5468571ugm; Fri, 15 Sep 2006 09:07:58 -0700 (PDT) Received: by 10.67.105.8 with HTTP; Fri, 15 Sep 2006 09:07:58 -0700 (PDT) Message-ID: Date: Fri, 15 Sep 2006 12:07:58 -0400 From: "Scott Ullrich" To: "Larry Baird" In-Reply-To: <20060915091430.A45488@gta.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <20060914093034.A83805@gta.com> <20060915091430.A45488@gta.com> Cc: freebsd-net@freebsd.org Subject: Re: FAST_IPSEC NAT-T support X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2006 16:08:01 -0000 On 9/15/06, Larry Baird wrote: > On Thu, Sep 14, 2006 at 09:43:38PM -0400, Scott Ullrich wrote: > > On 9/14/06, Larry Baird wrote: > > > Please find attached two patches for adding FAST_IPSEC NAT-T support to > > > FreeBSD 6.x. The patch "freebsd6-fastipsec-natt.diff" is dependent > > > upon Yvan's IPSEC NAT-T patch "freebsd6-natt.diff" which can be found at > > > http://ipsec-tools.cvs.sourceforge.net/ipsec-tools/htdocs/. The second > > > patch "freebsd6-ipsec-fastipsec-natt.diff" is a cumulative patch > > > combining both patches together. Great, thanks! Next problem that I have encountered (with FAST_IPSEC) is: # /sbin/setkey -D Invalid extension type Invalid extension type Invalid extension type Invalid extension type Invalid extension type Invalid extension type Invalid extension type Invalid extension type Invalid extension type Invalid extension type Invalid extension type Invalid extension type Invalid extension type Invalid extension type Let me know if I can do any further testing, still waiting for status reports from a few of the pfSense users, but IPSEC seems to work okay even with this small cosmetic setkey issue. Scott From owner-freebsd-net@FreeBSD.ORG Fri Sep 15 17:49:01 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7B88916A47B for ; Fri, 15 Sep 2006 17:49:01 +0000 (UTC) (envelope-from jon.otterholm@ide.resurscentrum.se) Received: from mail1.cil.se (mail1.cil.se [217.197.56.125]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7209443D58 for ; Fri, 15 Sep 2006 17:48:59 +0000 (GMT) (envelope-from jon.otterholm@ide.resurscentrum.se) Received: from [192.168.2.10] ([192.168.2.10]) by mail1.cil.se with Microsoft SMTPSVC(6.0.3790.0); Fri, 15 Sep 2006 19:48:57 +0200 Message-ID: <450AE789.5020402@ide.resurscentrum.se> Date: Fri, 15 Sep 2006 19:48:57 +0200 From: Jon Otterholm User-Agent: Thunderbird 1.5 (X11/20060204) MIME-Version: 1.0 To: Andrew Thompson , freebsd-net@freebsd.org References: <45084BBD.7090903@ide.resurscentrum.se> <20060914042010.GA35371@heff.fud.org.nz> <4509131D.8090900@ide.resurscentrum.se> <20060914083612.GD35371@heff.fud.org.nz> <450965CB.6050904@ide.resurscentrum.se> <20060914192045.GA37784@heff.fud.org.nz> In-Reply-To: <20060914192045.GA37784@heff.fud.org.nz> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-OriginalArrivalTime: 15 Sep 2006 17:48:57.0554 (UTC) FILETIME=[38091320:01C6D8EF] Cc: Subject: Re: Bridge X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2006 17:49:01 -0000 Andrew Thompson wrote: > On Thu, Sep 14, 2006 at 04:23:07PM +0200, Jon Otterholm wrote: > >> Andrew Thompson wrote: >> >>> On Thu, Sep 14, 2006 at 10:30:21AM +0200, Jon Otterholm wrote: >>> >>> >>>> Andrew Thompson wrote: >>>> >>>> >>>>> On Wed, Sep 13, 2006 at 08:19:41PM +0200, Jon Otterholm wrote: >>>>> >From man if_bridge: >>>>> >>>>> >>>>>> ARP and REVARP packets are forwarded without being filtered and >>>>>> others >>>>>> that are not IP nor IPv6 packets are not forwarded when pfil_onlyip >>>>>> is >>>>>> enabled. IPFW can filter Ethernet types using mac-type so all >>>>>> packets >>>>>> are passed to the filter for processing. >>>>>> >>>>>> ARP is still forwarded though I have the following config: >>>>>> >>>>>> >>>>> The check for ARP happens before the ipfw layer2 code so it isnt >>>>> currently possible to filter them. >>>>> >>>>> >>>>> >>>> What impact would it have to others using bridge? Could it be made in >>>> combination with a sysctl that must be enabled? I can onley speak for me >>>> an my needs - I would like this to be committed. >>>> >>>> >>>> >>> You can try the patch I sent in a later email, it should work fine. >>> >>> >>> Andrew >>> >>> >> Do I have to go to -current for version 1.79 of if_bridge.c? >> > > No, the patch will apply fine to RELENG_6 too. > > > Andrew > It works fine. Thanks for all the help (let me know if you are in town (Ljungby-Sweden) and I will buy you lunch :-)). I hope to put this in production soon - will this patch work on future releases? How about committing this? /Jon From owner-freebsd-net@FreeBSD.ORG Fri Sep 15 20:52:48 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 01BCA16A407 for ; Fri, 15 Sep 2006 20:52:48 +0000 (UTC) (envelope-from lab@gta.com) Received: from gta.com (gta-edge-199-20.gta.com [199.120.225.20]) by mx1.FreeBSD.org (Postfix) with SMTP id 6851943D55 for ; Fri, 15 Sep 2006 20:52:47 +0000 (GMT) (envelope-from lab@gta.com) Received: (qmail 95154 invoked by uid 1000); 15 Sep 2006 20:52:46 -0000 Date: Fri, 15 Sep 2006 16:52:46 -0400 From: Larry Baird To: Scott Ullrich Message-ID: <20060915165246.A92818@gta.com> References: <20060914093034.A83805@gta.com> <20060915091430.A45488@gta.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: ; from sullrich@gmail.com on Fri, Sep 15, 2006 at 12:07:58PM -0400 Cc: freebsd-net@freebsd.org Subject: Re: FAST_IPSEC NAT-T support X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2006 20:52:48 -0000 On Fri, Sep 15, 2006 at 12:07:58PM -0400, Scott Ullrich wrote: > On 9/15/06, Larry Baird wrote: > > On Thu, Sep 14, 2006 at 09:43:38PM -0400, Scott Ullrich wrote: > > > On 9/14/06, Larry Baird wrote: > > > > Please find attached two patches for adding FAST_IPSEC NAT-T support to > > > > FreeBSD 6.x. The patch "freebsd6-fastipsec-natt.diff" is dependent > > > > upon Yvan's IPSEC NAT-T patch "freebsd6-natt.diff" which can be found at > > > > http://ipsec-tools.cvs.sourceforge.net/ipsec-tools/htdocs/. The second > > > > patch "freebsd6-ipsec-fastipsec-natt.diff" is a cumulative patch > > > > combining both patches together. > > Great, thanks! > > Next problem that I have encountered (with FAST_IPSEC) is: > > # /sbin/setkey -D > Invalid extension type > Invalid extension type > Invalid extension type > Invalid extension type > Invalid extension type > Invalid extension type > Invalid extension type > Invalid extension type > Invalid extension type > Invalid extension type > Invalid extension type > Invalid extension type > Invalid extension type > Invalid extension type > > Let me know if I can do any further testing, still waiting for status > reports from a few of the pfSense users, but IPSEC seems to work okay > even with this small cosmetic setkey issue. Just to be sure I understand the issue. You have a kernel built with the FAST_IPSEC NAT-T patches but without the IPSEC_NAT_T option. Your VPNs work but you are unable to dump your SAD entries. Larry -- ------------------------------------------------------------------------ Larry Baird | http://www.gta.com Global Technology Associates, Inc. | Orlando, FL Email: lab@gta.com | TEL 407-380-0220, FAX 407-380-6080 From owner-freebsd-net@FreeBSD.ORG Fri Sep 15 20:55:09 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3C39116A40F for ; Fri, 15 Sep 2006 20:55:09 +0000 (UTC) (envelope-from sullrich@gmail.com) Received: from ug-out-1314.google.com (ug-out-1314.google.com [66.249.92.174]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7C67543D55 for ; Fri, 15 Sep 2006 20:55:03 +0000 (GMT) (envelope-from sullrich@gmail.com) Received: by ug-out-1314.google.com with SMTP id m2so220480uge for ; Fri, 15 Sep 2006 13:55:02 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=tNS09p+hS3oZCj/X4IxxnTZ6o/s/UllA3GXRkYBmWnsRVCCnFyfzDgeq/MW5/JpPbOyGWWHUZ/ZWPDoEHRct4uLCISr+SJhagdPy5rEL8ake91ozGiMcZiks6pHrLNdsmhqTGyi+7mV0uaNGhyld2wtpYwjtsAFEoJhR5DUB9MI= Received: by 10.67.105.19 with SMTP id h19mr5626165ugm; Fri, 15 Sep 2006 13:55:01 -0700 (PDT) Received: by 10.67.105.8 with HTTP; Fri, 15 Sep 2006 13:55:01 -0700 (PDT) Message-ID: Date: Fri, 15 Sep 2006 16:55:01 -0400 From: "Scott Ullrich" To: "Larry Baird" In-Reply-To: <20060915165246.A92818@gta.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <20060914093034.A83805@gta.com> <20060915091430.A45488@gta.com> <20060915165246.A92818@gta.com> Cc: freebsd-net@freebsd.org Subject: Re: FAST_IPSEC NAT-T support X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Sep 2006 20:55:09 -0000 On 9/15/06, Larry Baird wrote: > Just to be sure I understand the issue. You have a kernel built > with the FAST_IPSEC NAT-T patches but without the IPSEC_NAT_T option. > Your VPNs work but you are unable to dump your SAD entries. No, I have it built with options IPSEC_NAT_T and FAST_IPSEC. builder# cat pfSense.6 | grep IPSEC options FAST_IPSEC options IPSEC_NAT_T IPSEC works correctly but setkey shows the error. # setkey -D Invalid extension type Invalid extension type Invalid extension type Invalid extension type Invalid extension type Invalid extension type Invalid extension type Invalid extension type Invalid extension type # Scott From owner-freebsd-net@FreeBSD.ORG Sat Sep 16 00:45:15 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B934D16A403 for ; Sat, 16 Sep 2006 00:45:15 +0000 (UTC) (envelope-from h.nieser@xs4all.nl) Received: from smtp-vbr4.xs4all.nl (smtp-vbr4.xs4all.nl [194.109.24.24]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2B36B43D5A for ; Sat, 16 Sep 2006 00:45:14 +0000 (GMT) (envelope-from h.nieser@xs4all.nl) Received: from [192.168.1.64] (aphax.nl [82.92.29.227]) by smtp-vbr4.xs4all.nl (8.13.6/8.13.6) with ESMTP id k8G0ixOA058395 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 16 Sep 2006 02:45:00 +0200 (CEST) (envelope-from h.nieser@xs4all.nl) Message-ID: <450B48C2.7030501@xs4all.nl> Date: Sat, 16 Sep 2006 02:43:46 +0200 From: Hans Nieser User-Agent: Thunderbird 1.5.0.5 (X11/20060910) MIME-Version: 1.0 To: Sam Leffler References: <44F4CF17.8060203@xs4all.nl> <44F70983.40705@errno.com> <44F71402.1060405@xs4all.nl> <44F7558A.4030907@errno.com> In-Reply-To: <44F7558A.4030907@errno.com> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Virus-Scanned: by XS4ALL Virus Scanner Cc: freebsd-net@freebsd.org Subject: Re: iwi discarding oversized packets while mtu=1500 for src/dst X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Sep 2006 00:45:15 -0000 Sam Leffler wrote: > Hans Nieser wrote: > >> root@aphax-laptop:~# uname -a >> FreeBSD aphax-laptop.lan 6.1-RELEASE FreeBSD 6.1-RELEASE #0: Thu May 11 >> 07:17:09 CEST 2006 >> root@aphax-laptop.nieser.local:/usr/obj/usr/src/sys/APHAX-LAPTOP i386 > > Are you running the iwi driver that came with 6.1-release? If so it has > numerous problems that have been fixed in 6-STABLE and HEAD. I'm not > sure how best to update your system except by going to 6-STABLE via a > src upgrade. Today I have upgraded my laptop to 6-STABLE, but unfortunately the problems remain. I don't even know wether iwi is to blame, because I can't figure out wether perhaps xl on my server really is sending out too large packets. That is, so far I've been assuming that an mtu of 1500 may not mean that there's exactly 1500 bytes going over the wire (overhead of protocols to which the mtu doesn't apply or something, I dunno, I'm no networking expert obviously :), because xl is definitely sending out packets of 1518 bytes. Which iwi on my laptop doesn't like, but the NIC in my desktop machine (which runs Linux) has no problem with. Maybe someone can tell me which of the machines is in error here, at least I'd know what to blame :( The fact that my Linux box doesn't discard these packages coming from my server made me suspicious of iwi initially, but maybe iwi is doing nothing wrong and my Linux box is simply willing to accept these oversized packets. From owner-freebsd-net@FreeBSD.ORG Sat Sep 16 02:40:47 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A0C1416A4EC for ; Sat, 16 Sep 2006 02:40:47 +0000 (UTC) (envelope-from jfvogel@gmail.com) Received: from py-out-1112.google.com (py-out-1112.google.com [64.233.166.179]) by mx1.FreeBSD.org (Postfix) with ESMTP id 925DB43DB6 for ; Sat, 16 Sep 2006 02:01:26 +0000 (GMT) (envelope-from jfvogel@gmail.com) Received: by py-out-1112.google.com with SMTP id o67so3999440pye for ; Fri, 15 Sep 2006 19:01:25 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=iPUs6PKd2tP6a1J/ZmqN6pj7aIMm5ezKsmYsadHonbLT6GbsR1jJ9OCXooRgqId4DRFpcQV3DQFDwpb91RyIRjQsQgUbaZgjlaxjZ9THU+lJGa1t7Kudtdhxmc6wRbjp/2WKDMTLNp7bxeA9sS6tWflYYWh8q1zQkdEcib04UpA= Received: by 10.35.33.15 with SMTP id l15mr18505189pyj; Fri, 15 Sep 2006 19:01:25 -0700 (PDT) Received: by 10.35.119.1 with HTTP; Fri, 15 Sep 2006 19:01:25 -0700 (PDT) Message-ID: <2a41acea0609151901v5f24643dv4cf550a5108e1052@mail.gmail.com> Date: Fri, 15 Sep 2006 19:01:25 -0700 From: "Jack Vogel" To: "Gleb Smirnoff" , "Jack Vogel" , freebsd-net , "Prafulla Deuskar" In-Reply-To: <20060915142330.GS27667@FreeBSD.org> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <2a41acea0609111402g68741d86ib185e9bb77908658@mail.gmail.com> <20060915142330.GS27667@FreeBSD.org> Cc: Subject: Re: Stale PCI ID X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Sep 2006 02:40:47 -0000 On 9/15/06, Gleb Smirnoff wrote: > On Mon, Sep 11, 2006 at 02:02:58PM -0700, Jack Vogel wrote: > J> In the last attempt to merge community CVS with Intel internal code I > J> came across an issue I'd like to bring up. > J> > J> There is an ancient e1000 card, pci id 1000, an 82542, that we > J> don't have in our source, yet community cvs still does. Support > J> for this was removed from Linux long ago because the card did > J> not even work. > J> > J> I just had our test group hunt up one of these and test, and sure > J> enough, the driver recognizes it, but it does NOT pass traffic. > J> > J> Clearly no one is using these, at least not with STABLE :) and > J> as Intel does not want to support this I would recommend removing > J> the ID from the driver. > J> > J> Comments? > > It should be removed then. When merging the Intel versions of driver to > FreeBSD, I've noticed that some PCI IDs disappeared from vendor driver. > Since I couldn't obtain any comments from the release tarball, I decided > to be on safe side and leave these PCI IDs in the driver untouched. > > Which exact one are you speaking about? The E1000_DEV_ID_82542, that is > equal to 0x1000 is supported by em-6.1.4 vendor's driver. I AM the vendor :) And I believe that the 0x1000 ID crept into my code from merging with your tree :) Our test group came back to me and said 'hey, this is old and we don't think these boards even work' , so I told them to test, they did, and sure enough, it wouldnt even pass traffic. There is actually 3 different rev boards, and rumor has it that the last revision would work, but I think its better to just drop the thing. Cheers, Jack From owner-freebsd-net@FreeBSD.ORG Sat Sep 16 03:32:44 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D346416A407 for ; Sat, 16 Sep 2006 03:32:44 +0000 (UTC) (envelope-from silby@silby.com) Received: from relay01.pair.com (relay01.pair.com [209.68.5.15]) by mx1.FreeBSD.org (Postfix) with SMTP id D615643D4C for ; Sat, 16 Sep 2006 03:32:43 +0000 (GMT) (envelope-from silby@silby.com) Received: (qmail 21419 invoked from network); 16 Sep 2006 03:32:42 -0000 Received: from unknown (HELO localhost) (unknown) by unknown with SMTP; 16 Sep 2006 03:32:42 -0000 X-pair-Authenticated: 209.68.2.70 Date: Fri, 15 Sep 2006 22:33:16 -0500 (CDT) From: Mike Silbersack To: Marcelo Gardini do Amaral In-Reply-To: <20060915145120.GA93074@registro.br> Message-ID: <20060915223211.R65248@odysseus.silby.com> References: <2a41acea0608301145j7bbed961j33ce903a27d8963d@mail.gmail.com> <20060904130827.GE12975@registro.br> <20060911195521.GD63300@registro.br> <20060913182019.R50147@fledge.watson.org> <20060913182457.W50147@fledge.watson.org> <20060914175049.GH49126@registro.br> <450A2A6E.3040408@yandex.ru> <20060915145120.GA93074@registro.br> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: freebsd-net@freebsd.org, "Andrey V. Elsukov" , Robert Watson , freebsd-stable@freebsd.org Subject: Re: DNS query performance X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Sep 2006 03:32:44 -0000 Although it sounds silly, could you try recompiling 6.1 and 7.0 with a non-SMP kernel and see how they perform? That would at least tell us if it's a general performance problem in 6.x and 7.x, or if SMP is somehow hurting performance in this case. Mike "Silby" Silbersack From owner-freebsd-net@FreeBSD.ORG Sat Sep 16 06:05:02 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id BAA0F16A407 for ; Sat, 16 Sep 2006 06:05:02 +0000 (UTC) (envelope-from freebsd-net@goldenpath.org) Received: from mail.sbsnet.com (mail.sbsnet.com [63.147.233.20]) by mx1.FreeBSD.org (Postfix) with ESMTP id 343E143D49 for ; Sat, 16 Sep 2006 06:05:02 +0000 (GMT) (envelope-from freebsd-net@goldenpath.org) Received: from [192.168.254.199] [24.199.124.162] by mail.sbsnet.com with ESMTP (SMTPD-8.22) id A3A80564; Sat, 16 Sep 2006 02:03:20 -0400 Message-ID: <450B93F6.4090409@goldenpath.org> Date: Sat, 16 Sep 2006 02:04:38 -0400 From: Tim Allender User-Agent: Thunderbird 1.5.0.7 (Windows/20060909) MIME-Version: 1.0 To: freebsd-net@freebsd.org Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: NIC Problems X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Sep 2006 06:05:02 -0000 Not sure if I should post this here or straight to the pfSensse list. I suspect this kind of thing is a faulty NIC but since I've not seen it before I'm not sure: vr0: receive error (81): rx buffer error vr0: revieve error (0024) no buffers vr0: receive error (81): rx buffer error vr0: revieve error (0024) no buffers vr0: receive error (81): rx buffer error vr0: revieve error (0024) no buffers vr0: receive error (81): rx buffer error vr0: revieve error (0024) no buffers From owner-freebsd-net@FreeBSD.ORG Sat Sep 16 16:06:18 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2C71116A51F for ; Sat, 16 Sep 2006 16:06:18 +0000 (UTC) (envelope-from sam@errno.com) Received: from ebb.errno.com (ebb.errno.com [69.12.149.25]) by mx1.FreeBSD.org (Postfix) with ESMTP id D4C8343D64 for ; Sat, 16 Sep 2006 16:06:16 +0000 (GMT) (envelope-from sam@errno.com) Received: from [10.0.0.199] ([10.0.0.199]) (authenticated bits=0) by ebb.errno.com (8.13.6/8.12.6) with ESMTP id k8GG6Gc0090727 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 16 Sep 2006 09:06:16 -0700 (PDT) (envelope-from sam@errno.com) Message-ID: <450C20F3.2000005@errno.com> Date: Sat, 16 Sep 2006 09:06:11 -0700 From: Sam Leffler Organization: Errno Consulting User-Agent: Thunderbird 1.5.0.7 (Macintosh/20060909) MIME-Version: 1.0 To: Phil Chadwick References: <200609131308.k8DD8Vrq001266@kt400.internode.on.net> In-Reply-To: <200609131308.k8DD8Vrq001266@kt400.internode.on.net> X-Enigmail-Version: 0.94.0.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Cc: freebsd-net@freebsd.org Subject: Re: FreeBSD 6.1 + ath0 + NAT X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Sep 2006 16:06:18 -0000 Phil Chadwick wrote: > Hi all, > > This is my first post, so please be gentle :-) > > I have a Linksys WAG54G V.2 ADSL modem (Firmware Version: 1.00.39) > connection to the Internet, and a Netgear WG311T wireless Ethernet card > running on FreeBSD 6.1 (PC#1). > > Recently I added a second FreeBSD 6.1 system (PC#2) which has no > wireless card (well it does, but it's a TI chipset not supported in > FreeBSD). So I connected it to PC#1 with a Gigabit copper wire > connection. I also added firewall and NATing on PC#1 to provide PC#2 > with a route to the Internet. > > When I boot PC#1, the connection between ath0 and the ADSL modem will run > as expected (routing to the Internet for itself and PC#2) for some time > (roughly anywhere from 0 to 30 minutes), but always eventually hangs. > It's then not possible to ping the ADSL modem. Do you really mean you ping the modem or a host on the far side of the modem? > > The hang happens regardless of whether the new (PC#2) system is booted > or not. Then ignore PC#2 and remove it from the system. > > The PC#1 ath0 wireless connection has been woking flawlessly (without > the firewall and NAT changs) for nearly a year (originally under FreeBSD > 6.0 with Sam Lefflers ath patches) and more recently on FreeBSD 6.1. > > Can anybody spot anything obviously wrong with the new setup, or know of > any bug reports that might impact a NATing gateway on a wireless connection? > > I have also recently discovered the link goes up and down every 20 or 30 > minutes with what looks like a DHCP lease renewal. This extracted from > /var/log/messages: > > Sep 13 19:42:21 kt400 kernel: ath0: link state changed to DOWN > Sep 13 19:42:23 kt400 kernel: ath0: link state changed to UP > Sep 13 19:42:23 kt400 dhclient: New IP Address (ath0): 192.168.1.64 > Sep 13 19:42:23 kt400 dhclient: New Subnet Mask (ath0): 255.255.255.0 > Sep 13 19:42:23 kt400 dhclient: New Broadcast Address (ath0): 192.168.1.255 > Sep 13 19:42:23 kt400 dhclient: New Routers (ath0): 192.168.1.1 > Sep 13 20:12:21 kt400 kernel: ath0: link state changed to DOWN > Sep 13 20:12:23 kt400 kernel: ath0: link state changed to UP > Sep 13 20:12:23 kt400 dhclient: New IP Address (ath0): 192.168.1.64 > Sep 13 20:12:23 kt400 dhclient: New Subnet Mask (ath0): 255.255.255.0 > Sep 13 20:12:23 kt400 dhclient: New Broadcast Address (ath0): 192.168.1.255 > Sep 13 20:12:23 kt400 dhclient: New Routers (ath0): 192.168.1.1 > Sep 13 21:32:21 kt400 kernel: ath0: link state changed to DOWN > Sep 13 21:32:24 kt400 kernel: ath0: link state changed to UP > > Looks like a smoking gun? Is this likely to upset the firewall/NATing? Unlikely. > > [I have not yet had a chance to correlate the hang with the lease renewal, > but will test that tomorrow.] > > In the kernel config file I have added: > > options IPFIREWALL > options IPDIVERT > > In /etc/rc.conf I have: > > # See also /etc/wpa_supplicant.conf > ifconfig_ath0="WPA DHCP" > # Private x-over to printer > ifconfig_rl0="inet kt400pr netmask 255.255.255.0 broadcast 10.0.0.255" > # Private x-over to Dell 350 (PC#2) > ifconfig_sk0="inet gbkt400 netmask 255.255.255.0 broadcast 192.168.2.255" > # These added for firewall/NATing > gateway_enable="YES" > firewall_enable="YES" > firewall_type="OPEN" > natd_enable="YES" > natd_interface="ath0" > natd_flags="" > > [kt400.145] cat /etc/wpa_supplicant.conf > network={ > ssid="linksys" > key_mgmt=NONE > wep_key0=xxxxxxxxxx > wep_tx_keyidx=0 > } > > [kt400.146] ifconfig -a > sk0: flags=8843 mtu 1500 > options=8 > inet6 fe80::215:e9ff:feb0:e5b0%sk0 prefixlen 64 scopeid 0x1 > inet 192.168.2.1 netmask 0xffffff00 broadcast 192.168.2.255 > ether 00:15:e9:b0:e5:b0 > media: Ethernet autoselect (none) > status: no carrier > > ath0: flags=8843 mtu 1500 > inet6 fe80::20f:b5ff:fef6:28eb%ath0 prefixlen 64 scopeid 0x2 > inet 192.168.1.64 netmask 0xffffff00 broadcast 192.168.1.255 > ether 00:0f:b5:f6:28:eb > media: IEEE 802.11 Wireless Ethernet autoselect (DS/11Mbps) > status: associated > ssid linksys channel 11 bssid 00:14:bf:7a:57:94 > authmode OPEN privacy ON deftxkey 1 wepkey 1:40-bit txpowmax 37 > protmode CTS burst roaming MANUAL bintval 100 > > rl0: flags=8843 mtu 1500 > options=8 > inet6 fe80::220:edff:fe70:471a%rl0 prefixlen 64 scopeid 0x3 > inet 10.0.0.254 netmask 0xffffff00 broadcast 10.0.0.255 > ether 00:20:ed:70:47:1a > media: Ethernet autoselect (none) > status: no carrier > > fwe0: flags=108802 mtu 1500 > options=8 > ether 02:00:20:71:b9:a6 > ch 1 dma -1 > lo0: flags=8049 mtu 16384 > inet6 ::1 prefixlen 128 > inet6 fe80::1%lo0 prefixlen 64 scopeid 0x5 > inet 127.0.0.1 netmask 0xff000000 > > > Thanks, > > I am confused about what the config is and what exactly is wrong. Try simplifying your configuration so you can pinpoint the problem. It sounds like you've got a sta associated to an ap using ath. That sta cannot pass packets beyond the ap after some period of time. Have you look on the ap to see if packets are still flowing? Have you used tcpdump to look for packets on the far side of the ap (on the wired network)? Sam From owner-freebsd-net@FreeBSD.ORG Sat Sep 16 16:09:30 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4C71916A403 for ; Sat, 16 Sep 2006 16:09:30 +0000 (UTC) (envelope-from sam@errno.com) Received: from ebb.errno.com (ebb.errno.com [69.12.149.25]) by mx1.FreeBSD.org (Postfix) with ESMTP id AECF243D49 for ; Sat, 16 Sep 2006 16:09:29 +0000 (GMT) (envelope-from sam@errno.com) Received: from [10.0.0.199] ([10.0.0.199]) (authenticated bits=0) by ebb.errno.com (8.13.6/8.12.6) with ESMTP id k8GG9Sko090756 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 16 Sep 2006 09:09:29 -0700 (PDT) (envelope-from sam@errno.com) Message-ID: <450C21B4.5030703@errno.com> Date: Sat, 16 Sep 2006 09:09:24 -0700 From: Sam Leffler Organization: Errno Consulting User-Agent: Thunderbird 1.5.0.7 (Macintosh/20060909) MIME-Version: 1.0 To: Hans Nieser References: <44F4CF17.8060203@xs4all.nl> <44F70983.40705@errno.com> <44F71402.1060405@xs4all.nl> <44F7558A.4030907@errno.com> <450B48C2.7030501@xs4all.nl> In-Reply-To: <450B48C2.7030501@xs4all.nl> X-Enigmail-Version: 0.94.0.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Cc: freebsd-net@freebsd.org Subject: Re: iwi discarding oversized packets while mtu=1500 for src/dst X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Sep 2006 16:09:30 -0000 Hans Nieser wrote: > Sam Leffler wrote: >> Hans Nieser wrote: >> >>> root@aphax-laptop:~# uname -a >>> FreeBSD aphax-laptop.lan 6.1-RELEASE FreeBSD 6.1-RELEASE #0: Thu May 11 >>> 07:17:09 CEST 2006 >>> root@aphax-laptop.nieser.local:/usr/obj/usr/src/sys/APHAX-LAPTOP i386 >> Are you running the iwi driver that came with 6.1-release? If so it has >> numerous problems that have been fixed in 6-STABLE and HEAD. I'm not >> sure how best to update your system except by going to 6-STABLE via a >> src upgrade. > > Today I have upgraded my laptop to 6-STABLE, but unfortunately the > problems remain. I don't even know wether iwi is to blame, because I can't > figure out wether perhaps xl on my server really is sending out too large > packets. > > That is, so far I've been assuming that an mtu of 1500 may not mean that > there's exactly 1500 bytes going over the wire (overhead of protocols to > which the mtu doesn't apply or something, I dunno, I'm no networking > expert obviously :), because xl is definitely sending out packets of 1518 > bytes. Which iwi on my laptop doesn't like, but the NIC in my desktop > machine (which runs Linux) has no problem with. Maybe someone can tell me > which of the machines is in error here, at least I'd know what to blame :( > > The fact that my Linux box doesn't discard these packages coming from my > server made me suspicious of iwi initially, but maybe iwi is doing nothing > wrong and my Linux box is simply willing to accept these oversized packets. > I can't speak to linux but an mtu of 1500 will cause a 1518 byte packet to be discarded. I don't recall what your problem was but if the iwi driver is receiving the frame and passing it up only to be discarded by the 802.3 layer then you've received a frame that's too large and you should look at the sender side for why it's being generated. If you don't want to do that you can probably just up the mtu on iwi and let the frame through. Sam From owner-freebsd-net@FreeBSD.ORG Sat Sep 16 16:44:41 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A8BB616A47C for ; Sat, 16 Sep 2006 16:44:41 +0000 (UTC) (envelope-from pauls@utdallas.edu) Received: from mail.stovebolt.com (mail.stovebolt.com [66.221.101.248]) by mx1.FreeBSD.org (Postfix) with ESMTP id 14CBC43DA8 for ; Sat, 16 Sep 2006 16:44:22 +0000 (GMT) (envelope-from pauls@utdallas.edu) Received: from [192.168.2.102] (unknown [66.142.189.190]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.stovebolt.com (Postfix) with ESMTP id 401C1114333 for ; Sat, 16 Sep 2006 11:37:18 -0500 (CDT) Date: Sat, 16 Sep 2006 11:44:12 -0500 From: pauls@utdallas.edu To: freebsd-net@freebsd.org Message-ID: <1255523FBB4AAE9CBCE5E949@paul-schmehls-powerbook59.local> In-Reply-To: <450B93F6.4090409@goldenpath.org> References: <450B93F6.4090409@goldenpath.org> X-Mailer: Mulberry/4.0.5 (Mac OS X) MIME-Version: 1.0 Content-Type: multipart/signed; micalg=sha1; protocol="application/pkcs7-signature"; boundary="==========89FADF8782A0D5781CD4==========" X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Subject: Re: NIC Problems X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Sep 2006 16:44:41 -0000 --==========89FADF8782A0D5781CD4========== Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: quoted-printable Content-Disposition: inline --On September 16, 2006 2:04:38 AM -0400 Tim Allender=20 wrote: > Not sure if I should post this here or straight to the pfSensse list. > I suspect this kind of thing is a faulty NIC but since I've not seen it > before I'm not sure: > > vr0: receive error (81): rx buffer error > vr0: revieve error (0024) no buffers > vr0: receive error (81): rx buffer error > vr0: revieve error (0024) no buffers > vr0: receive error (81): rx buffer error > vr0: revieve error (0024) no buffers > vr0: receive error (81): rx buffer error > vr0: revieve error (0024) no buffers > What NIC is it? Paul Schmehl (pauls@utdallas.edu) Adjunct Information Security Officer The University of Texas at Dallas http://www.utdallas.edu/ir/security/ --==========89FADF8782A0D5781CD4==========--