Skip to content

Commit

Permalink
netfilter: nf_tables: add NFTA_RULE_ID attribute
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
ummakynes committed Feb 12, 2017
1 parent 74e8bcd commit 1a94e38
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 0 deletions.
3 changes: 3 additions & 0 deletions include/net/netfilter/nf_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -1202,10 +1202,13 @@ struct nft_trans {

struct nft_trans_rule {
struct nft_rule *rule;
u32 rule_id;
};

#define nft_trans_rule(trans) \
(((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_set *set;
Expand Down
2 changes: 2 additions & 0 deletions include/uapi/linux/netfilter/nf_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ enum nft_chain_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_USERDATA: user data (NLA_BINARY, NFT_USERDATA_MAXLEN)
* @NFTA_RULE_ID: uniquely identifies a rule in a transaction (NLA_U32)
*/
enum nft_rule_attributes {
NFTA_RULE_UNSPEC,
Expand All @@ -218,6 +219,7 @@ enum nft_rule_attributes {
NFTA_RULE_POSITION,
NFTA_RULE_USERDATA,
NFTA_RULE_PAD,
NFTA_RULE_ID,
__NFTA_RULE_MAX
};
#define NFTA_RULE_MAX (__NFTA_RULE_MAX - 1)
Expand Down
26 changes: 26 additions & 0 deletions net/netfilter/nf_tables_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,10 @@ static struct nft_trans *nft_trans_rule_add(struct nft_ctx *ctx, int msg_type,
if (trans == 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;
list_add_tail(&trans->list, &ctx->net->nft.commit_list);

Expand Down Expand Up @@ -2293,6 +2297,22 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
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,
struct sk_buff *skb, const struct nlmsghdr *nlh,
const struct nlattr * const nla[])
Expand Down Expand Up @@ -2330,6 +2350,12 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk,
if (IS_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);
} else {
err = nft_delrule_by_chain(&ctx);
Expand Down

0 comments on commit 1a94e38

Please sign in to comment.