diff mbox series

[net-next] bridge: ebtables: Avoid resetting limit rule state

Message ID 20171125074418.16537-1-linus.luessing@c0d3.blue
State Changes Requested
Delegated to: Pablo Neira
Headers show
Series [net-next] bridge: ebtables: Avoid resetting limit rule state | expand

Commit Message

Linus Lüssing Nov. 25, 2017, 7:44 a.m. UTC
So far any changes with ebtables will reset the state of limit rules,
leading to spikes in traffic. This is especially noticeable if changes
are done frequently, for instance via a daemon.

This patch fixes this by bailing out from (re)setting if the limit
rule was initialized before.

When sending packets every 250ms for 600s, with a
"--limit 1/sec --limit-burst 50" rule and a command like this
in the background:

$ ebtables -N VOIDCHAIN
$ while true; do ebtables -F VOIDCHAIN; sleep 30; done

The results are:

Before: ~1600 packets
After: 650 packets

Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
---
 net/bridge/netfilter/ebt_limit.c | 4 ++++
 1 file changed, 4 insertions(+)

Comments

Pablo Neira Ayuso Nov. 27, 2017, 11:30 p.m. UTC | #1
Hi Linus,

On Sat, Nov 25, 2017 at 08:44:18AM +0100, Linus Lüssing wrote:
> So far any changes with ebtables will reset the state of limit rules,
> leading to spikes in traffic. This is especially noticeable if changes
> are done frequently, for instance via a daemon.
> 
> This patch fixes this by bailing out from (re)setting if the limit
> rule was initialized before.
> 
> When sending packets every 250ms for 600s, with a
> "--limit 1/sec --limit-burst 50" rule and a command like this
> in the background:
> 
> $ ebtables -N VOIDCHAIN
> $ while true; do ebtables -F VOIDCHAIN; sleep 30; done
> 
> The results are:
> 
> Before: ~1600 packets
> After: 650 packets
> 
> Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
> ---
>  net/bridge/netfilter/ebt_limit.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/net/bridge/netfilter/ebt_limit.c b/net/bridge/netfilter/ebt_limit.c
> index 61a9f1be1263..f74b48633feb 100644
> --- a/net/bridge/netfilter/ebt_limit.c
> +++ b/net/bridge/netfilter/ebt_limit.c
> @@ -69,6 +69,10 @@ static int ebt_limit_mt_check(const struct xt_mtchk_param *par)
>  {
>  	struct ebt_limit_info *info = par->matchinfo;
>  
> +	/* Do not reset state on unrelated table changes */
> +	if (info->prev)
> +		return 0;

What kernel version are you using? I suspect you don't have this
applied?

commit ec23189049651b16dc2ffab35a4371dc1f491aca
Author: Willem de Bruijn <willemb@google.com>
Date:   Mon Jan 2 17:19:46 2017 -0500

    xtables: extend matches and targets with .usersize
--
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
Linus Lüssing Dec. 4, 2017, 4:53 a.m. UTC | #2
Hi Pablo,

Thanks for your reply!

On Tue, Nov 28, 2017 at 12:30:08AM +0100, Pablo Neira Ayuso wrote:
> [...]
> > diff --git a/net/bridge/netfilter/ebt_limit.c b/net/bridge/netfilter/ebt_limit.c
> > index 61a9f1be1263..f74b48633feb 100644
> > --- a/net/bridge/netfilter/ebt_limit.c
> > +++ b/net/bridge/netfilter/ebt_limit.c
> > @@ -69,6 +69,10 @@ static int ebt_limit_mt_check(const struct xt_mtchk_param *par)
> >  {
> >  	struct ebt_limit_info *info = par->matchinfo;
> >  
> > +	/* Do not reset state on unrelated table changes */
> > +	if (info->prev)
> > +		return 0;
> 
> What kernel version are you using? I suspect you don't have this
> applied?

I'm indeed using a 4.4.102 kernel, as LEDE is still in the process
of updating to 4.14. So 4.4 with LEDE is where I got the measurement
results from.

> 
> commit ec23189049651b16dc2ffab35a4371dc1f491aca
> Author: Willem de Bruijn <willemb@google.com>
> Date:   Mon Jan 2 17:19:46 2017 -0500
> 
>     xtables: extend matches and targets with .usersize

And so, no I do not have this patch. I looked at it now, but it
does not seem to have any relation with .matchinfo, does it?

I also had a quick look at a 4.15-rc1 kernel in a VM now. I still
end up in ebt_limit_mt_check() with the variables being reset
when editing the table somewhere.

Regards, Linus
--
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
Linus Lüssing Dec. 4, 2017, 5:20 a.m. UTC | #3
On Mon, Dec 04, 2017 at 05:53:35AM +0100, Linus Lüssing wrote:
> And so, no I do not have this patch. I looked at it now, but it
> does not seem to have any relation with .matchinfo, does it?

Relation between .usersize and .checkentry I ment, not
.usersize and .matchinfo.
--
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
Pablo Neira Ayuso Dec. 4, 2017, 10:13 a.m. UTC | #4
On Mon, Dec 04, 2017 at 06:20:06AM +0100, Linus Lüssing wrote:
> On Mon, Dec 04, 2017 at 05:53:35AM +0100, Linus Lüssing wrote:
> > And so, no I do not have this patch. I looked at it now, but it
> > does not seem to have any relation with .matchinfo, does it?
> 
> Relation between .usersize and .checkentry I ment, not
> .usersize and .matchinfo.

In your patch, info->prev comes set to a value from userspace, right?

commit 324318f0248c31be8a08984146e7e4dd7cdd091d
Author: Willem de Bruijn <willemb@google.com>
Date:   Tue May 9 16:17:37 2017 -0400

    netfilter: xtables: zero padding in data_to_user

Since that patch above, the data area is zero'ed before dumped to
userspace, so we would get a null info->prev, hence defeating the
trick your patch relies on.

Am I missing anything?
--
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
Pablo Neira Ayuso Dec. 7, 2017, 12:26 a.m. UTC | #5
Hi Linus,

On Mon, Dec 04, 2017 at 05:53:35AM +0100, Linus Lüssing wrote:
> Hi Pablo,
> 
> Thanks for your reply!
> 
> On Tue, Nov 28, 2017 at 12:30:08AM +0100, Pablo Neira Ayuso wrote:
> > [...]
> > > diff --git a/net/bridge/netfilter/ebt_limit.c b/net/bridge/netfilter/ebt_limit.c
> > > index 61a9f1be1263..f74b48633feb 100644
> > > --- a/net/bridge/netfilter/ebt_limit.c
> > > +++ b/net/bridge/netfilter/ebt_limit.c
> > > @@ -69,6 +69,10 @@ static int ebt_limit_mt_check(const struct xt_mtchk_param *par)
> > >  {
> > >  	struct ebt_limit_info *info = par->matchinfo;
> > >  
> > > +	/* Do not reset state on unrelated table changes */
> > > +	if (info->prev)
> > > +		return 0;
> > 
> > What kernel version are you using? I suspect you don't have this
> > applied?
> 
> I'm indeed using a 4.4.102 kernel, as LEDE is still in the process
> of updating to 4.14. So 4.4 with LEDE is where I got the measurement
> results from.
> 
> > 
> > commit ec23189049651b16dc2ffab35a4371dc1f491aca
> > Author: Willem de Bruijn <willemb@google.com>
> > Date:   Mon Jan 2 17:19:46 2017 -0500
> > 
> >     xtables: extend matches and targets with .usersize
> 
> And so, no I do not have this patch. I looked at it now, but it
> does not seem to have any relation with .matchinfo, does it?
> 
> I also had a quick look at a 4.15-rc1 kernel in a VM now. I still
> end up in ebt_limit_mt_check() with the variables being reset
> when editing the table somewhere.

My question is if your fix would work with 4.15-rc1.
--
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
Linus Lüssing Dec. 8, 2017, 5:46 a.m. UTC | #6
On Thu, Dec 07, 2017 at 01:26:19AM +0100, Pablo Neira Ayuso wrote:
> > I also had a quick look at a 4.15-rc1 kernel in a VM now. I still
> > end up in ebt_limit_mt_check() with the variables being reset
> > when editing the table somewhere.
> 
> My question is if your fix would work with 4.15-rc1.

You are absoluetly right, it's not working anymore since the
commit you mentioned initially :-(
("xtables: extend matches and targets with .usersize").
info->prev is always 0 since exactly this commit.

That means, trying tricks in ebt_limit_mt_check() is too
late now, the old values are already overwritten? (or is there
some commit scheme which installs the ebt_limit_info provided
by ebt_limit_check() some time after its call?)

Extending the usersize to include info->prev would probably be too
hackish/ugly, right?
--
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
Linus Lüssing Dec. 8, 2017, 5:49 a.m. UTC | #7
On Fri, Dec 08, 2017 at 06:46:06AM +0100, Linus Lüssing wrote:
> Extending the usersize to include info->prev would probably be too
> hackish/ugly, right?

And wouldn't be enough anyway, since
info->{credit,credit_cap,cost} would still be zeroed... Hm.
--
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
diff mbox series

Patch

diff --git a/net/bridge/netfilter/ebt_limit.c b/net/bridge/netfilter/ebt_limit.c
index 61a9f1be1263..f74b48633feb 100644
--- a/net/bridge/netfilter/ebt_limit.c
+++ b/net/bridge/netfilter/ebt_limit.c
@@ -69,6 +69,10 @@  static int ebt_limit_mt_check(const struct xt_mtchk_param *par)
 {
 	struct ebt_limit_info *info = par->matchinfo;
 
+	/* Do not reset state on unrelated table changes */
+	if (info->prev)
+		return 0;
+
 	/* Check for overflow. */
 	if (info->burst == 0 ||
 	    user2credits(info->avg * info->burst) < user2credits(info->avg)) {