header pictures for dedicated hosting services header image of world
Guests Visit the FreeBSD Forums  •  Login to the FreeBSD Forums  •  Register for FREE

Transparent cache/Bridge with FreeBSD

 
 
Thread Tools Display Modes
  #1  
10-02-2003, 11:39 PM
 
admin vbmenu_register("postmenu_81418", true);
Administrator
 
Join Date: Jan 2002
Posts: 2,873
Transparent cache/Bridge with FreeBSD

FreeBSD's Luigi Rizzo has made some changes to the ipfw code so it can forward packets also when acting as a bridge. The usual restrictions apply -- if you 'forward' to another box then it must be on the same subnet as one of the interfaces of the middle box, because IP addresses are unchanged. You can find quick usage instructions and sample topology with patches to ip_fw2.c and ip_input.c. Luigi has not yet committed these changes.

[Read email]
-------------------------------------

Date: Mon, 22 Sep 2003 16:07:44 -0700
From: Luigi Rizzo <rizzo@icir.org>
To: ipfw@freebsd.org
Subject: [PATCH FOR REVIEW] layer2 ipfw 'fwd' support

hi,
for those interested in using ipfw 'fwd' instructions in a bridge
(e.g. to create a transparent proxy with a bridge) here is a patch
to try for ip_fw2.c (and a trivial one-line change in ip_input.c)

The change to ip_input.c matches more closely what the comment says:
if the packet is tagged by the firewall as 'PACKET_TAG_IPFORWARD'
than you skip the pass through the firewall, but still check to see
where the packet goes.

The ip_fw2.c change does the following: when the bridge detects a
layer2 packet, it passes it to ip_input() [!!!layering violation!!!]
with a proper tag so that the packet is subject to the same processing
it would have in a router.

[BTW i believe the same approach could be used to implement 'divert'
within a bridge if we only care for IP packets -- i.e. we tag the
packet and pass it to the upper layer]


The usual restrictions apply -- if you 'forward' to another box
then it must be on the same subnet as one of the interfaces of the
middlebox, because IP addresses are unchanged. Also, despite the
fact you are doing the forwarding on a bridge, if the packet must
go out you need to set net.inet.ip.forwarding=1 because the forwarding
is done at layer 3.

-------------------------------
So, QUICK USAGE INSTRUCTIONS:

sample topology:

rl0 rl1
[clients]------[bridge]--+----[rest of the world]]
|
+----[proxy]

on clients:
no configuration necessary, as the proxy is transparent!

on bridge:
sysctl net.link.ether.bridge_cfg="rl0 rl1"
sysctl net.link.ether.bridge_ipfw=1
sysctl net.link.ether.bridge=1
sysctl net.inet.ip.forwarding=1
ipfw add forward proxy proto tcp from any to any 80

on proxy:
ipfw add forward localhost,8080 tcp from not me to any 80

-------------------------------

cheers
luigi

Index: ip_fw2.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_fw2.c,v
retrieving revision 1.6.2.16
diff -u -r1.6.2.16 ip_fw2.c
--- ip_fw2.c 17 Jul 2003 06:03:39 -0000 1.6.2.16
+++ ip_fw2.c 22 Sep 2003 22:21:38 -0000
@@ -1977,12 +2022,33 @@
goto done;

case O_FORWARD_IP:
+#if 0
if (args->eh) /* not valid on layer2 pkts */
break;
+#endif
if (!q || dyn_dir == MATCH_FORWARD)
args->next_hop =
&((ipfw_insn_sa *)cmd)->sa;
retval = 0;
+ if (args->eh) {
+ struct m_hdr tag;
+
+ if (hlen == 0) /* non IP */
+ break;
+ /*
+ * tag with PACKET_TAG_IPFORWARD
+ * call ip_input() (need ip_forwarding=1
+ * if this has to go out)
+ * mark packet as comsumed by the firewall
+ */
+ tag.mh_type = MT_TAG;
+ tag.mh_flags = PACKET_TAG_IPFORWARD;
+ tag.mh_data = (caddr_t)args->next_hop;
+ tag.mh_next = m;
+ args->m = NULL;
+ retval = IP_FW_PORT_DENY_FLAG;
+ ip_input((struct mbuf *)&tag);
+ }
goto done;

default:
Index: ip_input.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.130.2.53
diff -u -r1.130.2.53 ip_input.c
--- ip_input.c 23 Jun 2003 17:53:50 -0000 1.130.2.53
+++ ip_input.c 22 Sep 2003 22:23:23 -0000
@@ -462,7 +462,7 @@
* skip the firewall a second time
*/
if (args.next_hop)
- goto ours;
+ goto pass; /* XXX was 'ours' */

args.m = m;
i = ip_fw_chk_ptr(&args);
 

 

 

 

Looking for our FreeBSD Forums? We have moved them off our main page,just follow the link to our FreeBSD Forums page.


Copyright © 2009, WEBSERVER CONSUMER GUIDE

Privacy Policy

Please note:
(1) FreeBSD is a registered trademark of The FreeBSD Foundation.
(2) WEBSERVER CONSUMER GUIDE is in no way affiliated with The FreeBSD Foundation