@@ -1056,6 +1056,9 @@ static int nft_flush_table(struct nft_ctx *ctx)
1056
1056
if (!nft_is_active_next (ctx -> net , chain ))
1057
1057
continue ;
1058
1058
1059
+ if (nft_chain_is_bound (chain ))
1060
+ continue ;
1061
+
1059
1062
ctx -> chain = chain ;
1060
1063
1061
1064
err = nft_delrule_by_chain (ctx );
@@ -1098,6 +1101,9 @@ static int nft_flush_table(struct nft_ctx *ctx)
1098
1101
if (!nft_is_active_next (ctx -> net , chain ))
1099
1102
continue ;
1100
1103
1104
+ if (nft_chain_is_bound (chain ))
1105
+ continue ;
1106
+
1101
1107
ctx -> chain = chain ;
1102
1108
1103
1109
err = nft_delchain (ctx );
@@ -1413,13 +1419,12 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net,
1413
1419
lockdep_commit_lock_is_held (net ));
1414
1420
if (nft_dump_stats (skb , stats ))
1415
1421
goto nla_put_failure ;
1416
-
1417
- if ((chain -> flags & NFT_CHAIN_HW_OFFLOAD ) &&
1418
- nla_put_be32 (skb , NFTA_CHAIN_FLAGS ,
1419
- htonl (NFT_CHAIN_HW_OFFLOAD )))
1420
- goto nla_put_failure ;
1421
1422
}
1422
1423
1424
+ if (chain -> flags &&
1425
+ nla_put_be32 (skb , NFTA_CHAIN_FLAGS , htonl (chain -> flags )))
1426
+ goto nla_put_failure ;
1427
+
1423
1428
if (nla_put_be32 (skb , NFTA_CHAIN_USE , htonl (chain -> use )))
1424
1429
goto nla_put_failure ;
1425
1430
@@ -1621,7 +1626,7 @@ static void nf_tables_chain_free_chain_rules(struct nft_chain *chain)
1621
1626
kvfree (chain -> rules_next );
1622
1627
}
1623
1628
1624
- static void nf_tables_chain_destroy (struct nft_ctx * ctx )
1629
+ void nf_tables_chain_destroy (struct nft_ctx * ctx )
1625
1630
{
1626
1631
struct nft_chain * chain = ctx -> chain ;
1627
1632
struct nft_hook * hook , * next ;
@@ -1928,6 +1933,8 @@ static int nft_chain_add(struct nft_table *table, struct nft_chain *chain)
1928
1933
return 0 ;
1929
1934
}
1930
1935
1936
+ static u64 chain_id ;
1937
+
1931
1938
static int nf_tables_addchain (struct nft_ctx * ctx , u8 family , u8 genmask ,
1932
1939
u8 policy , u32 flags )
1933
1940
{
@@ -1936,6 +1943,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
1936
1943
struct nft_base_chain * basechain ;
1937
1944
struct nft_stats __percpu * stats ;
1938
1945
struct net * net = ctx -> net ;
1946
+ char name [NFT_NAME_MAXLEN ];
1939
1947
struct nft_trans * trans ;
1940
1948
struct nft_chain * chain ;
1941
1949
struct nft_rule * * rules ;
@@ -1947,6 +1955,9 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
1947
1955
if (nla [NFTA_CHAIN_HOOK ]) {
1948
1956
struct nft_chain_hook hook ;
1949
1957
1958
+ if (flags & NFT_CHAIN_BINDING )
1959
+ return - EOPNOTSUPP ;
1960
+
1950
1961
err = nft_chain_parse_hook (net , nla , & hook , family , true);
1951
1962
if (err < 0 )
1952
1963
return err ;
@@ -1976,16 +1987,33 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
1976
1987
return err ;
1977
1988
}
1978
1989
} else {
1990
+ if (flags & NFT_CHAIN_BASE )
1991
+ return - EINVAL ;
1992
+ if (flags & NFT_CHAIN_HW_OFFLOAD )
1993
+ return - EOPNOTSUPP ;
1994
+
1979
1995
chain = kzalloc (sizeof (* chain ), GFP_KERNEL );
1980
1996
if (chain == NULL )
1981
1997
return - ENOMEM ;
1998
+
1999
+ chain -> flags = flags ;
1982
2000
}
1983
2001
ctx -> chain = chain ;
1984
2002
1985
2003
INIT_LIST_HEAD (& chain -> rules );
1986
2004
chain -> handle = nf_tables_alloc_handle (table );
1987
2005
chain -> table = table ;
1988
- chain -> name = nla_strdup (nla [NFTA_CHAIN_NAME ], GFP_KERNEL );
2006
+
2007
+ if (nla [NFTA_CHAIN_NAME ]) {
2008
+ chain -> name = nla_strdup (nla [NFTA_CHAIN_NAME ], GFP_KERNEL );
2009
+ } else {
2010
+ if (!(flags & NFT_CHAIN_BINDING ))
2011
+ return - EINVAL ;
2012
+
2013
+ snprintf (name , sizeof (name ), "__chain%llu" , ++ chain_id );
2014
+ chain -> name = kstrdup (name , GFP_KERNEL );
2015
+ }
2016
+
1989
2017
if (!chain -> name ) {
1990
2018
err = - ENOMEM ;
1991
2019
goto err1 ;
@@ -2976,8 +3004,7 @@ static void nf_tables_rule_destroy(const struct nft_ctx *ctx,
2976
3004
kfree (rule );
2977
3005
}
2978
3006
2979
- static void nf_tables_rule_release (const struct nft_ctx * ctx ,
2980
- struct nft_rule * rule )
3007
+ void nf_tables_rule_release (const struct nft_ctx * ctx , struct nft_rule * rule )
2981
3008
{
2982
3009
nft_rule_expr_deactivate (ctx , rule , NFT_TRANS_RELEASE );
2983
3010
nf_tables_rule_destroy (ctx , rule );
@@ -3075,6 +3102,9 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
3075
3102
NL_SET_BAD_ATTR (extack , nla [NFTA_RULE_CHAIN ]);
3076
3103
return PTR_ERR (chain );
3077
3104
}
3105
+ if (nft_chain_is_bound (chain ))
3106
+ return - EOPNOTSUPP ;
3107
+
3078
3108
} else if (nla [NFTA_RULE_CHAIN_ID ]) {
3079
3109
chain = nft_chain_lookup_byid (net , nla [NFTA_RULE_CHAIN_ID ]);
3080
3110
if (IS_ERR (chain )) {
@@ -3294,6 +3324,8 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk,
3294
3324
NL_SET_BAD_ATTR (extack , nla [NFTA_RULE_CHAIN ]);
3295
3325
return PTR_ERR (chain );
3296
3326
}
3327
+ if (nft_chain_is_bound (chain ))
3328
+ return - EOPNOTSUPP ;
3297
3329
}
3298
3330
3299
3331
nft_ctx_init (& ctx , net , skb , nlh , family , table , chain , nla );
@@ -5330,11 +5362,24 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
5330
5362
*/
5331
5363
void nft_data_hold (const struct nft_data * data , enum nft_data_types type )
5332
5364
{
5365
+ struct nft_chain * chain ;
5366
+ struct nft_rule * rule ;
5367
+
5333
5368
if (type == NFT_DATA_VERDICT ) {
5334
5369
switch (data -> verdict .code ) {
5335
5370
case NFT_JUMP :
5336
5371
case NFT_GOTO :
5337
- data -> verdict .chain -> use ++ ;
5372
+ chain = data -> verdict .chain ;
5373
+ chain -> use ++ ;
5374
+
5375
+ if (!nft_chain_is_bound (chain ))
5376
+ break ;
5377
+
5378
+ chain -> table -> use ++ ;
5379
+ list_for_each_entry (rule , & chain -> rules , list )
5380
+ chain -> use ++ ;
5381
+
5382
+ nft_chain_add (chain -> table , chain );
5338
5383
break ;
5339
5384
}
5340
5385
}
@@ -7474,7 +7519,7 @@ static void nft_obj_del(struct nft_object *obj)
7474
7519
list_del_rcu (& obj -> list );
7475
7520
}
7476
7521
7477
- static void nft_chain_del (struct nft_chain * chain )
7522
+ void nft_chain_del (struct nft_chain * chain )
7478
7523
{
7479
7524
struct nft_table * table = chain -> table ;
7480
7525
@@ -7825,6 +7870,10 @@ static int __nf_tables_abort(struct net *net, bool autoload)
7825
7870
kfree (nft_trans_chain_name (trans ));
7826
7871
nft_trans_destroy (trans );
7827
7872
} else {
7873
+ if (nft_chain_is_bound (trans -> ctx .chain )) {
7874
+ nft_trans_destroy (trans );
7875
+ break ;
7876
+ }
7828
7877
trans -> ctx .table -> use -- ;
7829
7878
nft_chain_del (trans -> ctx .chain );
7830
7879
nf_tables_unregister_hook (trans -> ctx .net ,
@@ -8321,10 +8370,23 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
8321
8370
8322
8371
static void nft_verdict_uninit (const struct nft_data * data )
8323
8372
{
8373
+ struct nft_chain * chain ;
8374
+ struct nft_rule * rule ;
8375
+
8324
8376
switch (data -> verdict .code ) {
8325
8377
case NFT_JUMP :
8326
8378
case NFT_GOTO :
8327
- data -> verdict .chain -> use -- ;
8379
+ chain = data -> verdict .chain ;
8380
+ chain -> use -- ;
8381
+
8382
+ if (!nft_chain_is_bound (chain ))
8383
+ break ;
8384
+
8385
+ chain -> table -> use -- ;
8386
+ list_for_each_entry (rule , & chain -> rules , list )
8387
+ chain -> use -- ;
8388
+
8389
+ nft_chain_del (chain );
8328
8390
break ;
8329
8391
}
8330
8392
}
0 commit comments