Commit a1050dd0 authored by Phil Sutter's avatar Phil Sutter Committed by Pablo Neira Ayuso
Browse files

netfilter: nf_tables: Reintroduce shortened deletion notifications



Restore commit 28339b21 ("netfilter: nf_tables: do not send complete
notification of deletions") and fix it:

- Avoid upfront modification of 'event' variable so the conditionals
  become effective.
- Always include NFTA_OBJ_TYPE attribute in object notifications, user
  space requires it for proper deserialisation.
- Catch DESTROY events, too.

Signed-off-by: default avatarPhil Sutter <phil@nwl.cc>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 8080357a
Loading
Loading
Loading
Loading
+50 −17
Original line number Diff line number Diff line
@@ -1153,9 +1153,9 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
{
	struct nlmsghdr *nlh;

	event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
	nlh = nfnl_msg_put(skb, portid, seq, event, flags, family,
			   NFNETLINK_V0, nft_base_seq(net));
	nlh = nfnl_msg_put(skb, portid, seq,
			   nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event),
			   flags, family, NFNETLINK_V0, nft_base_seq(net));
	if (!nlh)
		goto nla_put_failure;

@@ -1165,6 +1165,12 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
			 NFTA_TABLE_PAD))
		goto nla_put_failure;

	if (event == NFT_MSG_DELTABLE ||
	    event == NFT_MSG_DESTROYTABLE) {
		nlmsg_end(skb, nlh);
		return 0;
	}

	if (nla_put_be32(skb, NFTA_TABLE_FLAGS,
			 htonl(table->flags & NFT_TABLE_F_MASK)))
		goto nla_put_failure;
@@ -2011,9 +2017,9 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net,
{
	struct nlmsghdr *nlh;

	event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
	nlh = nfnl_msg_put(skb, portid, seq, event, flags, family,
			   NFNETLINK_V0, nft_base_seq(net));
	nlh = nfnl_msg_put(skb, portid, seq,
			   nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event),
			   flags, family, NFNETLINK_V0, nft_base_seq(net));
	if (!nlh)
		goto nla_put_failure;

@@ -2023,6 +2029,13 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net,
			 NFTA_CHAIN_PAD))
		goto nla_put_failure;

	if (!hook_list &&
	    (event == NFT_MSG_DELCHAIN ||
	     event == NFT_MSG_DESTROYCHAIN)) {
		nlmsg_end(skb, nlh);
		return 0;
	}

	if (nft_is_base_chain(chain)) {
		const struct nft_base_chain *basechain = nft_base_chain(chain);
		struct nft_stats __percpu *stats;
@@ -4835,9 +4848,10 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
	u32 seq = ctx->seq;
	int i;

	event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
	nlh = nfnl_msg_put(skb, portid, seq, event, flags, ctx->family,
			   NFNETLINK_V0, nft_base_seq(ctx->net));
	nlh = nfnl_msg_put(skb, portid, seq,
			   nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event),
			   flags, ctx->family, NFNETLINK_V0,
			   nft_base_seq(ctx->net));
	if (!nlh)
		goto nla_put_failure;

@@ -4849,6 +4863,12 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
			 NFTA_SET_PAD))
		goto nla_put_failure;

	if (event == NFT_MSG_DELSET ||
	    event == NFT_MSG_DESTROYSET) {
		nlmsg_end(skb, nlh);
		return 0;
	}

	if (set->flags != 0)
		if (nla_put_be32(skb, NFTA_SET_FLAGS, htonl(set->flags)))
			goto nla_put_failure;
@@ -8323,20 +8343,26 @@ static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net,
{
	struct nlmsghdr *nlh;

	event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
	nlh = nfnl_msg_put(skb, portid, seq, event, flags, family,
			   NFNETLINK_V0, nft_base_seq(net));
	nlh = nfnl_msg_put(skb, portid, seq,
			   nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event),
			   flags, family, NFNETLINK_V0, nft_base_seq(net));
	if (!nlh)
		goto nla_put_failure;

	if (nla_put_string(skb, NFTA_OBJ_TABLE, table->name) ||
	    nla_put_string(skb, NFTA_OBJ_NAME, obj->key.name) ||
	    nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->ops->type->type)) ||
	    nla_put_be64(skb, NFTA_OBJ_HANDLE, cpu_to_be64(obj->handle),
			 NFTA_OBJ_PAD))
		goto nla_put_failure;

	if (nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->ops->type->type)) ||
	    nla_put_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) ||
	if (event == NFT_MSG_DELOBJ ||
	    event == NFT_MSG_DESTROYOBJ) {
		nlmsg_end(skb, nlh);
		return 0;
	}

	if (nla_put_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) ||
	    nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset))
		goto nla_put_failure;

@@ -9362,9 +9388,9 @@ static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net,
	struct nft_hook *hook;
	struct nlmsghdr *nlh;

	event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
	nlh = nfnl_msg_put(skb, portid, seq, event, flags, family,
			   NFNETLINK_V0, nft_base_seq(net));
	nlh = nfnl_msg_put(skb, portid, seq,
			   nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event),
			   flags, family, NFNETLINK_V0, nft_base_seq(net));
	if (!nlh)
		goto nla_put_failure;

@@ -9374,6 +9400,13 @@ static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net,
			 NFTA_FLOWTABLE_PAD))
		goto nla_put_failure;

	if (!hook_list &&
	    (event == NFT_MSG_DELFLOWTABLE ||
	     event == NFT_MSG_DESTROYFLOWTABLE)) {
		nlmsg_end(skb, nlh);
		return 0;
	}

	if (nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use)) ||
	    nla_put_be32(skb, NFTA_FLOWTABLE_FLAGS, htonl(flowtable->data.flags)))
		goto nla_put_failure;