In-kernel NAT [ipfw] dropping large UDP return packets

Julian Elischer julian at freebsd.org
Mon Jun 18 03:32:43 UTC 2018


On 14/6/18 7:44 am, Jeff Kletsky wrote:
>
>
> On 6/13/18 1:28 PM, Andrey V. Elsukov wrote:
>> On 13.06.2018 23:04, Jeff Kletsky wrote:
>>>> The kernel version of libalias uses m_megapullup() function to make
>>>> single contiguous buffer. m_megapullup() uses m_get2() function to
>>>> allocate mbuf of appropriate size. If size of packet greater than 
>>>> 4k it
>>>> will fail. So, if you use MTU greater than 4k or if after fragments
>>>> reassembly you get a packet with length greater than 4k, ipfw_nat()
>>>> function will drop this packet.
>>>>
>>> Thanks!!
>>>
>>> Mystery solved...
>>>
>>> /usr/src/sys/netinet/libalias/alias.c
>>>
>>> #ifdef _KERNEL
>>> /*
>>>   * m_megapullup() - this function is a big hack.
>>>   * Thankfully, it's only used in ng_nat and ipfw+nat.
>>>
>>> suggests that the "old school" approach of natd might resolve 
>>> this. I'll
>>> give it a try when I'm close enough to the box to resolve it when 
>>> I make
>>> a configuration error.
>> I didn't look at the rest of libalias, but you, probably, can improve
>> this hack to use 9k or 16k mbufs. You can replace m_get2() call in
>> m_megapullup() with the following code:
>>
>> if (len <= MJUMPAGESIZE)
>>     mcl = m_get2(len, M_NOWAIT, MT_DATA, M_PKTHDR);
>> else if (len <= MJUM9BYTES)
>>     mcl = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUM9BYTES);
>> else if (len <= MJUM16BYTES)
>>     mcl = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUM16BYTES);
>> else
>>     goto bad;
>>
>
> Tested and "works for me" on 11.1-RELEASE-p10 with GENERIC kernconf
>
> 8<
> --- alias.c.orig    2017-07-20 16:42:02.000000000 -0700
> +++ alias.c    2018-06-13 15:41:46.862121000 -0700
> @@ -1758,7 +1758,14 @@
>      if (m->m_next == NULL && M_WRITABLE(m))
>          return (m);
>
> -    mcl = m_get2(len, M_NOWAIT, MT_DATA, M_PKTHDR);
> +    if (len <= MJUMPAGESIZE)
> +        mcl = m_get2(len, M_NOWAIT, MT_DATA, M_PKTHDR);
> +    else if (len <= MJUM9BYTES)
> +        mcl = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUM9BYTES);
> +    else if (len <= MJUM16BYTES)
> +        mcl = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUM16BYTES);
> +    else
> +        goto bad;
>      if (mcl == NULL)
>          goto bad;
>      m_align(mcl, len);
> >8
>
> Thanks again!

Hi Andey,  please commit..
>
> Jeff
>
> _______________________________________________
> freebsd-net at freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-net
> To unsubscribe, send any mail to "freebsd-net-unsubscribe at freebsd.org"
>
>



More information about the freebsd-ipfw mailing list