1717
1818struct nft_quota {
1919 u64 quota ;
20- bool invert ;
20+ unsigned long flags ;
2121 atomic64_t consumed ;
2222};
2323
@@ -27,11 +27,16 @@ static inline bool nft_overquota(struct nft_quota *priv,
2727 return atomic64_add_return (skb -> len , & priv -> consumed ) >= priv -> quota ;
2828}
2929
30+ static inline bool nft_quota_invert (struct nft_quota * priv )
31+ {
32+ return priv -> flags & NFT_QUOTA_F_INV ;
33+ }
34+
3035static inline void nft_quota_do_eval (struct nft_quota * priv ,
3136 struct nft_regs * regs ,
3237 const struct nft_pktinfo * pkt )
3338{
34- if (nft_overquota (priv , pkt -> skb ) ^ priv -> invert )
39+ if (nft_overquota (priv , pkt -> skb ) ^ nft_quota_invert ( priv ) )
3540 regs -> verdict .code = NFT_BREAK ;
3641}
3742
@@ -40,19 +45,29 @@ static const struct nla_policy nft_quota_policy[NFTA_QUOTA_MAX + 1] = {
4045 [NFTA_QUOTA_FLAGS ] = { .type = NLA_U32 },
4146};
4247
48+ #define NFT_QUOTA_DEPLETED_BIT 1 /* From NFT_QUOTA_F_DEPLETED. */
49+
4350static void nft_quota_obj_eval (struct nft_object * obj ,
4451 struct nft_regs * regs ,
4552 const struct nft_pktinfo * pkt )
4653{
4754 struct nft_quota * priv = nft_obj_data (obj );
55+ bool overquota ;
4856
49- nft_quota_do_eval (priv , regs , pkt );
57+ overquota = nft_overquota (priv , pkt -> skb );
58+ if (overquota ^ nft_quota_invert (priv ))
59+ regs -> verdict .code = NFT_BREAK ;
60+
61+ if (overquota &&
62+ !test_and_set_bit (NFT_QUOTA_DEPLETED_BIT , & priv -> flags ))
63+ nft_obj_notify (nft_net (pkt ), obj -> table , obj , 0 , 0 ,
64+ NFT_MSG_NEWOBJ , nft_pf (pkt ), 0 , GFP_ATOMIC );
5065}
5166
5267static int nft_quota_do_init (const struct nlattr * const tb [],
5368 struct nft_quota * priv )
5469{
55- u32 flags = 0 ;
70+ unsigned long flags = 0 ;
5671 u64 quota ;
5772
5873 if (!tb [NFTA_QUOTA_BYTES ])
@@ -66,10 +81,12 @@ static int nft_quota_do_init(const struct nlattr * const tb[],
6681 flags = ntohl (nla_get_be32 (tb [NFTA_QUOTA_FLAGS ]));
6782 if (flags & ~NFT_QUOTA_F_INV )
6883 return - EINVAL ;
84+ if (flags & NFT_QUOTA_F_DEPLETED )
85+ return - EOPNOTSUPP ;
6986 }
7087
7188 priv -> quota = quota ;
72- priv -> invert = ( flags & NFT_QUOTA_F_INV ) ? true : false ;
89+ priv -> flags = flags ;
7390 atomic64_set (& priv -> consumed , 0 );
7491
7592 return 0 ;
@@ -86,13 +103,16 @@ static int nft_quota_obj_init(const struct nlattr * const tb[],
86103static int nft_quota_do_dump (struct sk_buff * skb , struct nft_quota * priv ,
87104 bool reset )
88105{
89- u32 flags = priv -> invert ? NFT_QUOTA_F_INV : 0 ;
106+ u32 flags = priv -> flags ;
90107 u64 consumed ;
91108
92- if (reset )
109+ if (reset ) {
93110 consumed = atomic64_xchg (& priv -> consumed , 0 );
94- else
111+ if (test_and_clear_bit (NFT_QUOTA_DEPLETED_BIT , & priv -> flags ))
112+ flags |= NFT_QUOTA_F_DEPLETED ;
113+ } else {
95114 consumed = atomic64_read (& priv -> consumed );
115+ }
96116
97117 /* Since we inconditionally increment consumed quota for each packet
98118 * that we see, don't go over the quota boundary in what we send to
0 commit comments