From 645b5e1319e8efdc28ffb0acb0a3f0c9647e4cd1 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Tue, 16 Dec 2025 10:50:40 -0400 Subject: [PATCH] MT#55283 return flexible error strings Change-Id: I0d6dee21901f85be1bfffaabe9c94e66073b99ba --- daemon/main.c | 15 +++--- daemon/nftables.c | 128 ++++++++++++++++++++++++++------------------- include/nftables.h | 4 +- 3 files changed, 84 insertions(+), 63 deletions(-) diff --git a/daemon/main.c b/daemon/main.c index f703dc58f..6d3943351 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -988,7 +988,7 @@ static void options(int *argc, char ***argv, charp_ht templates) { die("Cannot do nftables setup without configured kernel table number"); if (nftables_actions > 1) die("Cannot do more than one of --nftables-start, --nftables-stop or --nftables-status"); - const char *err; + g_autoptr(char) err = NULL; if (nftables_status) { int xv = nftables_check(rtpe_config.nftables_chain, rtpe_config.nftables_base_chain, (nftables_args) { @@ -1012,7 +1012,7 @@ static void options(int *argc, char ***argv, charp_ht templates) { .family = rtpe_config.nftables_family, }); if (err) - die("Failed to perform nftables action: %s (%s)", err, strerror(errno)); + die("Failed to perform nftables action: %s", err); printf("Success\n"); exit(0); } @@ -1584,19 +1584,20 @@ static void clib_loop(void) { #endif static void kernel_setup(void) { + g_autoptr(char) err = NULL; if (rtpe_config.kernel_table < 0) goto fallback; #ifndef WITHOUT_NFTABLES - const char *err = nftables_setup(rtpe_config.nftables_chain, rtpe_config.nftables_base_chain, + err = nftables_setup(rtpe_config.nftables_chain, rtpe_config.nftables_base_chain, (nftables_args) {.table = rtpe_config.kernel_table, .append = rtpe_config.nftables_append, .xtables = rtpe_config.xtables, .family = rtpe_config.nftables_family}); if (err) { if (rtpe_config.no_fallback) - die("Failed to create nftables chains or rules: %s (%s)", err, strerror(errno)); + die("Failed to create nftables chains or rules: %s", err); ilog(LOG_ERR, "FAILED TO CREATE NFTABLES CHAINS OR RULES, KERNEL FORWARDING POSSIBLY WON'T WORK: " - "%s (%s)", err, strerror(errno)); + "%s", err); } #endif if (!kernel_setup_table(rtpe_config.kernel_table)) { @@ -2043,8 +2044,8 @@ int main(int argc, char **argv) { release_closed_sockets(); interfaces_free(); #ifndef WITHOUT_NFTABLES - nftables_shutdown(rtpe_config.nftables_chain, rtpe_config.nftables_base_chain, - (nftables_args){.family = rtpe_config.nftables_family}); + g_free( nftables_shutdown(rtpe_config.nftables_chain, rtpe_config.nftables_base_chain, + (nftables_args){.family = rtpe_config.nftables_family}) ); #endif ng_client_cleanup(); bufferpool_destroy(shm_bufferpool); diff --git a/daemon/nftables.c b/daemon/nftables.c index effa79433..c54236eae 100644 --- a/daemon/nftables.c +++ b/daemon/nftables.c @@ -29,7 +29,7 @@ struct iterate_callbacks { void (*rule_final)(struct iterate_callbacks *); // called after all rules have been iterated - const char *(*iterate_final)(nfapi_socket *nl, int family, const char *chain, + char *(*iterate_final)(nfapi_socket *nl, int family, const char *chain, struct iterate_callbacks *); // common arguments @@ -162,7 +162,7 @@ static const char *nftables_do_rule(const int8_t *b, size_t l, void *data) { } -static const char *iterate_rules(nfapi_socket *nl, int family, const char *chain, +static char *iterate_rules(nfapi_socket *nl, int family, const char *chain, struct iterate_callbacks *callbacks) { g_autoptr(nfapi_buf) b = nfapi_buf_new(); @@ -173,31 +173,33 @@ static const char *iterate_rules(nfapi_socket *nl, int family, const char *chain nfapi_add_str_attr(b, NFTA_RULE_CHAIN, chain, "chain '%s'", chain); if (!nfapi_send_buf(nl, b)) - return "failed to write to netlink socket for iteration"; + return g_strdup_printf("failed to write to netlink socket trying to read rules (%s)", + strerror(errno)); const char *err = nfapi_recv_iter(nl, &(nfapi_callbacks) { .rule = nftables_do_rule }, callbacks); if (err) - return err; + return g_strdup_printf("error received from netlink socket reading rules (%s): %s", + strerror(errno), err); - if (callbacks->iterate_final) - err = callbacks->iterate_final(nl, family, chain, callbacks); - if (err) - return err; + if (callbacks->iterate_final) { + char *e = callbacks->iterate_final(nl, family, chain, callbacks); + if (e) + return e; + } return NULL; } -static bool set_rule_handle(nfapi_buf *b, void *data) { +static void set_rule_handle(nfapi_buf *b, void *data) { uint64_t *handle = data; nfapi_add_u64_attr(b, NFTA_RULE_HANDLE, *handle, "handle %" PRIu64, *handle); - return true; } -static const char *delete_rules(nfapi_socket *nl, int family, const char *chain, - bool (*callback)(nfapi_buf *b, void *data), void *data) +static char *delete_rules(nfapi_socket *nl, int family, const char *chain, + void (*callback)(nfapi_buf *b, void *data), void *data) { g_autoptr(nfapi_buf) b = nfapi_buf_new(); @@ -207,26 +209,26 @@ static const char *delete_rules(nfapi_socket *nl, int family, const char *chain, nfapi_add_str_attr(b, NFTA_RULE_TABLE, "filter", "table 'filter'"); nfapi_add_str_attr(b, NFTA_RULE_CHAIN, chain, "chain '%s'", chain); - if (callback) { - if (!callback(b, data)) - return "delete rule callback returned error"; - } + if (callback) + callback(b, data); nfapi_batch_end(b); if (!nfapi_send_buf(nl, b)) - return "failed to write to netlink socket for delete rule"; + return g_strdup_printf("failed to write to netlink socket trying to delete rule (%s)", + strerror(errno)); const char *err = nfapi_recv_iter(nl, NULL, NULL); if (err) - return err; + return g_strdup_printf("error received from netlink socket trying to delete rule (%s): %s", + strerror(errno), err); return NULL; } -static const char *iterate_delete_rules(nfapi_socket *nl, int family, const char *chain, +static char *iterate_delete_rules(nfapi_socket *nl, int family, const char *chain, struct iterate_callbacks *callbacks) { while (callbacks->iterate_scratch.handles.length) { @@ -235,7 +237,7 @@ static const char *iterate_delete_rules(nfapi_socket *nl, int family, const char uint64_t h = *handle; g_free(handle); - const char *err = delete_rules(nl, family, chain, set_rule_handle, &h); + char *err = delete_rules(nl, family, chain, set_rule_handle, &h); if (err) return err; } @@ -281,7 +283,7 @@ static const char *chain_exists(nfapi_socket *nl, int family, const char *chain) } -static const char *add_chain(nfapi_socket *nl, int family, const char *chain, +static char *add_chain(nfapi_socket *nl, int family, const char *chain, const char *(*callback)(nfapi_buf *)) { if (chain_exists(nl, family, chain) == NULL) @@ -299,23 +301,26 @@ static const char *add_chain(nfapi_socket *nl, int family, const char *chain, if (callback) { const char *err = callback(b); if (err) - return err; + return g_strdup_printf("error returned from callback trying to add chain: %s", + err); } nfapi_batch_end(b); if (!nfapi_send_buf(nl, b)) - return "failed to write to netlink socket for add chain"; + return g_strdup_printf("failed to write to netlink socket trying to add chain (%s)", + strerror(errno)); const char *err = nfapi_recv_iter(nl, NULL, NULL); if (err) - return err; + return g_strdup_printf("error received from netlink socket trying to add chain (%s): %s", + strerror(errno), err); return NULL; } -static const char *add_rule(nfapi_socket *nl, int family, +static char *add_rule(nfapi_socket *nl, int family, struct add_rule_callbacks callbacks) { g_autoptr(nfapi_buf) b = nfapi_buf_new(); @@ -329,16 +334,19 @@ static const char *add_rule(nfapi_socket *nl, int family, const char *err = callbacks.rule_callback(b, family, &callbacks); if (err) - return err; + return g_strdup_printf("error returned from callback trying to add table: %s", + err); nfapi_batch_end(b); if (!nfapi_send_buf(nl, b)) - return "failed to write to netlink socket for add rule"; + return g_strdup_printf("failed to write to netlink socket trying to add rule (%s)", + strerror(errno)); err = nfapi_recv_iter(nl, NULL, NULL); if (err) - return err; + return g_strdup_printf("error received from netlink socket trying to add rule (%s): %s", + strerror(errno), err); return NULL; } @@ -592,7 +600,7 @@ static const char *rtpe_target_filter(nfapi_buf *b, int family, struct add_rule_ } -static const char *delete_chain(nfapi_socket *nl, int family, const char *chain) { +static char *delete_chain(nfapi_socket *nl, int family, const char *chain) { g_autoptr(nfapi_buf) b = nfapi_buf_new(); nfapi_batch_begin(b); @@ -605,20 +613,22 @@ static const char *delete_chain(nfapi_socket *nl, int family, const char *chain) nfapi_batch_end(b); if (!nfapi_send_buf(nl, b)) - return "failed to write to netlink socket for delete chain"; + return g_strdup_printf("failed to write to netlink socket trying to delete chain (%s)", + strerror(errno)); const char *err = nfapi_recv_iter(nl, NULL, NULL); if (err) - return err; + return g_strdup_printf("error received from netlink socket trying to delete chain (%s): %s", + strerror(errno), err); return NULL; } -static const char *nftables_shutdown_family(nfapi_socket *nl, int family, +static char *nftables_shutdown_family(nfapi_socket *nl, int family, const char *chain, const char *base_chain, nftables_args *args) { - const char *err; + char *err; if (!base_chain || strcmp(base_chain, "none")) { // clean up rules in legacy `INPUT` chain @@ -665,19 +675,21 @@ static const char *nftables_shutdown_family(nfapi_socket *nl, int family, if (err) { if (errno != ENOENT) // ignore trying to delete stuff that doesn't exist return err; + g_free(err); } err = delete_chain(nl, family, chain); if (err) { if (errno != ENOENT && errno != EBUSY) // ignore trying to delete stuff that doesn't exist return err; + g_free(err); } return NULL; } -static const char *add_table(nfapi_socket *nl, int family) { +static char *add_table(nfapi_socket *nl, int family) { g_autoptr(nfapi_buf) b = nfapi_buf_new(); nfapi_batch_begin(b); @@ -689,20 +701,22 @@ static const char *add_table(nfapi_socket *nl, int family) { nfapi_batch_end(b); if (!nfapi_send_buf(nl, b)) - return "failed to write to netlink socket for add table"; + return g_strdup_printf("failed to write to netlink socket trying to add table (%s)", + strerror(errno)); const char *err = nfapi_recv_iter(nl, NULL, NULL); if (err) - return err; + return g_strdup_printf("error received from netlink socket trying to add table (%s): %s", + strerror(errno), err); return NULL; } -static const char *nftables_setup_family(nfapi_socket *nl, int family, +static char *nftables_setup_family(nfapi_socket *nl, int family, const char *chain, const char *base_chain, nftables_args *args) { - const char *err = nftables_shutdown_family(nl, family, chain, base_chain, args); + char *err = nftables_shutdown_family(nl, family, chain, base_chain, args); if (err) return err; @@ -781,8 +795,8 @@ static const char *nftables_setup_family(nfapi_socket *nl, int family, } -static const char *nftables_do(const char *chain, const char *base_chain, - const char *(*do_func)(nfapi_socket *nl, int family, +static char *nftables_do(const char *chain, const char *base_chain, + char *(*do_func)(nfapi_socket *nl, int family, const char *chain, const char *base_chain, nftables_args *args), nftables_args *args) { @@ -793,9 +807,9 @@ static const char *nftables_do(const char *chain, const char *base_chain, g_autoptr(nfapi_socket) nl = nfapi_socket_open(); if (!nl) - return "failed to open netlink socket"; + return g_strdup_printf("failed to open netlink socket (%s)", strerror(errno)); - const char *err = NULL; + char *err = NULL; if (args->family == 0 || args->family == NFPROTO_IPV4) err = do_func(nl, NFPROTO_IPV4, chain, base_chain, args); @@ -816,7 +830,7 @@ static const char *nftables_do(const char *chain, const char *base_chain, } -static const char *nftables_check_family(nfapi_socket *nl, int family, +static char *nftables_check_family(nfapi_socket *nl, int family, const char *chain, const char *base_chain, nftables_args *args) { // look for our custom module rule in the specified chain @@ -827,10 +841,10 @@ static const char *nftables_check_family(nfapi_socket *nl, int family, .table = args->table, }; - iterate_rules(nl, family, chain, &callbacks); + g_free( iterate_rules(nl, family, chain, &callbacks) ); if (!callbacks.iterate_scratch.have_rtpengine_rule) - return "RTPENGINE rule not found"; + return g_strdup("rtpengine handler rule not found"); // look for a rule to jump from a base chain to our custom chain @@ -841,31 +855,37 @@ static const char *nftables_check_family(nfapi_socket *nl, int family, .table = args->table, }; - iterate_rules(nl, family, "INPUT", &callbacks); - iterate_rules(nl, family, "input", &callbacks); + g_free( iterate_rules(nl, family, "INPUT", &callbacks) ); + g_free( iterate_rules(nl, family, "input", &callbacks) ); if (base_chain && strcmp(base_chain, "none")) - iterate_rules(nl, family, base_chain, &callbacks); - - if (!callbacks.iterate_scratch.have_imm_jump_rule) - return "immediate-goto rule not found"; + g_free( iterate_rules(nl, family, base_chain, &callbacks) ); + + if (!callbacks.iterate_scratch.have_imm_jump_rule) { + if (base_chain && strcmp(base_chain, "none")) + return g_strdup_printf("immediate-goto rule not found in 'INPUT' or 'input' or '%s'", + base_chain); + else + return g_strdup("immediate-goto rule not found in 'INPUT' or 'input'"); + } return NULL; } -const char *nftables_setup(const char *chain, const char *base_chain, nftables_args args) { +char *nftables_setup(const char *chain, const char *base_chain, nftables_args args) { return nftables_do(chain, base_chain, nftables_setup_family, &args); } -const char *nftables_shutdown(const char *chain, const char *base_chain, nftables_args args) { +char *nftables_shutdown(const char *chain, const char *base_chain, nftables_args args) { return nftables_do(chain, base_chain, nftables_shutdown_family, &args); } int nftables_check(const char *chain, const char *base_chain, nftables_args args) { - const char *err = nftables_do(chain, base_chain, nftables_check_family, &args); + char *err = nftables_do(chain, base_chain, nftables_check_family, &args); if (err) { printf("Netfilter rules check NOT successful: %s\n", err); + g_free(err); return 1; } diff --git a/include/nftables.h b/include/nftables.h index 68f88e4f8..75964bddc 100644 --- a/include/nftables.h +++ b/include/nftables.h @@ -10,8 +10,8 @@ typedef struct { bool xtables; } 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, nftables_args); +char *nftables_setup(const char *chain, const char *base_chain, nftables_args); +char *nftables_shutdown(const char *chain, const char *base_chain, nftables_args); int nftables_check(const char *chain, const char *base_chain, nftables_args); #endif