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