Question about bridging code

Luigi Rizzo rizzo at icir.org
Wed Jul 9 19:56:16 PDT 2003


Hi,

On Wed, Jul 09, 2003 at 03:23:52PM -0400, kw3wong at engmail.uwaterloo.ca wrote:
<description skipped>
> 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 at 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
-----------------------------------+-------------------------------------


More information about the freebsd-net mailing list