From: Eric Dumazet <eric.dumazet@gmail.com>
To: hawk@comx.dk
Cc: Jesper Dangaard Brouer <hawk@diku.dk>,
paulmck@linux.vnet.ibm.com, Patrick McHardy <kaber@trash.net>,
Changli Gao <xiaosuo@gmail.com>,
Linux Kernel Network Hackers <netdev@vger.kernel.org>,
Netfilter Developers <netfilter-devel@vger.kernel.org>
Subject: Re: DDoS attack causing bad effect on conntrack searches
Date: Mon, 31 May 2010 23:21:36 +0200 [thread overview]
Message-ID: <1275340896.2478.26.camel@edumazet-laptop> (raw)
In-Reply-To: <1272292568.13192.43.camel@jdb-workstation>
Le lundi 26 avril 2010 à 16:36 +0200, Jesper Dangaard Brouer a écrit :
> On Sat, 2010-04-24 at 22:11 +0200, Eric Dumazet wrote:
> >
> > > Monday or Tuesdag I'll do a test setup with some old HP380 G4 machines to
> > > see if I can reproduce the DDoS attack senario. And see if I can get
> > > it into to lookup loop.
> >
> > Theorically a loop is very unlikely, given a single retry is very
> > unlikly too.
> >
> > Unless a cpu gets in its cache a corrupted value of a 'next' pointer.
> >
> ...
> >
> > With same hash bucket size (300.032) and max conntracks (800.000), and
> > after more than 10 hours of test, not a single lookup was restarted
> > because of a nulls with wrong value.
>
> So fare, I have to agree with you. I have now tested on the same type
> of hardware (although running a 64-bit kernel, and off net-next-2.6),
> and the result is, the same as yours, I don't see a any restarts of the
> loop. The test systems differs a bit, as it has two physical CPU and 2M
> cache (and annoyingly the system insists on using HPET as clocksource).
>
> Guess, the only explanation would be bad/sub-optimal hash distribution.
> With 40 kpps and 700.000 'searches' per second, the hash bucket list
> length "only" need to be 17.5 elements on average, where optimum is 3.
> With my pktgen DoS test, where I tried to reproduce the DoS attack, only
> see a screw of 6 elements on average.
>
>
> > I can setup a test on a 16 cpu machine, multiqueue card too.
>
> Don't think that is necessary. My theory was it was possible on slower
> single queue NIC, where one CPU is 100% busy in the conntrack search,
> and the other CPUs delete the entries (due to early drop and
> call_rcu()). But guess that note the case, and RCU works perfectly ;-)
>
> > Hmm, I forgot to say I am using net-next-2.6, not your kernel version...
>
> I also did this test using net-next-2.6, perhaps I should try the
> version I use in production...
>
>
I had a look at current conntrack and found the 'unconfirmed' list was
maybe a candidate for a potential blackhole.
That is, if a reader happens to hit an entry that is moved from regular
hash table slot 'hash' to unconfirmed list, reader might scan whole
unconfirmed list to find out he is not anymore on the wanted hash chain.
Problem is this unconfirmed list might be very very long in case of
DDOS. It's really not designed to be scanned during a lookup.
So I guess we should stop early if we find an unconfirmed entry ?
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index bde095f..0573641 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -298,8 +298,10 @@ extern int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp);
extern unsigned int nf_conntrack_htable_size;
extern unsigned int nf_conntrack_max;
-#define NF_CT_STAT_INC(net, count) \
+#define NF_CT_STAT_INC(net, count) \
__this_cpu_inc((net)->ct.stat->count)
+#define NF_CT_STAT_ADD(net, count, value) \
+ __this_cpu_add((net)->ct.stat->count, value)
#define NF_CT_STAT_INC_ATOMIC(net, count) \
do { \
local_bh_disable(); \
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index eeeb8bc..e96d999 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -299,6 +299,7 @@ __nf_conntrack_find(struct net *net, u16 zone,
struct nf_conntrack_tuple_hash *h;
struct hlist_nulls_node *n;
unsigned int hash = hash_conntrack(net, zone, tuple);
+ unsigned int cnt = 0;
/* Disable BHs the entire time since we normally need to disable them
* at least once for the stats anyway.
@@ -309,10 +310,19 @@ begin:
if (nf_ct_tuple_equal(tuple, &h->tuple) &&
nf_ct_zone(nf_ct_tuplehash_to_ctrack(h)) == zone) {
NF_CT_STAT_INC(net, found);
+ NF_CT_STAT_ADD(net, searched, cnt);
local_bh_enable();
return h;
}
- NF_CT_STAT_INC(net, searched);
+ /*
+ * If we find an unconfirmed entry, restart the lookup to
+ * avoid scanning whole unconfirmed list
+ */
+ if (unlikely(++cnt > 8 &&
+ !nf_ct_is_confirmed(nf_ct_tuplehash_to_ctrack(h)))) {
+ NF_CT_STAT_INC(net, search_restart);
+ goto begin;
+ }
}
/*
* if the nulls value we got at the end of this lookup is
@@ -323,6 +333,7 @@ begin:
NF_CT_STAT_INC(net, search_restart);
goto begin;
}
+ NF_CT_STAT_ADD(net, searched, cnt);
local_bh_enable();
return NULL;
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2010-05-31 21:21 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-04-22 12:58 DDoS attack causing bad effect on conntrack searches Jesper Dangaard Brouer
2010-04-22 13:13 ` Changli Gao
2010-04-22 13:17 ` Patrick McHardy
2010-04-22 14:36 ` Eric Dumazet
2010-04-22 14:53 ` Eric Dumazet
2010-04-22 15:51 ` Paul E. McKenney
2010-04-22 16:02 ` Eric Dumazet
2010-04-22 16:34 ` Paul E. McKenney
2010-04-22 20:38 ` Jesper Dangaard Brouer
2010-04-22 21:03 ` Eric Dumazet
2010-04-22 21:14 ` Eric Dumazet
2010-04-22 23:44 ` David Miller
2010-04-23 5:44 ` Eric Dumazet
2010-04-23 8:13 ` David Miller
2010-04-23 8:18 ` David Miller
2010-04-23 8:40 ` Jesper Dangaard Brouer
2010-04-23 10:36 ` Patrick McHardy
2010-04-23 11:06 ` Eric Dumazet
2010-04-22 21:28 ` Jesper Dangaard Brouer
2010-04-23 7:23 ` Jan Engelhardt
2010-04-23 7:46 ` Eric Dumazet
2010-04-23 7:55 ` Jan Engelhardt
2010-04-23 9:23 ` Eric Dumazet
2010-04-23 10:55 ` Patrick McHardy
2010-04-23 11:05 ` Eric Dumazet
2010-04-23 11:06 ` Patrick McHardy
2010-04-23 20:57 ` Eric Dumazet
2010-04-24 11:11 ` Jesper Dangaard Brouer
2010-04-24 20:11 ` Eric Dumazet
2010-04-26 14:36 ` Jesper Dangaard Brouer
2010-05-31 21:21 ` Eric Dumazet [this message]
2010-06-01 0:28 ` Changli Gao
2010-06-01 5:05 ` Eric Dumazet
2010-06-01 5:48 ` Changli Gao
2010-06-01 10:18 ` Patrick McHardy
2010-06-01 10:31 ` Eric Dumazet
2010-06-01 10:41 ` Patrick McHardy
2010-06-01 16:20 ` [RFC nf-next-2.6] conntrack: per cpu nf_conntrack_untracked Eric Dumazet
2010-06-04 11:40 ` Patrick McHardy
2010-06-04 12:10 ` Changli Gao
2010-06-04 12:29 ` Patrick McHardy
2010-06-04 12:36 ` Eric Dumazet
2010-06-04 16:25 ` [PATCH nf-next-2.6] conntrack: IPS_UNTRACKED bit Eric Dumazet
2010-06-04 20:15 ` [PATCH nf-next-2.6 2/2] conntrack: per_cpu untracking Eric Dumazet
2010-06-08 14:29 ` Patrick McHardy
2010-06-08 14:52 ` Eric Dumazet
2010-06-08 15:12 ` Eric Dumazet
2010-06-09 12:45 ` Patrick McHardy
2010-06-08 14:12 ` [PATCH nf-next-2.6] conntrack: IPS_UNTRACKED bit Patrick McHardy
2010-04-23 10:56 ` DDoS attack causing bad effect on conntrack searches Patrick McHardy
2010-04-23 12:45 ` Jesper Dangaard Brouer
2010-04-23 13:57 ` Patrick McHardy
2010-04-22 13:31 ` Jesper Dangaard Brouer
2010-04-23 10:35 ` Patrick McHardy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1275340896.2478.26.camel@edumazet-laptop \
--to=eric.dumazet@gmail.com \
--cc=hawk@comx.dk \
--cc=hawk@diku.dk \
--cc=kaber@trash.net \
--cc=netdev@vger.kernel.org \
--cc=netfilter-devel@vger.kernel.org \
--cc=paulmck@linux.vnet.ibm.com \
--cc=xiaosuo@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox