Blame SOURCES/0058-nft-cache-Retry-if-kernel-returns-EINTR.patch

082114
From 681cb811e4cb8c5f22fd0fae60a3533289657705 Mon Sep 17 00:00:00 2001
7d6475
From: Phil Sutter <psutter@redhat.com>
7d6475
Date: Wed, 4 Aug 2021 17:14:05 +0200
7d6475
Subject: [PATCH] nft: cache: Retry if kernel returns EINTR
7d6475
7d6475
In case of parallel ruleset updates, recvfrom() calls may return EINTR.
7d6475
Due to the fact that cache fetches may get triggered while iterating
7d6475
over cache elements, __nft_build_cache must not restart based on
7d6475
comparing before and after generation ID like upstream does. Instead,
7d6475
just retry the recvfrom() calls until they either succeed or return a
7d6475
different error than EINTR.
7d6475
---
7d6475
 iptables/nft-cache.c | 18 ++++++++++++++----
7d6475
 1 file changed, 14 insertions(+), 4 deletions(-)
7d6475
7d6475
diff --git a/iptables/nft-cache.c b/iptables/nft-cache.c
7d6475
index 9623b463f0dd5..699dc66a95cd1 100644
7d6475
--- a/iptables/nft-cache.c
7d6475
+++ b/iptables/nft-cache.c
7d6475
@@ -98,9 +98,12 @@ static int fetch_table_cache(struct nft_handle *h)
7d6475
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_GETTABLE, h->family,
7d6475
 					NLM_F_DUMP, h->seq);
7d6475
 
7d6475
+retry:
7d6475
 	ret = mnl_talk(h, nlh, nftnl_table_list_cb, list);
7d6475
-	if (ret < 0 && errno == EINTR)
7d6475
+	if (ret < 0 && errno == EINTR) {
7d6475
 		assert(nft_restart(h) >= 0);
7d6475
+		goto retry;
7d6475
+	}
7d6475
 
7d6475
 	h->cache->tables = list;
7d6475
 
7d6475
@@ -275,10 +278,11 @@ static int fetch_set_cache(struct nft_handle *h,
7d6475
 						NLM_F_DUMP, h->seq);
7d6475
 	}
7d6475
 
7d6475
+retry:
7d6475
 	ret = mnl_talk(h, nlh, nftnl_set_list_cb, &d);
7d6475
 	if (ret < 0 && errno == EINTR) {
7d6475
 		assert(nft_restart(h) >= 0);
7d6475
-		return ret;
7d6475
+		goto retry;
7d6475
 	}
7d6475
 
7d6475
 	if (t && set) {
7d6475
@@ -355,9 +359,12 @@ static int fetch_chain_cache(struct nft_handle *h,
7d6475
 						  h->seq);
7d6475
 	}
7d6475
 
7d6475
+retry:
7d6475
 	ret = mnl_talk(h, nlh, nftnl_chain_list_cb, &d);
7d6475
-	if (ret < 0 && errno == EINTR)
7d6475
+	if (ret < 0 && errno == EINTR) {
7d6475
 		assert(nft_restart(h) >= 0);
7d6475
+		goto retry;
7d6475
+	}
7d6475
 
7d6475
 	return ret;
7d6475
 }
7d6475
@@ -404,9 +411,12 @@ static int nft_rule_list_update(struct nftnl_chain *c, void *data)
7d6475
 					NLM_F_DUMP, h->seq);
7d6475
 	nftnl_rule_nlmsg_build_payload(nlh, rule);
7d6475
 
7d6475
+retry:
7d6475
 	ret = mnl_talk(h, nlh, nftnl_rule_list_cb, c);
7d6475
-	if (ret < 0 && errno == EINTR)
7d6475
+	if (ret < 0 && errno == EINTR) {
7d6475
 		assert(nft_restart(h) >= 0);
7d6475
+		goto retry;
7d6475
+	}
7d6475
 
7d6475
 	nftnl_rule_free(rule);
7d6475
 
7d6475
-- 
7d6475
2.32.0
7d6475