Skip to content

Commit d152159

Browse files
Florian Westphalummakynes
authored andcommitted
netfilter: nf_tables: prepare nft_object for lookups via hashtable
Add a 'key' structure for object, so we can look them up by name + table combination (the name can be the same in each table). Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
1 parent 435f3f2 commit d152159

File tree

4 files changed

+32
-18
lines changed

4 files changed

+32
-18
lines changed

include/net/netfilter/nf_tables.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,12 +1011,22 @@ void nft_unregister_expr(struct nft_expr_type *);
10111011
int nft_verdict_dump(struct sk_buff *skb, int type,
10121012
const struct nft_verdict *v);
10131013

1014+
/**
1015+
* struct nft_object_hash_key - key to lookup nft_object
1016+
*
1017+
* @name: name of the stateful object to look up
1018+
* @table: table the object belongs to
1019+
*/
1020+
struct nft_object_hash_key {
1021+
const char *name;
1022+
const struct nft_table *table;
1023+
};
1024+
10141025
/**
10151026
* struct nft_object - nf_tables stateful object
10161027
*
10171028
* @list: table stateful object list node
1018-
* @table: table this object belongs to
1019-
* @name: name of this stateful object
1029+
* @key: keys that identify this object
10201030
* @genmask: generation mask
10211031
* @use: number of references to this stateful object
10221032
* @handle: unique object handle
@@ -1025,8 +1035,7 @@ int nft_verdict_dump(struct sk_buff *skb, int type,
10251035
*/
10261036
struct nft_object {
10271037
struct list_head list;
1028-
char *name;
1029-
struct nft_table *table;
1038+
struct nft_object_hash_key key;
10301039
u32 genmask:2,
10311040
use:30;
10321041
u64 handle;
@@ -1047,7 +1056,7 @@ struct nft_object *nft_obj_lookup(const struct nft_table *table,
10471056
const struct nlattr *nla, u32 objtype,
10481057
u8 genmask);
10491058

1050-
void nft_obj_notify(struct net *net, struct nft_table *table,
1059+
void nft_obj_notify(struct net *net, const struct nft_table *table,
10511060
struct nft_object *obj, u32 portid, u32 seq,
10521061
int event, int family, int report, gfp_t gfp);
10531062

net/netfilter/nf_tables_api.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3853,7 +3853,7 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
38533853

38543854
if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) &&
38553855
nla_put_string(skb, NFTA_SET_ELEM_OBJREF,
3856-
(*nft_set_ext_obj(ext))->name) < 0)
3856+
(*nft_set_ext_obj(ext))->key.name) < 0)
38573857
goto nla_put_failure;
38583858

