[ovs-dev] compat: Fixup ipv6 fragmentation on 4.9.135+ kernels

Message ID 1547158191-3370-1-git-send-email-gvrose8192@gmail.com
State Accepted
Headers show
Series
  • [ovs-dev] compat: Fixup ipv6 fragmentation on 4.9.135+ kernels
Related show

Commit Message

Greg Rose Jan. 10, 2019, 10:09 p.m.
Upstream commit 648700f76b03 ("inet: frags: use rhashtables...") changed
how ipv6 fragmentation is implemented.  This patch was backported to
the upstream stable 4.9.x kernel starting at 4.9.135.

This patch creates the compatibility layer changes required to both
compile and also operate correctly with ipv6 fragmentation on these
kernels. Check if the inet_frags 'rnd' field is present to key on
whether the upstream patch is present.  Also update Travis to the
latest 4.9 kernel release so that this patch is compile tested.

Passes Travis:
https://travis-ci.org/gvrose8192/ovs-experimental/builds/478033409

Cc: William Tu <u9012063@gmail.com>
Cc: Yi-Hung Wei <yihung.wei@gmail.com>
Cc: Yifeng Sun <pkusunyifeng@gmail.com>
Signed-off-by: Greg Rose <gvrose8192@gmail.com>
---
 .travis.yml                                |  2 +-
 acinclude.m4                               |  3 ++
 datapath/linux/compat/nf_conntrack_reasm.c | 54 ++++++++++++++++++++++++++++--
 3 files changed, 56 insertions(+), 3 deletions(-)

Comments

Yi-Hung Wei Jan. 14, 2019, 11:22 p.m. | #1
On Thu, Jan 10, 2019 at 2:09 PM Greg Rose <gvrose8192@gmail.com> wrote:
>
> Upstream commit 648700f76b03 ("inet: frags: use rhashtables...") changed
> how ipv6 fragmentation is implemented.  This patch was backported to
> the upstream stable 4.9.x kernel starting at 4.9.135.
>
> This patch creates the compatibility layer changes required to both
> compile and also operate correctly with ipv6 fragmentation on these
> kernels. Check if the inet_frags 'rnd' field is present to key on
> whether the upstream patch is present.  Also update Travis to the
> latest 4.9 kernel release so that this patch is compile tested.
>
> Passes Travis:
> https://travis-ci.org/gvrose8192/ovs-experimental/builds/478033409
>
> Cc: William Tu <u9012063@gmail.com>
> Cc: Yi-Hung Wei <yihung.wei@gmail.com>
> Cc: Yifeng Sun <pkusunyifeng@gmail.com>
> Signed-off-by: Greg Rose <gvrose8192@gmail.com>
> ---
Thanks Greg for the patch.  In general, it looks good to me, I only
have two small questions as below. I tested it on 4.10.17 stable
kernel from linux-stable tree.  The compilation is passed, and the
relevant IPv6 fragmentation system traffic tests are passed.

> @@ -614,10 +658,12 @@ void ovs_netns_frags6_init(struct net *net)
>
>  void ovs_netns_frags6_exit(struct net *net)
>  {
> +#ifdef HAVE_INET_FRAGS_RND
>         struct netns_frags *frags;
>
>         frags = get_netns_frags6_from_net(net);
>         inet_frags_exit_net(frags, &nf_frags);
> +#endif
>  }
Don't we need to do inet_frags_exit_net() if HAVE_INET_FRAGS_RND is false?

From ./net/ipv6/netfilter/nf_conntrack_reasm.c in the linux-stable
branch 4.10.y, it looks like inet_frags_exit_net() is still be used.


