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

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