]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
firewall-util: gracefully handle -EOVERFLOW returned from older kernel
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 22 Mar 2021 16:57:51 +0000 (01:57 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 23 Mar 2021 06:17:44 +0000 (15:17 +0900)
src/shared/firewall-util-nft.c

index b661a81ff7871a9ebc8f3bca8c59cb14f01ca711..1c6a25c4c0c27e8092d1b6ef6facc8b3fd01e1b1 100644 (file)
@@ -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)