Skip to content

Commit

Permalink
netfilter: nf_tables: add generation mask to tables
Browse files Browse the repository at this point in the history
This patch addresses two problems:

1) The netlink dump is inconsistent when interfering with an ongoing
   transaction update for several reasons:

1.a) We don't honor the internal NFT_TABLE_INACTIVE flag, and we should
     be skipping these inactive objects in the dump.

1.b) We perform speculative deletion during the preparation phase, that
     may result in skipping active objects.

1.c) The listing order changes, which generates noise when tracking
     incremental ruleset update via tools like git or our own
     testsuite.

2) We don't allow to add and to update the object in the same batch,
   eg. add table x; add table x { flags dormant\; }.

In order to resolve these problems:

1) If the user requests a deletion, the object becomes inactive in the
   next generation. Then, ignore objects that scheduled to be deleted
   from the lookup path, as they will be effectively removed in the
   next generation.

2) From the get/dump path, if the object is not currently active, we
   skip it.

3) Support 'add X -> update X' sequence from a transaction.

After this update, we obtain a consistent list as long as we stay
in the same generation. The userspace side can detect interferences
through the generation counter so it can restart the dumping.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  • Loading branch information
Pablo Neira Ayuso committed Jun 24, 2016
1 parent 889f7ee commit f2a6d76
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 45 deletions.
6 changes: 5 additions & 1 deletion include/net/netfilter/nf_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,7 @@ unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv);
* @hgenerator: handle generator state
* @use: number of chain references to this table
* @flags: table flag (see enum nft_table_flags)
* @genmask: generation mask
* @name: name of the table
*/
struct nft_table {
Expand All @@ -846,7 +847,8 @@ struct nft_table {
struct list_head sets;
u64 hgenerator;
u32 use;
u16 flags;
u16 flags:14,
genmask:2;
char name[NFT_TABLE_MAXNAMELEN];
};

Expand Down Expand Up @@ -992,6 +994,8 @@ static inline u8 nft_genmask_cur(const struct net *net)
/* After committing the ruleset, clear the stale generation bit. */
#define nft_clear(__net, __obj) \
(__obj)->genmask &= ~nft_genmask_next(__net)
#define nft_active_genmask(__obj, __genmask) \
!((__obj)->genmask & __genmask)

/*
* Set element transaction helpers
Expand Down
Loading

0 comments on commit f2a6d76

Please sign in to comment.