summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/netfilter/xt_quota2.c29
1 files changed, 14 insertions, 15 deletions
diff --git a/net/netfilter/xt_quota2.c b/net/netfilter/xt_quota2.c
index 8e1e48c121f1..5c1c1601d6df 100644
--- a/net/netfilter/xt_quota2.c
+++ b/net/netfilter/xt_quota2.c
@@ -306,6 +306,8 @@ quota_mt2(const struct sk_buff *skb, struct xt_action_param *par)
{
struct xt_quota_mtinfo2 *q = (void *)par->matchinfo;
struct xt_quota_counter *e = q->master;
+ int charge = (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len;
+ bool no_change = q->flags & XT_QUOTA_NO_CHANGE;
bool ret = q->flags & XT_QUOTA_INVERT;
spin_lock_bh(&e->lock);
@@ -314,24 +316,21 @@ quota_mt2(const struct sk_buff *skb, struct xt_action_param *par)
* While no_change is pointless in "grow" mode, we will
* implement it here simply to have a consistent behavior.
*/
- if (!(q->flags & XT_QUOTA_NO_CHANGE)) {
- e->quota += (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len;
- }
- ret = true;
+ if (!no_change)
+ e->quota += charge;
+ ret = true; /* note: does not respect inversion (bug??) */
} else {
- if (e->quota >= skb->len) {
- if (!(q->flags & XT_QUOTA_NO_CHANGE))
- e->quota -= (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len;
+ if (e->quota > charge) {
+ if (!no_change)
+ e->quota -= charge;
ret = !ret;
- } else {
+ } else if (e->quota) {
/* We are transitioning, log that fact. */
- if (e->quota) {
- quota2_log(par->hooknum,
- skb,
- par->in,
- par->out,
- q->name);
- }
+ quota2_log(par->hooknum,
+ skb,
+ par->in,
+ par->out,
+ q->name);
/* we do not allow even small packets from now on */
e->quota = 0;
}