diff --git a/daemon/main.c b/daemon/main.c index 9a0120895..108268150 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -19,6 +19,9 @@ #ifdef HAVE_MQTT #include <mosquitto.h> #endif +#ifndef WITHOUT_NFTABLES +#include <linux/netfilter.h> +#endif #include "poller.h" #include "control_tcp.h" @@ -488,6 +491,7 @@ static void options(int *argc, char ***argv) { #ifndef WITHOUT_NFTABLES bool nftables_start = false; bool nftables_stop = false; + AUTO_CLEANUP_GBUF(nftables_family); #endif rwlock_lock_w(&rtpe_config.config_lock); @@ -499,6 +503,7 @@ static void options(int *argc, char ***argv) { { "nftables-chain",0,0, G_OPTION_ARG_STRING, &rtpe_config.nftables_chain, "Name of nftables chain to manage", "STR" }, { "nftables-base-chain",0,0, G_OPTION_ARG_STRING,&rtpe_config.nftables_base_chain,"Name of nftables base chain to use", "STR" }, { "nftables-append",0,0, G_OPTION_ARG_NONE, &rtpe_config.nftables_append, "Append instead of prepend created rules", NULL }, + { "nftables-family",0,0, G_OPTION_ARG_STRING, &nftables_family, "Address family/ies to manage via nftables", "ip|ip6|ip,ip6" }, { "nftables-start",0,0, G_OPTION_ARG_NONE, &nftables_start, "Just add nftables rules and exit", NULL }, { "nftables-stop",0, 0, G_OPTION_ARG_NONE, &nftables_stop, "Just remove nftables rules and exit", NULL }, #endif @@ -660,6 +665,17 @@ static void options(int *argc, char ***argv) { if (rtpe_config.nftables_base_chain == NULL) rtpe_config.nftables_base_chain = g_strdup("INPUT"); + + if (!nftables_family + || !strcmp(nftables_family, "ip,ip6") || !strcmp(nftables_family, "ip4,ip6") + || !strcmp(nftables_family, "ip6,ip") || !strcmp(nftables_family, "ip6,ip4")) + rtpe_config.nftables_family = 0; // default + else if (!strcmp(nftables_family, "ip") || !strcmp(nftables_family, "ip4")) + rtpe_config.nftables_family = NFPROTO_IPV4; + else if (!strcmp(nftables_family, "ip6")) + rtpe_config.nftables_family = NFPROTO_IPV6; + else + die("Invalid value for 'nftables-family' ('%s')", nftables_family); #endif if (codecs) { @@ -679,9 +695,11 @@ static void options(int *argc, char ***argv) { if (nftables_start) err = nftables_setup(rtpe_config.nftables_chain, rtpe_config.nftables_base_chain, (nftables_args) {.table = rtpe_config.kernel_table, - .append = rtpe_config.nftables_append}); + .append = rtpe_config.nftables_append, + .family = rtpe_config.nftables_family}); else // nftables_stop - err = nftables_shutdown(rtpe_config.nftables_chain, rtpe_config.nftables_base_chain); + err = nftables_shutdown(rtpe_config.nftables_chain, rtpe_config.nftables_base_chain, + (nftables_args){.family = rtpe_config.nftables_family}); if (err) die("Failed to perform nftables action: %s (%s)", err, strerror(errno)); printf("Success\n"); @@ -1173,7 +1191,8 @@ static void create_everything(void) { #ifndef WITHOUT_NFTABLES const char *err = nftables_setup(rtpe_config.nftables_chain, rtpe_config.nftables_base_chain, (nftables_args) {.table = rtpe_config.kernel_table, - .append = rtpe_config.nftables_append}); + .append = rtpe_config.nftables_append, + .family = rtpe_config.nftables_family}); if (err) die("Failed to create nftables chains or rules: %s (%s)", err, strerror(errno)); #endif @@ -1457,7 +1476,8 @@ int main(int argc, char **argv) { poller_map_free(&rtpe_poller_map); interfaces_free(); #ifndef WITHOUT_NFTABLES - nftables_shutdown(rtpe_config.nftables_chain, rtpe_config.nftables_base_chain); + nftables_shutdown(rtpe_config.nftables_chain, rtpe_config.nftables_base_chain, + (nftables_args){.family = rtpe_config.nftables_family}); #endif kernel_shutdown_table(); diff --git a/daemon/nftables.c b/daemon/nftables.c index ad153b06c..015a7d097 100644 --- a/daemon/nftables.c +++ b/daemon/nftables.c @@ -343,12 +343,14 @@ static const char *add_rule(struct mnl_socket *nl, int family, uint32_t *seq, static const char *udp_filter(struct nftnl_rule *r, int family) { - AUTO_CLEANUP(struct nftnl_expr *e, expr_free) = nftnl_expr_alloc("payload"); + AUTO_CLEANUP(struct nftnl_expr *e, expr_free); + + static const uint8_t proto = IPPROTO_UDP; + + e = nftnl_expr_alloc("payload"); if (!e) return "failed to allocate payload expr for UDP filter"; - uint8_t proto = IPPROTO_UDP; - nftnl_expr_set_u32(e, NFTNL_EXPR_PAYLOAD_BASE, NFT_PAYLOAD_NETWORK_HEADER); nftnl_expr_set_u32(e, NFTNL_EXPR_PAYLOAD_DREG, NFT_REG_1); if (family == NFPROTO_IPV4) @@ -612,10 +614,15 @@ static const char *nftables_do(const char *chain, const char *base_chain, uint32_t seq = time(NULL); - const char *err = do_func(nl, NFPROTO_IPV4, &seq, chain, base_chain, args); + const char *err = NULL; + + if (args->family == 0 || args->family == NFPROTO_IPV4) + err = do_func(nl, NFPROTO_IPV4, &seq, chain, base_chain, args); if (err) return err; - err = do_func(nl, NFPROTO_IPV6, &seq, chain, base_chain, args); + + if (args->family == 0 || args->family == NFPROTO_IPV6) + err = do_func(nl, NFPROTO_IPV6, &seq, chain, base_chain, args); if (err) return err; @@ -627,6 +634,6 @@ const char *nftables_setup(const char *chain, const char *base_chain, nftables_a return nftables_do(chain, base_chain, nftables_setup_family, &args); } -const char *nftables_shutdown(const char *chain, const char *base_chain) { - return nftables_do(chain, base_chain, nftables_shutdown_family, NULL); +const char *nftables_shutdown(const char *chain, const char *base_chain, nftables_args args) { + return nftables_do(chain, base_chain, nftables_shutdown_family, &args); } diff --git a/docs/rtpengine.md b/docs/rtpengine.md index 6684b26e2..1c45ec7da 100644 --- a/docs/rtpengine.md +++ b/docs/rtpengine.md @@ -123,6 +123,11 @@ at the command line. See the __\-\-config-file__ option below for details. appended to the list of existing rules. The default is to prepend it (insert it at the beginning). +- __\-\-nftables-family=ip__|__ip6__|__ip,ip6__ + + Configure for which netfilter address family to manage tables, chains, and + rules. The default is to manage both IPv4 and IPv6 address families. + - __\-\-nftables-start__ - __\-\-nftables-stop__ diff --git a/include/main.h b/include/main.h index a5bdf7f27..316d3cf86 100644 --- a/include/main.h +++ b/include/main.h @@ -94,6 +94,7 @@ struct rtpengine_config { char *nftables_chain; char *nftables_base_chain; gboolean nftables_append; + int nftables_family; int load_limit; int cpu_limit; uint64_t bw_limit; diff --git a/include/nftables.h b/include/nftables.h index 37a47f5e0..68ccfa458 100644 --- a/include/nftables.h +++ b/include/nftables.h @@ -6,9 +6,10 @@ typedef struct { int table; bool append; + int family; } nftables_args; const char *nftables_setup(const char *chain, const char *base_chain, nftables_args); -const char *nftables_shutdown(const char *chain, const char *base_chain); +const char *nftables_shutdown(const char *chain, const char *base_chain, nftables_args); #endif