summaryrefslogtreecommitdiffstats
path: root/src/shared/firewall-util-nft.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2021-03-22 17:57:51 +0100
committerYu Watanabe <watanabe.yu+github@gmail.com>2021-03-23 07:17:44 +0100
commit175bc86315403a6c779530c7f3c495ffe1c2e9ef (patch)
treed6dd5b3ea17e417bed79766bb801f9b89caccab7 /src/shared/firewall-util-nft.c
parentfirewall-util: do not use goto for retrying (diff)
downloadsystemd-175bc86315403a6c779530c7f3c495ffe1c2e9ef.tar.xz
systemd-175bc86315403a6c779530c7f3c495ffe1c2e9ef.zip
firewall-util: gracefully handle -EOVERFLOW returned from older kernel
Diffstat (limited to 'src/shared/firewall-util-nft.c')
-rw-r--r--src/shared/firewall-util-nft.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/shared/firewall-util-nft.c b/src/shared/firewall-util-nft.c
index b661a81ff7..1c6a25c4c0 100644
--- a/src/shared/firewall-util-nft.c
+++ b/src/shared/firewall-util-nft.c
@@ -943,12 +943,16 @@ static int fw_nftables_add_local_dnat_internal(
const union in_addr_union *previous_remote) {
sd_netlink_message *transaction[NFT_DNAT_MSGS] = {};
+ static bool ipv6_supported = true;
uint32_t data[5], key[2], dlen;
size_t tsize;
int r;
assert(add || !previous_remote);
+ if (!ipv6_supported && af == AF_INET6)
+ return -EOPNOTSUPP;
+
if (!IN_SET(protocol, IPPROTO_TCP, IPPROTO_UDP))
return -EPROTONOSUPPORT;
@@ -1014,7 +1018,16 @@ static int fw_nftables_add_local_dnat_internal(
tsize++;
assert(tsize <= NFT_DNAT_MSGS);
+
r = nfnl_netlink_sendv(ctx->nfnl, transaction, tsize);
+ if (r == -EOVERFLOW && af == AF_INET6) {
+ /* The current implementation of DNAT in systemd requires kernel's
+ * fdb9c405e35bdc6e305b9b4e20ebc141ed14fc81 (v5.8), and the older kernel returns
+ * -EOVERFLOW. Let's treat the error as -EOPNOTSUPP. */
+ log_debug_errno(r, "The current implementation of IPv6 DNAT in systemd requires kernel 5.8 or newer, ignoring: %m");
+ ipv6_supported = false;
+ r = -EOPNOTSUPP;
+ }
out_unref:
while (tsize > 0)