summaryrefslogtreecommitdiff
path: root/src/nspawn
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2020-09-15 19:58:44 +0200
committerFlorian Westphal <fw@strlen.de>2020-12-16 00:35:56 +0100
commit761cf19d7bc4b5950caff33965508d9fb7bbb547 (patch)
tree62a913a54080a2680138582a4753f5a9b52705ff /src/nspawn
parentf51343d0af559ed0d00f4dc82b9d3d9e784eea23 (diff)
downloadsystemd-761cf19d7bc4b5950caff33965508d9fb7bbb547.tar.gz
firewall-util: introduce context structure
for planned nft backend we have three choices: - open/close a new nfnetlink socket for every operation - keep a nfnetlink socket open internally - expose a opaque fw_ctx and stash all internal data here. Originally I opted for the 2nd option, but during review it was suggested to avoid static storage duration because of perceived problems with threaded applications. This adds fw_ctx and new/free functions, then converts the existing api and nspawn and networkd to use it.
Diffstat (limited to 'src/nspawn')
-rw-r--r--src/nspawn/nspawn-expose-ports.c12
-rw-r--r--src/nspawn/nspawn-expose-ports.h6
-rw-r--r--src/nspawn/nspawn.c34
3 files changed, 35 insertions, 17 deletions
diff --git a/src/nspawn/nspawn-expose-ports.c b/src/nspawn/nspawn-expose-ports.c
index db076c50c0..c368b20563 100644
--- a/src/nspawn/nspawn-expose-ports.c
+++ b/src/nspawn/nspawn-expose-ports.c
@@ -82,7 +82,7 @@ void expose_port_free_all(ExposePort *p) {
}
}
-int expose_port_flush(ExposePort* l, union in_addr_union *exposed) {
+int expose_port_flush(FirewallContext **fw_ctx, ExposePort* l, union in_addr_union *exposed) {
ExposePort *p;
int r, af = AF_INET;
@@ -97,7 +97,8 @@ int expose_port_flush(ExposePort* l, union in_addr_union *exposed) {
log_debug("Lost IP address.");
LIST_FOREACH(ports, p, l) {
- r = fw_add_local_dnat(false,
+ r = fw_add_local_dnat(fw_ctx,
+ false,
af,
p->protocol,
p->host_port,
@@ -112,7 +113,7 @@ int expose_port_flush(ExposePort* l, union in_addr_union *exposed) {
return 0;
}
-int expose_port_execute(sd_netlink *rtnl, ExposePort *l, union in_addr_union *exposed) {
+int expose_port_execute(sd_netlink *rtnl, FirewallContext **fw_ctx, ExposePort *l, union in_addr_union *exposed) {
_cleanup_free_ struct local_address *addresses = NULL;
union in_addr_union new_exposed;
ExposePort *p;
@@ -136,7 +137,7 @@ int expose_port_execute(sd_netlink *rtnl, ExposePort *l, union in_addr_union *ex
addresses[0].scope < RT_SCOPE_LINK;
if (!add)
- return expose_port_flush(l, exposed);
+ return expose_port_flush(fw_ctx, l, exposed);
new_exposed = addresses[0].address;
if (in_addr_equal(af, exposed, &new_exposed))
@@ -150,7 +151,8 @@ int expose_port_execute(sd_netlink *rtnl, ExposePort *l, union in_addr_union *ex
LIST_FOREACH(ports, p, l) {
- r = fw_add_local_dnat(true,
+ r = fw_add_local_dnat(fw_ctx,
+ true,
af,
p->protocol,
p->host_port,
diff --git a/src/nspawn/nspawn-expose-ports.h b/src/nspawn/nspawn-expose-ports.h
index d0c1cecbe8..c1677cb61b 100644
--- a/src/nspawn/nspawn-expose-ports.h
+++ b/src/nspawn/nspawn-expose-ports.h
@@ -3,6 +3,8 @@
#include <inttypes.h>
+#include "firewall-util.h"
+
#include "sd-event.h"
#include "sd-netlink.h"
@@ -22,5 +24,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, ExposePort *l, union in_addr_union *exposed);
-int expose_port_flush(ExposePort* l, union in_addr_union *exposed);
+int expose_port_execute(sd_netlink *rtnl, FirewallContext **fw_ctx, ExposePort *l, union in_addr_union *exposed);
+int expose_port_flush(FirewallContext **fw_ctx, ExposePort* l, union in_addr_union *exposed);
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index cfbc8f11bf..a6f64e8415 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -2474,14 +2474,19 @@ static int setup_kmsg(int kmsg_socket) {
return 0;
}
+struct ExposeArgs {
+ union in_addr_union address;
+ struct FirewallContext *fw_ctx;
+};
+
static int on_address_change(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
- union in_addr_union *exposed = userdata;
+ struct ExposeArgs *args = userdata;
assert(rtnl);
assert(m);
- assert(exposed);
+ assert(args);
- expose_port_execute(rtnl, arg_expose_ports, exposed);
+ expose_port_execute(rtnl, &args->fw_ctx, arg_expose_ports, &args->address);
return 0;
}
@@ -4466,7 +4471,7 @@ static int run_container(
bool secondary,
FDSet *fds,
char veth_name[IFNAMSIZ], bool *veth_created,
- union in_addr_union *exposed,
+ struct ExposeArgs *expose_args,
int *master, pid_t *pid, int *ret) {
static const struct sigaction sa = {
@@ -4895,11 +4900,11 @@ static int run_container(
(void) sd_event_add_signal(event, NULL, SIGCHLD, on_sigchld, PID_TO_PTR(*pid));
if (arg_expose_ports) {
- r = expose_port_watch_rtnl(event, rtnl_socket_pair[0], on_address_change, exposed, &rtnl);
+ r = expose_port_watch_rtnl(event, rtnl_socket_pair[0], on_address_change, expose_args, &rtnl);
if (r < 0)
return r;
- (void) expose_port_execute(rtnl, arg_expose_ports, exposed);
+ (void) expose_port_execute(rtnl, &expose_args->fw_ctx, arg_expose_ports, &expose_args->address);
}
rtnl_socket_pair[0] = safe_close(rtnl_socket_pair[0]);
@@ -5026,7 +5031,7 @@ static int run_container(
return 0; /* finito */
}
- expose_port_flush(arg_expose_ports, exposed);
+ expose_port_flush(&expose_args->fw_ctx, arg_expose_ports, &expose_args->address);
(void) remove_veth_links(veth_name, arg_network_veth_extra);
*veth_created = false;
@@ -5155,12 +5160,13 @@ static int run(int argc, char *argv[]) {
_cleanup_fdset_free_ FDSet *fds = NULL;
int r, n_fd_passed, ret = EXIT_SUCCESS;
char veth_name[IFNAMSIZ] = "";
- union in_addr_union exposed = {};
+ struct ExposeArgs expose_args = {};
_cleanup_(release_lock_file) LockFile tree_global_lock = LOCK_FILE_INIT, tree_local_lock = LOCK_FILE_INIT;
char tmprootdir[] = "/tmp/nspawn-root-XXXXXX";
_cleanup_(loop_device_unrefp) LoopDevice *loop = NULL;
_cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
_cleanup_(dissected_image_unrefp) DissectedImage *dissected_image = NULL;
+ _cleanup_(fw_ctx_freep) FirewallContext *fw_ctx = NULL;
pid_t pid = 0;
log_parse_environment();
@@ -5517,12 +5523,20 @@ static int run(int argc, char *argv[]) {
goto finish;
}
+ if (arg_expose_ports) {
+ r = fw_ctx_new(&fw_ctx);
+ if (r < 0) {
+ log_error_errno(r, "Cannot expose configured ports, firewall initialization failed: %m");
+ goto finish;
+ }
+ expose_args.fw_ctx = fw_ctx;
+ }
for (;;) {
r = run_container(dissected_image,
secondary,
fds,
veth_name, &veth_created,
- &exposed, &master,
+ &expose_args, &master,
&pid, &ret);
if (r <= 0)
break;
@@ -5572,7 +5586,7 @@ finish:
(void) rm_rf(p, REMOVE_ROOT);
}
- expose_port_flush(arg_expose_ports, &exposed);
+ expose_port_flush(&fw_ctx, arg_expose_ports, &expose_args.address);
if (veth_created)
(void) remove_veth_links(veth_name, arg_network_veth_extra);