@@ -77,7 +77,8 @@ static __read_mostly bool nf_conntrack_locks_all;
7777#define GC_SCAN_INTERVAL (120u * HZ)
7878#define GC_SCAN_MAX_DURATION msecs_to_jiffies(10)
7979
80- #define MAX_CHAINLEN 64u
80+ #define MIN_CHAINLEN 8u
81+ #define MAX_CHAINLEN (32u - MIN_CHAINLEN)
8182
8283static struct conntrack_gc_work conntrack_gc_work ;
8384
@@ -842,6 +843,7 @@ nf_conntrack_hash_check_insert(struct nf_conn *ct)
842843 unsigned int hash , reply_hash ;
843844 struct nf_conntrack_tuple_hash * h ;
844845 struct hlist_nulls_node * n ;
846+ unsigned int max_chainlen ;
845847 unsigned int chainlen = 0 ;
846848 unsigned int sequence ;
847849 int err = - EEXIST ;
@@ -857,13 +859,15 @@ nf_conntrack_hash_check_insert(struct nf_conn *ct)
857859 & ct -> tuplehash [IP_CT_DIR_REPLY ].tuple );
858860 } while (nf_conntrack_double_lock (net , hash , reply_hash , sequence ));
859861
862+ max_chainlen = MIN_CHAINLEN + prandom_u32_max (MAX_CHAINLEN );
863+
860864 /* See if there's one in the list already, including reverse */
861865 hlist_nulls_for_each_entry (h , n , & nf_conntrack_hash [hash ], hnnode ) {
862866 if (nf_ct_key_equal (h , & ct -> tuplehash [IP_CT_DIR_ORIGINAL ].tuple ,
863867 zone , net ))
864868 goto out ;
865869
866- if (chainlen ++ > MAX_CHAINLEN )
870+ if (chainlen ++ > max_chainlen )
867871 goto chaintoolong ;
868872 }
869873
@@ -873,7 +877,7 @@ nf_conntrack_hash_check_insert(struct nf_conn *ct)
873877 if (nf_ct_key_equal (h , & ct -> tuplehash [IP_CT_DIR_REPLY ].tuple ,
874878 zone , net ))
875879 goto out ;
876- if (chainlen ++ > MAX_CHAINLEN )
880+ if (chainlen ++ > max_chainlen )
877881 goto chaintoolong ;
878882 }
879883
@@ -1103,8 +1107,8 @@ nf_ct_resolve_clash(struct sk_buff *skb, struct nf_conntrack_tuple_hash *h,
11031107int
11041108__nf_conntrack_confirm (struct sk_buff * skb )
11051109{
1110+ unsigned int chainlen = 0 , sequence , max_chainlen ;
11061111 const struct nf_conntrack_zone * zone ;
1107- unsigned int chainlen = 0 , sequence ;
11081112 unsigned int hash , reply_hash ;
11091113 struct nf_conntrack_tuple_hash * h ;
11101114 struct nf_conn * ct ;
@@ -1168,14 +1172,15 @@ __nf_conntrack_confirm(struct sk_buff *skb)
11681172 goto dying ;
11691173 }
11701174
1175+ max_chainlen = MIN_CHAINLEN + prandom_u32_max (MAX_CHAINLEN );
11711176 /* See if there's one in the list already, including reverse:
11721177 NAT could have grabbed it without realizing, since we're
11731178 not in the hash. If there is, we lost race. */
11741179 hlist_nulls_for_each_entry (h , n , & nf_conntrack_hash [hash ], hnnode ) {
11751180 if (nf_ct_key_equal (h , & ct -> tuplehash [IP_CT_DIR_ORIGINAL ].tuple ,
11761181 zone , net ))
11771182 goto out ;
1178- if (chainlen ++ > MAX_CHAINLEN )
1183+ if (chainlen ++ > max_chainlen )
11791184 goto chaintoolong ;
11801185 }
11811186
@@ -1184,7 +1189,7 @@ __nf_conntrack_confirm(struct sk_buff *skb)
11841189 if (nf_ct_key_equal (h , & ct -> tuplehash [IP_CT_DIR_REPLY ].tuple ,
11851190 zone , net ))
11861191 goto out ;
1187- if (chainlen ++ > MAX_CHAINLEN ) {
1192+ if (chainlen ++ > max_chainlen ) {
11881193chaintoolong :
11891194 nf_ct_add_to_dying_list (ct );
11901195 NF_CT_STAT_INC (net , chaintoolong );
0 commit comments