]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
firewall-util: drop FirewallContext
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 17 Aug 2025 19:24:02 +0000 (04:24 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 19 Sep 2025 06:33:17 +0000 (15:33 +0900)
After iptables support is dropped, FirewallContext is a trivial
wrapper of sd_netlink. Let's drop it and directly use sd_netlink.

21 files changed:
src/basic/forward.h
src/core/cgroup.c
src/core/dbus-cgroup.c
src/core/load-fragment.c
src/core/manager.c
src/core/manager.h
src/core/unit.c
src/network/networkd-address.c
src/network/networkd-manager.c
src/network/networkd-manager.h
src/network/networkd-queue.c
src/nspawn/nspawn-expose-ports.c
src/nspawn/nspawn-expose-ports.h
src/nspawn/nspawn.c
src/shared/firewall-util-nft.c
src/shared/firewall-util-private.h [deleted file]
src/shared/firewall-util.c [deleted file]
src/shared/firewall-util.h
src/shared/meson.build
src/test/test-firewall-util.c
src/test/test-nft-set.c

index 66da2b13a57c5bcd7559f92b1ab9935488148a73..a9fda3b917a1b039c370676ef001a9551541a745 100644 (file)
@@ -284,7 +284,6 @@ typedef struct ConfigTableItem ConfigTableItem;
 typedef struct CPUSet CPUSet;
 typedef struct FDSet FDSet;
 typedef struct Fido2HmacSalt Fido2HmacSalt;
-typedef struct FirewallContext FirewallContext;
 typedef struct GroupRecord GroupRecord;
 typedef struct Image Image;
 typedef struct ImagePolicy ImagePolicy;
index 48149e15bd50f8eb5b9c4646a54b469132425b16..db51539e01dffbf003e59d0b9d9e03fb7dc2d2f1 100644 (file)
 #include "fd-util.h"
 #include "fdset.h"
 #include "fileio.h"
-#include "firewall-util.h"
 #include "in-addr-prefix-util.h"
 #include "inotify-util.h"
 #include "ip-protocol-list.h"
 #include "limits-util.h"
 #include "manager.h"
+#include "netlink-internal.h"
 #include "nulstr-util.h"
 #include "parse-util.h"
 #include "path-util.h"
@@ -1335,12 +1335,10 @@ void unit_modify_nft_set(Unit *u, bool add) {
         if (!crt || crt->cgroup_id == 0)
                 return;
 
-        if (!u->manager->fw_ctx) {
-                r = fw_ctx_new_full(&u->manager->fw_ctx, /* init_tables= */ false);
+        if (!u->manager->nfnl) {
+                r = sd_nfnl_socket_open(&u->manager->nfnl);
                 if (r < 0)
                         return;
-
-                assert(u->manager->fw_ctx);
         }
 
         CGroupContext *c = ASSERT_PTR(unit_get_cgroup_context(u));
@@ -1351,7 +1349,7 @@ void unit_modify_nft_set(Unit *u, bool add) {
 
                 uint64_t element = crt->cgroup_id;
 
-                r = nft_set_element_modify_any(u->manager->fw_ctx, add, nft_set->nfproto, nft_set->table, nft_set->set, &element, sizeof(element));
+                r = nft_set_element_modify_any(u->manager->nfnl, add, nft_set->nfproto, nft_set->table, nft_set->set, &element, sizeof(element));
                 if (r < 0)
                         log_warning_errno(r, "Failed to %s NFT set entry: family %s, table %s, set %s, cgroup %" PRIu64 ", ignoring: %m",
                                           add? "add" : "delete", nfproto_to_string(nft_set->nfproto), nft_set->table, nft_set->set, crt->cgroup_id);
index dd4a6e8367efd0f3024a7c6930bdc4e29d7ef0ee..82e2a9f9618382115a8e096bbb38fddbbfda7e30 100644 (file)
@@ -9,7 +9,6 @@
 #include "cgroup-util.h"
 #include "dbus-cgroup.h"
 #include "escape.h"
-#include "firewall-util.h"
 #include "in-addr-prefix-util.h"
 #include "limits-util.h"
 #include "manager.h"
index 4b7bfc772f02bc37825dc80c322035dce0dacaab..c4ebec160115eb23d5740d8cc3fac41d2fcbdb7e 100644 (file)
@@ -32,7 +32,6 @@
 #include "execute.h"
 #include "extract-word.h"
 #include "fd-util.h"
-#include "firewall-util.h"
 #include "fstab-util.h"
 #include "hashmap.h"
 #include "hexdecoct.h"
index 5bba7e81b0cf020ae0019441d6fd2a0b1ed30748..2529a7c3f10ac213abb8b611fa3464f74aa0893a 100644 (file)
@@ -12,6 +12,7 @@
 #include "sd-bus.h"
 #include "sd-daemon.h"
 #include "sd-messages.h"
+#include "sd-netlink.h"
 #include "sd-path.h"
 
 #include "all-units.h"
@@ -1753,7 +1754,7 @@ Manager* manager_free(Manager *m) {
         free(m->watchdog_pretimeout_governor);
         free(m->watchdog_pretimeout_governor_overridden);
 
-        fw_ctx_free(m->fw_ctx);
+        sd_netlink_unref(m->nfnl);
 
 #if BPF_FRAMEWORK
         bpf_restrict_fs_destroy(m->restrict_fs);
index a7009a49d791b16b65ce2df3bbfcb01273c83909..b4f34f66e69590d49d4922e8990c7dea9a4ecd66 100644 (file)
@@ -474,7 +474,7 @@ typedef struct Manager {
         sd_event_source *memory_pressure_event_source;
 
         /* For NFTSet= */
-        FirewallContext *fw_ctx;
+        sd_netlink *nfnl;
 
         /* Pin the systemd-executor binary, so that it never changes until re-exec, ensuring we don't have
          * serialization/deserialization compatibility issues during upgrades. */
index a6c3fd8bda588ae9fbddced353bfa7ca62055246..22c080da09cb7d6d777337da37f846143e797990 100644 (file)
@@ -44,6 +44,7 @@
 #include "manager.h"
 #include "mount-util.h"
 #include "mountpoint-util.h"
+#include "netlink-internal.h"
 #include "path-util.h"
 #include "process-util.h"
 #include "quota-util.h"
@@ -5290,19 +5291,17 @@ static void unit_modify_user_nft_set(Unit *u, bool add, NFTSetSource source, uin
         if (!c)
                 return;
 
-        if (!u->manager->fw_ctx) {
-                r = fw_ctx_new_full(&u->manager->fw_ctx, /* init_tables= */ false);
+        if (!u->manager->nfnl) {
+                r = sd_nfnl_socket_open(&u->manager->nfnl);
                 if (r < 0)
                         return;
-
-                assert(u->manager->fw_ctx);
         }
 
         FOREACH_ARRAY(nft_set, c->nft_set_context.sets, c->nft_set_context.n_sets) {
                 if (nft_set->source != source)
                         continue;
 
-                r = nft_set_element_modify_any(u->manager->fw_ctx, add, nft_set->nfproto, nft_set->table, nft_set->set, &element, sizeof(element));
+                r = nft_set_element_modify_any(u->manager->nfnl, add, nft_set->nfproto, nft_set->table, nft_set->set, &element, sizeof(element));
                 if (r < 0)
                         log_warning_errno(r, "Failed to %s NFT set entry: family %s, table %s, set %s, ID %u, ignoring: %m",
                                           add? "add" : "delete", nfproto_to_string(nft_set->nfproto), nft_set->table, nft_set->set, element);
index 716bee731f0d41115e48fde813fb9747b2ed0ff4..131a84aa72ffe72c9f42ebba461d20e74667ef73 100644 (file)
@@ -669,6 +669,10 @@ static int address_set_masquerade(Address *address, bool add) {
 
         assert(address);
         assert(address->link);
+        assert(address->link->manager);
+
+        if (!address->link->manager->nfnl)
+                return 0;
 
         if (!address->link->network)
                 return 0;
@@ -687,7 +691,7 @@ static int address_set_masquerade(Address *address, bool add) {
         if (r < 0)
                 return r;
 
-        r = fw_add_masquerade(&address->link->manager->fw_ctx, add, address->family, &masked, address->prefixlen);
+        r = fw_nftables_add_masquerade(address->link->manager->nfnl, add, address->family, &masked, address->prefixlen);
         if (r < 0)
                 return r;
 
@@ -702,14 +706,9 @@ static void address_modify_nft_set_context(Address *address, bool add, NFTSetCon
         assert(address);
         assert(address->link);
         assert(address->link->manager);
+        assert(address->link->manager->nfnl);
         assert(nft_set_context);
 
-        if (!address->link->manager->fw_ctx) {
-                r = fw_ctx_new_full(&address->link->manager->fw_ctx, /* init_tables= */ false);
-                if (r < 0)
-                        return;
-        }
-
         FOREACH_ARRAY(nft_set, nft_set_context->sets, nft_set_context->n_sets) {
                 uint32_t ifindex;
 
@@ -717,16 +716,16 @@ static void address_modify_nft_set_context(Address *address, bool add, NFTSetCon
 
                 switch (nft_set->source) {
                 case NFT_SET_SOURCE_ADDRESS:
-                        r = nft_set_element_modify_ip(address->link->manager->fw_ctx, add, nft_set->nfproto, address->family, nft_set->table, nft_set->set,
+                        r = nft_set_element_modify_ip(address->link->manager->nfnl, add, nft_set->nfproto, address->family, nft_set->table, nft_set->set,
                                                       &address->in_addr);
                         break;
                 case NFT_SET_SOURCE_PREFIX:
-                        r = nft_set_element_modify_iprange(address->link->manager->fw_ctx, add, nft_set->nfproto, address->family, nft_set->table, nft_set->set,
+                        r = nft_set_element_modify_iprange(address->link->manager->nfnl, add, nft_set->nfproto, address->family, nft_set->table, nft_set->set,
                                                            &address->in_addr, address->prefixlen);
                         break;
                 case NFT_SET_SOURCE_IFINDEX:
                         ifindex = address->link->ifindex;
-                        r = nft_set_element_modify_any(address->link->manager->fw_ctx, add, nft_set->nfproto, nft_set->table, nft_set->set,
+                        r = nft_set_element_modify_any(address->link->manager->nfnl, add, nft_set->nfproto, nft_set->table, nft_set->set,
                                                        &ifindex, sizeof(ifindex));
                         break;
                 default:
@@ -749,6 +748,10 @@ static void address_modify_nft_set_context(Address *address, bool add, NFTSetCon
 static void address_modify_nft_set(Address *address, bool add) {
         assert(address);
         assert(address->link);
+        assert(address->link->manager);
+
+        if (!address->link->manager->nfnl)
+                return;
 
         if (!IN_SET(address->family, AF_INET, AF_INET6))
                 return;
index ef61a90fcb3ddc97d9844607790b3a4cd0714d1b..4004be81c0f6df68f0c4af4d6e9350fd4417f496 100644 (file)
@@ -23,9 +23,9 @@
 #include "env-util.h"
 #include "errno-util.h"
 #include "fd-util.h"
-#include "firewall-util.h"
 #include "initrd-util.h"
 #include "mount-util.h"
+#include "netlink-internal.h"
 #include "netlink-util.h"
 #include "networkd-address.h"
 #include "networkd-address-label.h"
@@ -285,6 +285,28 @@ static int manager_connect_genl(Manager *m) {
         return 0;
 }
 
+static int manager_connect_nfnl(Manager *m) {
+        int r;
+
+        assert(m);
+
+        r = sd_nfnl_socket_open(&m->nfnl);
+        if (r < 0) {
+                log_warning_errno(r, "Failed to open nftables netlink socket. IPMasquerade= and NFTSet= settings will not be applied. Ignoring: %m");
+                return 0;
+        }
+
+        r = sd_netlink_increase_rxbuf(m->nfnl, RCVBUF_SIZE);
+        if (r < 0)
+                log_warning_errno(r, "Failed to increase receive buffer size for nftables netlink socket, ignoring: %m");
+
+        r = sd_netlink_attach_event(m->nfnl, m->event, 0);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
 static int manager_setup_rtnl_filter(Manager *manager) {
         struct sock_filter filter[] = {
                 /* Check the packet length. */
@@ -435,7 +457,7 @@ static int manager_post_handler(sd_event_source *s, void *userdata) {
 
                 if (netlink_get_reply_callback_count(manager->rtnl) > 0 ||
                     netlink_get_reply_callback_count(manager->genl) > 0 ||
-                    fw_ctx_get_reply_callback_count(manager->fw_ctx) > 0)
+                    netlink_get_reply_callback_count(manager->nfnl) > 0)
                         return 0; /* There are some message calls waiting for their replies. */
 
                 (void) manager_serialize(manager);
@@ -557,6 +579,10 @@ int manager_setup(Manager *m) {
         if (r < 0)
                 return r;
 
+        r = manager_connect_nfnl(m);
+        if (r < 0)
+                return r;
+
         if (m->test_mode)
                 return 0;
 
@@ -696,6 +722,7 @@ Manager* manager_free(Manager *m) {
 
         sd_netlink_unref(m->rtnl);
         sd_netlink_unref(m->genl);
+        sd_netlink_unref(m->nfnl);
         sd_resolve_unref(m->resolve);
 
         m->routes = set_free(m->routes);
@@ -720,8 +747,6 @@ Manager* manager_free(Manager *m) {
         safe_close(m->ethtool_fd);
         safe_close(m->persistent_storage_fd);
 
-        m->fw_ctx = fw_ctx_free(m->fw_ctx);
-
         m->serialization_fd = safe_close(m->serialization_fd);
 
         return mfree(m);
index ad3d815b0c8a86e020ef607db5b144d358cc15e7..e350fe80c5b6c6af245c753ef5a74fef4c1bc5c2 100644 (file)
@@ -17,6 +17,7 @@ typedef struct Manager {
         sd_netlink *rtnl;
         /* lazy initialized */
         sd_netlink *genl;
+        sd_netlink *nfnl;
         sd_event *event;
         sd_resolve *resolve;
         sd_bus *bus;
@@ -103,8 +104,6 @@ typedef struct Manager {
         usec_t speed_meter_usec_new;
         usec_t speed_meter_usec_old;
 
-        FirewallContext *fw_ctx;
-
         bool request_queued;
         OrderedSet *request_queue;
         OrderedSet *remove_request_queue;
index bc2e7095fa8bbd40c8966ba381c8671afb2d702f..0ab372b4b21e788d733f8f7e97c5464b97b26c3a 100644 (file)
@@ -293,7 +293,7 @@ int manager_process_requests(Manager *manager) {
                  * queued, then this event may make reply callback queue in sd-netlink full. */
                 if (netlink_get_reply_callback_count(manager->rtnl) >= REPLY_CALLBACK_COUNT_THRESHOLD ||
                     netlink_get_reply_callback_count(manager->genl) >= REPLY_CALLBACK_COUNT_THRESHOLD ||
-                    fw_ctx_get_reply_callback_count(manager->fw_ctx) >= REPLY_CALLBACK_COUNT_THRESHOLD)
+                    netlink_get_reply_callback_count(manager->nfnl) >= REPLY_CALLBACK_COUNT_THRESHOLD)
                         break;
 
                 /* Avoid the request and link freed by req->process() and request_detach(). */
index 9a194089da4dae21ad6391507fbdfd2893f57c81..e312a90710ca609829ceeb00ac0e4b9e5fbb1ed8 100644 (file)
@@ -76,12 +76,13 @@ void expose_port_free_all(ExposePort *p) {
         LIST_CLEAR(ports, p, free);
 }
 
-int expose_port_flush(FirewallContext **fw_ctx, ExposePort* l, int af, union in_addr_union *exposed) {
+int expose_port_flush(sd_netlink *nfnl, ExposePort* l, int af, union in_addr_union *exposed) {
         int r;
 
+        assert(IN_SET(af, AF_INET, AF_INET6));
         assert(exposed);
 
-        if (!l)
+        if (!nfnl || !l)
                 return 0;
 
         if (!in_addr_is_set(af, exposed))
@@ -90,14 +91,15 @@ int expose_port_flush(FirewallContext **fw_ctx, ExposePort* l, int af, union in_
         log_debug("Lost IP address.");
 
         LIST_FOREACH(ports, p, l) {
-                r = fw_add_local_dnat(fw_ctx,
-                                      false,
-                                      af,
-                                      p->protocol,
-                                      p->host_port,
-                                      exposed,
-                                      p->container_port,
-                                      NULL);
+                r = fw_nftables_add_local_dnat(
+                                nfnl,
+                                /* add = */ false,
+                                af,
+                                p->protocol,
+                                p->host_port,
+                                exposed,
+                                p->container_port,
+                                /* previous_remote = */ NULL);
                 if (r < 0)
                         log_warning_errno(r, "Failed to modify %s firewall: %m", af_to_name(af));
         }
@@ -106,12 +108,15 @@ int expose_port_flush(FirewallContext **fw_ctx, ExposePort* l, int af, union in_
         return 0;
 }
 
-int expose_port_execute(sd_netlink *rtnl, FirewallContext **fw_ctx, ExposePort *l, int af, union in_addr_union *exposed) {
+int expose_port_execute(sd_netlink *rtnl, sd_netlink *nfnl, ExposePort *l, int af, union in_addr_union *exposed) {
         _cleanup_free_ struct local_address *addresses = NULL;
         union in_addr_union new_exposed;
         bool add;
         int r;
 
+        assert(rtnl);
+        assert(nfnl);
+        assert(IN_SET(af, AF_INET, AF_INET6));
         assert(exposed);
 
         /* Invoked each time an address is added or removed inside the
@@ -129,7 +134,7 @@ int expose_port_execute(sd_netlink *rtnl, FirewallContext **fw_ctx, ExposePort *
                 addresses[0].scope < RT_SCOPE_LINK;
 
         if (!add)
-                return expose_port_flush(fw_ctx, l, af, exposed);
+                return expose_port_flush(nfnl, l, af, exposed);
 
         new_exposed = addresses[0].address;
         if (in_addr_equal(af, exposed, &new_exposed))
@@ -138,14 +143,15 @@ int expose_port_execute(sd_netlink *rtnl, FirewallContext **fw_ctx, ExposePort *
         log_debug("New container IP is %s.", IN_ADDR_TO_STRING(af, &new_exposed));
 
         LIST_FOREACH(ports, p, l) {
-                r = fw_add_local_dnat(fw_ctx,
-                                      true,
-                                      af,
-                                      p->protocol,
-                                      p->host_port,
-                                      &new_exposed,
-                                      p->container_port,
-                                      in_addr_is_set(af, exposed) ? exposed : NULL);
+                r = fw_nftables_add_local_dnat(
+                                nfnl,
+                                /* add = */ true,
+                                af,
+                                p->protocol,
+                                p->host_port,
+                                &new_exposed,
+                                p->container_port,
+                                in_addr_is_set(af, exposed) ? exposed : NULL);
                 if (r < 0)
                         log_warning_errno(r, "Failed to modify %s firewall: %m", af_to_name(af));
         }
index 4f1ecc22991d7e786807c251d1a9f8a5ba8b985b..3a1717946254dca709fdccbb07c3e83d0512e314 100644 (file)
@@ -1,7 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include "firewall-util.h"
 #include "forward.h"
 #include "list.h"
 
@@ -18,5 +17,5 @@ int expose_port_parse(ExposePort **l, const char *s);
 int expose_port_watch_rtnl(sd_event *event, int recv_fd, sd_netlink_message_handler_t handler, void *userdata, sd_netlink **ret);
 int expose_port_send_rtnl(int send_fd);
 
-int expose_port_execute(sd_netlink *rtnl, FirewallContext **fw_ctx, ExposePort *l, int af, union in_addr_union *exposed);
-int expose_port_flush(FirewallContext **fw_ctx, ExposePort* l, int af, union in_addr_union *exposed);
+int expose_port_execute(sd_netlink *rtnl, sd_netlink *nfnl, ExposePort *l, int af, union in_addr_union *exposed);
+int expose_port_flush(sd_netlink *nfnl, ExposePort* l, int af, union in_addr_union *exposed);
index ab8746c442b26d62de0baebdf871c1a856ef2386..88187a906e6647bb936e8b04fd66e805885ad28c 100644 (file)
@@ -71,6 +71,7 @@
 #include "mount-util.h"
 #include "mountpoint-util.h"
 #include "namespace-util.h"
+#include "netlink-internal.h"
 #include "notify-recv.h"
 #include "nspawn-bind-user.h"
 #include "nspawn-cgroup.h"
@@ -2539,7 +2540,7 @@ static int setup_kmsg(int fd_inner_socket) {
 struct ExposeArgs {
         union in_addr_union address4;
         union in_addr_union address6;
-        struct FirewallContext *fw_ctx;
+        sd_netlink *nfnl;
 };
 
 static int on_address_change(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
@@ -2548,8 +2549,8 @@ static int on_address_change(sd_netlink *rtnl, sd_netlink_message *m, void *user
         assert(rtnl);
         assert(m);
 
-        (void) expose_port_execute(rtnl, &args->fw_ctx, arg_expose_ports, AF_INET, &args->address4);
-        (void) expose_port_execute(rtnl, &args->fw_ctx, arg_expose_ports, AF_INET6, &args->address6);
+        (void) expose_port_execute(rtnl, args->nfnl, arg_expose_ports, AF_INET, &args->address4);
+        (void) expose_port_execute(rtnl, args->nfnl, arg_expose_ports, AF_INET6, &args->address6);
         return 0;
 }
 
@@ -5607,8 +5608,8 @@ static int run_container(
                 if (r < 0)
                         return r;
 
-                (void) expose_port_execute(rtnl, &expose_args->fw_ctx, arg_expose_ports, AF_INET, &expose_args->address4);
-                (void) expose_port_execute(rtnl, &expose_args->fw_ctx, arg_expose_ports, AF_INET6, &expose_args->address6);
+                (void) expose_port_execute(rtnl, expose_args->nfnl, arg_expose_ports, AF_INET, &expose_args->address4);
+                (void) expose_port_execute(rtnl, expose_args->nfnl, arg_expose_ports, AF_INET6, &expose_args->address6);
         }
 
         _cleanup_(osc_context_closep) sd_id128_t osc_context_id = SD_ID128_NULL;
@@ -5730,8 +5731,8 @@ static int run_container(
                 return 0; /* finito */
         }
 
-        expose_port_flush(&expose_args->fw_ctx, arg_expose_ports, AF_INET, &expose_args->address4);
-        expose_port_flush(&expose_args->fw_ctx, arg_expose_ports, AF_INET6, &expose_args->address6);
+        expose_port_flush(expose_args->nfnl, arg_expose_ports, AF_INET, &expose_args->address4);
+        expose_port_flush(expose_args->nfnl, arg_expose_ports, AF_INET6, &expose_args->address6);
 
         (void) remove_veth_links(veth_name, arg_network_veth_extra);
         *veth_created = false;
@@ -5900,7 +5901,7 @@ static int run(int argc, char *argv[]) {
         _cleanup_(rmdir_and_freep) char *rootdir = NULL;
         _cleanup_(loop_device_unrefp) LoopDevice *loop = NULL;
         _cleanup_(dissected_image_unrefp) DissectedImage *dissected_image = NULL;
-        _cleanup_(fw_ctx_freep) FirewallContext *fw_ctx = NULL;
+        _cleanup_(sd_netlink_unrefp) sd_netlink *nfnl = NULL;
         _cleanup_(pidref_done) PidRef pid = PIDREF_NULL;
 
         log_setup();
@@ -6385,12 +6386,12 @@ static int run(int argc, char *argv[]) {
         }
 
         if (arg_expose_ports) {
-                r = fw_ctx_new(&fw_ctx);
+                r = sd_nfnl_socket_open(&nfnl);
                 if (r < 0) {
-                        log_error_errno(r, "Cannot expose configured ports, firewall initialization failed: %m");
+                        log_error_errno(r, "Cannot expose configured ports, failed to initialize nftables: %m");
                         goto finish;
                 }
-                expose_args.fw_ctx = fw_ctx;
+                expose_args.nfnl = nfnl;
         }
 
         for (;;) {
@@ -6454,8 +6455,8 @@ finish:
 
         cleanup_propagation_and_export_directories();
 
-        expose_port_flush(&fw_ctx, arg_expose_ports, AF_INET,  &expose_args.address4);
-        expose_port_flush(&fw_ctx, arg_expose_ports, AF_INET6, &expose_args.address6);
+        expose_port_flush(nfnl, arg_expose_ports, AF_INET,  &expose_args.address4);
+        expose_port_flush(nfnl, arg_expose_ports, AF_INET6, &expose_args.address6);
 
         if (arg_userns_mode != USER_NAMESPACE_MANAGED) {
                 if (veth_created)
index 66c0665d6662b337f2c65b144ce988012697aa99..b59740166e794a1409e872b730d176ae08735095 100644 (file)
@@ -14,7 +14,6 @@
 #include "escape.h"
 #include "extract-word.h"
 #include "firewall-util.h"
-#include "firewall-util-private.h"
 #include "in-addr-util.h"
 #include "log.h"
 #include "netlink-internal.h"
@@ -815,43 +814,6 @@ static int fw_nftables_init_family(sd_netlink *nfnl, int family) {
         return 0;
 }
 
-int fw_nftables_init_full(FirewallContext *ctx, bool init_tables) {
-        _cleanup_(sd_netlink_unrefp) sd_netlink *nfnl = NULL;
-        int r;
-
-        assert(ctx);
-        assert(!ctx->nfnl);
-
-        r = sd_nfnl_socket_open(&nfnl);
-        if (r < 0)
-                return r;
-
-        if (init_tables) {
-                r = fw_nftables_init_family(nfnl, AF_INET);
-                if (r < 0)
-                        return r;
-
-                if (socket_ipv6_is_supported()) {
-                        r = fw_nftables_init_family(nfnl, AF_INET6);
-                        if (r < 0)
-                                return log_error_errno(r, "Failed to init ipv6 NAT: %m");
-                }
-        }
-
-        ctx->nfnl = TAKE_PTR(nfnl);
-        return 0;
-}
-
-int fw_nftables_init(FirewallContext *ctx) {
-        return fw_nftables_init_full(ctx, /* init_tables= */ true);
-}
-
-void fw_nftables_exit(FirewallContext *ctx) {
-        assert(ctx);
-
-        ctx->nfnl = sd_netlink_unref(ctx->nfnl);
-}
-
 static int nft_message_append_setelem_iprange(
                 sd_netlink_message *m,
                 const union in_addr_union *source,
@@ -922,7 +884,7 @@ static int nft_message_append_setelem_ip6range(
 }
 
 int nft_set_element_modify_iprange(
-                FirewallContext *ctx,
+                sd_netlink *nfnl,
                 bool add,
                 int nfproto,
                 int af,
@@ -934,7 +896,7 @@ int nft_set_element_modify_iprange(
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
         int r;
 
-        assert(ctx->nfnl);
+        assert(nfnl);
         assert(IN_SET(af, AF_INET, AF_INET6));
         assert(nfproto_is_valid(nfproto));
         assert(table);
@@ -946,7 +908,7 @@ int nft_set_element_modify_iprange(
         if (af == AF_INET6 && source_prefixlen < 8)
                 return -EINVAL;
 
-        r = sd_nfnl_nft_message_new_setelems(ctx->nfnl, &m, add, nfproto, table, set);
+        r = sd_nfnl_nft_message_new_setelems(nfnl, &m, add, nfproto, table, set);
         if (r < 0)
                 return r;
 
@@ -957,11 +919,11 @@ int nft_set_element_modify_iprange(
         if (r < 0)
                 return r;
 
-        return sd_nfnl_call_batch(ctx->nfnl, &m, 1, NFNL_DEFAULT_TIMEOUT_USECS, NULL);
+        return sd_nfnl_call_batch(nfnl, &m, 1, NFNL_DEFAULT_TIMEOUT_USECS, NULL);
 }
 
 int nft_set_element_modify_ip(
-                FirewallContext *ctx,
+                sd_netlink *nfnl,
                 bool add,
                 int nfproto,
                 int af,
@@ -972,7 +934,7 @@ int nft_set_element_modify_ip(
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
         int r;
 
-        assert(ctx->nfnl);
+        assert(nfnl);
         assert(IN_SET(af, AF_INET, AF_INET6));
         assert(nfproto_is_valid(nfproto));
         assert(table);
@@ -981,7 +943,7 @@ int nft_set_element_modify_ip(
         if (!source)
                 return -EINVAL;
 
-        r = sd_nfnl_nft_message_new_setelems(ctx->nfnl, &m, add, nfproto, table, set);
+        r = sd_nfnl_nft_message_new_setelems(nfnl, &m, add, nfproto, table, set);
         if (r < 0)
                 return r;
 
@@ -997,28 +959,35 @@ int nft_set_element_modify_ip(
         if (r < 0)
                 return r;
 
-        return sd_nfnl_call_batch(ctx->nfnl, &m, 1, NFNL_DEFAULT_TIMEOUT_USECS, NULL);
+        return sd_nfnl_call_batch(nfnl, &m, 1, NFNL_DEFAULT_TIMEOUT_USECS, NULL);
 }
 
-int nft_set_element_modify_any(FirewallContext *ctx, bool add, int nfproto, const char *table, const char *set, const void *element, size_t element_size) {
+int nft_set_element_modify_any(
+                sd_netlink *nfnl,
+                bool add,
+                int nfproto,
+                const char *table,
+                const char *set,
+                const void *element,
+                size_t element_size) {
+
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
         int r;
 
-        assert(ctx);
-        assert(ctx->nfnl);
+        assert(nfnl);
         assert(nfproto_is_valid(nfproto));
         assert(table);
         assert(set);
         assert(element);
 
         if (add)
-                r = nft_add_element(ctx->nfnl, &m, nfproto, table, set, element, element_size, NULL, 0);
+                r = nft_add_element(nfnl, &m, nfproto, table, set, element, element_size, NULL, 0);
         else
-                r = nft_del_element(ctx->nfnl, &m, nfproto, table, set, element, element_size, NULL, 0);
+                r = nft_del_element(nfnl, &m, nfproto, table, set, element, element_size, NULL, 0);
         if (r < 0)
                 return r;
 
-        return sd_nfnl_call_batch(ctx->nfnl, &m, 1, NFNL_DEFAULT_TIMEOUT_USECS, NULL);
+        return sd_nfnl_call_batch(nfnl, &m, 1, NFNL_DEFAULT_TIMEOUT_USECS, NULL);
 }
 
 static int af_to_nfproto(int af) {
@@ -1035,7 +1004,7 @@ static int af_to_nfproto(int af) {
 }
 
 int fw_nftables_add_masquerade(
-                FirewallContext *ctx,
+                sd_netlink *nfnl,
                 bool add,
                 int af,
                 const union in_addr_union *source,
@@ -1043,14 +1012,13 @@ int fw_nftables_add_masquerade(
 
         int r;
 
-        assert(ctx);
-        assert(ctx->nfnl);
+        assert(nfnl);
         assert(IN_SET(af, AF_INET, AF_INET6));
 
         if (!socket_ipv6_is_supported() && af == AF_INET6)
                 return -EOPNOTSUPP;
 
-        r = nft_set_element_modify_iprange(ctx, add, af_to_nfproto(af), af, nft_table_name(), NFT_SYSTEMD_MASQ_SET_NAME,
+        r = nft_set_element_modify_iprange(nfnl, add, af_to_nfproto(af), af, nft_table_name(), NFT_SYSTEMD_MASQ_SET_NAME,
                                            source, source_prefixlen);
         if (r != -ENOENT)
                 return r;
@@ -1072,11 +1040,11 @@ int fw_nftables_add_masquerade(
          * of extending the kernel to allow tables to be owned by stystemd-networkd and making them
          * non-deleteable except by the 'owning process'. */
 
-        r = fw_nftables_init_family(ctx->nfnl, af);
+        r = fw_nftables_init_family(nfnl, af);
         if (r < 0)
                 return r;
 
-        return nft_set_element_modify_iprange(ctx, add, af_to_nfproto(af), af, nft_table_name(), NFT_SYSTEMD_MASQ_SET_NAME,
+        return nft_set_element_modify_iprange(nfnl, add, af_to_nfproto(af), af, nft_table_name(), NFT_SYSTEMD_MASQ_SET_NAME,
                                               source, source_prefixlen);
 }
 
@@ -1172,7 +1140,7 @@ static int fw_nftables_add_local_dnat_internal(
 }
 
 int fw_nftables_add_local_dnat(
-                FirewallContext *ctx,
+                sd_netlink *nfnl,
                 bool add,
                 int af,
                 int protocol,
@@ -1183,24 +1151,23 @@ int fw_nftables_add_local_dnat(
 
         int r;
 
-        assert(ctx);
-        assert(ctx->nfnl);
+        assert(nfnl);
         assert(IN_SET(af, AF_INET, AF_INET6));
 
         if (!socket_ipv6_is_supported() && af == AF_INET6)
                 return -EOPNOTSUPP;
 
-        r = fw_nftables_add_local_dnat_internal(ctx->nfnl, add, af, protocol, local_port, remote, remote_port, previous_remote);
+        r = fw_nftables_add_local_dnat_internal(nfnl, add, af, protocol, local_port, remote, remote_port, previous_remote);
         if (r != -ENOENT)
                 return r;
 
         /* See comment in fw_nftables_add_masquerade(). */
-        r = fw_nftables_init_family(ctx->nfnl, af);
+        r = fw_nftables_init_family(nfnl, af);
         if (r < 0)
                 return r;
 
         /* table created anew; previous address already gone */
-        return fw_nftables_add_local_dnat_internal(ctx->nfnl, add, af, protocol, local_port, remote, remote_port, NULL);
+        return fw_nftables_add_local_dnat_internal(nfnl, add, af, protocol, local_port, remote, remote_port, NULL);
 }
 
 static const char *const nfproto_table[] = {
diff --git a/src/shared/firewall-util-private.h b/src/shared/firewall-util-private.h
deleted file mode 100644 (file)
index 70c6678..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#pragma once
-
-#include "firewall-util.h"
-#include "forward.h"
-
-typedef enum FirewallBackend {
-        FW_BACKEND_NONE,
-        FW_BACKEND_NFTABLES,
-        _FW_BACKEND_MAX,
-        _FW_BACKEND_INVALID = -EINVAL,
-} FirewallBackend;
-
-struct FirewallContext {
-        FirewallBackend backend;
-        sd_netlink *nfnl;
-};
-
-const char* firewall_backend_to_string(FirewallBackend b) _const_;
-
-int fw_nftables_init(FirewallContext *ctx);
-int fw_nftables_init_full(FirewallContext *ctx, bool init_tables);
-void fw_nftables_exit(FirewallContext *ctx);
-
-int fw_nftables_add_masquerade(
-                FirewallContext *ctx,
-                bool add,
-                int af,
-                const union in_addr_union *source,
-                unsigned source_prefixlen);
-
-int fw_nftables_add_local_dnat(
-                FirewallContext *ctx,
-                bool add,
-                int af,
-                int protocol,
-                uint16_t local_port,
-                const union in_addr_union *remote,
-                uint16_t remote_port,
-                const union in_addr_union *previous_remote);
diff --git a/src/shared/firewall-util.c b/src/shared/firewall-util.c
deleted file mode 100644 (file)
index d4c0e4f..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "alloc-util.h"
-#include "firewall-util.h"
-#include "firewall-util-private.h"
-#include "log.h"
-#include "netlink-util.h"
-#include "string-table.h"
-#include "string-util.h"
-
-static const char * const firewall_backend_table[_FW_BACKEND_MAX] = {
-        [FW_BACKEND_NONE] = "none",
-        [FW_BACKEND_NFTABLES] = "nftables",
-};
-
-DEFINE_STRING_TABLE_LOOKUP_TO_STRING(firewall_backend, FirewallBackend);
-
-static void firewall_backend_probe(FirewallContext *ctx, bool init_tables) {
-        const char *e;
-
-        assert(ctx);
-
-        if (ctx->backend != _FW_BACKEND_INVALID)
-                return;
-
-        e = secure_getenv("SYSTEMD_FIREWALL_BACKEND");
-        if (e) {
-                if (streq(e, "nftables"))
-                        ctx->backend = FW_BACKEND_NFTABLES;
-                else
-                        log_debug("Unrecognized $SYSTEMD_FIREWALL_BACKEND value, ignoring: %s", e);
-        }
-
-        if (ctx->backend == _FW_BACKEND_INVALID) {
-
-                if (fw_nftables_init_full(ctx, init_tables) >= 0)
-                        ctx->backend = FW_BACKEND_NFTABLES;
-                else
-                        ctx->backend = FW_BACKEND_NONE;
-        }
-
-        if (ctx->backend != FW_BACKEND_NONE)
-                log_debug("Using %s as firewall backend.", firewall_backend_to_string(ctx->backend));
-        else
-                log_debug("No firewall backend found.");
-}
-
-int fw_ctx_new_full(FirewallContext **ret, bool init_tables) {
-        _cleanup_free_ FirewallContext *ctx = NULL;
-
-        ctx = new(FirewallContext, 1);
-        if (!ctx)
-                return -ENOMEM;
-
-        *ctx = (FirewallContext) {
-                .backend = _FW_BACKEND_INVALID,
-        };
-
-        firewall_backend_probe(ctx, init_tables);
-
-        *ret = TAKE_PTR(ctx);
-        return 0;
-}
-
-int fw_ctx_new(FirewallContext **ret) {
-        return fw_ctx_new_full(ret, /* init_tables= */ true);
-}
-
-FirewallContext *fw_ctx_free(FirewallContext *ctx) {
-        if (!ctx)
-                return NULL;
-
-        fw_nftables_exit(ctx);
-
-        return mfree(ctx);
-}
-
-size_t fw_ctx_get_reply_callback_count(FirewallContext *ctx) {
-        if (!ctx || !ctx->nfnl)
-                return 0;
-
-        return netlink_get_reply_callback_count(ctx->nfnl);
-}
-
-int fw_add_masquerade(
-                FirewallContext **ctx,
-                bool add,
-                int af,
-                const union in_addr_union *source,
-                unsigned source_prefixlen) {
-
-        int r;
-
-        assert(ctx);
-
-        if (!*ctx) {
-                r = fw_ctx_new(ctx);
-                if (r < 0)
-                        return r;
-        }
-
-        switch ((*ctx)->backend) {
-        case FW_BACKEND_NFTABLES:
-                return fw_nftables_add_masquerade(*ctx, add, af, source, source_prefixlen);
-        default:
-                return -EOPNOTSUPP;
-        }
-}
-
-int fw_add_local_dnat(
-                FirewallContext **ctx,
-                bool add,
-                int af,
-                int protocol,
-                uint16_t local_port,
-                const union in_addr_union *remote,
-                uint16_t remote_port,
-                const union in_addr_union *previous_remote) {
-
-        int r;
-
-        assert(ctx);
-
-        if (!*ctx) {
-                r = fw_ctx_new(ctx);
-                if (r < 0)
-                        return r;
-        }
-
-        switch ((*ctx)->backend) {
-        case FW_BACKEND_NFTABLES:
-                return fw_nftables_add_local_dnat(*ctx, add, af, protocol, local_port, remote, remote_port, previous_remote);
-        default:
-                return -EOPNOTSUPP;
-        }
-}
index d4acac55eed7f301a0e9d02ecab74d52a63eb5f1..595da38ef6fa5952e25f6f562601068f6b325834 100644 (file)
@@ -4,25 +4,15 @@
 #include "conf-parser-forward.h"
 #include "forward.h"
 
-typedef struct FirewallContext FirewallContext;
-
-int fw_ctx_new(FirewallContext **ret);
-int fw_ctx_new_full(FirewallContext **ret, bool init_tables);
-FirewallContext *fw_ctx_free(FirewallContext *ctx);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(FirewallContext *, fw_ctx_free);
-
-size_t fw_ctx_get_reply_callback_count(FirewallContext *ctx);
-
-int fw_add_masquerade(
-                FirewallContext **ctx,
+int fw_nftables_add_masquerade(
+                sd_netlink *nfnl,
                 bool add,
                 int af,
                 const union in_addr_union *source,
                 unsigned source_prefixlen);
 
-int fw_add_local_dnat(
-                FirewallContext **ctx,
+int fw_nftables_add_local_dnat(
+                sd_netlink *nfnl,
                 bool add,
                 int af,
                 int protocol,
@@ -64,7 +54,7 @@ const char* nft_set_source_to_string(int i) _const_;
 int nft_set_source_from_string(const char *s) _pure_;
 
 int nft_set_element_modify_iprange(
-                FirewallContext *ctx,
+                sd_netlink *nfnl,
                 bool add,
                 int nfproto,
                 int af,
@@ -74,7 +64,7 @@ int nft_set_element_modify_iprange(
                 unsigned source_prefixlen);
 
 int nft_set_element_modify_ip(
-                FirewallContext *ctx,
+                sd_netlink *nfnl,
                 bool add,
                 int nfproto,
                 int af,
@@ -83,7 +73,7 @@ int nft_set_element_modify_ip(
                 const union in_addr_union *source);
 
 int nft_set_element_modify_any(
-                FirewallContext *ctx,
+                sd_netlink *nfnl,
                 bool add,
                 int nfproto,
                 const char *table,
index ef59f2655893f9029356237161cbbb819819498a..27b81de098380c520297f8a97929421a98b37996 100644 (file)
@@ -77,7 +77,6 @@ shared_sources = files(
         'fido2-util.c',
         'find-esp.c',
         'firewall-util-nft.c',
-        'firewall-util.c',
         'fork-notify.c',
         'format-table.c',
         'fstab-util.c',
index d36de6bf16de63b3b930d6ae2a203350cd152d6b..d7080fa34956ff75fa308bb08381cc000cc8a3ed 100644 (file)
@@ -3,22 +3,24 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+#include "sd-netlink.h"
+
 #include "firewall-util.h"
-#include "firewall-util-private.h"
 #include "in-addr-util.h"
 #include "log.h"
+#include "netlink-internal.h"
 #include "random-util.h"
 #include "socket-util.h"
 #include "tests.h"
 
-static void test_v6(FirewallContext *ctx) {
+static sd_netlink *nfnl = NULL;
+
+TEST(v6) {
         union in_addr_union u1, u2, u3;
         uint8_t prefixlen;
         int r;
 
-        ASSERT_NOT_NULL(ctx);
-
-        log_info("/* %s(backend=%s) */", __func__, firewall_backend_to_string(ctx->backend));
+        ASSERT_NOT_NULL(nfnl);
 
         if (!socket_ipv6_is_supported())
                 return log_info("IPv6 is not supported by kernel, skipping tests.");
@@ -29,22 +31,19 @@ static void test_v6(FirewallContext *ctx) {
         prefixlen = random_u64_range(128 + 1 - 8) + 8;
         random_bytes(&u3, sizeof(u3));
 
-        ASSERT_OK(fw_add_masquerade(&ctx, true, AF_INET6, &u1, 128));
-        ASSERT_OK(fw_add_masquerade(&ctx, false, AF_INET6, &u1, 128));
-        ASSERT_OK(fw_add_masquerade(&ctx, true, AF_INET6, &u1, 64));
-        ASSERT_OK(fw_add_masquerade(&ctx, false, AF_INET6, &u1, 64));
-        ASSERT_OK(fw_add_masquerade(&ctx, true, AF_INET6, &u3, prefixlen));
-        ASSERT_OK(fw_add_masquerade(&ctx, false, AF_INET6, &u3, prefixlen));
-
-        r = fw_add_local_dnat(&ctx, true, AF_INET6, IPPROTO_TCP, 4711, &u1, 815, NULL);
-        if (r == -EOPNOTSUPP) {
-                log_info("IPv6 DNAT seems not supported, skipping the following tests.");
-                return;
-        }
-        ASSERT_OK(r);
-
-        ASSERT_OK(fw_add_local_dnat(&ctx, true, AF_INET6, IPPROTO_TCP, 4711, &u2, 815, &u1));
-        ASSERT_OK(fw_add_local_dnat(&ctx, false, AF_INET6, IPPROTO_TCP, 4711, &u2, 815, NULL));
+        ASSERT_OK_OR(r = fw_nftables_add_masquerade(nfnl, true, AF_INET6, &u1, 128),
+                     -EPERM, -EOPNOTSUPP, -ENOPROTOOPT);
+        if (r < 0)
+                return (void) log_tests_skipped_errno(r, "Failed to add IPv6 masquerade");
+
+        ASSERT_OK(fw_nftables_add_masquerade(nfnl, false, AF_INET6, &u1, 128));
+        ASSERT_OK(fw_nftables_add_masquerade(nfnl, true, AF_INET6, &u1, 64));
+        ASSERT_OK(fw_nftables_add_masquerade(nfnl, false, AF_INET6, &u1, 64));
+        ASSERT_OK(fw_nftables_add_masquerade(nfnl, true, AF_INET6, &u3, prefixlen));
+        ASSERT_OK(fw_nftables_add_masquerade(nfnl, false, AF_INET6, &u3, prefixlen));
+        ASSERT_OK(fw_nftables_add_local_dnat(nfnl, true, AF_INET6, IPPROTO_TCP, 4711, &u1, 815, NULL));
+        ASSERT_OK(fw_nftables_add_local_dnat(nfnl, true, AF_INET6, IPPROTO_TCP, 4711, &u2, 815, &u1));
+        ASSERT_OK(fw_nftables_add_local_dnat(nfnl, false, AF_INET6, IPPROTO_TCP, 4711, &u2, 815, NULL));
 }
 
 static union in_addr_union *parse_addr(const char *str, union in_addr_union *u) {
@@ -54,45 +53,31 @@ static union in_addr_union *parse_addr(const char *str, union in_addr_union *u)
         return u;
 }
 
-static bool test_v4(FirewallContext *ctx) {
+TEST(v4) {
         union in_addr_union u, v;
         int r;
 
-        ASSERT_NOT_NULL(ctx);
-
-        log_info("/* %s(backend=%s) */", __func__, firewall_backend_to_string(ctx->backend));
-
-        ASSERT_ERROR(fw_add_masquerade(&ctx, true, AF_INET, NULL, 0), EINVAL);
-        ASSERT_ERROR(fw_add_masquerade(&ctx, true, AF_INET, parse_addr("10.1.2.0", &u), 0), EINVAL);
-
-        r = fw_add_masquerade(&ctx, true, AF_INET, parse_addr("10.1.2.3", &u), 32);
-        if (r < 0) {
-                bool ignore = IN_SET(r, -EPERM, -EOPNOTSUPP, -ENOPROTOOPT);
-
-                log_full_errno(ignore ? LOG_DEBUG : LOG_ERR, r,
-                               "Failed to add IPv4 masquerade%s: %m",
-                               ignore ? ", skipping following tests" : "");
+        ASSERT_NOT_NULL(nfnl);
 
-                if (ignore)
-                        return false;
-        }
-        ASSERT_OK(r);
+        ASSERT_ERROR(fw_nftables_add_masquerade(nfnl, true, AF_INET, NULL, 0), EINVAL);
+        ASSERT_ERROR(fw_nftables_add_masquerade(nfnl, true, AF_INET, parse_addr("10.1.2.0", &u), 0), EINVAL);
 
-        ASSERT_OK(fw_add_masquerade(&ctx, true, AF_INET, parse_addr("10.0.2.0", &u), 28));
-        ASSERT_OK(fw_add_masquerade(&ctx, false, AF_INET, parse_addr("10.0.2.0", &u), 28));
-        ASSERT_OK(fw_add_masquerade(&ctx, false, AF_INET, parse_addr("10.1.2.3", &u), 32));
-        ASSERT_OK(fw_add_local_dnat(&ctx, true, AF_INET, IPPROTO_TCP, 4711, parse_addr("1.2.3.4", &u), 815, NULL));
-        ASSERT_OK(fw_add_local_dnat(&ctx, true, AF_INET, IPPROTO_TCP, 4711, parse_addr("1.2.3.4", &u), 815, NULL));
-        ASSERT_OK(fw_add_local_dnat(&ctx, true, AF_INET, IPPROTO_TCP, 4711, parse_addr("1.2.3.5", &u), 815, parse_addr("1.2.3.4", &v)));
-        ASSERT_OK(fw_add_local_dnat(&ctx, false, AF_INET, IPPROTO_TCP, 4711, parse_addr("1.2.3.5", &u), 815, NULL));
+        ASSERT_OK_OR(r = fw_nftables_add_masquerade(nfnl, true, AF_INET, parse_addr("10.1.2.3", &u), 32),
+                     -EPERM, -EOPNOTSUPP, -ENOPROTOOPT);
+        if (r < 0)
+                return (void) log_tests_skipped_errno(r, "Failed to add IPv4 masquerade");
 
-        return true;
+        ASSERT_OK(fw_nftables_add_masquerade(nfnl, true, AF_INET, parse_addr("10.0.2.0", &u), 28));
+        ASSERT_OK(fw_nftables_add_masquerade(nfnl, false, AF_INET, parse_addr("10.0.2.0", &u), 28));
+        ASSERT_OK(fw_nftables_add_masquerade(nfnl, false, AF_INET, parse_addr("10.1.2.3", &u), 32));
+        ASSERT_OK(fw_nftables_add_local_dnat(nfnl, true, AF_INET, IPPROTO_TCP, 4711, parse_addr("1.2.3.4", &u), 815, NULL));
+        ASSERT_OK(fw_nftables_add_local_dnat(nfnl, true, AF_INET, IPPROTO_TCP, 4711, parse_addr("1.2.3.4", &u), 815, NULL));
+        ASSERT_OK(fw_nftables_add_local_dnat(nfnl, true, AF_INET, IPPROTO_TCP, 4711, parse_addr("1.2.3.5", &u), 815, parse_addr("1.2.3.4", &v)));
+        ASSERT_OK(fw_nftables_add_local_dnat(nfnl, false, AF_INET, IPPROTO_TCP, 4711, parse_addr("1.2.3.5", &u), 815, NULL));
 }
 
-int main(int argc, char *argv[]) {
-        _cleanup_(fw_ctx_freep) FirewallContext *ctx = NULL;
-
-        test_setup_logging(LOG_DEBUG);
+static int intro(void) {
+        int r;
 
         if (getuid() != 0)
                 return log_tests_skipped("not root");
@@ -100,14 +85,16 @@ int main(int argc, char *argv[]) {
         ASSERT_OK_ERRNO(setenv("SYSTEMD_FIREWALL_UTIL_NFT_TABLE_NAME", "io.systemd-test.nat", /* overwrite = */ true));
         ASSERT_OK_ERRNO(setenv("SYSTEMD_FIREWALL_UTIL_DNAT_MAP_NAME", "test_map_port_ipport", /* overwrite = */ true));
 
-        ASSERT_OK(fw_ctx_new(&ctx));
-        ASSERT_NOT_NULL(ctx);
-
-        if (ctx->backend == FW_BACKEND_NONE)
-                return log_tests_skipped("no firewall backend supported");
+        r = sd_nfnl_socket_open(&nfnl);
+        if (r < 0)
+                return log_tests_skipped_errno(r, "Failed to initialize nftables");
 
-        if (test_v4(ctx) && ctx->backend == FW_BACKEND_NFTABLES)
-                test_v6(ctx);
+        return 0;
+}
 
+static int outro(void) {
+        sd_netlink_unref(nfnl);
         return 0;
 }
+
+DEFINE_TEST_MAIN_FULL(LOG_DEBUG, intro, outro);
index 6ae2da03eb4cd3aac70db829c083090e1cc77517..239f9a08f7b430fac6708cc055da29f5959e2031 100644 (file)
@@ -2,6 +2,8 @@
 
 #include <unistd.h>
 
+#include "sd-netlink.h"
+
 #include "firewall-util.h"
 #include "in-addr-util.h"
 #include "netlink-internal.h"
@@ -25,9 +27,8 @@ int main(int argc, char **argv) {
 
         const char *table = argv[3], *set = argv[4];
 
-        FirewallContext *ctx;
-        r = fw_ctx_new(&ctx);
-        assert_se(r == 0);
+        _cleanup_(sd_netlink_unrefp) sd_netlink *nfnl = NULL;
+        ASSERT_OK(sd_nfnl_socket_open(&nfnl));
 
         bool add;
         if (streq(argv[1], "add"))
@@ -41,7 +42,7 @@ int main(int argc, char **argv) {
                 r = safe_atou32(argv[6], &element);
                 assert_se(r == 0);
 
-                r = nft_set_element_modify_any(ctx, add, nfproto, table, set, &element, sizeof(element));
+                r = nft_set_element_modify_any(nfnl, add, nfproto, table, set, &element, sizeof(element));
                 assert_se(r == 0);
         } else if (streq(argv[5], "uint64")) {
                 uint64_t element;
@@ -49,7 +50,7 @@ int main(int argc, char **argv) {
                 r = safe_atou64(argv[6], &element);
                 assert_se(r == 0);
 
-                r = nft_set_element_modify_any(ctx, add, nfproto, table, set, &element, sizeof(element));
+                r = nft_set_element_modify_any(nfnl, add, nfproto, table, set, &element, sizeof(element));
                 assert_se(r == 0);
         } else if (streq(argv[5], "in_addr")) {
                 union in_addr_union addr;
@@ -58,7 +59,7 @@ int main(int argc, char **argv) {
                 r = in_addr_from_string_auto(argv[6], &af, &addr);
                 assert_se(r == 0);
 
-                r = nft_set_element_modify_ip(ctx, add, nfproto, af, table, set, &addr);
+                r = nft_set_element_modify_ip(nfnl, add, nfproto, af, table, set, &addr);
                 assert_se(r == 0);
         } else if (streq(argv[5], "network")) {
                 union in_addr_union addr;
@@ -68,7 +69,7 @@ int main(int argc, char **argv) {
                 r = in_addr_prefix_from_string_auto(argv[6], &af, &addr, &prefixlen);
                 assert_se(r == 0);
 
-                r = nft_set_element_modify_iprange(ctx, add, nfproto, af, table, set, &addr, prefixlen);
+                r = nft_set_element_modify_iprange(nfnl, add, nfproto, af, table, set, &addr, prefixlen);
                 assert_se(r == 0);
         }