>
>  static struct pernet_operations nf_ct_net_ops = {
> @@ -634,13 +680,17 @@ int rpl_nf_ct_frag6_init(void)
>  #ifndef HAVE_DEFRAG_ENABLE_TAKES_NET
>         nf_defrag_ipv6_enable();
>  #endif
> +#ifdef HAVE_INET_FRAGS_RND
>         nf_frags.hashfn = nf_hashfn;
> +       nf_frags.match = ip6_frag_match;
> +#else
> +       nf_frags.rhash_params = ip6_rhash_params;
> +#endif
>         nf_frags.constructor = ip6_frag_init;
>         nf_frags.destructor = NULL;
>         nf_frags.qsize = sizeof(struct frag_queue);
> -       nf_frags.match = ip6_frag_match;
>         nf_frags.frag_expire = nf_ct_frag6_expire;

.....
> -#ifdef HAVE_INET_FRAGS_WITH_FRAGS_WORK
> +#if defined(HAVE_INET_FRAGS_WITH_FRAGS_WORK) || !defined(HAVE_INET_FRAGS_RND)
>         nf_frags.frags_cache_name = nf_frags_cache_name;
>  #endif
Not sure if this changed is needed? It seems to me that it depends on
HAVE_INET_FRAGS_WITH_FRAGS_WORK but not on HAVE_INET_FRAGS_RND?


Thanks,

-Yi-Hung
Greg Rose Jan. 15, 2019, 12:20 a.m. | #2
On 1/14/2019 3:22 PM, Yi-Hung Wei wrote:
> On Thu, Jan 10, 2019 at 2:09 PM Greg Rose <gvrose8192@gmail.com> wrote:
>> Upstream commit 648700f76b03 ("inet: frags: use rhashtables...") changed
>> how ipv6 fragmentation is implemented.  This patch was backported to
>> the upstream stable 4.9.x kernel starting at 4.9.135.
>>
>> This patch creates the compatibility layer changes required to both
>> compile and also operate correctly with ipv6 fragmentation on these
>> kernels. Check if the inet_frags 'rnd' field is present to key on
>> whether the upstream patch is present.  Also update Travis to the
>> latest 4.9 kernel release so that this patch is compile tested.
>>
>> Passes Travis:
>> https://travis-ci.org/gvrose8192/ovs-experimental/builds/478033409
>>
>> Cc: William Tu <u9012063@gmail.com>
>> Cc: Yi-Hung Wei <yihung.wei@gmail.com>
>> Cc: Yifeng Sun <pkusunyifeng@gmail.com>
>> Signed-off-by: Greg Rose <gvrose8192@gmail.com>
>> ---
> Thanks Greg for the patch.  In general, it looks good to me, I only
> have two small questions as below. I tested it on 4.10.17 stable
> kernel from linux-stable tree.  The compilation is passed, and the
> relevant IPv6 fragmentation system traffic tests are passed.
>
>> @@ -614,10 +658,12 @@ void ovs_netns_frags6_init(struct net *net)
>>
>>   void ovs_netns_frags6_exit(struct net *net)
>>   {
>> +#ifdef HAVE_INET_FRAGS_RND
>>          struct netns_frags *frags;
>>
>>          frags = get_netns_frags6_from_net(net);
>>          inet_frags_exit_net(frags, &nf_frags);
>> +#endif
>>   }
> Don't we need to do inet_frags_exit_net() if HAVE_INET_FRAGS_RND is false?
>
>  From ./net/ipv6/netfilter/nf_conntrack_reasm.c in the linux-stable
> branch 4.10.y, it looks like inet_frags_exit_net() is still be used.

In 4.9.135 it was causing a panic.  I added that at the time to prevent 
the panic but perhaps there's a better
solution I should be looking for.

- Greg

>
>>   static struct pernet_operations nf_ct_net_ops = {
>> @@ -634,13 +680,17 @@ int rpl_nf_ct_frag6_init(void)
>>   #ifndef HAVE_DEFRAG_ENABLE_TAKES_NET
>>          nf_defrag_ipv6_enable();
>>   #endif
>> +#ifdef HAVE_INET_FRAGS_RND
>>          nf_frags.hashfn = nf_hashfn;
>> +       nf_frags.match = ip6_frag_match;
>> +#else
>> +       nf_frags.rhash_params = ip6_rhash_params;
>> +#endif
>>          nf_frags.constructor = ip6_frag_init;
>>          nf_frags.destructor = NULL;
>>          nf_frags.qsize = sizeof(struct frag_queue);
>> -       nf_frags.match = ip6_frag_match;
>>          nf_frags.frag_expire = nf_ct_frag6_expire;
> .....
>> -#ifdef HAVE_INET_FRAGS_WITH_FRAGS_WORK
>> +#if defined(HAVE_INET_FRAGS_WITH_FRAGS_WORK) || !defined(HAVE_INET_FRAGS_RND)
>>          nf_frags.frags_cache_name = nf_frags_cache_name;
>>   #endif
> Not sure if this changed is needed? It seems to me that it depends on
> HAVE_INET_FRAGS_WITH_FRAGS_WORK but not on HAVE_INET_FRAGS_RND?
>
>
> Thanks,
>
> -Yi-Hung
Greg Rose Jan. 21, 2019, 10:06 p.m. | #3
On 1/14/2019 4:20 PM, Gregory Rose wrote:
>
> On 1/14/2019 3:22 PM, Yi-Hung Wei wrote:
>> On Thu, Jan 10, 2019 at 2:09 PM Greg Rose <gvrose8192@gmail.com> wrote:
>>> Upstream commit 648700f76b03 ("inet: frags: use rhashtables...") 
>>> changed
>>> how ipv6 fragmentation is implemented.  This patch was backported to
>>> the upstream stable 4.9.x kernel starting at 4.9.135.
>>>
>>> This patch creates the compatibility layer changes required to both
>>> compile and also operate correctly with ipv6 fragmentation on these
>>> kernels. Check if the inet_frags 'rnd' field is present to key on
>>> whether the upstream patch is present.  Also update Travis to the
>>> latest 4.9 kernel release so that this patch is compile tested.
>>>
>>> Passes Travis:
>>> https://travis-ci.org/gvrose8192/ovs-experimental/builds/478033409
>>>
>>> Cc: William Tu <u9012063@gmail.com>
>>> Cc: Yi-Hung Wei <yihung.wei@gmail.com>
>>> Cc: Yifeng Sun <pkusunyifeng@gmail.com>
>>> Signed-off-by: Greg Rose <gvrose8192@gmail.com>
>>> ---
>> Thanks Greg for the patch.  In general, it looks good to me, I only
>> have two small questions as below. I tested it on 4.10.17 stable
>> kernel from linux-stable tree.  The compilation is passed, and the
>> relevant IPv6 fragmentation system traffic tests are passed.
>>
>>> @@ -614,10 +658,12 @@ void ovs_netns_frags6_init(struct net *net)
>>>
>>>   void ovs_netns_frags6_exit(struct net *net)
>>>   {
>>> +#ifdef HAVE_INET_FRAGS_RND
>>>          struct netns_frags *frags;
>>>
>>>          frags = get_netns_frags6_from_net(net);
>>>          inet_frags_exit_net(frags, &nf_frags);
>>> +#endif
>>>   }
>> Don't we need to do inet_frags_exit_net() if HAVE_INET_FRAGS_RND is 
>> false?
>>
>>  From ./net/ipv6/netfilter/nf_conntrack_reasm.c in the linux-stable
>> branch 4.10.y, it looks like inet_frags_exit_net() is still be used.
>
> In 4.9.135 it was causing a panic.  I added that at the time to 
> prevent the panic but perhaps there's a better
> solution I should be looking for.

Yi-hung,

I looked more closely at this in the stable tree and for 4.10.y 
HAVE_INET_FRAGS_RND will be defined and
this function will work as you expect.  So unless I'm missing something 
I feel confident that this is the correct
thing to do here.


> .....
>>> -#ifdef HAVE_INET_FRAGS_WITH_FRAGS_WORK
>>> +#if defined(HAVE_INET_FRAGS_WITH_FRAGS_WORK) || 
>>> !defined(HAVE_INET_FRAGS_RND)
>>>          nf_frags.frags_cache_name = nf_frags_cache_name;
>>>   #endif
>> Not sure if this changed is needed? It seems to me that it depends on
>> HAVE_INET_FRAGS_WITH_FRAGS_WORK but not on HAVE_INET_FRAGS_RND?
>>

It turns out after I had more of a chance to look at this that 
HAVE_INET_FRAGS_WITH_FRAGS_WORK and
HAVE_INET_FRAGS_RND are both keying off the same upstream patch I 
mentioned in the commit message
(648700f76b03).  There's no need for the redundancy.  Nice catch!

I'm going to fix this by getting rid of HAVE_INET_FRAGS_WITH_FRAGS_WORK 
because that is sort of
unwieldy and only used in a few spots.  We can simplify acinclude.m4 a 
bit and work with a single define
for the compilation switch.

A v2 patch will be forthcoming.  Thanks for the review!

- Greg
Greg Rose Jan. 21, 2019, 10:20 p.m. | #4
On 1/21/2019 2:06 PM, Gregory Rose wrote:
> It turns out after I had more of a chance to look at this that 
> HAVE_INET_FRAGS_WITH_FRAGS_WORK and
> HAVE_INET_FRAGS_RND are both keying off the same upstream patch I 
> mentioned in the commit message
> (648700f76b03).  There's no need for the redundancy.  Nice catch!
>
> I'm going to fix this by getting rid of 
> HAVE_INET_FRAGS_WITH_FRAGS_WORK because that is sort of
> unwieldy and only used in a few spots.  We can simplify acinclude.m4 a 
> bit and work with a single define
> for the compilation switch.
>
> A v2 patch will be forthcoming.  Thanks for the review!

I take that back.  If you go far enough back (3.16.1) then you see that 
the frags_work field is added
independently of the rnd field in the inet_frags structure.

It is correct to separately check for frags_work and rnd as done in this 
patch because there are times when one
field will be defined but not the other.  It is true that upstream 
commit 648700f76b03 removed the frags_work
and rnd fields at the same time but they were introduced separately and 
require discrete compilation flags.

If there are no other objections can I please get an ack?

Thanks,

- Greg
Yi-Hung Wei Jan. 23, 2019, 12:38 a.m. | #5
On Thu, Jan 10, 2019 at 2:09 PM Greg Rose <gvrose8192@gmail.com> wrote:
>
> Upstream commit 648700f76b03 ("inet: frags: use rhashtables...") changed
> how ipv6 fragmentation is implemented.  This patch was backported to
> the upstream stable 4.9.x kernel starting at 4.9.135.
>
> This patch creates the compatibility layer changes required to both
> compile and also operate correctly with ipv6 fragmentation on these
> kernels. Check if the inet_frags 'rnd' field is present to key on
> whether the upstream patch is present.  Also update Travis to the
> latest 4.9 kernel release so that this patch is compile tested.
>
> Passes Travis:
> https://travis-ci.org/gvrose8192/ovs-experimental/builds/478033409
>
> Cc: William Tu <u9012063@gmail.com>
> Cc: Yi-Hung Wei <yihung.wei@gmail.com>
> Cc: Yifeng Sun <pkusunyifeng@gmail.com>
> Signed-off-by: Greg Rose <gvrose8192@gmail.com>
> ---
Thanks for all the explanation in the follow up e-mails. This patch
looks good to me now.

Acked-by: Yi-Hung Wei <yihung.wei@gmail.com>
Greg Rose Jan. 23, 2019, 1:07 a.m. | #6
On 1/22/2019 4:38 PM, Yi-Hung Wei wrote:
> On Thu, Jan 10, 2019 at 2:09 PM Greg Rose <gvrose8192@gmail.com> wrote:
>> Upstream commit 648700f76b03 ("inet: frags: use rhashtables...") changed
>> how ipv6 fragmentation is implemented.  This patch was backported to
>> the upstream stable 4.9.x kernel starting at 4.9.135.
>>
>> This patch creates the compatibility layer changes required to both
>> compile and also operate correctly with ipv6 fragmentation on these
>> kernels. Check if the inet_frags 'rnd' field is present to key on
>> whether the upstream patch is present.  Also update Travis to the
>> latest 4.9 kernel release so that this patch is compile tested.
>>
>> Passes Travis:
>> https://travis-ci.org/gvrose8192/ovs-experimental/builds/478033409
>>
>> Cc: William Tu <u9012063@gmail.com>
>> Cc: Yi-Hung Wei <yihung.wei@gmail.com>
>> Cc: Yifeng Sun <pkusunyifeng@gmail.com>
>> Signed-off-by: Greg Rose <gvrose8192@gmail.com>
>> ---
> Thanks for all the explanation in the follow up e-mails. This patch
> looks good to me now.
>
> Acked-by: Yi-Hung Wei <yihung.wei@gmail.com>

Thanks!

This should probably be backported to 2.9 and 2.10.

- Greg
Ben Pfaff Jan. 23, 2019, 1:08 a.m. | #7
On Tue, Jan 22, 2019 at 04:38:24PM -0800, Yi-Hung Wei wrote:
> On Thu, Jan 10, 2019 at 2:09 PM Greg Rose <gvrose8192@gmail.com> wrote:
> >
> > Upstream commit 648700f76b03 ("inet: frags: use rhashtables...") changed
> > how ipv6 fragmentation is implemented.  This patch was backported to
> > the upstream stable 4.9.x kernel starting at 4.9.135.
> >
> > This patch creates the compatibility layer changes required to both
> > compile and also operate correctly with ipv6 fragmentation on these
> > kernels. Check if the inet_frags 'rnd' field is present to key on
> > whether the upstream patch is present.  Also update Travis to the
> > latest 4.9 kernel release so that this patch is compile tested.
> >
> > Passes Travis:
> > https://travis-ci.org/gvrose8192/ovs-experimental/builds/478033409
> >
> > Cc: William Tu <u9012063@gmail.com>
> > Cc: Yi-Hung Wei <yihung.wei@gmail.com>
> > Cc: Yifeng Sun <pkusunyifeng@gmail.com>
> > Signed-off-by: Greg Rose <gvrose8192@gmail.com>
> > ---
> Thanks for all the explanation in the follow up e-mails. This patch
> looks good to me now.
> 
> Acked-by: Yi-Hung Wei <yihung.wei@gmail.com>

I applied this patch to master.
Ben Pfaff Jan. 23, 2019, 1:09 a.m. | #8
On Tue, Jan 22, 2019 at 05:08:38PM -0800, Ben Pfaff wrote:
> On Tue, Jan 22, 2019 at 04:38:24PM -0800, Yi-Hung Wei wrote:
> > On Thu, Jan 10, 2019 at 2:09 PM Greg Rose <gvrose8192@gmail.com> wrote:
> > >
> > > Upstream commit 648700f76b03 ("inet: frags: use rhashtables...") changed
> > > how ipv6 fragmentation is implemented.  This patch was backported to
> > > the upstream stable 4.9.x kernel starting at 4.9.135.
> > >
> > > This patch creates the compatibility layer changes required to both
> > > compile and also operate correctly with ipv6 fragmentation on these
> > > kernels. Check if the inet_frags 'rnd' field is present to key on
> > > whether the upstream patch is present.  Also update Travis to the
> > > latest 4.9 kernel release so that this patch is compile tested.
> > >
> > > Passes Travis:
> > > https://travis-ci.org/gvrose8192/ovs-experimental/builds/478033409
> > >
> > > Cc: William Tu <u9012063@gmail.com>
> > > Cc: Yi-Hung Wei <yihung.wei@gmail.com>
> > > Cc: Yifeng Sun <pkusunyifeng@gmail.com>
> > > Signed-off-by: Greg Rose <gvrose8192@gmail.com>
> > > ---
> > Thanks for all the explanation in the follow up e-mails. This patch
> > looks good to me now.
> > 
> > Acked-by: Yi-Hung Wei <yihung.wei@gmail.com>
> 
> I applied this patch to master.

and branch-2.11; let me know if it should be backported further.
Greg Rose Jan. 23, 2019, 1:14 a.m. | #9
On 1/22/2019 5:09 PM, Ben Pfaff wrote:
> On Tue, Jan 22, 2019 at 05:08:38PM -0800, Ben Pfaff wrote:
>> On Tue, Jan 22, 2019 at 04:38:24PM -0800, Yi-Hung Wei wrote:
>>> On Thu, Jan 10, 2019 at 2:09 PM Greg Rose <gvrose8192@gmail.com> wrote:
>>>> Upstream commit 648700f76b03 ("inet: frags: use rhashtables...") changed
>>>> how ipv6 fragmentation is implemented.  This patch was backported to
>>>> the upstream stable 4.9.x kernel starting at 4.9.135.
>>>>
>>>> This patch creates the compatibility layer changes required to both
>>>> compile and also operate correctly with ipv6 fragmentation on these
>>>> kernels. Check if the inet_frags 'rnd' field is present to key on
>>>> whether the upstream patch is present.  Also update Travis to the
>>>> latest 4.9 kernel release so that this patch is compile tested.
>>>>
>>>> Passes Travis:
>>>> https://travis-ci.org/gvrose8192/ovs-experimental/builds/478033409
>>>>
>>>> Cc: William Tu <u9012063@gmail.com>
>>>> Cc: Yi-Hung Wei <yihung.wei@gmail.com>
>>>> Cc: Yifeng Sun <pkusunyifeng@gmail.com>
>>>> Signed-off-by: Greg Rose <gvrose8192@gmail.com>
>>>> ---
>>> Thanks for all the explanation in the follow up e-mails. This patch
>>> looks good to me now.
>>>
>>> Acked-by: Yi-Hung Wei <yihung.wei@gmail.com>
>> I applied this patch to master.
> and branch-2.11; let me know if it should be backported further.

I think 2.9 and 2.10 as well.

Thanks Ben!

- Greg
Ben Pfaff Jan. 23, 2019, 1:22 a.m. | #10
On Tue, Jan 22, 2019 at 05:14:05PM -0800, Gregory Rose wrote:
> 
> On 1/22/2019 5:09 PM, Ben Pfaff wrote:
> > On Tue, Jan 22, 2019 at 05:08:38PM -0800, Ben Pfaff wrote:
> > > On Tue, Jan 22, 2019 at 04:38:24PM -0800, Yi-Hung Wei wrote:
> > > > On Thu, Jan 10, 2019 at 2:09 PM Greg Rose <gvrose8192@gmail.com> wrote:
> > > > > Upstream commit 648700f76b03 ("inet: frags: use rhashtables...") changed
> > > > > how ipv6 fragmentation is implemented.  This patch was backported to
> > > > > the upstream stable 4.9.x kernel starting at 4.9.135.
> > > > > 
> > > > > This patch creates the compatibility layer changes required to both
> > > > > compile and also operate correctly with ipv6 fragmentation on these
> > > > > kernels. Check if the inet_frags 'rnd' field is present to key on
> > > > > whether the upstream patch is present.  Also update Travis to the
> > > > > latest 4.9 kernel release so that this patch is compile tested.
> > > > > 
> > > > > Passes Travis:
> > > > > https://travis-ci.org/gvrose8192/ovs-experimental/builds/478033409
> > > > > 
> > > > > Cc: William Tu <u9012063@gmail.com>
> > > > > Cc: Yi-Hung Wei <yihung.wei@gmail.com>
> > > > > Cc: Yifeng Sun <pkusunyifeng@gmail.com>
> > > > > Signed-off-by: Greg Rose <gvrose8192@gmail.com>
> > > > > ---
> > > > Thanks for all the explanation in the follow up e-mails. This patch
> > > > looks good to me now.
> > > > 
> > > > Acked-by: Yi-Hung Wei <yihung.wei@gmail.com>
> > > I applied this patch to master.
> > and branch-2.11; let me know if it should be backported further.
> 
> I think 2.9 and 2.10 as well.

It gave me a patch conflict on 2.10, would you mind posting a manual
backport?
Greg Rose Jan. 23, 2019, 1:24 a.m. | #11
On 1/22/2019 5:22 PM, Ben Pfaff wrote:
> On Tue, Jan 22, 2019 at 05:14:05PM -0800, Gregory Rose wrote:
>> On 1/22/2019 5:09 PM, Ben Pfaff wrote:
>>> On Tue, Jan 22, 2019 at 05:08:38PM -0800, Ben Pfaff wrote:
>>>> On Tue, Jan 22, 2019 at 04:38:24PM -0800, Yi-Hung Wei wrote:
>>>>> On Thu, Jan 10, 2019 at 2:09 PM Greg Rose <gvrose8192@gmail.com> wrote:
>>>>>> Upstream commit 648700f76b03 ("inet: frags: use rhashtables...") changed
>>>>>> how ipv6 fragmentation is implemented.  This patch was backported to
>>>>>> the upstream stable 4.9.x kernel starting at 4.9.135.
>>>>>>
>>>>>> This patch creates the compatibility layer changes required to both
>>>>>> compile and also operate correctly with ipv6 fragmentation on these
>>>>>> kernels. Check if the inet_frags 'rnd' field is present to key on
>>>>>> whether the upstream patch is present.  Also update Travis to the
>>>>>> latest 4.9 kernel release so that this patch is compile tested.
>>>>>>
>>>>>> Passes Travis:
>>>>>> https://travis-ci.org/gvrose8192/ovs-experimental/builds/478033409
>>>>>>
>>>>>> Cc: William Tu <u9012063@gmail.com>
>>>>>> Cc: Yi-Hung Wei <yihung.wei@gmail.com>
>>>>>> Cc: Yifeng Sun <pkusunyifeng@gmail.com>
>>>>>> Signed-off-by: Greg Rose <gvrose8192@gmail.com>
>>>>>> ---
>>>>> Thanks for all the explanation in the follow up e-mails. This patch
>>>>> looks good to me now.
>>>>>
>>>>> Acked-by: Yi-Hung Wei <yihung.wei@gmail.com>
>>>> I applied this patch to master.
>>> and branch-2.11; let me know if it should be backported further.
>> I think 2.9 and 2.10 as well.
> It gave me a patch conflict on 2.10, would you mind posting a manual
> backport?
Sure, will do.  I'll also look at 2.9.

Thanks,

Patch

diff --git a/.travis.yml b/.travis.yml
index a2ef8bd..4d82e2e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -39,7 +39,7 @@  env:
   - KERNEL=4.16.18
   - KERNEL=4.15.18
   - KERNEL=4.14.63
-  - KERNEL=4.9.120
+  - KERNEL=4.9.149
   - KERNEL=4.4.148
   - KERNEL=3.19.8
   - KERNEL=3.16.57
diff --git a/acinclude.m4 b/acinclude.m4
index 8b43d2b..f038fd4 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -915,6 +915,9 @@  AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
   OVS_FIND_PARAM_IFELSE([$KSRC/include/net/ip_tunnels.h],
                         [ip_tunnel_info_opts_set], [flags],
                         [OVS_DEFINE([HAVE_IP_TUNNEL_INFO_OPTS_SET_FLAGS])])
+  OVS_FIND_FIELD_IFELSE([$KSRC/include/net/inet_frag.h], [inet_frags],
+                        [rnd],
+                        [OVS_DEFINE([HAVE_INET_FRAGS_RND])])
 
   if cmp -s datapath/linux/kcompat.h.new \
             datapath/linux/kcompat.h >/dev/null 2>&1; then
diff --git a/datapath/linux/compat/nf_conntrack_reasm.c b/datapath/linux/compat/nf_conntrack_reasm.c
index ce13112..9d77d98 100644
--- a/datapath/linux/compat/nf_conntrack_reasm.c
+++ b/datapath/linux/compat/nf_conntrack_reasm.c
@@ -99,6 +99,7 @@  static inline u8 ip6_frag_ecn(const struct ipv6hdr *ipv6h)
 	return 1 << (ipv6_get_dsfield(ipv6h) & INET_ECN_MASK);
 }
 
+#ifdef HAVE_INET_FRAGS_RND
 static unsigned int nf_hash_frag(__be32 id, const struct in6_addr *saddr,
 				 const struct in6_addr *daddr)
 {
@@ -125,6 +126,7 @@  static unsigned int nf_hashfn(struct inet_frag_queue *q)
 	return nf_hash_frag(nq->id, &nq->saddr, &nq->daddr);
 }
 
+#endif /* HAVE_INET_FRAGS_RND */
 static void nf_ct_frag6_expire(unsigned long data)
 {
 	struct frag_queue *fq;
@@ -133,9 +135,14 @@  static void nf_ct_frag6_expire(unsigned long data)
 	fq = container_of((struct inet_frag_queue *)data, struct frag_queue, q);
 	net = get_net_from_netns_frags6(fq->q.net);
 
+#ifdef HAVE_INET_FRAGS_RND
 	ip6_expire_frag_queue(net, fq, &nf_frags);
+#else
+	ip6_expire_frag_queue(net, fq);
+#endif
 }
 
+#ifdef HAVE_INET_FRAGS_RND
 /* Creation primitives. */
 static inline struct frag_queue *fq_find(struct net *net, __be32 id,
 					 u32 user, struct in6_addr *src,
@@ -168,7 +175,27 @@  static inline struct frag_queue *fq_find(struct net *net, __be32 id,
 	}
 	return container_of(q, struct frag_queue, q);
 }
+#else
+static struct frag_queue *fq_find(struct net *net, __be32 id, u32 user,
+				  const struct ipv6hdr *hdr, int iif)
+{
+	struct frag_v6_compare_key key = {
+		.id = id,
+		.saddr = hdr->saddr,
+		.daddr = hdr->daddr,
+		.user = user,
+		.iif = iif,
+	};
+	struct inet_frag_queue *q;
+
+	q = inet_frag_find(&net->nf_frag.frags, &key);
+	if (!q)
+		return NULL;
+
+	return container_of(q, struct frag_queue, q);
+}
 
+#endif  /* HAVE_INET_FRAGS_RND */
 
 static int nf_ct_frag6_queue(struct frag_queue *fq, struct sk_buff *skb,
 			     const struct frag_hdr *fhdr, int nhoff)
@@ -317,7 +344,11 @@  found:
 	return 0;
 
 discard_fq:
+#ifdef HAVE_INET_FRAGS_RND
 	inet_frag_kill(&fq->q, &nf_frags);
+#else
+	inet_frag_kill(&fq->q);
+#endif
 err:
 	return -1;
 }
