Skip to content

Commit 1a94e38

Browse files
committed
netfilter: nf_tables: add NFTA_RULE_ID attribute
This new attribute allows us to uniquely identify a rule in transaction. Robots may trigger an insertion followed by deletion in a batch, in that scenario we still don't have a public rule handle that we can use to delete the rule. This is similar to the NFTA_SET_ID attribute that allows us to refer to an anonymous set from a batch. Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 74e8bcd commit 1a94e38

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

include/net/netfilter/nf_tables.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,10 +1202,13 @@ struct nft_trans {
12021202

12031203
struct nft_trans_rule {
12041204
struct nft_rule *rule;
1205+
u32 rule_id;
12051206
};
12061207

12071208
#define nft_trans_rule(trans) \
12081209
(((struct nft_trans_rule *)trans->data)->rule)
1210+
#define nft_trans_rule_id(trans) \
1211+
(((struct nft_trans_rule *)trans->data)->rule_id)
12091212

12101213
struct nft_trans_set {
12111214
struct nft_set *set;

include/uapi/linux/netfilter/nf_tables.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ enum nft_chain_attributes {
207207
* @NFTA_RULE_COMPAT: compatibility specifications of the rule (NLA_NESTED: nft_rule_compat_attributes)
208208
* @NFTA_RULE_POSITION: numeric handle of the previous rule (NLA_U64)
209209
* @NFTA_RULE_USERDATA: user data (NLA_BINARY, NFT_USERDATA_MAXLEN)
210+
* @NFTA_RULE_ID: uniquely identifies a rule in a transaction (NLA_U32)
210211
*/
211212
enum nft_rule_attributes {
212213
NFTA_RULE_UNSPEC,
@@ -218,6 +219,7 @@ enum nft_rule_attributes {
218219
NFTA_RULE_POSITION,
219220
NFTA_RULE_USERDATA,
220221
NFTA_RULE_PAD,
222+
NFTA_RULE_ID,
221223
__NFTA_RULE_MAX
222224
};
223225
#define NFTA_RULE_MAX (__NFTA_RULE_MAX - 1)

net/netfilter/nf_tables_api.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,10 @@ static struct nft_trans *nft_trans_rule_add(struct nft_ctx *ctx, int msg_type,
240240
if (trans == NULL)
241241
return NULL;
242242

243+
if (msg_type == NFT_MSG_NEWRULE && ctx->nla[NFTA_RULE_ID] != NULL) {
244+
nft_trans_rule_id(trans) =
245+
ntohl(nla_get_be32(ctx->nla[NFTA_RULE_ID]));
246+
}
243247
nft_trans_rule(trans) = rule;
244248
list_add_tail(&trans->list, &ctx->net->nft.commit_list);
245249

@@ -2293,6 +2297,22 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
22932297
return err;
22942298
}
22952299

2300+
static struct nft_rule *nft_rule_lookup_byid(const struct net *net,
2301+
const struct nlattr *nla)
2302+
{
2303+
u32 id = ntohl(nla_get_be32(nla));
2304+
struct nft_trans *trans;
2305+
2306+
list_for_each_entry(trans, &net->nft.commit_list, list) {
2307+
struct nft_rule *rule = nft_trans_rule(trans);
2308+
2309+
if (trans->msg_type == NFT_MSG_NEWRULE &&
2310+
id == nft_trans_rule_id(trans))
2311+
return rule;
2312+
}
2313+
return ERR_PTR(-ENOENT);
2314+
}
2315+
22962316
static int nf_tables_delrule(struct net *net, struct sock *nlsk,
22972317
struct sk_buff *skb, const struct nlmsghdr *nlh,
22982318
const struct nlattr * const nla[])
@@ -2330,6 +2350,12 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk,
23302350
if (IS_ERR(rule))
23312351
return PTR_ERR(rule);
23322352

2353+
err = nft_delrule(&ctx, rule);
2354+
} else if (nla[NFTA_RULE_ID]) {
2355+
rule = nft_rule_lookup_byid(net, nla[NFTA_RULE_ID]);
2356+
if (IS_ERR(rule))
2357+
return PTR_ERR(rule);
2358+
23332359
err = nft_delrule(&ctx, rule);
23342360
} else {
23352361
err = nft_delrule_by_chain(&ctx);

0 commit comments

Comments
 (0)