Patrick McHardy wrote: > Attached. The first patch still crashed, we need to prevent new > fragments from getting queued after the queue is flushed until the > hook in unregistered. The patch is racy, another CPU could already have passed the check for ip_ct_no_defrag and queue the packet after __ip_evictor calculated the work to do, so the packet (or another one) will not get evicted. This patch on top calls synchronize_net() to prevent this. > >@@ -1181,6 +1183,12 @@ > #ifdef CONFIG_NETFILTER_DEBUG > unsigned int olddebug = skb->nf_debug; > #endif >+ >+ if (unlikely(ip_ct_no_defrag)) { >+ kfree_skb(skb); >+ return NULL; >+ } >+ > if (sk) { > sock_hold(sk); > skb_orphan(skb); >diff -Nru a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c >--- a/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-08-29 20:55:13 +02:00 >+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-08-29 20:55:13 +02:00 >@@ -805,6 +805,12 @@ > cleanup_defraglocalops: > nf_unregister_hook(&ip_conntrack_defrag_local_out_ops); > cleanup_defragops: >+ /* Frag queues may hold fragments with skb->dst == NULL */ >+ ip_ct_no_defrag = 1; >+ smp_wmb(); >+ local_bh_disable(); >+ ipfrag_flush(); >+ local_bh_enable(); > nf_unregister_hook(&ip_conntrack_defrag_ops); > cleanup_proc_stat: > proc_net_remove("ip_conntrack_stat"); > >