From owner-freebsd-net@FreeBSD.ORG Fri Nov 12 10:37:29 2004 Return-Path: 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 B53D716A4CE; Fri, 12 Nov 2004 10:37:29 +0000 (GMT) Received: from relay.bestcom.ru (relay.bestcom.ru [217.72.144.5]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0A03F43D31; Fri, 12 Nov 2004 10:37:29 +0000 (GMT) (envelope-from glebius@freebsd.org) Received: from cell.sick.ru (root@cell.sick.ru [217.72.144.68]) by relay.bestcom.ru (8.13.1/8.12.9) with ESMTP id iACAbPpS034045 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 12 Nov 2004 13:37:26 +0300 (MSK) (envelope-from glebius@freebsd.org) Received: from cell.sick.ru (glebius@localhost [127.0.0.1]) by cell.sick.ru (8.12.11/8.12.8) with ESMTP id iACAbOUR072821 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 12 Nov 2004 13:37:25 +0300 (MSK) (envelope-from glebius@freebsd.org) Received: (from glebius@localhost) by cell.sick.ru (8.12.11/8.12.11/Submit) id iACAbOle072820; Fri, 12 Nov 2004 13:37:24 +0300 (MSK) (envelope-from glebius@freebsd.org) X-Authentication-Warning: cell.sick.ru: glebius set sender to glebius@freebsd.org using -f Date: Fri, 12 Nov 2004 13:37:23 +0300 From: Gleb Smirnoff To: green@freebsd.org, julian@freebsd.org Message-ID: <20041112103723.GA72779@cell.sick.ru> References: <20041109082903.GA42446@cell.sick.ru> <20041109205703.GB48632@cell.sick.ru> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="EeQfGwPcQSOJBaQU" Content-Disposition: inline In-Reply-To: <20041109205703.GB48632@cell.sick.ru> User-Agent: Mutt/1.5.6i X-Virus-Scanned: clamd / ClamAV version devel-20041013, clamav-milter version 0.75l on 127.0.0.1 X-Virus-Status: Clean cc: net@freebsd.org Subject: Re: ng_ksocket as divert socket is broken X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.1 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, 12 Nov 2004 10:37:29 -0000 --EeQfGwPcQSOJBaQU Content-Type: text/plain; charset=koi8-r Content-Disposition: inline Brian, I have finally resolved this problem. In case when ng_ksocket acts as divert socket, we get diverted packets returned from 'pseudo-userland' with their tags on them. In ip_divert.c rev 1.100 you do unconditional m_tag_prepend() of a new tag with cookie equal 0, and this sends packet back to ipfw rule 0. The packed is looped forever. Attached patch solves this problem (also fixing incorrect KASSERT, which blocked this functionality on invarianted kernels). I've also added M_ZERO to malloc args, removing explicit zeroing of fields. If there are no objections, I'll commit it ASAP. On Tue, Nov 09, 2004 at 11:57:03PM +0300, Gleb Smirnoff wrote: T> Brian, T> T> doing a serie of tests I have found that this commit T> has introduced regression described below: T> T> http://lists.freebsd.org/pipermail/cvs-src/2004-October/032888.html T> T> Now I'm working on this, but I'd be glad if you join. T> T> On Tue, Nov 09, 2004 at 11:29:03AM +0300, Gleb Smirnoff wrote: T> T> I've recently noticed a regression between RELENG_5 and CURRENT. T> T> In CURRENT ng_ksocket is unable to work as divert socket. Since T> T> you have touched divert code recently I'm asking you. Today I'm T> T> going to dig deeply there, but probably you can give some ideas T> T> without investigation. T> T> T> T> A test for this functionality looks like this: T> T> T> T> /usr/sbin/ngctl -f- <<-SEQ T> T> mkpeer echo dummy dummy T> T> name .:dummy echo_div T> T> mkpeer echo_div: ksocket echo inet/raw/divert T> T> name echo_div:echo div_sock T> T> rmhook dummy T> T> msg div_sock: bind inet/0.0.0.0:8888 T> T> SEQ T> T> T> T> ipfw add 1000 divert 8888 all from any to any via fxp0 T> T> T> T> And packets should flow thru fxp0 in both directions. Do not T> T> try lo0, there are some problems in there. T> T> T> T> You also need this patch (going to commit it soon), if you are T> T> running INVARIANTS: T> T> T> T> --- ip_divert.c 25 Oct 2004 20:02:34 -0000 1.106 T> T> +++ ip_divert.c 9 Nov 2004 08:27:24 -0000 T> T> @@ -277,7 +277,7 @@ T> T> struct divert_tag *dt; T> T> int error = 0; T> T> T> T> - KASSERT(m->m_pkthdr.rcvif == NULL, ("rcvif not null")); T> T> + m->m_pkthdr.rcvif = NULL; T> T> T> T> if (control) T> T> m_freem(control); /* XXX */ T> T> -- Totus tuus, Glebius. GLEBIUS-RIPN GLEB-RIPE --EeQfGwPcQSOJBaQU Content-Type: text/plain; charset=koi8-r Content-Disposition: attachment; filename="ip_divert.c.diff" Index: ip_divert.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_divert.c,v retrieving revision 1.107 diff -u -r1.107 ip_divert.c --- ip_divert.c 8 Nov 2004 14:44:53 -0000 1.107 +++ ip_divert.c 12 Nov 2004 10:28:11 -0000 @@ -277,21 +277,22 @@ struct divert_tag *dt; int error = 0; - KASSERT(m->m_pkthdr.rcvif == NULL, ("rcvif not null")); + m->m_pkthdr.rcvif = NULL; if (control) m_freem(control); /* XXX */ - mtag = m_tag_get(PACKET_TAG_DIVERT, - sizeof(struct divert_tag), M_NOWAIT); - if (mtag == NULL) { - error = ENOBUFS; - goto cantsend; - } - dt = (struct divert_tag *)(mtag+1); - dt->info = 0; - dt->cookie = 0; - m_tag_prepend(m, mtag); + if ((mtag = m_tag_find(m, PACKET_TAG_DIVERT, NULL)) == NULL) { + mtag = m_tag_get(PACKET_TAG_DIVERT, sizeof(struct divert_tag), + M_NOWAIT | M_ZERO); + if (mtag == NULL) { + error = ENOBUFS; + goto cantsend; + } + dt = (struct divert_tag *)(mtag+1); + m_tag_prepend(m, mtag); + } else + dt = (struct divert_tag *)(mtag+1); /* Loopback avoidance and state recovery */ if (sin) { --EeQfGwPcQSOJBaQU--