--- zzzz-none-000/linux-4.9.276/net/netfilter/nf_conntrack_core.c 2021-07-20 14:21:16.000000000 +0000 +++ falcon-5530-750/linux-4.9.276/net/netfilter/nf_conntrack_core.c 2023-04-05 08:19:02.000000000 +0000 @@ -59,6 +59,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; @@ -928,8 +930,13 @@ /* 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; @@ -944,10 +951,23 @@ 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; @@ -959,10 +979,23 @@ * 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); } @@ -974,6 +1007,11 @@ { unsigned int i, bucket; +#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 hsize, drops; @@ -985,7 +1023,14 @@ else bucket = (bucket + 1) % hsize; +#ifdef LTQ_IP_CONNTRACK_REPLACEMENT + if (!recheck) + drops = early_drop_list(net, &ct_hash[bucket], 1); + else + drops = early_drop_list(net, &ct_hash[bucket], 0); +#else drops = early_drop_list(net, &ct_hash[bucket]); +#endif rcu_read_unlock(); if (drops) { @@ -993,7 +1038,12 @@ return true; } } - +#ifdef LTQ_IP_CONNTRACK_REPLACEMENT + if (recheck) { + recheck = 0; + goto redo; + } +#endif return false; } @@ -1104,7 +1154,7 @@ 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); } }