#include <net/netfilter/nf_tables.h>
 
 struct nft_quota {
-       u64             quota;
+       atomic64_t      quota;
        unsigned long   flags;
        atomic64_t      consumed;
 };
 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)
                        return -EOPNOTSUPP;
        }
 
-       priv->quota = quota;
+       atomic64_set(&priv->quota, quota);
        priv->flags = flags;
        atomic64_set(&priv->consumed, consumed);
 
        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
         * 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) ||
        .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 = {