Skip to content

Commit 28339b2

Browse files
committed
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: Pablo Neira Ayuso <[email protected]>
1 parent c3c060a commit 28339b2

File tree

1 file changed

+51
-19
lines changed

1 file changed

+51
-19
lines changed

net/netfilter/nf_tables_api.c

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -819,12 +819,20 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
819819
goto nla_put_failure;
820820

821821
if (nla_put_string(skb, NFTA_TABLE_NAME, table->name) ||
822-
nla_put_be32(skb, NFTA_TABLE_FLAGS,
823-
htonl(table->flags & NFT_TABLE_F_MASK)) ||
824822
nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use)) ||
825823
nla_put_be64(skb, NFTA_TABLE_HANDLE, cpu_to_be64(table->handle),
826824
NFTA_TABLE_PAD))
827825
goto nla_put_failure;
826+
827+
if (event == NFT_MSG_DELTABLE) {
828+
nlmsg_end(skb, nlh);
829+
return 0;
830+
}
831+
832+
if (nla_put_be32(skb, NFTA_TABLE_FLAGS,
833+
htonl(table->flags & NFT_TABLE_F_MASK)))
834+
goto nla_put_failure;
835+
828836
if (nft_table_has_owner(table) &&
829837
nla_put_be32(skb, NFTA_TABLE_OWNER, htonl(table->nlpid)))
830838
goto nla_put_failure;
@@ -1626,13 +1634,16 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net,
16261634
if (!nlh)
16271635
goto nla_put_failure;
16281636

1629-
if (nla_put_string(skb, NFTA_CHAIN_TABLE, table->name))
1630-
goto nla_put_failure;
1631-
if (nla_put_be64(skb, NFTA_CHAIN_HANDLE, cpu_to_be64(chain->handle),
1637+
if (nla_put_string(skb, NFTA_CHAIN_TABLE, table->name) ||
1638+
nla_put_string(skb, NFTA_CHAIN_NAME, chain->name) ||
1639+
nla_put_be64(skb, NFTA_CHAIN_HANDLE, cpu_to_be64(chain->handle),
16321640
NFTA_CHAIN_PAD))
16331641
goto nla_put_failure;
1634-
if (nla_put_string(skb, NFTA_CHAIN_NAME, chain->name))
1635-
goto nla_put_failure;
1642+
1643+
if (event == NFT_MSG_DELCHAIN) {
1644+
nlmsg_end(skb, nlh);
1645+
return 0;
1646+
}
16361647

16371648
if (nft_is_base_chain(chain)) {
16381649
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,
41504161
if (nla_put_be64(skb, NFTA_SET_HANDLE, cpu_to_be64(set->handle),
41514162
NFTA_SET_PAD))
41524163
goto nla_put_failure;
4164+
4165+
if (event == NFT_MSG_DELSET) {
4166+
nlmsg_end(skb, nlh);
4167+
return 0;
4168+
}
4169+
41534170
if (set->flags != 0)
41544171
if (nla_put_be32(skb, NFTA_SET_FLAGS, htonl(set->flags)))
41554172
goto nla_put_failure;
@@ -7154,13 +7171,20 @@ static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net,
71547171

71557172
if (nla_put_string(skb, NFTA_OBJ_TABLE, table->name) ||
71567173
nla_put_string(skb, NFTA_OBJ_NAME, obj->key.name) ||
7157-
nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->ops->type->type)) ||
7158-
nla_put_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) ||
7159-
nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset) ||
71607174
nla_put_be64(skb, NFTA_OBJ_HANDLE, cpu_to_be64(obj->handle),
71617175
NFTA_OBJ_PAD))
71627176
goto nla_put_failure;
71637177

7178+
if (event == NFT_MSG_DELOBJ) {
7179+
nlmsg_end(skb, nlh);
7180+
return 0;
7181+
}
7182+
7183+
if (nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->ops->type->type)) ||
7184+
nla_put_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) ||
7185+
nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset))
7186+
goto nla_put_failure;
7187+
71647188
if (obj->udata &&
71657189
nla_put(skb, NFTA_OBJ_USERDATA, obj->udlen, obj->udata))
71667190
goto nla_put_failure;
@@ -8089,9 +8113,16 @@ static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net,
80898113

