datapath: Fix IPv6 fragment expiry crash.
Prior to a series of commits in 3.17 like the following, the model
used to manage and expire fragments was different. We already backport
several of these functions (See datapath/compat/inet_fragment.c) to do
things like allocate/evict/destroy frags and frag queues. In the IPv4
code, we use these. In most of the IPv6 cases, we already reuse these
also. However, for timed frag expiration we instead call the upstream
version of the function, which proceeds to use the upstream versions
of the functions we backport in inet_fragment.c. There can be some
discrepancy between the offsets used in these upstream versions vs. the
backport versions, so if you mix/match them then it leads to invalid
dereferences.
b13d3cbfb8e8 ("inet: frag: move eviction of queues to work queue")
ab1c724f6330 ("inet: frag: use seqlock for hash rebuild")
Fixes the following kernel oops on kernels < 3.17 when IPv6 fragments
are expired without reassembling the frame.
BUG: unable to handle kernel paging request at
00000006845d69a8
IP: [<
ffffffff8172c09e>] _raw_spin_lock+0xe/0x50
...
Call Trace:
<IRQ>
[<
ffffffff816a32d3>] inet_frag_kill+0x63/0x100
[<
ffffffff816ead93>] ip6_expire_frag_queue+0x63/0x110
[<
ffffffffa01130e6>] nf_ct_frag6_expire+0x26/0x30 [openvswitch]
[<
ffffffff810744f6>] call_timer_fn+0x36/0x100
[<
ffffffffa01130c0>] ? nf_ct_net_init+0x20/0x20 [openvswitch]
[<
ffffffff8107548f>] run_timer_softirq+0x1ef/0x2f0
[<
ffffffff8106cccc>] __do_softirq+0xec/0x2c0
[<
ffffffff8106d215>] irq_exit+0x105/0x110
[<
ffffffff81737095>] smp_apic_timer_interrupt+0x45/0x60
[<
ffffffff81735a1d>] apic_timer_interrupt+0x6d/0x80
<EOI>
[<
ffffffff8104f596>] ? native_safe_halt+0x6/0x10
[<
ffffffff8101cb2f>] default_idle+0x1f/0xc0
[<
ffffffff8101d406>] arch_cpu_idle+0x26/0x30
[<
ffffffff810bf3a5>] cpu_startup_entry+0xc5/0x290
[<
ffffffff817122e7>] rest_init+0x77/0x80
[<
ffffffff81d34f70>] start_kernel+0x438/0x443
Signed-off-by: Joe Stringer <joe@ovn.org>
Acked-by: Pravin B Shelar <pshelar@ovn.org>