From owner-freebsd-net@FreeBSD.ORG Wed Jul 9 19:56:16 2003 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 042F337B401 for ; Wed, 9 Jul 2003 19:56:16 -0700 (PDT) Received: from xorpc.icir.org (xorpc.icir.org [192.150.187.68]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7376B43FE3 for ; Wed, 9 Jul 2003 19:56:15 -0700 (PDT) (envelope-from rizzo@xorpc.icir.org) Received: from xorpc.icir.org (localhost [127.0.0.1]) by xorpc.icir.org (8.12.8p1/8.12.3) with ESMTP id h6A2t0kN033521; Wed, 9 Jul 2003 19:55:00 -0700 (PDT) (envelope-from rizzo@xorpc.icir.org) Received: (from rizzo@localhost) by xorpc.icir.org (8.12.8p1/8.12.3/Submit) id h6A2stCw033509; Wed, 9 Jul 2003 19:54:55 -0700 (PDT) (envelope-from rizzo) Date: Wed, 9 Jul 2003 19:54:55 -0700 From: Luigi Rizzo To: kw3wong@engmail.uwaterloo.ca Message-ID: <20030709195455.A24039@xorpc.icir.org> References: <1057778632.3f0c6bc8af474@www.nexusmail.uwaterloo.ca> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i In-Reply-To: <1057778632.3f0c6bc8af474@www.nexusmail.uwaterloo.ca>; from kw3wong@engmail.uwaterloo.ca on Wed, Jul 09, 2003 at 03:23:52PM -0400 cc: freebsd-net@freebsd.org cc: dsze@engmail.uwaterloo.ca Subject: Re: Question about bridging code 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: Thu, 10 Jul 2003 02:56:16 -0000 Hi, On Wed, Jul 09, 2003 at 03:23:52PM -0400, kw3wong@engmail.uwaterloo.ca wrote: > So here is what my code changes involved so far. BTW, I'm using FreeBSD 4.8 > > 1) Removed the check in ipfw_chk (ip_fw2.c) for whether it is layer2 or not. > This allows briged packets to still match the ipfw2 divert rules ok... >2) In bridge.c at function bdg_forward, after the ip_fw_chk_ptr (and after the >check for dummynet, around line 974), the following code fragment is added first, i would omit the special case for IP packets. Given that this code is driven by packets selected by ipfw, you can easily put the check there. At this point, this section of code becomes essentially the same as the one used for dummynet packets, so i would do the following change: if (i == 0) /* a PASS rule. */ goto forward ; - if (DUMMYNET_LOADED && (i & IP_FW_PORT_DYNT_FLAG)) { + if ((DUMMYNET_LOADED && (i & IP_FW_PORT_DYNT_FLAG)) || (i != 0 && (i & IP_FW_PORT_DYNT_FLAG) == 0)) { /* * Pass the pkt to dummynet, which consumes it. ... args.oif = real_dst; + if (DUMMYNET_LOADED && (i & IP_FW_PORT_DYNT_FLAG)) ip_dn_io_ptr(m, (i & 0xffff),DN_TO_BDG_FWD, &args); + else + divert_packet(m, 1, i & 0xffff, args.divert_rule); return m0 ; } /* * XXX at some point, add support for divert/forward actions. * If none of the above matches, we have to drop the packet. >3) To allow me to inject ethernet frames back into the system via divert >sockets, I've modified div_output so that it will call ether_output_frame. The >following are my changes to div_output, which is added before ip_output is >called: ok-ish though i'd probably look for a better way to tell ethernet frames from IP packets (this also for the input path, of course). >reinject it via the divert sockets - ping, ftp, etc. all work over the bridge >when my test program is running. However, I'm finding that I'm losing/leaking >mbufs.sbdrop will complain and panic that the sb_cc doesn't match up with what >the mbuf chains says - usually the sb_cc will be larger by a couple of hundred > bytes. Furthermore, a netstat -m will show that I have mbufs allocated to no idea about the sb_cc stuff, but your code in bdg_forward had a suspicious 'return NULL' which might cause a leakage. Apart from this (and from the suggestion of using netgraph), have you looked at the approach followed by vtun ? It bridges between physical and virtual (vmnet/tap) ethernet interfaces, then grabs packets from /dev/tap, processes them, and reinjects them as appropriate (ssl or whatever). In your case you could build two bridging clusters sysctl net.link.ether.bridge_cfg="xl0:1 vmnet0:1 xl1:2 vmnet1:2" and build your application as a userland bridge between /dev/tap0 and /dev/tap1. Performance should not be too different from the one you could get with your divert sockets. cheers luigi -----------------------------------+------------------------------------- Luigi RIZZO, luigi@iet.unipi.it . Dip. di Ing. dell'Informazione http://www.iet.unipi.it/~luigi/ . Universita` di Pisa TEL/FAX: +39-050-568.533/522 . via Diotisalvi 2, 56122 PISA (Italy) Mobile +39-347-0373137 -----------------------------------+-------------------------------------