Check for generation ID after the cache is populated. In case of interference, release the inconsistent cache and retry. Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- src/rule.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/rule.c b/src/rule.c index 1e081c8fe862..cb5bd2162c02 100644 --- a/src/rule.c +++ b/src/rule.c @@ -244,8 +244,6 @@ static bool cache_is_updated(struct nft_cache *cache, uint16_t genid) int cache_update(struct nft_ctx *nft, enum cmd_ops cmd, struct list_head *msgs) { - uint16_t genid; - int ret; struct netlink_ctx ctx = { .list = LIST_HEAD_INIT(ctx.list), .nft = nft, @@ -253,7 +251,8 @@ int cache_update(struct nft_ctx *nft, enum cmd_ops cmd, struct list_head *msgs) .nft = nft, }; struct nft_cache *cache = &nft->cache; - + uint16_t genid, genid_stop; + int ret; replay: ctx.seqnum = cache->seqnum++; genid = mnl_genid_get(&ctx); @@ -273,6 +272,13 @@ replay: } return -1; } + + genid_stop = mnl_genid_get(&ctx); + if (genid != genid_stop) { + cache_release(cache); + goto replay; + } + cache->genid = genid; cache->cmd = cmd; return 0; -- 2.11.0