From 58d7de0181f61570bdf9ba2b88964d5009860c39 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 23 Apr 2019 15:16:24 +0200 Subject: xtables: handle concurrent ruleset modifications We currently race when several xtables-nft-restore processes attempt to handle rules in parallel. For instance, when no rules are present at all, then iptables-nft-restore < X & iptables-nft-restore < X ... can cause rules to be restored twice. Reason is that both processes might detect 'no rules exist', so neither issues a flush operation. We can't unconditionally issue the flush, because it would cause kernel to fail with -ENOENT unless the to-be-flushed table exists. This change passes the generation id that was used to build the transaction to the kernel. In case another process changed *any* rule somewhere, the transaction will now fail with -ERESTART. We then flush the cache, re-fetch the ruleset and refresh our transaction. For example, in the above 'parallel restore' case, the iptables-restore instance that lost the race would detect that the table has been created already, and would add the needed flush. In a similar vein, in case --noflush is used, we will add the flush op for user-defined chains that were created in the mean-time. Signed-off-by: Florian Westphal Acked-by: Pablo Neira Ayuso --- iptables/nft.h | 1 + 1 file changed, 1 insertion(+) (limited to 'iptables/nft.h') diff --git a/iptables/nft.h b/iptables/nft.h index 97c28b35..23bd2b79 100644 --- a/iptables/nft.h +++ b/iptables/nft.h @@ -32,6 +32,7 @@ struct nft_handle { struct mnl_socket *nl; uint32_t portid; uint32_t seq; + uint32_t nft_genid; uint32_t rule_id; struct list_head obj_list; int obj_list_num; -- cgit v1.2.3