Maciej Żenczykowski <maze@xxxxxxxxxx> wrote: > > ret = -EINPROGRESS; > > if (fq->q.flags == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && > > - fq->q.meat == fq->q.len && > > - nf_ct_frag6_reasm(fq, skb, dev)) > > - ret = 0; > > - else > > + fq->q.meat == fq->q.len) { > > + unsigned long orefdst = skb->_skb_refdst; > > + > > + skb->_skb_refdst = 0UL; > > + if (nf_ct_frag6_reasm(fq, skb, dev)) > > + ret = 0; > > + skb->_skb_refdst = orefdst; > > + } else { > > skb_dst_drop(skb); > > + } > > > > out_unlock: > > spin_unlock_bh(&fq->q.lock); > > -- > > 2.18.1 > > > > I don't quite follow how this fixes things, but I'll trust you on it. The problematic spot is skb_morph() in nf_ct_frag6_reasm(), when we hit this code path we take dst from a dst-less skb that got queued earlier. > (nor do I understand why only 4.9 LTS appears to crash with a null ptr deref) Newer kernels need nft or iptables rule that enables defrag, such as "ip6tables -A INPUT -m conntrack --ctstate NEW"; 4.9 still enables it by default.