Loading net/netfilter/nft_quota.c +22 −7 Original line number Diff line number Diff line Loading @@ -13,7 +13,7 @@ #include <net/netfilter/nf_tables.h> struct nft_quota { u64 quota; atomic64_t quota; unsigned long flags; atomic64_t consumed; }; Loading @@ -21,7 +21,8 @@ struct nft_quota { static inline bool nft_overquota(struct nft_quota *priv, const struct sk_buff *skb) { return atomic64_add_return(skb->len, &priv->consumed) >= priv->quota; return atomic64_add_return(skb->len, &priv->consumed) >= atomic64_read(&priv->quota); } static inline bool nft_quota_invert(struct nft_quota *priv) Loading Loading @@ -89,7 +90,7 @@ static int nft_quota_do_init(const struct nlattr * const tb[], return -EOPNOTSUPP; } priv->quota = quota; atomic64_set(&priv->quota, quota); priv->flags = flags; atomic64_set(&priv->consumed, consumed); Loading @@ -105,10 +106,22 @@ static int nft_quota_obj_init(const struct nft_ctx *ctx, return nft_quota_do_init(tb, priv); } static void nft_quota_obj_update(struct nft_object *obj, struct nft_object *newobj) { struct nft_quota *newpriv = nft_obj_data(newobj); struct nft_quota *priv = nft_obj_data(obj); u64 newquota; newquota = atomic64_read(&newpriv->quota); atomic64_set(&priv->quota, newquota); priv->flags = newpriv->flags; } static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv, bool reset) { u64 consumed, consumed_cap; u64 consumed, consumed_cap, quota; u32 flags = priv->flags; /* Since we inconditionally increment consumed quota for each packet Loading @@ -116,14 +129,15 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv, * userspace. */ consumed = atomic64_read(&priv->consumed); if (consumed >= priv->quota) { consumed_cap = priv->quota; quota = atomic64_read(&priv->quota); if (consumed >= quota) { consumed_cap = quota; flags |= NFT_QUOTA_F_DEPLETED; } else { consumed_cap = consumed; } if (nla_put_be64(skb, NFTA_QUOTA_BYTES, cpu_to_be64(priv->quota), if (nla_put_be64(skb, NFTA_QUOTA_BYTES, cpu_to_be64(quota), NFTA_QUOTA_PAD) || nla_put_be64(skb, NFTA_QUOTA_CONSUMED, cpu_to_be64(consumed_cap), NFTA_QUOTA_PAD) || Loading Loading @@ -155,6 +169,7 @@ static const struct nft_object_ops nft_quota_obj_ops = { .init = nft_quota_obj_init, .eval = nft_quota_obj_eval, .dump = nft_quota_obj_dump, .update = nft_quota_obj_update, }; static struct nft_object_type nft_quota_obj_type __read_mostly = { Loading Loading
net/netfilter/nft_quota.c +22 −7 Original line number Diff line number Diff line Loading @@ -13,7 +13,7 @@ #include <net/netfilter/nf_tables.h> struct nft_quota { u64 quota; atomic64_t quota; unsigned long flags; atomic64_t consumed; }; Loading @@ -21,7 +21,8 @@ struct nft_quota { static inline bool nft_overquota(struct nft_quota *priv, const struct sk_buff *skb) { return atomic64_add_return(skb->len, &priv->consumed) >= priv->quota; return atomic64_add_return(skb->len, &priv->consumed) >= atomic64_read(&priv->quota); } static inline bool nft_quota_invert(struct nft_quota *priv) Loading Loading @@ -89,7 +90,7 @@ static int nft_quota_do_init(const struct nlattr * const tb[], return -EOPNOTSUPP; } priv->quota = quota; atomic64_set(&priv->quota, quota); priv->flags = flags; atomic64_set(&priv->consumed, consumed); Loading @@ -105,10 +106,22 @@ static int nft_quota_obj_init(const struct nft_ctx *ctx, return nft_quota_do_init(tb, priv); } static void nft_quota_obj_update(struct nft_object *obj, struct nft_object *newobj) { struct nft_quota *newpriv = nft_obj_data(newobj); struct nft_quota *priv = nft_obj_data(obj); u64 newquota; newquota = atomic64_read(&newpriv->quota); atomic64_set(&priv->quota, newquota); priv->flags = newpriv->flags; } static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv, bool reset) { u64 consumed, consumed_cap; u64 consumed, consumed_cap, quota; u32 flags = priv->flags; /* Since we inconditionally increment consumed quota for each packet Loading @@ -116,14 +129,15 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv, * userspace. */ consumed = atomic64_read(&priv->consumed); if (consumed >= priv->quota) { consumed_cap = priv->quota; quota = atomic64_read(&priv->quota); if (consumed >= quota) { consumed_cap = quota; flags |= NFT_QUOTA_F_DEPLETED; } else { consumed_cap = consumed; } if (nla_put_be64(skb, NFTA_QUOTA_BYTES, cpu_to_be64(priv->quota), if (nla_put_be64(skb, NFTA_QUOTA_BYTES, cpu_to_be64(quota), NFTA_QUOTA_PAD) || nla_put_be64(skb, NFTA_QUOTA_CONSUMED, cpu_to_be64(consumed_cap), NFTA_QUOTA_PAD) || Loading Loading @@ -155,6 +169,7 @@ static const struct nft_object_ops nft_quota_obj_ops = { .init = nft_quota_obj_init, .eval = nft_quota_obj_eval, .dump = nft_quota_obj_dump, .update = nft_quota_obj_update, }; static struct nft_object_type nft_quota_obj_type __read_mostly = { Loading