Commit 28339b21 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso

netfilter: nf_tables: do not send complete notification of deletions

In most cases, table, name and handle is sufficient for userspace to
identify an object that has been deleted. Skipping unneeded fields in
the netlink attributes in the message saves bandwidth (ie. less chances
of hitting ENOBUFS).

Rules are an exception: the existing userspace monitor code relies on
the rule definition. This exception can be removed by implementing a
rule cache in userspace, this is already supported by the tracing
infrastructure.

Regarding flowtables, incremental deletion of devices is possible.
Skipping a full notification allows userspace to differentiate between
flowtable removal and incremental removal of devices.
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent c3c060ad
...@@ -819,12 +819,20 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net, ...@@ -819,12 +819,20 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
goto nla_put_failure; goto nla_put_failure;
if (nla_put_string(skb, NFTA_TABLE_NAME, table->name) || if (nla_put_string(skb, NFTA_TABLE_NAME, table->name) ||
nla_put_be32(skb, NFTA_TABLE_FLAGS,
htonl(table->flags & NFT_TABLE_F_MASK)) ||
nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use)) || nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use)) ||
nla_put_be64(skb, NFTA_TABLE_HANDLE, cpu_to_be64(table->handle), nla_put_be64(skb, NFTA_TABLE_HANDLE, cpu_to_be64(table->handle),
NFTA_TABLE_PAD)) NFTA_TABLE_PAD))
goto nla_put_failure; goto nla_put_failure;
if (event == NFT_MSG_DELTABLE) {
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;
if (nft_table_has_owner(table) && if (nft_table_has_owner(table) &&
nla_put_be32(skb, NFTA_TABLE_OWNER, htonl(table->nlpid))) nla_put_be32(skb, NFTA_TABLE_OWNER, htonl(table->nlpid)))
goto nla_put_failure; goto nla_put_failure;
...@@ -1626,13 +1634,16 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net, ...@@ -1626,13 +1634,16 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net,
if (!nlh) if (!nlh)
goto nla_put_failure; goto nla_put_failure;
if (nla_put_string(skb, NFTA_CHAIN_TABLE, table->name)) if (nla_put_string(skb, NFTA_CHAIN_TABLE, table->name) ||
goto nla_put_failure; nla_put_string(skb, NFTA_CHAIN_NAME, chain->name) ||
if (nla_put_be64(skb, NFTA_CHAIN_HANDLE, cpu_to_be64(chain->handle), nla_put_be64(skb, NFTA_CHAIN_HANDLE, cpu_to_be64(chain->handle),
NFTA_CHAIN_PAD)) NFTA_CHAIN_PAD))
goto nla_put_failure; goto nla_put_failure;
if (nla_put_string(skb, NFTA_CHAIN_NAME, chain->name))
goto nla_put_failure; if (event == NFT_MSG_DELCHAIN) {
nlmsg_end(skb, nlh);
return 0;
}
if (nft_is_base_chain(chain)) { if (nft_is_base_chain(chain)) {
const struct nft_base_chain *basechain = nft_base_chain(chain); const struct nft_base_chain *basechain = nft_base_chain(chain);
...@@ -4150,6 +4161,12 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx, ...@@ -4150,6 +4161,12 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
if (nla_put_be64(skb, NFTA_SET_HANDLE, cpu_to_be64(set->handle), if (nla_put_be64(skb, NFTA_SET_HANDLE, cpu_to_be64(set->handle),
NFTA_SET_PAD)) NFTA_SET_PAD))
goto nla_put_failure; goto nla_put_failure;
if (event == NFT_MSG_DELSET) {
nlmsg_end(skb, nlh);
return 0;
}
if (set->flags != 0) if (set->flags != 0)
if (nla_put_be32(skb, NFTA_SET_FLAGS, htonl(set->flags))) if (nla_put_be32(skb, NFTA_SET_FLAGS, htonl(set->flags)))
goto nla_put_failure; goto nla_put_failure;
...@@ -7154,13 +7171,20 @@ static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net, ...@@ -7154,13 +7171,20 @@ static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net,
if (nla_put_string(skb, NFTA_OBJ_TABLE, table->name) || if (nla_put_string(skb, NFTA_OBJ_TABLE, table->name) ||
nla_put_string(skb, NFTA_OBJ_NAME, obj->key.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_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) ||
nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset) ||
nla_put_be64(skb, NFTA_OBJ_HANDLE, cpu_to_be64(obj->handle), nla_put_be64(skb, NFTA_OBJ_HANDLE, cpu_to_be64(obj->handle),
NFTA_OBJ_PAD)) NFTA_OBJ_PAD))
goto nla_put_failure; goto nla_put_failure;
if (event == NFT_MSG_DELOBJ) {
nlmsg_end(skb, nlh);
return 0;
}
if (nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->ops->type->type)) ||
nla_put_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) ||
nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset))
goto nla_put_failure;
if (obj->udata && if (obj->udata &&
nla_put(skb, NFTA_OBJ_USERDATA, obj->udlen, obj->udata)) nla_put(skb, NFTA_OBJ_USERDATA, obj->udlen, obj->udata))
goto nla_put_failure; goto nla_put_failure;
...@@ -8089,9 +8113,16 @@ static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net, ...@@ -8089,9 +8113,16 @@ static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net,
if (nla_put_string(skb, NFTA_FLOWTABLE_TABLE, flowtable->table->name) || if (nla_put_string(skb, NFTA_FLOWTABLE_TABLE, flowtable->table->name) ||
nla_put_string(skb, NFTA_FLOWTABLE_NAME, flowtable->name) || nla_put_string(skb, NFTA_FLOWTABLE_NAME, flowtable->name) ||
nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use)) ||
nla_put_be64(skb, NFTA_FLOWTABLE_HANDLE, cpu_to_be64(flowtable->handle), nla_put_be64(skb, NFTA_FLOWTABLE_HANDLE, cpu_to_be64(flowtable->handle),
NFTA_FLOWTABLE_PAD) || NFTA_FLOWTABLE_PAD))
goto nla_put_failure;
if (event == NFT_MSG_DELFLOWTABLE && !hook_list) {
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))) nla_put_be32(skb, NFTA_FLOWTABLE_FLAGS, htonl(flowtable->data.flags)))
goto nla_put_failure; goto nla_put_failure;
...@@ -8106,6 +8137,9 @@ static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net, ...@@ -8106,6 +8137,9 @@ static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net,
if (!nest_devs) if (!nest_devs)
goto nla_put_failure; goto nla_put_failure;
if (!hook_list)
hook_list = &flowtable->hook_list;
list_for_each_entry_rcu(hook, hook_list, list) { list_for_each_entry_rcu(hook, hook_list, list) {
if (nla_put_string(skb, NFTA_DEVICE_NAME, hook->ops.dev->name)) if (nla_put_string(skb, NFTA_DEVICE_NAME, hook->ops.dev->name))
goto nla_put_failure; goto nla_put_failure;
...@@ -8162,8 +8196,7 @@ static int nf_tables_dump_flowtable(struct sk_buff *skb, ...@@ -8162,8 +8196,7 @@ static int nf_tables_dump_flowtable(struct sk_buff *skb,
NFT_MSG_NEWFLOWTABLE, NFT_MSG_NEWFLOWTABLE,
NLM_F_MULTI | NLM_F_APPEND, NLM_F_MULTI | NLM_F_APPEND,
table->family, table->family,
flowtable, flowtable, NULL) < 0)
&flowtable->hook_list) < 0)
goto done; goto done;
nl_dump_check_consistent(cb, nlmsg_hdr(skb)); nl_dump_check_consistent(cb, nlmsg_hdr(skb));
...@@ -8258,7 +8291,7 @@ static int nf_tables_getflowtable(struct sk_buff *skb, ...@@ -8258,7 +8291,7 @@ static int nf_tables_getflowtable(struct sk_buff *skb,
err = nf_tables_fill_flowtable_info(skb2, net, NETLINK_CB(skb).portid, err = nf_tables_fill_flowtable_info(skb2, net, NETLINK_CB(skb).portid,
info->nlh->nlmsg_seq, info->nlh->nlmsg_seq,
NFT_MSG_NEWFLOWTABLE, 0, family, NFT_MSG_NEWFLOWTABLE, 0, family,
flowtable, &flowtable->hook_list); flowtable, NULL);
if (err < 0) if (err < 0)
goto err_fill_flowtable_info; goto err_fill_flowtable_info;
...@@ -8271,8 +8304,7 @@ static int nf_tables_getflowtable(struct sk_buff *skb, ...@@ -8271,8 +8304,7 @@ static int nf_tables_getflowtable(struct sk_buff *skb,
static void nf_tables_flowtable_notify(struct nft_ctx *ctx, static void nf_tables_flowtable_notify(struct nft_ctx *ctx,
struct nft_flowtable *flowtable, struct nft_flowtable *flowtable,
struct list_head *hook_list, struct list_head *hook_list, int event)
int event)
{ {
struct nftables_pernet *nft_net = nft_pernet(ctx->net); struct nftables_pernet *nft_net = nft_pernet(ctx->net);
struct sk_buff *skb; struct sk_buff *skb;
...@@ -9333,7 +9365,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) ...@@ -9333,7 +9365,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
nft_clear(net, nft_trans_flowtable(trans)); nft_clear(net, nft_trans_flowtable(trans));
nf_tables_flowtable_notify(&trans->ctx, nf_tables_flowtable_notify(&trans->ctx,
nft_trans_flowtable(trans), nft_trans_flowtable(trans),
&nft_trans_flowtable(trans)->hook_list, NULL,
NFT_MSG_NEWFLOWTABLE); NFT_MSG_NEWFLOWTABLE);
} }
nft_trans_destroy(trans); nft_trans_destroy(trans);
...@@ -9351,7 +9383,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) ...@@ -9351,7 +9383,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
list_del_rcu(&nft_trans_flowtable(trans)->list); list_del_rcu(&nft_trans_flowtable(trans)->list);
nf_tables_flowtable_notify(&trans->ctx, nf_tables_flowtable_notify(&trans->ctx,
nft_trans_flowtable(trans), nft_trans_flowtable(trans),
&nft_trans_flowtable(trans)->hook_list, NULL,
trans->msg_type); trans->msg_type);
nft_unregister_flowtable_net_hooks(net, nft_unregister_flowtable_net_hooks(net,
&nft_trans_flowtable(trans)->hook_list); &nft_trans_flowtable(trans)->hook_list);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment