layer2 ipfw 'fwd' support

Julian Elischer julian at freebsd.org
Mon Oct 4 21:22:39 UTC 2010


  On 10/4/10 12:18 PM, Eduardo Meyer wrote:
> On Mon, Oct 4, 2010 at 3:35 PM, Julian Elischer<julian at freebsd.org>  wrote:
>>   On 10/4/10 10:16 AM, Eduardo Meyer wrote:
>>> On Mon, Oct 4, 2010 at 2:02 PM, Brandon Gooch
>>> <jamesbrandongooch at gmail.com>    wrote:
>>>> On Mon, Oct 4, 2010 at 9:44 AM, Eduardo Meyer<dudu.meyer at gmail.com>
>>>>   wrote:
>>>>> Hello,
>>>>>
>>>>> In the past I have used this patch by Luigi Rizzo, which helped me well.
>>>>>
>>>>>
>>>>> http://lists.freebsd.org/pipermail/freebsd-ipfw/2003-September/000526.html
>>>>>
>>>>> I tried with a friend to port it to -STABLE, but we were not able to
>>>>> find out what has replaced mt_tag. Also on ip_input.c we dirty hacked
>>>>> to following piece of code:
>>>>>
>>>>> #ifdef IPFIREWALL_FORWARD
>>>>>         if (m->m_flags&    M_FASTFWD_OURS) {
>>>>>                 m->m_flags&= ~M_FASTFWD_OURS;
>>>>>                 goto pass; /* XXX was 'ours' - SHOULD WE MODIFY IT HERE
>>>>> */
>>>>>         }
>>>>>         if ((dchg = (m_tag_find(m, PACKET_TAG_IPFORWARD, NULL) != NULL))
>>>>> != 0) {
>>>>>                 /*
>>>>>                  * Directly ship the packet on.  This allows forwarding
>>>>>                  * packets originally destined to us to some other
>>>>> directly
>>>>>                  * connected host.
>>>>>                  */
>>>>>                 ip_forward(m, dchg);
>>>>>                 return;
>>>>>         }
>>>>> #endif /* IPFIREWALL_FORWARD */
>>>>>
>>>>> And this is something we are not sure if its correct.
>>>>>
>>>>> So my very obvious question is:
>>>>>
>>>>> Does anyone has a recent version of this patch to share?
>>>>>
>>>>> Can anyone familiar with ipfw source code help me with that?
>>>>>
>>>> I'm certainly not an expert, but I wonder if the patch your referring
>>>> to is still required? Can you provide more detail about your
>>>> particular application?
>>>>
>>>> -Brandon
>>> Yes, its still required since ipfw fwd ignores layer2 frames.
>>>
>>> The application is the very same: squid. I mean, Lusca in fact (squid
>>> fork).
>>>
>>> Thank you for your interest.
>> Cisco/Ironport have a patch that does this..
>> I had permission to bring it back when I worked there but never got it
>> committed.
>>
>> Adrian, was it part of the set I gave you?
> Hello Elischer,
>
> Was this made public?
>
> I hope Chadd has some good news. In fact I tent to use with Lusca in
> tproxy mode. I bet this is the only missing piece of software.
>

I just dug up my old changes.
do you want to fwd from a bridge? or what?
(it makes a difference what patches are needed)

If you want to fwd from a bridge to make a transparent layer 2 proxy, 
this may help..


Here are parts of it that may be relevent:
these are old (2007 I think) but may be of use still.

adrian had the full set at

==quote adrian=====
   The stuff is in p4 now, but I haven't tested it out at all.

     //depo/projects/adrian_spoof_clientip/   I -think-.
== end quote===




Index: net/if_bridge.c
===================================================================
RCS file: /usr/local/cvsroot/freebsd/src/sys/net/if_bridge.c,v
retrieving revision 1.107
diff -u -r1.107 if_bridge.c
--- net/if_bridge.c	6 Nov 2007 23:01:42 -0000	1.107
+++ net/if_bridge.c	28 Nov 2007 06:59:10 -0000
@@ -2908,6 +2908,11 @@
  	struct ip *ip;
  	struct llc llc1;
  	u_int16_t ether_type;
+	int	is_ip = 0;
+#ifdef IPFIREWALL_FORWARD
+	struct m_tag *fwd_tag;
+#endif
+

  	snap = 0;
  	error = -1;	/* Default error if not error == 0 */
@@ -2967,6 +2972,7 @@
  #ifdef INET6
  		case ETHERTYPE_IPV6:
  #endif /* INET6 */
+			is_ip = 1;
  			break;
  		default:
  			/*
@@ -3024,6 +3030,30 @@

  		if (*mp == NULL)
  			return (error);
+
+#ifdef IPFIREWALL_FORWARD
+	       /*
+		* Did the firewall want to forward it somewhere?
+		* If so, let the ip stack handle it.
+		*/
+	       if (i == 0&&  args.next_hop != NULL&&
+			is_ip /*&&  src != NULL */) {
+
+		       fwd_tag = m_tag_get(PACKET_TAG_IPFORWARD,
+				       sizeof(struct sockaddr_in), M_NOWAIT);
+		       if (fwd_tag == NULL)
+			       goto drop;
+		       bcopy(args.next_hop, (fwd_tag+1),
+				sizeof(struct sockaddr_in));
+		       m_tag_prepend(*mp, fwd_tag);
+
+		       if (in_localip(args.next_hop->sin_addr))
+			       (*mp)->m_flags |= M_FASTFWD_OURS;
+		       ether_demux(src, *mp);
+		       return (NULL);
+	       }
+#endif
+

  		if (DUMMYNET_LOADED&&  (i == IP_FW_DUMMYNET)) {

==================
Index: netinet/ip_fw2.c
===================================================================
RCS file: /usr/local/cvsroot/freebsd/src/sys/netinet/ip_fw2.c,v
retrieving revision 1.178
diff -u -r1.178 ip_fw2.c
--- netinet/ip_fw2.c	28 Oct 2007 17:12:47 -0000	1.178
+++ netinet/ip_fw2.c	28 Nov 2007 06:59:10 -0000

@@ -3446,8 +3507,10 @@
  			case O_FORWARD_IP: {
  				struct sockaddr_in *sa;
  				sa =&(((ipfw_insn_sa *)cmd)->sa);
+#if 0
  				if (args->eh)	/* not valid on layer2 pkts */
  					break;
+#endif
  				if (!q || dyn_dir == MATCH_FORWARD) {
  					if (sa->sin_addr.s_addr == INADDR_ANY) {
  						bcopy(sa,&args->hopstore,

=============================================
Index: netinet/ip_output.c






More information about the freebsd-ipfw mailing list