mirror of
https://github.com/systemd/systemd
synced 2024-07-21 10:17:21 +00:00
Merge pull request #29836 from poettering/libiptc-dlopen
make libiptc dep a dlopen() one
This commit is contained in:
commit
b75b8e1d02
2
TODO
2
TODO
|
@ -1409,8 +1409,6 @@ Features:
|
|||
- libpam (only when called from PID 1)
|
||||
- bzip2, xz, lz4 (always — gzip and zstd should probably stay static deps the way they are,
|
||||
since they are so basic and our defaults)
|
||||
o move into separate libsystemd-shared-iptables.so .so
|
||||
- iptables-libs (only used by nspawn + networkd)
|
||||
|
||||
* seccomp: maybe use seccomp_merge() to merge our filters per-arch if we can.
|
||||
Apparently kernel performance is much better with fewer larger seccomp
|
||||
|
|
|
@ -573,3 +573,9 @@ SYSTEMD_HOME_DEBUG_SUFFIX=foo \
|
|||
|
||||
* `$SYSTEMD_REPART_OVERRIDE_FSTYPE` – if set the value will override the file
|
||||
system type specified in Format= lines in partition definition files.
|
||||
|
||||
`systemd-nspawn`, `systemd-networkd`:
|
||||
|
||||
* `$SYSTEMD_FIREWALL_BACKEND` – takes a string, either `iptables` or
|
||||
`nftables`. Selects the firewall backend to use. If not specified tries to
|
||||
use `nftables` and falls back to `iptables` if that's not available.
|
||||
|
|
|
@ -1288,6 +1288,7 @@ conf.set10('HAVE_LIBIDN2', have)
|
|||
libiptc = dependency('libiptc',
|
||||
required : get_option('libiptc'))
|
||||
conf.set10('HAVE_LIBIPTC', libiptc.found())
|
||||
libiptc_cflags = libiptc.partial_dependency(includes: true, compile_args: true)
|
||||
|
||||
libqrencode = dependency('libqrencode',
|
||||
version : '>= 3',
|
||||
|
|
|
@ -15,6 +15,11 @@ int dlopen_many_sym_or_warn_sentinel(void **dlp, const char *filename, int log_l
|
|||
#define dlopen_many_sym_or_warn(dlp, filename, log_level, ...) \
|
||||
dlopen_many_sym_or_warn_sentinel(dlp, filename, log_level, __VA_ARGS__, NULL)
|
||||
|
||||
#define DLSYM_PROTOTYPE(symbol) \
|
||||
extern typeof(symbol)* sym_##symbol
|
||||
#define DLSYM_FUNCTION(symbol) \
|
||||
typeof(symbol)* sym_##symbol = NULL
|
||||
|
||||
/* Macro useful for putting together variable/symbol name pairs when calling dlsym_many_or_warn(). Assumes
|
||||
* that each library symbol to resolve will be placed in a variable with the "sym_" prefix, i.e. a symbol
|
||||
* "foobar" is loaded into a variable "sym_foobar". */
|
||||
|
|
|
@ -21,13 +21,24 @@
|
|||
#include <libiptc/libiptc.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "dlfcn-util.h"
|
||||
#include "firewall-util.h"
|
||||
#include "firewall-util-private.h"
|
||||
#include "in-addr-util.h"
|
||||
#include "macro.h"
|
||||
#include "socket-util.h"
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct xtc_handle*, iptc_free, NULL);
|
||||
static DLSYM_FUNCTION(iptc_check_entry);
|
||||
static DLSYM_FUNCTION(iptc_commit);
|
||||
static DLSYM_FUNCTION(iptc_delete_entry);
|
||||
static DLSYM_FUNCTION(iptc_free);
|
||||
static DLSYM_FUNCTION(iptc_init);
|
||||
static DLSYM_FUNCTION(iptc_insert_entry);
|
||||
static DLSYM_FUNCTION(iptc_strerror);
|
||||
|
||||
static void *iptc_dl = NULL;
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct xtc_handle*, sym_iptc_free, NULL);
|
||||
|
||||
static int entry_fill_basics(
|
||||
struct ipt_entry *entry,
|
||||
|
@ -86,7 +97,7 @@ int fw_iptables_add_masquerade(
|
|||
unsigned source_prefixlen) {
|
||||
|
||||
static const xt_chainlabel chain = "POSTROUTING";
|
||||
_cleanup_(iptc_freep) struct xtc_handle *h = NULL;
|
||||
_cleanup_(sym_iptc_freep) struct xtc_handle *h = NULL;
|
||||
struct ipt_entry *entry, *mask;
|
||||
struct ipt_entry_target *t;
|
||||
size_t sz;
|
||||
|
@ -132,15 +143,15 @@ int fw_iptables_add_masquerade(
|
|||
memset(mask, 0xFF, sz);
|
||||
|
||||
if (add) {
|
||||
if (iptc_check_entry(chain, entry, (unsigned char*) mask, h))
|
||||
if (sym_iptc_check_entry(chain, entry, (unsigned char*) mask, h))
|
||||
return 0;
|
||||
if (errno != ENOENT) /* if other error than not existing yet, fail */
|
||||
return -errno;
|
||||
|
||||
if (!iptc_insert_entry(chain, entry, 0, h))
|
||||
if (!sym_iptc_insert_entry(chain, entry, 0, h))
|
||||
return -errno;
|
||||
} else {
|
||||
if (!iptc_delete_entry(chain, entry, (unsigned char*) mask, h)) {
|
||||
if (!sym_iptc_delete_entry(chain, entry, (unsigned char*) mask, h)) {
|
||||
if (errno == ENOENT) /* if it's already gone, all is good! */
|
||||
return 0;
|
||||
|
||||
|
@ -148,7 +159,7 @@ int fw_iptables_add_masquerade(
|
|||
}
|
||||
}
|
||||
|
||||
if (!iptc_commit(h))
|
||||
if (!sym_iptc_commit(h))
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
|
@ -164,7 +175,7 @@ int fw_iptables_add_local_dnat(
|
|||
const union in_addr_union *previous_remote) {
|
||||
|
||||
static const xt_chainlabel chain_pre = "PREROUTING", chain_output = "OUTPUT";
|
||||
_cleanup_(iptc_freep) struct xtc_handle *h = NULL;
|
||||
_cleanup_(sym_iptc_freep) struct xtc_handle *h = NULL;
|
||||
struct ipt_entry *entry, *mask;
|
||||
struct ipt_entry_target *t;
|
||||
struct ipt_entry_match *m;
|
||||
|
@ -275,11 +286,11 @@ int fw_iptables_add_local_dnat(
|
|||
|
||||
if (add) {
|
||||
/* Add the PREROUTING rule, if it is missing so far */
|
||||
if (!iptc_check_entry(chain_pre, entry, (unsigned char*) mask, h)) {
|
||||
if (!sym_iptc_check_entry(chain_pre, entry, (unsigned char*) mask, h)) {
|
||||
if (errno != ENOENT)
|
||||
return -EINVAL;
|
||||
|
||||
if (!iptc_insert_entry(chain_pre, entry, 0, h))
|
||||
if (!sym_iptc_insert_entry(chain_pre, entry, 0, h))
|
||||
return -errno;
|
||||
}
|
||||
|
||||
|
@ -287,7 +298,7 @@ int fw_iptables_add_local_dnat(
|
|||
if (previous_remote && previous_remote->in.s_addr != remote->in.s_addr) {
|
||||
mr->range[0].min_ip = mr->range[0].max_ip = previous_remote->in.s_addr;
|
||||
|
||||
if (!iptc_delete_entry(chain_pre, entry, (unsigned char*) mask, h)) {
|
||||
if (!sym_iptc_delete_entry(chain_pre, entry, (unsigned char*) mask, h)) {
|
||||
if (errno != ENOENT)
|
||||
return -errno;
|
||||
}
|
||||
|
@ -305,11 +316,11 @@ int fw_iptables_add_local_dnat(
|
|||
entry->ip.invflags = IPT_INV_DSTIP;
|
||||
}
|
||||
|
||||
if (!iptc_check_entry(chain_output, entry, (unsigned char*) mask, h)) {
|
||||
if (!sym_iptc_check_entry(chain_output, entry, (unsigned char*) mask, h)) {
|
||||
if (errno != ENOENT)
|
||||
return -errno;
|
||||
|
||||
if (!iptc_insert_entry(chain_output, entry, 0, h))
|
||||
if (!sym_iptc_insert_entry(chain_output, entry, 0, h))
|
||||
return -errno;
|
||||
}
|
||||
|
||||
|
@ -317,14 +328,14 @@ int fw_iptables_add_local_dnat(
|
|||
if (previous_remote && previous_remote->in.s_addr != remote->in.s_addr) {
|
||||
mr->range[0].min_ip = mr->range[0].max_ip = previous_remote->in.s_addr;
|
||||
|
||||
if (!iptc_delete_entry(chain_output, entry, (unsigned char*) mask, h)) {
|
||||
if (!sym_iptc_delete_entry(chain_output, entry, (unsigned char*) mask, h)) {
|
||||
if (errno != ENOENT)
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!iptc_delete_entry(chain_pre, entry, (unsigned char*) mask, h)) {
|
||||
if (!sym_iptc_delete_entry(chain_pre, entry, (unsigned char*) mask, h)) {
|
||||
if (errno != ENOENT)
|
||||
return -errno;
|
||||
}
|
||||
|
@ -336,25 +347,43 @@ int fw_iptables_add_local_dnat(
|
|||
entry->ip.invflags = IPT_INV_DSTIP;
|
||||
}
|
||||
|
||||
if (!iptc_delete_entry(chain_output, entry, (unsigned char*) mask, h)) {
|
||||
if (!sym_iptc_delete_entry(chain_output, entry, (unsigned char*) mask, h)) {
|
||||
if (errno != ENOENT)
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!iptc_commit(h))
|
||||
if (!sym_iptc_commit(h))
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fw_iptables_init_nat(struct xtc_handle **ret) {
|
||||
_cleanup_(iptc_freep) struct xtc_handle *h = NULL;
|
||||
static int dlopen_iptc(void) {
|
||||
return dlopen_many_sym_or_warn(
|
||||
&iptc_dl,
|
||||
"libip4tc.so.2", LOG_DEBUG,
|
||||
DLSYM_ARG(iptc_check_entry),
|
||||
DLSYM_ARG(iptc_commit),
|
||||
DLSYM_ARG(iptc_delete_entry),
|
||||
DLSYM_ARG(iptc_free),
|
||||
DLSYM_ARG(iptc_init),
|
||||
DLSYM_ARG(iptc_insert_entry),
|
||||
DLSYM_ARG(iptc_strerror));
|
||||
}
|
||||
|
||||
h = iptc_init("nat");
|
||||
int fw_iptables_init_nat(struct xtc_handle **ret) {
|
||||
_cleanup_(sym_iptc_freep) struct xtc_handle *h = NULL;
|
||||
int r;
|
||||
|
||||
r = dlopen_iptc();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
h = sym_iptc_init("nat");
|
||||
if (!h)
|
||||
return log_debug_errno(errno, "Failed to init \"nat\" table: %s", iptc_strerror(errno));
|
||||
return log_debug_errno(errno, "Failed to init \"nat\" table: %s", sym_iptc_strerror(errno));
|
||||
|
||||
if (ret)
|
||||
*ret = TAKE_PTR(h);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "sd-netlink.h"
|
||||
|
||||
#include "firewall-util.h"
|
||||
#include "in-addr-util.h"
|
||||
|
||||
typedef enum FirewallBackend {
|
||||
|
|
|
@ -21,19 +21,38 @@ static const char * const firewall_backend_table[_FW_BACKEND_MAX] = {
|
|||
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;
|
||||
|
||||
if (fw_nftables_init_full(ctx, init_tables) >= 0)
|
||||
ctx->backend = FW_BACKEND_NFTABLES;
|
||||
else
|
||||
e = secure_getenv("SYSTEMD_FIREWALL_BACKEND");
|
||||
if (e) {
|
||||
if (streq(e, "nftables"))
|
||||
ctx->backend = FW_BACKEND_NFTABLES;
|
||||
else if (streq(e, "iptables"))
|
||||
#if HAVE_LIBIPTC
|
||||
ctx->backend = FW_BACKEND_IPTABLES;
|
||||
ctx->backend = FW_BACKEND_IPTABLES;
|
||||
#else
|
||||
ctx->backend = FW_BACKEND_NONE;
|
||||
log_debug("Unsupported firewall backend requested, ignoring: %s", e);
|
||||
#endif
|
||||
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
|
||||
#if HAVE_LIBIPTC
|
||||
ctx->backend = FW_BACKEND_IPTABLES;
|
||||
#else
|
||||
ctx->backend = FW_BACKEND_NONE;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ctx->backend != FW_BACKEND_NONE)
|
||||
log_debug("Using %s as firewall backend.", firewall_backend_to_string(ctx->backend));
|
||||
|
|
|
@ -316,7 +316,7 @@ libshared_deps = [threads,
|
|||
libcrypt,
|
||||
libdl,
|
||||
libgcrypt,
|
||||
libiptc,
|
||||
libiptc_cflags,
|
||||
libkmod,
|
||||
liblz4,
|
||||
libmount,
|
||||
|
|
Loading…
Reference in a new issue