From: Tim Gardner <timg@tpi.com>
To: Eric Dumazet <eric.dumazet@gmail.com>
Cc: kaber@trash.net, coreteam@netfilter.org,
netfilter-devel@vger.kernel.org, netfilter@vger.kernel.org
Subject: Re: linux-next netfilter: xt_recent: Add an entry reaper
Date: Mon, 01 Mar 2010 13:24:04 -0700 [thread overview]
Message-ID: <4B8C2264.2040808@tpi.com> (raw)
In-Reply-To: <1267409855.9082.103.camel@edumazet-laptop>
[-- Attachment #1: Type: text/plain, Size: 2167 bytes --]
Eric Dumazet wrote:
> Le dimanche 28 février 2010 à 16:12 -0700, Tim Gardner a écrit :
>
>> You are right about the reaper pointer. I'd forgotten that the LRU list
>> was already sorted oldest to newest. Doh! I've cleaned that up some.
>>
>> This version adds the '--reap' flag and only looks at the head of the
>> LRU list once per ip_reaper_freq packets.
>>
>> I also added a check that makes sure --rttl and --reap modify only the
>> --rcheck and --update options.
>>
>> rtg
>
> @@ -272,6 +295,16 @@ recent_mt(const struct sk_buff *skb, const struct
> xt_match_param *par)
> break;
> }
> }
> +
> + /*
> + * Run the reaper every ip_reaper_freq packets.
> + */
> + if ((info->check_set & XT_RECENT_REAP) &&
> + info->seconds &&
>
> This (info->seconds) test is redundant, if you test it _once_ in
> recent_mt_check()
>
> + (++t->reaper_cnt >= ip_reaper_freq)) {
> + t->reaper_cnt = 0;
> + recent_entry_reap(t, time);
> + }
> }
>
>
> ie :
>
> diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c
> index fc70a49..66d68f3 100644
> --- a/net/netfilter/xt_recent.c
> +++ b/net/netfilter/xt_recent.c
> @@ -294,6 +294,8 @@ static bool recent_mt_check(const struct
> xt_mtchk_param *par)
> if ((info->check_set & (XT_RECENT_SET | XT_RECENT_REMOVE)) &&
> (info->seconds || info->hit_count))
> return false;
> + if ((info->check_set & XT_RECENT_REAP) && !info->seconds)
> + return false;
> if (info->hit_count > ip_pkt_list_tot)
> return false;
> if (info->name[0] == '\0' ||
>
>
>
> Then, now that reaping is done as a rule option only, I am not sure we
> still need the reaper_cnt logic, since you probably want ip_reaper_freq
> = 1, or else table size will probably grow at its limit, even in non DOS
> situation.
>
>
>
Agreed, see attached.
--
Tim Gardner timg@tpi.com www.tpi.com
OR 503-601-0234 x102 MT 406-443-5357
[-- Attachment #2: 0001-netfilter-xt_recent-Add-an-entry-reaper-V4.patch --]
[-- Type: text/x-patch, Size: 3290 bytes --]
From 3cd53e6474b307bba448103865bed63ffe81b626 Mon Sep 17 00:00:00 2001
From: Tim Gardner <tim.gardner@canonical.com>
Date: Sat, 27 Feb 2010 20:22:07 -0700
Subject: [PATCH] netfilter: xt_recent: Add an entry reaper (V4)
One of the problems with the way xt_recent is implemented is that
there is no efficient way to remove expired entries. Of course,
one can write a rule '-m recent --remove', but you have to know
beforehand which entry to delete. This commit adds reaper
logic which checks the head of the LRU list when a rule
is invoked that has a '--seconds' value and XT_RECENT_REAP set. If an
entry ceases to accumulate time stamps, then it will eventually bubble
to the top of the LRU list where it is then reaped.
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
---
include/linux/netfilter/xt_recent.h | 4 ++++
net/netfilter/xt_recent.c | 28 +++++++++++++++++++++++++++-
2 files changed, 31 insertions(+), 1 deletions(-)
diff --git a/include/linux/netfilter/xt_recent.h b/include/linux/netfilter/xt_recent.h
index d2c2766..bba990e 100644
--- a/include/linux/netfilter/xt_recent.h
+++ b/include/linux/netfilter/xt_recent.h
@@ -9,6 +9,7 @@ enum {
XT_RECENT_UPDATE = 1 << 2,
XT_RECENT_REMOVE = 1 << 3,
XT_RECENT_TTL = 1 << 4,
+ XT_RECENT_REAP = 1 << 5,
XT_RECENT_SOURCE = 0,
XT_RECENT_DEST = 1,
@@ -16,6 +17,9 @@ enum {
XT_RECENT_NAME_LEN = 200,
};
+/* Only allowed with --rcheck and --update */
+#define XT_RECENT_MODIFIERS (XT_RECENT_TTL|XT_RECENT_REAP)
+
struct xt_recent_mtinfo {
__u32 seconds;
__u32 hit_count;
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c
index 7073dbb..873a101 100644
--- a/net/netfilter/xt_recent.c
+++ b/net/netfilter/xt_recent.c
@@ -146,6 +146,25 @@ static void recent_entry_remove(struct recent_table *t, struct recent_entry *e)
t->entries--;
}
+/*
+ * Drop entries with timestamps older then 'time'.
+ */
+static void recent_entry_reap(struct recent_table *t, unsigned long time)
+{
+ struct recent_entry *e;
+
+ /*
+ * The head of the LRU list is always the oldest entry.
+ */
+ e = list_entry(t->lru_list.next, struct recent_entry, lru_list);
+
+ /*
+ * The last time stamp is the most recent.
+ */
+ if (time_after(time, e->stamps[e->index-1]))
+ recent_entry_remove(t, e);
+}
+
static struct recent_entry *
recent_entry_init(struct recent_table *t, const union nf_inet_addr *addr,
u_int16_t family, u_int8_t ttl)
@@ -272,6 +291,10 @@ recent_mt(const struct sk_buff *skb, const struct xt_match_param *par)
break;
}
}
+
+ /* info->seconds must be non-zero */
+ if (info->check_set & XT_RECENT_REAP)
+ recent_entry_reap(t, time);
}
if (info->check_set & XT_RECENT_SET ||
@@ -304,7 +327,10 @@ static bool recent_mt_check(const struct xt_mtchk_param *par)
XT_RECENT_CHECK | XT_RECENT_UPDATE)) != 1)
return false;
if ((info->check_set & (XT_RECENT_SET | XT_RECENT_REMOVE)) &&
- (info->seconds || info->hit_count))
+ (info->seconds || info->hit_count ||
+ (info->check_set & XT_RECENT_MODIFIERS)))
+ return false;
+ if ((info->check_set & XT_RECENT_REAP) && !info->seconds)
return false;
if (info->hit_count > ip_pkt_list_tot) {
pr_info(KBUILD_MODNAME ": hitcount (%u) is larger than "
--
1.7.0
WARNING: multiple messages have this Message-ID (diff)
From: Tim Gardner <timg@tpi.com>
To: Eric Dumazet <eric.dumazet@gmail.com>
Cc: kaber@trash.net, coreteam@netfilter.org,
netfilter-devel@vger.kernel.org, netfilter@vger.kernel.org
Subject: Re: linux-next netfilter: xt_recent: Add an entry reaper
Date: Mon, 01 Mar 2010 13:24:04 -0700 [thread overview]
Message-ID: <4B8C2264.2040808@tpi.com> (raw)
In-Reply-To: <1267409855.9082.103.camel@edumazet-laptop>
[-- Attachment #1: Type: text/plain, Size: 2167 bytes --]
Eric Dumazet wrote:
> Le dimanche 28 février 2010 à 16:12 -0700, Tim Gardner a écrit :
>
>> You are right about the reaper pointer. I'd forgotten that the LRU list
>> was already sorted oldest to newest. Doh! I've cleaned that up some.
>>
>> This version adds the '--reap' flag and only looks at the head of the
>> LRU list once per ip_reaper_freq packets.
>>
>> I also added a check that makes sure --rttl and --reap modify only the
>> --rcheck and --update options.
>>
>> rtg
>
> @@ -272,6 +295,16 @@ recent_mt(const struct sk_buff *skb, const struct
> xt_match_param *par)
> break;
> }
> }
> +
> + /*
> + * Run the reaper every ip_reaper_freq packets.
> + */
> + if ((info->check_set & XT_RECENT_REAP) &&
> + info->seconds &&
>
> This (info->seconds) test is redundant, if you test it _once_ in
> recent_mt_check()
>
> + (++t->reaper_cnt >= ip_reaper_freq)) {
> + t->reaper_cnt = 0;
> + recent_entry_reap(t, time);
> + }
> }
>
>
> ie :
>
> diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c
> index fc70a49..66d68f3 100644
> --- a/net/netfilter/xt_recent.c
> +++ b/net/netfilter/xt_recent.c
> @@ -294,6 +294,8 @@ static bool recent_mt_check(const struct
> xt_mtchk_param *par)
> if ((info->check_set & (XT_RECENT_SET | XT_RECENT_REMOVE)) &&
> (info->seconds || info->hit_count))
> return false;
> + if ((info->check_set & XT_RECENT_REAP) && !info->seconds)
> + return false;
> if (info->hit_count > ip_pkt_list_tot)
> return false;
> if (info->name[0] == '\0' ||
>
>
>
> Then, now that reaping is done as a rule option only, I am not sure we
> still need the reaper_cnt logic, since you probably want ip_reaper_freq
> = 1, or else table size will probably grow at its limit, even in non DOS
> situation.
>
>
>
Agreed, see attached.
--
Tim Gardner timg@tpi.com www.tpi.com
OR 503-601-0234 x102 MT 406-443-5357
[-- Attachment #2: 0001-netfilter-xt_recent-Add-an-entry-reaper-V4.patch --]
[-- Type: text/x-patch, Size: 3291 bytes --]
>From 3cd53e6474b307bba448103865bed63ffe81b626 Mon Sep 17 00:00:00 2001
From: Tim Gardner <tim.gardner@canonical.com>
Date: Sat, 27 Feb 2010 20:22:07 -0700
Subject: [PATCH] netfilter: xt_recent: Add an entry reaper (V4)
One of the problems with the way xt_recent is implemented is that
there is no efficient way to remove expired entries. Of course,
one can write a rule '-m recent --remove', but you have to know
beforehand which entry to delete. This commit adds reaper
logic which checks the head of the LRU list when a rule
is invoked that has a '--seconds' value and XT_RECENT_REAP set. If an
entry ceases to accumulate time stamps, then it will eventually bubble
to the top of the LRU list where it is then reaped.
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
---
include/linux/netfilter/xt_recent.h | 4 ++++
net/netfilter/xt_recent.c | 28 +++++++++++++++++++++++++++-
2 files changed, 31 insertions(+), 1 deletions(-)
diff --git a/include/linux/netfilter/xt_recent.h b/include/linux/netfilter/xt_recent.h
index d2c2766..bba990e 100644
--- a/include/linux/netfilter/xt_recent.h
+++ b/include/linux/netfilter/xt_recent.h
@@ -9,6 +9,7 @@ enum {
XT_RECENT_UPDATE = 1 << 2,
XT_RECENT_REMOVE = 1 << 3,
XT_RECENT_TTL = 1 << 4,
+ XT_RECENT_REAP = 1 << 5,
XT_RECENT_SOURCE = 0,
XT_RECENT_DEST = 1,
@@ -16,6 +17,9 @@ enum {
XT_RECENT_NAME_LEN = 200,
};
+/* Only allowed with --rcheck and --update */
+#define XT_RECENT_MODIFIERS (XT_RECENT_TTL|XT_RECENT_REAP)
+
struct xt_recent_mtinfo {
__u32 seconds;
__u32 hit_count;
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c
index 7073dbb..873a101 100644
--- a/net/netfilter/xt_recent.c
+++ b/net/netfilter/xt_recent.c
@@ -146,6 +146,25 @@ static void recent_entry_remove(struct recent_table *t, struct recent_entry *e)
t->entries--;
}
+/*
+ * Drop entries with timestamps older then 'time'.
+ */
+static void recent_entry_reap(struct recent_table *t, unsigned long time)
+{
+ struct recent_entry *e;
+
+ /*
+ * The head of the LRU list is always the oldest entry.
+ */
+ e = list_entry(t->lru_list.next, struct recent_entry, lru_list);
+
+ /*
+ * The last time stamp is the most recent.
+ */
+ if (time_after(time, e->stamps[e->index-1]))
+ recent_entry_remove(t, e);
+}
+
static struct recent_entry *
recent_entry_init(struct recent_table *t, const union nf_inet_addr *addr,
u_int16_t family, u_int8_t ttl)
@@ -272,6 +291,10 @@ recent_mt(const struct sk_buff *skb, const struct xt_match_param *par)
break;
}
}
+
+ /* info->seconds must be non-zero */
+ if (info->check_set & XT_RECENT_REAP)
+ recent_entry_reap(t, time);
}
if (info->check_set & XT_RECENT_SET ||
@@ -304,7 +327,10 @@ static bool recent_mt_check(const struct xt_mtchk_param *par)
XT_RECENT_CHECK | XT_RECENT_UPDATE)) != 1)
return false;
if ((info->check_set & (XT_RECENT_SET | XT_RECENT_REMOVE)) &&
- (info->seconds || info->hit_count))
+ (info->seconds || info->hit_count ||
+ (info->check_set & XT_RECENT_MODIFIERS)))
+ return false;
+ if ((info->check_set & XT_RECENT_REAP) && !info->seconds)
return false;
if (info->hit_count > ip_pkt_list_tot) {
pr_info(KBUILD_MODNAME ": hitcount (%u) is larger than "
--
1.7.0
next prev parent reply other threads:[~2010-03-01 20:24 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-28 3:38 linux-next netfilter: xt_recent: Add an entry reaper Tim Gardner
2010-02-28 3:38 ` Tim Gardner
2010-02-28 4:34 ` Eric Dumazet
2010-02-28 10:50 ` Jan Engelhardt
2010-02-28 20:26 ` Eric Dumazet
2010-02-28 22:42 ` Tim Gardner
2010-02-28 18:23 ` Tim Gardner
2010-02-28 18:23 ` Tim Gardner
2010-02-28 20:02 ` Jan Engelhardt
2010-02-28 20:20 ` Eric Dumazet
2010-02-28 23:12 ` Tim Gardner
2010-02-28 23:12 ` Tim Gardner
2010-03-01 2:17 ` Eric Dumazet
2010-03-01 20:24 ` Tim Gardner [this message]
2010-03-01 20:24 ` Tim Gardner
2010-03-01 20:40 ` Eric Dumazet
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=4B8C2264.2040808@tpi.com \
--to=timg@tpi.com \
--cc=coreteam@netfilter.org \
--cc=eric.dumazet@gmail.com \
--cc=kaber@trash.net \
--cc=netfilter-devel@vger.kernel.org \
--cc=netfilter@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.