@@ -339,7 +370,11 @@  nf_ct_frag6_reasm(struct frag_queue *fq, struct sk_buff *prev,  struct net_devic
 	int    payload_len;
 	u8 ecn;
 
+#ifdef HAVE_INET_FRAGS_RND
 	inet_frag_kill(&fq->q, &nf_frags);
+#else
+	inet_frag_kill(&fq->q);
+#endif
 
 	WARN_ON(head == NULL);
 	WARN_ON(NFCT_FRAG6_CB(head)->offset != 0);
@@ -561,8 +596,13 @@  int rpl_nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user)
 #endif
 
 	skb_orphan(skb);
+#ifdef HAVE_INET_FRAGS_RND
 	fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr,
 		     ip6_frag_ecn(hdr));
+#else
+	fq = fq_find(net, fhdr->identification, user, hdr,
+		     skb->dev ? skb->dev->ifindex : 0);
+#endif
 	if (fq == NULL)
 		return -ENOMEM;
 
@@ -584,7 +624,11 @@  int rpl_nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user)
 
 out_unlock:
 	spin_unlock_bh(&fq->q.lock);
+#ifdef HAVE_INET_FRAGS_RND
 	inet_frag_put(&fq->q, &nf_frags);
+#else
+	inet_frag_put(&fq->q);
+#endif
 	return ret;
 }
 
