netfilter: nf_tables: notify internal updates of stateful objects
authorPablo Neira Ayuso <pablo@netfilter.org>
Sun, 27 Nov 2016 23:05:48 +0000 (00:05 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 7 Dec 2016 11:57:20 +0000 (12:57 +0100)
Introduce nf_tables_obj_notify() to notify internal state changes in
stateful objects. This is used by the quota object to report depletion
in a follow up patch.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/net/netfilter/nf_tables.h
net/netfilter/nf_tables_api.c

index 6f7d6a1dc09c824510083cac13fb90d41c9ba0b0..339e374c28b5d69252748d89d0d5dcf0464db370 100644 (file)
@@ -969,6 +969,10 @@ struct nft_object *nf_tables_obj_lookup(const struct nft_table *table,
                                        const struct nlattr *nla, u32 objtype,
                                        u8 genmask);
 
+int nft_obj_notify(struct net *net, struct nft_table *table,
+                  struct nft_object *obj, u32 portid, u32 seq,
+                  int event, int family, int report, gfp_t gfp);
+
 /**
  *     struct nft_object_type - stateful object type
  *
index bfc015af366a72476b2e3d45a9bc8bb61b3afed8..9d2ed3f520ef7673c98687f30095da946fd4e193 100644 (file)
@@ -4282,38 +4282,45 @@ static int nf_tables_delobj(struct net *net, struct sock *nlsk,
        return nft_delobj(&ctx, obj);
 }
 
-static int nf_tables_obj_notify(const struct nft_ctx *ctx,
-                               struct nft_object *obj, int event)
+int nft_obj_notify(struct net *net, struct nft_table *table,
+                  struct nft_object *obj, u32 portid, u32 seq, int event,
+                  int family, int report, gfp_t gfp)
 {
        struct sk_buff *skb;
        int err;
 
-       if (!ctx->report &&
-           !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
+       if (!report &&
+           !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
                return 0;
 
        err = -ENOBUFS;
-       skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       skb = nlmsg_new(NLMSG_GOODSIZE, gfp);
        if (skb == NULL)
                goto err;
 
-       err = nf_tables_fill_obj_info(skb, ctx->net, ctx->portid, ctx->seq,
-                                     event, 0, ctx->afi->family, ctx->table,
-                                     obj, false);
+       err = nf_tables_fill_obj_info(skb, net, portid, seq, event, 0, family,
+                                     table, obj, false);
        if (err < 0) {
                kfree_skb(skb);
                goto err;
        }
 
-       err = nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
-                            ctx->report, GFP_KERNEL);
+       err = nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report, gfp);
 err:
        if (err < 0) {
-               nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES,
-                                 err);
+               nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, err);
        }
        return err;
 }
+EXPORT_SYMBOL_GPL(nft_obj_notify);
+
+static int nf_tables_obj_notify(const struct nft_ctx *ctx,
+                               struct nft_object *obj, int event)
+{
+       return nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid,
+                             ctx->seq, event, ctx->afi->family, ctx->report,
+                             GFP_KERNEL);
+}
 
 static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net,
                                   u32 portid, u32 seq)