vxlan: ecmp support for mac fdb entries
[linux-2.6-microblaze.git] / net / netfilter / nf_conntrack_core.c
index 1927fc2..1d57b95 100644 (file)
@@ -143,6 +143,7 @@ static bool nf_conntrack_double_lock(struct net *net, unsigned int h1,
 }
 
 static void nf_conntrack_all_lock(void)
+       __acquires(&nf_conntrack_locks_all_lock)
 {
        int i;
 
@@ -162,6 +163,7 @@ static void nf_conntrack_all_lock(void)
 }
 
 static void nf_conntrack_all_unlock(void)
+       __releases(&nf_conntrack_locks_all_lock)
 {
        /* All prior stores must be complete before we clear
         * 'nf_conntrack_locks_all'. Otherwise nf_conntrack_lock()
@@ -863,9 +865,8 @@ out:
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_hash_check_insert);
 
-static inline void nf_ct_acct_update(struct nf_conn *ct,
-                                    enum ip_conntrack_info ctinfo,
-                                    unsigned int len)
+void nf_ct_acct_add(struct nf_conn *ct, u32 dir, unsigned int packets,
+                   unsigned int bytes)
 {
        struct nf_conn_acct *acct;
 
@@ -873,10 +874,11 @@ static inline void nf_ct_acct_update(struct nf_conn *ct,
        if (acct) {
                struct nf_conn_counter *counter = acct->counter;
 
-               atomic64_inc(&counter[CTINFO2DIR(ctinfo)].packets);
-               atomic64_add(len, &counter[CTINFO2DIR(ctinfo)].bytes);
+               atomic64_add(packets, &counter[dir].packets);
+               atomic64_add(bytes, &counter[dir].bytes);
        }
 }
+EXPORT_SYMBOL_GPL(nf_ct_acct_add);
 
 static void nf_ct_acct_merge(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
                             const struct nf_conn *loser_ct)
@@ -890,7 +892,7 @@ static void nf_ct_acct_merge(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
 
                /* u32 should be fine since we must have seen one packet. */
                bytes = atomic64_read(&counter[CTINFO2DIR(ctinfo)].bytes);
-               nf_ct_acct_update(ct, ctinfo, bytes);
+               nf_ct_acct_update(ct, CTINFO2DIR(ctinfo), bytes);
        }
 }
 
@@ -1517,9 +1519,9 @@ __nf_conntrack_alloc(struct net *net,
        ct->status = 0;
        ct->timeout = 0;
        write_pnet(&ct->ct_net, net);
-       memset(&ct->__nfct_init_offset[0], 0,
+       memset(&ct->__nfct_init_offset, 0,
               offsetof(struct nf_conn, proto) -
-              offsetof(struct nf_conn, __nfct_init_offset[0]));
+              offsetof(struct nf_conn, __nfct_init_offset));
 
        nf_ct_zone_add(ct, zone);
 
@@ -1931,7 +1933,7 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
                WRITE_ONCE(ct->timeout, extra_jiffies);
 acct:
        if (do_acct)
-               nf_ct_acct_update(ct, ctinfo, skb->len);
+               nf_ct_acct_update(ct, CTINFO2DIR(ctinfo), skb->len);
 }
 EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct);
 
@@ -1939,7 +1941,7 @@ bool nf_ct_kill_acct(struct nf_conn *ct,
                     enum ip_conntrack_info ctinfo,
                     const struct sk_buff *skb)
 {
-       nf_ct_acct_update(ct, ctinfo, skb->len);
+       nf_ct_acct_update(ct, CTINFO2DIR(ctinfo), skb->len);
 
        return nf_ct_delete(ct, 0, 0);
 }
@@ -2137,8 +2139,19 @@ get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
                nf_conntrack_lock(lockp);
                if (*bucket < nf_conntrack_htable_size) {
                        hlist_nulls_for_each_entry(h, n, &nf_conntrack_hash[*bucket], hnnode) {
-                               if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
+                               if (NF_CT_DIRECTION(h) != IP_CT_DIR_REPLY)
                                        continue;
+                               /* All nf_conn objects are added to hash table twice, one
+                                * for original direction tuple, once for the reply tuple.
+                                *
+                                * Exception: In the IPS_NAT_CLASH case, only the reply
+                                * tuple is added (the original tuple already existed for
+                                * a different object).
+                                *
+                                * We only need to call the iterator once for each
+                                * conntrack, so we just use the 'reply' direction
+                                * tuple while iterating.
+                                */
                                ct = nf_ct_tuplehash_to_ctrack(h);
                                if (iter(ct, data))
                                        goto found;
@@ -2633,7 +2646,6 @@ void nf_conntrack_init_end(void)
  */
 #define UNCONFIRMED_NULLS_VAL  ((1<<30)+0)
 #define DYING_NULLS_VAL                ((1<<30)+1)
-#define TEMPLATE_NULLS_VAL     ((1<<30)+2)
 
 int nf_conntrack_init_net(struct net *net)
 {