From 34aa3f0abd41111ac379c74de60306db98aef949 Mon Sep 17 00:00:00 2001
From: "Nagaraj, Suresh" <suresh.nagaraj@intel.com>
Date: Tue, 13 Mar 2018 07:51:27 +0100
Subject: [PATCH] Merge pull request #266 in SW_PON/linux from
 bugfix/UGW_SW-22101-conntrack-table-full-drop-packet-and-early-drop-changes-as-per-7.3.x
 to xrx500

Jira id: UGW_SW-22101: early_drop changes port from 7.3.1 (currently disabled though)

* commit 'd941926bade7501a3e0392e735f29ce66de58a30':
  Jira id: UGW_SW-22101: early_drop changes port from 7.3.1 (currently disabled though)
  early_drop changes port from 7.3.1 (currently disabled though)
---
 net/netfilter/nf_conntrack_core.c | 56 +++++++++++++++++++++++++++++--
 1 file changed, 53 insertions(+), 3 deletions(-)

diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index ed9ce7c63..2d526a872 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -58,6 +58,8 @@
 
 #define NF_CONNTRACK_VERSION	"0.5.0"
 
+#undef LTQ_IP_CONNTRACK_REPLACEMENT
+
 int (*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
 				      enum nf_nat_manip_type manip,
 				      const struct nlattr *attr) __read_mostly;
@@ -876,8 +878,13 @@ EXPORT_SYMBOL_GPL(nf_conntrack_tuple_taken);
 
 /* There's a small race here where we may free a just-assured
    connection.  Too bad: we're in trouble anyway. */
+#ifdef LTQ_IP_CONNTRACK_REPLACEMENT
+static unsigned int early_drop_list(struct net *net,
+				    struct hlist_nulls_head *head, int force)
+#else
 static unsigned int early_drop_list(struct net *net,
 				    struct hlist_nulls_head *head)
+#endif
 {
 	struct nf_conntrack_tuple_hash *h;
 	struct hlist_nulls_node *n;
@@ -892,10 +899,23 @@ static unsigned int early_drop_list(struct net *net,
 			continue;
 		}
 
+#ifdef LTQ_IP_CONNTRACK_REPLACEMENT
+		if (!force) {
+			if (test_bit(IPS_ASSURED_BIT, &tmp->status) ||
+				!net_eq(nf_ct_net(tmp), net) ||
+				nf_ct_is_dying(tmp))
+				continue;
+		} else {
+			if (!net_eq(nf_ct_net(tmp), net) ||
+				nf_ct_is_dying(tmp))
+				continue;
+		}
+#else
 		if (test_bit(IPS_ASSURED_BIT, &tmp->status) ||
 		    !net_eq(nf_ct_net(tmp), net) ||
 		    nf_ct_is_dying(tmp))
 			continue;
+#endif
 
 		if (!atomic_inc_not_zero(&tmp->ct_general.use))
 			continue;
@@ -907,10 +927,23 @@ static unsigned int early_drop_list(struct net *net,
 		 * already fired or someone else deleted it. Just drop ref
 		 * and move to next entry.
 		 */
+#ifdef LTQ_IP_CONNTRACK_REPLACEMENT
+		if (!force) {
+			if (net_eq(nf_ct_net(tmp), net) &&
+		   		nf_ct_is_confirmed(tmp) &&
+		   	 	nf_ct_delete(tmp, 0, 0))
+				drops++;
+		} else {
+			if (net_eq(nf_ct_net(tmp), net) &&
+		   	 	nf_ct_delete(tmp, 0, 0))
+				drops++;
+		}
+#else
 		if (net_eq(nf_ct_net(tmp), net) &&
 		    nf_ct_is_confirmed(tmp) &&
 		    nf_ct_delete(tmp, 0, 0))
 			drops++;
+#endif
 
 		nf_ct_put(tmp);
 	}
@@ -922,6 +955,11 @@ static noinline int early_drop(struct net *net, unsigned int _hash)
 {
 	unsigned int i;
 
+#ifdef LTQ_IP_CONNTRACK_REPLACEMENT
+	int recheck  = 1;
+redo:
+#endif
+
 	for (i = 0; i < NF_CT_EVICTION_RANGE; i++) {
 		struct hlist_nulls_head *ct_hash;
 		unsigned int hash, hsize, drops;
@@ -930,7 +968,14 @@ static noinline int early_drop(struct net *net, unsigned int _hash)
 		nf_conntrack_get_ht(&ct_hash, &hsize);
 		hash = reciprocal_scale(_hash++, hsize);
 
-		drops = early_drop_list(net, &ct_hash[hash]);
+#ifdef LTQ_IP_CONNTRACK_REPLACEMENT
+		if (!recheck)
+			drops = early_drop_list(net, &ct_hash[hash], 1);
+		else
+			drops = early_drop_list(net, &ct_hash[hash], 0);
+#else
+			drops = early_drop_list(net, &ct_hash[hash]);
+#endif
 		rcu_read_unlock();
 
 		if (drops) {
@@ -938,7 +983,12 @@ static noinline int early_drop(struct net *net, unsigned int _hash)
 			return true;
 		}
 	}
-
+#ifdef LTQ_IP_CONNTRACK_REPLACEMENT
+	if (recheck) {
+		recheck = 0;
+		goto redo;
+	}
+#endif
 	return false;
 }
 
@@ -1049,7 +1099,7 @@ __nf_conntrack_alloc(struct net *net,
 	    unlikely(atomic_read(&net->ct.count) > nf_conntrack_max)) {
 		if (!early_drop(net, hash)) {
 			atomic_dec(&net->ct.count);
-			net_warn_ratelimited("nf_conntrack: table full, dropping packet\n");
+			/*net_warn_ratelimited("nf_conntrack: table full, dropping packet\n");*/
 			return ERR_PTR(-ENOMEM);
 		}
 	}
-- 
GitLab