38593859
if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
@@ -4826,7 +4826,7 @@ struct nft_object *nft_obj_lookup(const struct nft_table *table,
48264826
struct nft_object *obj;
48274827

48284828
list_for_each_entry_rcu(obj, &table->objects, list) {
4829-
if (!nla_strcmp(nla, obj->name) &&
4829+
if (!nla_strcmp(nla, obj->key.name) &&
48304830
objtype == obj->ops->type->type &&
48314831
nft_active_genmask(obj, genmask))
48324832
return obj;
@@ -5014,11 +5014,11 @@ static int nf_tables_newobj(struct net *net, struct sock *nlsk,
50145014
err = PTR_ERR(obj);
50155015
goto err1;
50165016
}
5017-
obj->table = table;
5017+
obj->key.table = table;
50185018
obj->handle = nf_tables_alloc_handle(table);
50195019

5020-
obj->name = nla_strdup(nla[NFTA_OBJ_NAME], GFP_KERNEL);
5021-
if (!obj->name) {
5020+
obj->key.name = nla_strdup(nla[NFTA_OBJ_NAME], GFP_KERNEL);
5021+
if (!obj->key.name) {
50225022
err = -ENOMEM;
50235023
goto err2;
50245024
}
@@ -5031,7 +5031,7 @@ static int nf_tables_newobj(struct net *net, struct sock *nlsk,
50315031
table->use++;
50325032
return 0;
50335033
err3:
5034-
kfree(obj->name);
5034+
kfree(obj->key.name);
50355035
err2:
50365036
if (obj->ops->destroy)
50375037
obj->ops->destroy(&ctx, obj);
@@ -5060,7 +5060,7 @@ static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net,
50605060
nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
50615061

50625062
if (nla_put_string(skb, NFTA_OBJ_TABLE, table->name) ||
5063-
nla_put_string(skb, NFTA_OBJ_NAME, obj->name) ||
5063+
nla_put_string(skb, NFTA_OBJ_NAME, obj->key.name) ||
50645064
nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->ops->type->type)) ||
50655065
nla_put_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) ||
50665066
nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset) ||
@@ -5246,7 +5246,7 @@ static void nft_obj_destroy(const struct nft_ctx *ctx, struct nft_object *obj)
52465246
obj->ops->destroy(ctx, obj);
52475247

52485248
module_put(obj->ops->type->owner);
5249-
kfree(obj->name);
5249+
kfree(obj->key.name);
52505250
kfree(obj);
52515251
}
52525252

@@ -5297,7 +5297,7 @@ static int nf_tables_delobj(struct net *net, struct sock *nlsk,
52975297
return nft_delobj(&ctx, obj);
52985298
}
52995299

5300-
void nft_obj_notify(struct net *net, struct nft_table *table,
5300+
void nft_obj_notify(struct net *net, const struct nft_table *table,
53015301
struct nft_object *obj, u32 portid, u32 seq, int event,
53025302
int family, int report, gfp_t gfp)
53035303
{
@@ -6404,6 +6404,11 @@ static void nf_tables_commit_chain(struct net *net, struct nft_chain *chain)
64046404
nf_tables_commit_chain_free_rules_old(g0);
64056405
}
64066406

6407+
static void nft_obj_del(struct nft_object *obj)
6408+
{
6409+
list_del_rcu(&obj->list);
6410+
}
6411+
64076412
static void nft_chain_del(struct nft_chain *chain)
64086413
{
64096414
struct nft_table *table = chain->table;
@@ -6580,7 +6585,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
65806585
nft_trans_destroy(trans);
65816586
break;
65826587
case NFT_MSG_DELOBJ:
6583-
list_del_rcu(&nft_trans_obj(trans)->list);
6588+
nft_obj_del(nft_trans_obj(trans));
65846589
nf_tables_obj_notify(&trans->ctx, nft_trans_obj(trans),
65856590
NFT_MSG_DELOBJ);
65866591
break;
@@ -7330,7 +7335,7 @@ static void __nft_release_tables(struct net *net)
73307335
nft_set_destroy(set);
73317336
}
73327337
list_for_each_entry_safe(obj, ne, &table->objects, list) {
7333-
list_del(&obj->list);
7338+
nft_obj_del(obj);
73347339
table->use--;
73357340
nft_obj_destroy(&ctx, obj);
73367341
}

net/netfilter/nft_objref.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ static int nft_objref_dump(struct sk_buff *skb, const struct nft_expr *expr)
5353
{
5454
const struct nft_object *obj = nft_objref_priv(expr);
5555

56-
if (nla_put_string(skb, NFTA_OBJREF_IMM_NAME, obj->name) ||
56+
if (nla_put_string(skb, NFTA_OBJREF_IMM_NAME, obj->key.name) ||
5757
nla_put_be32(skb, NFTA_OBJREF_IMM_TYPE,
5858
htonl(obj->ops->type->type)))
5959
goto nla_put_failure;

net/netfilter/nft_quota.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ static void nft_quota_obj_eval(struct nft_object *obj,
6161

6262
if (overquota &&
6363
!test_and_set_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags))
64-
nft_obj_notify(nft_net(pkt), obj->table, obj, 0, 0,
64+
nft_obj_notify(nft_net(pkt), obj->key.table, obj, 0, 0,
6565
NFT_MSG_NEWOBJ, nft_pf(pkt), 0, GFP_ATOMIC);
6666
}
6767

0 commit comments

Comments
 (0)