|
|
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 |
|