80908114
if (nla_put_string(skb, NFTA_FLOWTABLE_TABLE, flowtable->table->name) ||
80918115
nla_put_string(skb, NFTA_FLOWTABLE_NAME, flowtable->name) ||
8092-
nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use)) ||
80938116
nla_put_be64(skb, NFTA_FLOWTABLE_HANDLE, cpu_to_be64(flowtable->handle),
8094-
NFTA_FLOWTABLE_PAD) ||
8117+
NFTA_FLOWTABLE_PAD))
8118+
goto nla_put_failure;
8119+
8120+
if (event == NFT_MSG_DELFLOWTABLE && !hook_list) {
8121+
nlmsg_end(skb, nlh);
8122+
return 0;
8123+
}
8124+
8125+
if (nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use)) ||
80958126
nla_put_be32(skb, NFTA_FLOWTABLE_FLAGS, htonl(flowtable->data.flags)))
80968127
goto nla_put_failure;
80978128

@@ -8106,6 +8137,9 @@ static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net,
81068137
if (!nest_devs)
81078138
goto nla_put_failure;
81088139

8140+
if (!hook_list)
8141+
hook_list = &flowtable->hook_list;
8142+
81098143
list_for_each_entry_rcu(hook, hook_list, list) {
81108144
if (nla_put_string(skb, NFTA_DEVICE_NAME, hook->ops.dev->name))
81118145
goto nla_put_failure;
@@ -8162,8 +8196,7 @@ static int nf_tables_dump_flowtable(struct sk_buff *skb,
81628196
NFT_MSG_NEWFLOWTABLE,
81638197
NLM_F_MULTI | NLM_F_APPEND,
81648198
table->family,
8165-
flowtable,
8166-
&flowtable->hook_list) < 0)
8199+
flowtable, NULL) < 0)
81678200
goto done;
81688201

81698202
nl_dump_check_consistent(cb, nlmsg_hdr(skb));
@@ -8258,7 +8291,7 @@ static int nf_tables_getflowtable(struct sk_buff *skb,
82588291
err = nf_tables_fill_flowtable_info(skb2, net, NETLINK_CB(skb).portid,
82598292
info->nlh->nlmsg_seq,
82608293
NFT_MSG_NEWFLOWTABLE, 0, family,
8261-
flowtable, &flowtable->hook_list);
8294+
flowtable, NULL);
82628295
if (err < 0)
82638296
goto err_fill_flowtable_info;
82648297

@@ -8271,8 +8304,7 @@ static int nf_tables_getflowtable(struct sk_buff *skb,
82718304

82728305
static void nf_tables_flowtable_notify(struct nft_ctx *ctx,
82738306
struct nft_flowtable *flowtable,
8274-
struct list_head *hook_list,
8275-
int event)
8307+
struct list_head *hook_list, int event)
82768308
{
82778309
struct nftables_pernet *nft_net = nft_pernet(ctx->net);
82788310
struct sk_buff *skb;
@@ -9333,7 +9365,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
93339365
nft_clear(net, nft_trans_flowtable(trans));
93349366
nf_tables_flowtable_notify(&trans->ctx,
93359367
nft_trans_flowtable(trans),
9336-
&nft_trans_flowtable(trans)->hook_list,
9368+
NULL,
93379369
NFT_MSG_NEWFLOWTABLE);
93389370
}
93399371
nft_trans_destroy(trans);
@@ -9351,7 +9383,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
93519383
list_del_rcu(&nft_trans_flowtable(trans)->list);
93529384
nf_tables_flowtable_notify(&trans->ctx,
93539385
nft_trans_flowtable(trans),
9354-
&nft_trans_flowtable(trans)->hook_list,
9386+
NULL,
93559387
trans->msg_type);
93569388
nft_unregister_flowtable_net_hooks(net,
93579389
&nft_trans_flowtable(trans)->hook_list);

0 commit comments

Comments
 (0)