@@ -614,10 +658,12 @@  void ovs_netns_frags6_init(struct net *net)
 
 void ovs_netns_frags6_exit(struct net *net)
 {
+#ifdef HAVE_INET_FRAGS_RND
 	struct netns_frags *frags;
 
 	frags = get_netns_frags6_from_net(net);
 	inet_frags_exit_net(frags, &nf_frags);
+#endif
 }
 
 static struct pernet_operations nf_ct_net_ops = {
@@ -634,13 +680,17 @@  int rpl_nf_ct_frag6_init(void)
 #ifndef HAVE_DEFRAG_ENABLE_TAKES_NET
 	nf_defrag_ipv6_enable();
 #endif
+#ifdef HAVE_INET_FRAGS_RND
 	nf_frags.hashfn = nf_hashfn;
+	nf_frags.match = ip6_frag_match;
+#else
+	nf_frags.rhash_params = ip6_rhash_params;
+#endif
 	nf_frags.constructor = ip6_frag_init;
 	nf_frags.destructor = NULL;
 	nf_frags.qsize = sizeof(struct frag_queue);
-	nf_frags.match = ip6_frag_match;
 	nf_frags.frag_expire = nf_ct_frag6_expire;
-#ifdef HAVE_INET_FRAGS_WITH_FRAGS_WORK
+#if defined(HAVE_INET_FRAGS_WITH_FRAGS_WORK) || !defined(HAVE_INET_FRAGS_RND)
 	nf_frags.frags_cache_name = nf_frags_cache_name;
 #endif
 #if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,0)