diff --git a/daemon/main.c b/daemon/main.c index ce6f35ab1..9a0120895 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -498,6 +498,7 @@ static void options(int *argc, char ***argv) { #ifndef WITHOUT_NFTABLES { "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-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 @@ -677,7 +678,8 @@ static void options(int *argc, char ***argv) { const char *err; if (nftables_start) err = nftables_setup(rtpe_config.nftables_chain, rtpe_config.nftables_base_chain, - (nftables_args) {.table = rtpe_config.kernel_table}); + (nftables_args) {.table = rtpe_config.kernel_table, + .append = rtpe_config.nftables_append}); else // nftables_stop err = nftables_shutdown(rtpe_config.nftables_chain, rtpe_config.nftables_base_chain); if (err) @@ -1170,7 +1172,8 @@ static void create_everything(void) { goto no_kernel; #ifndef WITHOUT_NFTABLES const char *err = nftables_setup(rtpe_config.nftables_chain, rtpe_config.nftables_base_chain, - (nftables_args) {.table = rtpe_config.kernel_table}); + (nftables_args) {.table = rtpe_config.kernel_table, + .append = rtpe_config.nftables_append}); if (err) die("Failed to create nftables chains or rules: %s (%s)", err, strerror(errno)); #endif diff --git a/daemon/nftables.c b/daemon/nftables.c index 2bca9d5ee..e444e9d55 100644 --- a/daemon/nftables.c +++ b/daemon/nftables.c @@ -59,6 +59,7 @@ struct add_rule_callbacks { const char *chain; const char *base_chain; int table; + bool append; // intermediate storage area struct xt_rtpengine_info rtpe_target_info; @@ -335,7 +336,8 @@ static const char *add_rule(struct mnl_socket *nl, int family, uint32_t *seq, if (err) return err; - return batch_request("add rule", nl, family, seq, NFT_MSG_NEWRULE, NLM_F_APPEND | NLM_F_CREATE, + return batch_request("add rule", nl, family, seq, NFT_MSG_NEWRULE, + (callbacks.append ? NLM_F_APPEND : 0) | NLM_F_CREATE, nftnl_rule_nlmsg_build_payload, r); } @@ -561,6 +563,7 @@ static const char *nftables_setup_family(struct mnl_socket *nl, int family, uint .callback = input_immediate, .chain = chain, .base_chain = base_chain, + .append = args->append, }); if (err) return err; diff --git a/docs/rtpengine.md b/docs/rtpengine.md index f30ac89ea..70db27433 100644 --- a/docs/rtpengine.md +++ b/docs/rtpengine.md @@ -111,6 +111,12 @@ at the command line. See the __\-\-config-file__ option below for details. will directly create the chain given by __nftables-chain__ as a base chain and skip creating the immediate-goto rule. +- __\-\-nftables-append__ + + With this option set, the netfilter rule created in the base chain is + appended to the list of existing rules. The default is to prepend it + (insert it at the beginning). + - __\-\-nftables-start__ - __\-\-nftables-stop__ diff --git a/include/main.h b/include/main.h index 56cb22ae0..a5bdf7f27 100644 --- a/include/main.h +++ b/include/main.h @@ -93,6 +93,7 @@ struct rtpengine_config { char *iptables_chain; char *nftables_chain; char *nftables_base_chain; + gboolean nftables_append; int load_limit; int cpu_limit; uint64_t bw_limit; diff --git a/include/nftables.h b/include/nftables.h index da27930e4..37a47f5e0 100644 --- a/include/nftables.h +++ b/include/nftables.h @@ -1,8 +1,11 @@ #ifndef _NFTABLES_H_ #define _NFTABLES_H_ +#include + typedef struct { int table; + bool append; } nftables_args; const char *nftables_setup(const char *chain, const char *base_chain, nftables_args);