if (r < 0)
return r;
- r = fw_add_masquerade(add, AF_INET, &masked, address->prefixlen);
+ r = fw_add_masquerade(&address->link->manager->fw_ctx, add, AF_INET, &masked, address->prefixlen);
if (r < 0)
return r;
#include "dns-domain.h"
#include "fd-util.h"
#include "fileio.h"
+#include "firewall-util.h"
#include "local-addresses.h"
#include "netlink-util.h"
#include "network-internal.h"
safe_close(m->ethtool_fd);
+ m->fw_ctx = fw_ctx_free(m->fw_ctx);
+
free(m);
}
#include "sd-resolve.h"
#include "dhcp-identifier.h"
+#include "firewall-util.h"
#include "hashmap.h"
#include "networkd-link.h"
#include "networkd-network.h"
bool dhcp4_prefix_root_cannot_set_table:1;
bool bridge_mdb_on_master_not_supported:1;
+
+ FirewallContext *fw_ctx;
};
int manager_new(Manager **ret);
#include "capability-util.h"
#include "daemon-util.h"
+#include "firewall-util.h"
#include "main-func.h"
#include "mkdir.h"
#include "networkd-conf.h"
if (r < 0)
return r;
+ r = fw_ctx_new(&m->fw_ctx);
+ if (r < 0)
+ log_warning_errno(r, "Could not initialize firewall, IPMasquerade= option not available: %m");
+
r = manager_start(m);
if (r < 0)
return log_error_errno(r, "Could not start manager: %m");
}
}
-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;
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,
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;
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))
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,
#include <inttypes.h>
+#include "firewall-util.h"
+
#include "sd-event.h"
#include "sd-netlink.h"
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);
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;
}
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 = {
(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]);
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;
_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();
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;
(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);
#include "in-addr-util.h"
+enum FirewallBackend {
+ FW_BACKEND_NONE,
+#if HAVE_LIBIPTC
+ FW_BACKEND_IPTABLES,
+#endif
+};
+
+struct FirewallContext {
+ enum FirewallBackend firewall_backend;
+};
+
#if HAVE_LIBIPTC
int fw_iptables_add_masquerade(
#include "firewall-util.h"
#include "firewall-util-private.h"
-enum FirewallBackend {
- FW_BACKEND_NONE,
-#if HAVE_LIBIPTC
- FW_BACKEND_IPTABLES,
-#endif
-};
-
-static enum FirewallBackend FirewallBackend;
-
static enum FirewallBackend firewall_backend_probe(void) {
#if HAVE_LIBIPTC
return FW_BACKEND_IPTABLES;
#endif
}
+int fw_ctx_new(FirewallContext **ret) {
+ _cleanup_free_ FirewallContext *ctx = NULL;
+
+ ctx = new0(FirewallContext, 1);
+ if (!ctx)
+ return -ENOMEM;
+
+ *ret = TAKE_PTR(ctx);
+ return 0;
+}
+
+FirewallContext *fw_ctx_free(FirewallContext *ctx) {
+ return mfree(ctx);
+}
+
int fw_add_masquerade(
+ FirewallContext **fw_ctx,
bool add,
int af,
const union in_addr_union *source,
unsigned source_prefixlen) {
+ FirewallContext *ctx;
+ int r;
- if (FirewallBackend == FW_BACKEND_NONE)
- FirewallBackend = firewall_backend_probe();
+ if (!*fw_ctx) {
+ r = fw_ctx_new(fw_ctx);
+ if (r < 0)
+ return r;
+ }
- switch (FirewallBackend) {
+ ctx = *fw_ctx;
+ if (ctx->firewall_backend == FW_BACKEND_NONE)
+ ctx->firewall_backend = firewall_backend_probe();
+
+ switch (ctx->firewall_backend) {
case FW_BACKEND_NONE:
return -EOPNOTSUPP;
#if HAVE_LIBIPTC
}
int fw_add_local_dnat(
+ FirewallContext **fw_ctx,
bool add,
int af,
int protocol,
const union in_addr_union *remote,
uint16_t remote_port,
const union in_addr_union *previous_remote) {
+ FirewallContext *ctx;
+
+ if (!*fw_ctx) {
+ int ret = fw_ctx_new(fw_ctx);
+ if (ret < 0)
+ return ret;
+ }
- if (FirewallBackend == FW_BACKEND_NONE)
- FirewallBackend = firewall_backend_probe();
+ ctx = *fw_ctx;
+ if (ctx->firewall_backend == FW_BACKEND_NONE)
+ ctx->firewall_backend = firewall_backend_probe();
- switch (FirewallBackend) {
+ switch (ctx->firewall_backend) {
case FW_BACKEND_NONE:
return -EOPNOTSUPP;
#if HAVE_LIBIPTC
#include "in-addr-util.h"
+typedef struct FirewallContext FirewallContext;
+
+int fw_ctx_new(FirewallContext **ret);
+FirewallContext *fw_ctx_free(FirewallContext *fw_ctx);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(FirewallContext *, fw_ctx_free);
+
int fw_add_masquerade(
+ FirewallContext **fw_ctx,
bool add,
int af,
const union in_addr_union *source,
unsigned source_prefixlen);
int fw_add_local_dnat(
+ FirewallContext **fw_ctx,
bool add,
int af,
int protocol,
#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))}
int main(int argc, char *argv[]) {
+ _cleanup_(fw_ctx_freep) FirewallContext *ctx;
int r;
test_setup_logging(LOG_DEBUG);
uint8_t prefixlen = 32;
- r = fw_add_masquerade(true, AF_INET, NULL, 0);
+ r = fw_ctx_new(&ctx);
+ if (r < 0)
+ return log_error_errno(r, "Failed to init firewall: %m");
+
+ r = fw_add_masquerade(&ctx, true, AF_INET, NULL, 0);
if (r == 0)
log_error("Expected failure: NULL source");
- r = fw_add_masquerade(true, AF_INET, &MAKE_IN_ADDR_UNION(10,1,2,0), 0);
+ r = fw_add_masquerade(&ctx, true, AF_INET, &MAKE_IN_ADDR_UNION(10,1,2,0), 0);
if (r == 0)
log_error("Expected failure: 0 prefixlen");
- r = fw_add_masquerade(true, AF_INET, &MAKE_IN_ADDR_UNION(10,1,2,3), prefixlen);
+ r = fw_add_masquerade(&ctx, true, AF_INET, &MAKE_IN_ADDR_UNION(10,1,2,3), prefixlen);
if (r < 0)
log_error_errno(r, "Failed to modify firewall: %m");
prefixlen = 28;
- r = fw_add_masquerade(true, AF_INET, &MAKE_IN_ADDR_UNION(10,0,2,0), prefixlen);
+ r = fw_add_masquerade(&ctx, true, AF_INET, &MAKE_IN_ADDR_UNION(10,0,2,0), prefixlen);
if (r < 0)
log_error_errno(r, "Failed to modify firewall: %m");
- r = fw_add_masquerade(false, AF_INET, &MAKE_IN_ADDR_UNION(10,0,2,0), prefixlen);
+ r = fw_add_masquerade(&ctx, false, AF_INET, &MAKE_IN_ADDR_UNION(10,0,2,0), prefixlen);
if (r < 0)
log_error_errno(r, "Failed to modify firewall: %m");
- r = fw_add_masquerade(false, AF_INET, &MAKE_IN_ADDR_UNION(10,1,2,3), 32);
+ r = fw_add_masquerade(&ctx, false, AF_INET, &MAKE_IN_ADDR_UNION(10,1,2,3), 32);
if (r < 0)
log_error_errno(r, "Failed to modify firewall: %m");
- r = fw_add_local_dnat(true, AF_INET, IPPROTO_TCP, 4711, &MAKE_IN_ADDR_UNION(1, 2, 3, 4), 815, NULL);
+ r = fw_add_local_dnat(&ctx, true, AF_INET, IPPROTO_TCP, 4711, &MAKE_IN_ADDR_UNION(1, 2, 3, 4), 815, NULL);
if (r < 0)
log_error_errno(r, "Failed to modify firewall: %m");
- r = fw_add_local_dnat(true, AF_INET, IPPROTO_TCP, 4711, &MAKE_IN_ADDR_UNION(1, 2, 3, 4), 815, NULL);
+ r = fw_add_local_dnat(&ctx, true, AF_INET, IPPROTO_TCP, 4711, &MAKE_IN_ADDR_UNION(1, 2, 3, 4), 815, NULL);
if (r < 0)
log_error_errno(r, "Failed to modify firewall: %m");
- r = fw_add_local_dnat(true, AF_INET, IPPROTO_TCP, 4711, &MAKE_IN_ADDR_UNION(1, 2, 3, 5), 815, &MAKE_IN_ADDR_UNION(1, 2, 3, 4));
+ r = fw_add_local_dnat(&ctx, true, AF_INET, IPPROTO_TCP, 4711, &MAKE_IN_ADDR_UNION(1, 2, 3, 5), 815, &MAKE_IN_ADDR_UNION(1, 2, 3, 4));
if (r < 0)
log_error_errno(r, "Failed to modify firewall: %m");
- r = fw_add_local_dnat(false, AF_INET, IPPROTO_TCP, 4711, &MAKE_IN_ADDR_UNION(1, 2, 3, 5), 815, NULL);
+ r = fw_add_local_dnat(&ctx, false, AF_INET, IPPROTO_TCP, 4711, &MAKE_IN_ADDR_UNION(1, 2, 3, 5), 815, NULL);
if (r < 0)
log_error_errno(r, "Failed to modify firewall: %m");