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