summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorMaciej Żenczykowski <maze@google.com>2020-08-17 14:17:23 -0700
committerGreg Kroah-Hartman <gregkh@google.com>2020-08-21 11:10:25 +0000
commit59f04f292e871fb7fd7b3425d7fd3fd489a44078 (patch)
tree264a842c35b9d2215574a6637eb306f935dc9bf0 /net
parent5980066824e94701efef1b8c7e1b637e1efa4c96 (diff)
ANDROID: fix a bug in quota2
If quota is precisely equal to skb->len then a notification would not be sent due to immediately hitting 0. This fixes that, and takes the opportunity to slightly clean up the code and make quota behave more correctly for packet mode as well. Test: builds, net tests continue to pass Bug: 164336990 Signed-off-by: Maciej Żenczykowski <maze@google.com> Change-Id: I78a11b48794496255513a6226c0469d809d7aa56 (cherry picked from commit b20eacd8ddbd1dbf403df94f5ba6384e6fef0113)
Diffstat (limited to 'net')
-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;
}