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)
This commit is contained in:
Maciej Żenczykowski 2020-08-17 14:17:23 -07:00 committed by syphyr
parent 9fe9503eac
commit 533391cc59
1 changed files with 14 additions and 15 deletions

View File

@ -290,6 +290,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);
@ -298,24 +300,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;
}