layer2 ipfw 'fwd' support

Eduardo Meyer dudu.meyer at gmail.com
Mon Oct 4 22:56:28 UTC 2010


On Mon, Oct 4, 2010 at 6:23 PM, Julian Elischer <julian at freebsd.org> wrote:
>  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)

Yes, that's exactly what I want.

>
> 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.

Thank you, I will try it right now.

>
> 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
>
>
>
>
>



-- 
===========
Eduardo Meyer
pessoal: dudu.meyer at gmail.com
profissional: ddm.farmaciap at saude.gov.br


More information about the freebsd-ipfw mailing list