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 <pablo@netfilter.org>
This commit is contained in:
parent
74e8bcd21c
commit
1a94e38d25
@ -1202,10 +1202,13 @@ struct nft_trans {
|
|||||||
|
|
||||||
struct nft_trans_rule {
|
struct nft_trans_rule {
|
||||||
struct nft_rule *rule;
|
struct nft_rule *rule;
|
||||||
|
u32 rule_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define nft_trans_rule(trans) \
|
#define nft_trans_rule(trans) \
|
||||||
(((struct nft_trans_rule *)trans->data)->rule)
|
(((struct nft_trans_rule *)trans->data)->rule)
|
||||||
|
#define nft_trans_rule_id(trans) \
|
||||||
|
(((struct nft_trans_rule *)trans->data)->rule_id)
|
||||||
|
|
||||||
struct nft_trans_set {
|
struct nft_trans_set {
|
||||||
struct nft_set *set;
|
struct nft_set *set;
|
||||||
|
@ -207,6 +207,7 @@ enum nft_chain_attributes {
|
|||||||
* @NFTA_RULE_COMPAT: compatibility specifications of the rule (NLA_NESTED: nft_rule_compat_attributes)
|
* @NFTA_RULE_COMPAT: compatibility specifications of the rule (NLA_NESTED: nft_rule_compat_attributes)
|
||||||
* @NFTA_RULE_POSITION: numeric handle of the previous rule (NLA_U64)
|
* @NFTA_RULE_POSITION: numeric handle of the previous rule (NLA_U64)
|
||||||
* @NFTA_RULE_USERDATA: user data (NLA_BINARY, NFT_USERDATA_MAXLEN)
|
* @NFTA_RULE_USERDATA: user data (NLA_BINARY, NFT_USERDATA_MAXLEN)
|
||||||
|
* @NFTA_RULE_ID: uniquely identifies a rule in a transaction (NLA_U32)
|
||||||
*/
|
*/
|
||||||
enum nft_rule_attributes {
|
enum nft_rule_attributes {
|
||||||
NFTA_RULE_UNSPEC,
|
NFTA_RULE_UNSPEC,
|
||||||
@ -218,6 +219,7 @@ enum nft_rule_attributes {
|
|||||||
NFTA_RULE_POSITION,
|
NFTA_RULE_POSITION,
|
||||||
NFTA_RULE_USERDATA,
|
NFTA_RULE_USERDATA,
|
||||||
NFTA_RULE_PAD,
|
NFTA_RULE_PAD,
|
||||||
|
NFTA_RULE_ID,
|
||||||
__NFTA_RULE_MAX
|
__NFTA_RULE_MAX
|
||||||
};
|
};
|
||||||
#define NFTA_RULE_MAX (__NFTA_RULE_MAX - 1)
|
#define NFTA_RULE_MAX (__NFTA_RULE_MAX - 1)
|
||||||
|
@ -240,6 +240,10 @@ static struct nft_trans *nft_trans_rule_add(struct nft_ctx *ctx, int msg_type,
|
|||||||
if (trans == NULL)
|
if (trans == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (msg_type == NFT_MSG_NEWRULE && ctx->nla[NFTA_RULE_ID] != NULL) {
|
||||||
|
nft_trans_rule_id(trans) =
|
||||||
|
ntohl(nla_get_be32(ctx->nla[NFTA_RULE_ID]));
|
||||||
|
}
|
||||||
nft_trans_rule(trans) = rule;
|
nft_trans_rule(trans) = rule;
|
||||||
list_add_tail(&trans->list, &ctx->net->nft.commit_list);
|
list_add_tail(&trans->list, &ctx->net->nft.commit_list);
|
||||||
|
|
||||||
@ -2293,6 +2297,22 @@ err1:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct nft_rule *nft_rule_lookup_byid(const struct net *net,
|
||||||
|
const struct nlattr *nla)
|
||||||
|
{
|
||||||
|
u32 id = ntohl(nla_get_be32(nla));
|
||||||
|
struct nft_trans *trans;
|
||||||
|
|
||||||
|
list_for_each_entry(trans, &net->nft.commit_list, list) {
|
||||||
|
struct nft_rule *rule = nft_trans_rule(trans);
|
||||||
|
|
||||||
|
if (trans->msg_type == NFT_MSG_NEWRULE &&
|
||||||
|
id == nft_trans_rule_id(trans))
|
||||||
|
return rule;
|
||||||
|
}
|
||||||
|
return ERR_PTR(-ENOENT);
|
||||||
|
}
|
||||||
|
|
||||||
static int nf_tables_delrule(struct net *net, struct sock *nlsk,
|
static int nf_tables_delrule(struct net *net, struct sock *nlsk,
|
||||||
struct sk_buff *skb, const struct nlmsghdr *nlh,
|
struct sk_buff *skb, const struct nlmsghdr *nlh,
|
||||||
const struct nlattr * const nla[])
|
const struct nlattr * const nla[])
|
||||||
@ -2330,6 +2350,12 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk,
|
|||||||
if (IS_ERR(rule))
|
if (IS_ERR(rule))
|
||||||
return PTR_ERR(rule);
|
return PTR_ERR(rule);
|
||||||
|
|
||||||
|
err = nft_delrule(&ctx, rule);
|
||||||
|
} else if (nla[NFTA_RULE_ID]) {
|
||||||
|
rule = nft_rule_lookup_byid(net, nla[NFTA_RULE_ID]);
|
||||||
|
if (IS_ERR(rule))
|
||||||
|
return PTR_ERR(rule);
|
||||||
|
|
||||||
err = nft_delrule(&ctx, rule);
|
err = nft_delrule(&ctx, rule);
|
||||||
} else {
|
} else {
|
||||||
err = nft_delrule_by_chain(&ctx);
|
err = nft_delrule_by_chain(&ctx);
|
||||||
|
Loading…
Reference in New Issue
Block a user