netfilter: conntrack: remove timer from ecache extension
[firefly-linux-kernel-4.4.55.git] / net / netfilter / nf_conntrack_core.c
index 1f4f954c4b47c7ecf763290659e900277ad5cb89..de88c4ab5146a168bc0866f3fdc07098b5ebe543 100644 (file)
@@ -352,40 +352,6 @@ static void nf_ct_delete_from_lists(struct nf_conn *ct)
        local_bh_enable();
 }
 
-static void death_by_event(unsigned long ul_conntrack)
-{
-       struct nf_conn *ct = (void *)ul_conntrack;
-       struct net *net = nf_ct_net(ct);
-       struct nf_conntrack_ecache *ecache = nf_ct_ecache_find(ct);
-
-       BUG_ON(ecache == NULL);
-
-       if (nf_conntrack_event(IPCT_DESTROY, ct) < 0) {
-               /* bad luck, let's retry again */
-               ecache->timeout.expires = jiffies +
-                       (prandom_u32() % net->ct.sysctl_events_retry_timeout);
-               add_timer(&ecache->timeout);
-               return;
-       }
-       /* we've got the event delivered, now it's dying */
-       set_bit(IPS_DYING_BIT, &ct->status);
-       nf_ct_put(ct);
-}
-
-static void nf_ct_dying_timeout(struct nf_conn *ct)
-{
-       struct net *net = nf_ct_net(ct);
-       struct nf_conntrack_ecache *ecache = nf_ct_ecache_find(ct);
-
-       BUG_ON(ecache == NULL);
-
-       /* set a new timer to retry event delivery */
-       setup_timer(&ecache->timeout, death_by_event, (unsigned long)ct);
-       ecache->timeout.expires = jiffies +
-               (prandom_u32() % net->ct.sysctl_events_retry_timeout);
-       add_timer(&ecache->timeout);
-}
-
 bool nf_ct_delete(struct nf_conn *ct, u32 portid, int report)
 {
        struct nf_conn_tstamp *tstamp;
@@ -394,15 +360,20 @@ bool nf_ct_delete(struct nf_conn *ct, u32 portid, int report)
        if (tstamp && tstamp->stop == 0)
                tstamp->stop = ktime_to_ns(ktime_get_real());
 
-       if (!nf_ct_is_dying(ct) &&
-           unlikely(nf_conntrack_event_report(IPCT_DESTROY, ct,
-           portid, report) < 0)) {
+       if (nf_ct_is_dying(ct))
+               goto delete;
+
+       if (nf_conntrack_event_report(IPCT_DESTROY, ct,
+                                   portid, report) < 0) {
                /* destroy event was not delivered */
                nf_ct_delete_from_lists(ct);
-               nf_ct_dying_timeout(ct);
+               nf_conntrack_ecache_delayed_work(nf_ct_net(ct));
                return false;
        }
+
+       nf_conntrack_ecache_work(nf_ct_net(ct));
        set_bit(IPS_DYING_BIT, &ct->status);
+ delete:
        nf_ct_delete_from_lists(ct);
        nf_ct_put(ct);
        return true;
@@ -1464,26 +1435,6 @@ void nf_conntrack_flush_report(struct net *net, u32 portid, int report)
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_flush_report);
 
-static void nf_ct_release_dying_list(struct net *net)
-{
-       struct nf_conntrack_tuple_hash *h;
-       struct nf_conn *ct;
-       struct hlist_nulls_node *n;
-       int cpu;
-
-       for_each_possible_cpu(cpu) {
-               struct ct_pcpu *pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu);
-
-               spin_lock_bh(&pcpu->lock);
-               hlist_nulls_for_each_entry(h, n, &pcpu->dying, hnnode) {
-                       ct = nf_ct_tuplehash_to_ctrack(h);
-                       /* never fails to remove them, no listeners at this point */
-                       nf_ct_kill(ct);
-               }
-               spin_unlock_bh(&pcpu->lock);
-       }
-}
-
 static int untrack_refs(void)
 {
        int cnt = 0, cpu;
@@ -1548,7 +1499,6 @@ i_see_dead_people:
        busy = 0;
        list_for_each_entry(net, net_exit_list, exit_list) {
                nf_ct_iterate_cleanup(net, kill_all, NULL, 0, 0);
-               nf_ct_release_dying_list(net);
                if (atomic_read(&net->ct.count) != 0)
                        busy = 1;
        }