Skip to content

Commit 4dcb314

Browse files
pipchuvijay-suman
authored andcommitted
netfilter: nft_quota: match correctly when the quota just depleted
[ Upstream commit bfe7cfb65c753952735c3eed703eba9a8b96a18d ] The xt_quota compares skb length with remaining quota, but the nft_quota compares it with consumed bytes. The xt_quota can match consumed bytes up to quota at maximum. But the nft_quota break match when consumed bytes equal to quota. i.e., nft_quota match consumed bytes in [0, quota - 1], not [0, quota]. Fixes: 795595f ("netfilter: nft_quota: dump consumed quota") Signed-off-by: Zhongqiu Duan <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]> Signed-off-by: Sasha Levin <[email protected]> (cherry picked from commit e9022196bdbe556c721152f35e6d9b253c69596b) Signed-off-by: Vijayendra Suman <[email protected]>
1 parent e872b14 commit 4dcb314

File tree

1 file changed

+13
-7
lines changed

1 file changed

+13
-7
lines changed

net/netfilter/nft_quota.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,16 @@ struct nft_quota {
1919
};
2020

2121
static inline bool nft_overquota(struct nft_quota *priv,
22-
const struct sk_buff *skb)
22+
const struct sk_buff *skb,
23+
bool *report)
2324
{
24-
return atomic64_add_return(skb->len, priv->consumed) >=
25-
atomic64_read(&priv->quota);
25+
u64 consumed = atomic64_add_return(skb->len, priv->consumed);
26+
u64 quota = atomic64_read(&priv->quota);
27+
28+
if (report)
29+
*report = consumed >= quota;
30+
31+
return consumed > quota;
2632
}
2733

2834
static inline bool nft_quota_invert(struct nft_quota *priv)
@@ -34,7 +40,7 @@ static inline void nft_quota_do_eval(struct nft_quota *priv,
3440
struct nft_regs *regs,
3541
const struct nft_pktinfo *pkt)
3642
{
37-
if (nft_overquota(priv, pkt->skb) ^ nft_quota_invert(priv))
43+
if (nft_overquota(priv, pkt->skb, NULL) ^ nft_quota_invert(priv))
3844
regs->verdict.code = NFT_BREAK;
3945
}
4046

@@ -51,13 +57,13 @@ static void nft_quota_obj_eval(struct nft_object *obj,
5157
const struct nft_pktinfo *pkt)
5258
{
5359
struct nft_quota *priv = nft_obj_data(obj);
54-
bool overquota;
60+
bool overquota, report;
5561

56-
overquota = nft_overquota(priv, pkt->skb);
62+
overquota = nft_overquota(priv, pkt->skb, &report);
5763
if (overquota ^ nft_quota_invert(priv))
5864
regs->verdict.code = NFT_BREAK;
5965

60-
if (overquota &&
66+
if (report &&
6167
!test_and_set_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags))
6268
nft_obj_notify(nft_net(pkt), obj->key.table, obj, 0, 0,
6369
NFT_MSG_NEWOBJ, 0, nft_pf(pkt), 0, GFP_ATOMIC);

0 commit comments

Comments
 (0)