summaryrefslogtreecommitdiff
path: root/src/test/test-firewall-util.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2020-09-17 21:55:45 +0200
committerFlorian Westphal <fw@strlen.de>2021-01-19 16:22:58 +0100
commit0e544221c983b2fa044a9b890d0a8bff6de88964 (patch)
tree4522a35f6898b00cd1ad4201a9b12001eb3faa15 /src/test/test-firewall-util.c
parent656e5aa4520b6d26fd0f04379b7a0ab416563b9e (diff)
downloadsystemd-0e544221c983b2fa044a9b890d0a8bff6de88964.tar.gz
firewall-util: add ipv6 support to nftables backend
closely mirrors the existing ipv4 ruleset: table ip6 io.systemd.nat { set masq_saddr { type ipv6_addr flags interval } map map_port_ipport { type inet_proto . inet_service : ipv6_addr . inet_service } chain prerouting { type nat hook prerouting priority dstnat + 1; policy accept; fib daddr type local dnat ip6 addr . port to meta l4proto . th dport map @map_port_ipport } chain output { type nat hook output priority -99; policy accept; ip6 daddr != ::1 oif "lo" dnat ip6 addr . port to meta l4proto . th dport map @map_port_ipport } chain postrouting { type nat hook postrouting priority srcnat + 1; policy accept; ip6 saddr @masq_saddr masquerade } } Only difference is the use of ipv6 addresses instead of ipv4 ones. Currently has no effect: all in-tree callers pass AF_INET exclusively. Followup patches will make nspawn expose ipv6 too and rework IPMasquerade option to support both/v4/v6.
Diffstat (limited to 'src/test/test-firewall-util.c')
-rw-r--r--src/test/test-firewall-util.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/test/test-firewall-util.c b/src/test/test-firewall-util.c
index 14678c048d..4cb43cc585 100644
--- a/src/test/test-firewall-util.c
+++ b/src/test/test-firewall-util.c
@@ -1,11 +1,67 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#include <arpa/inet.h>
+#include <stdlib.h>
#include "firewall-util.h"
#include "log.h"
+#include "random-util.h"
#include "tests.h"
#define MAKE_IN_ADDR_UNION(a,b,c,d) (union in_addr_union) { .in.s_addr = htobe32((uint32_t) (a) << 24 | (uint32_t) (b) << 16 | (uint32_t) (c) << 8 | (uint32_t) (d))}
+static void make_in6_addr_union(const char *addr, union in_addr_union *u) {
+ assert_se(inet_pton(AF_INET6, addr, &u->in6) >= 0);
+}
+
+static void test_v6(FirewallContext **ctx) {
+ union in_addr_union u = {}, u2 = {};
+ uint8_t prefixlen;
+ int r;
+
+ make_in6_addr_union("dead::beef", &u);
+
+ r = fw_add_masquerade(ctx, true, AF_INET6, &u, 128);
+ if (r < 0)
+ log_error_errno(r, "Failed to modify ipv6 firewall: %m");
+
+ r = fw_add_masquerade(ctx, false, AF_INET6, &u, 128);
+ if (r < 0)
+ log_error_errno(r, "Failed to modify ipv6 firewall: %m");
+
+ r = fw_add_masquerade(ctx, true, AF_INET6, &u, 64);
+ if (r < 0)
+ log_error_errno(r, "Failed to modify ipv6 firewall: %m");
+
+ r = fw_add_masquerade(ctx, false, AF_INET6, &u, 64);
+ if (r < 0)
+ log_error_errno(r, "Failed to modify ipv6 firewall: %m");
+
+ r = fw_add_local_dnat(ctx, true, AF_INET6, IPPROTO_TCP, 4711, &u, 815, NULL);
+ if (r < 0)
+ log_error_errno(r, "Failed to modify firewall: %m");
+
+ make_in6_addr_union("1c3::c01d", &u2);
+ r = fw_add_local_dnat(ctx, true, AF_INET6, IPPROTO_TCP, 4711, &u2, 815, &u);
+ if (r < 0)
+ log_error_errno(r, "Failed to modify firewall: %m");
+
+ r = fw_add_local_dnat(ctx, false, AF_INET6, IPPROTO_TCP, 4711, &u2, 815, NULL);
+ if (r < 0)
+ log_error_errno(r, "Failed to modify firewall: %m");
+
+ prefixlen = random_u32() % (128 + 1 - 8);
+ prefixlen += 8;
+ pseudo_random_bytes(&u, sizeof(u));
+
+ r = fw_add_masquerade(ctx, true, AF_INET6, &u, prefixlen);
+ if (r < 0)
+ log_error_errno(r, "Failed to modify ipv6 firewall: %m");
+
+ r = fw_add_masquerade(ctx, false, AF_INET6, &u, prefixlen);
+ if (r < 0)
+ log_error_errno(r, "Failed to modify ipv6 firewall: %m");
+}
+
int main(int argc, char *argv[]) {
_cleanup_(fw_ctx_freep) FirewallContext *ctx;
int r;
@@ -57,5 +113,7 @@ int main(int argc, char *argv[]) {
if (r < 0)
log_error_errno(r, "Failed to modify firewall: %m");
+ test_v6(&ctx);
+
return 0;
}