From eebbece21454660991d7874205ce6a3f3f1c1771 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Tue, 14 Jul 2026 10:20:07 -0400 Subject: [PATCH] MT#55283 support table creation through nft Change-Id: I44c95d40e1c209505955f46a3208d0035027e4ef --- daemon/main.c | 15 +++++++++------ daemon/nftables.c | 15 +++++++++++++++ include/nftables.h | 2 ++ kernel-module/nft_rtpengine.c | 21 +++++++++++++++++++-- kernel-module/nft_rtpengine.h | 2 ++ 5 files changed, 47 insertions(+), 8 deletions(-) diff --git a/daemon/main.c b/daemon/main.c index 813fb55aa..d0e1597dc 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -1094,6 +1094,7 @@ static void options(int *argc, char ***argv, charp_ht templates) { .append = rtpe_config.nftables_append, .family = rtpe_config.nftables_family, .xtables = rtpe_config.xtables, + .may_exist = true, }); } else // nftables_stop @@ -1762,12 +1763,14 @@ static void kernel_setup(void) { } #endif - if (!kernel_create_table(rtpe_config.kernel_table)) { - ilog(LOG_ERR, "FAILED TO CREATE KERNEL TABLE %i (%s), KERNEL FORWARDING DISABLED", - rtpe_config.kernel_table, strerror(errno)); - if (rtpe_config.no_fallback) - die("Userspace fallback disallowed - exiting"); - goto fallback; + if (rtpe_config.xtables) { + if (!kernel_create_table(rtpe_config.kernel_table)) { + ilog(LOG_ERR, "FAILED TO CREATE KERNEL TABLE %i (%s), KERNEL FORWARDING DISABLED", + rtpe_config.kernel_table, strerror(errno)); + if (rtpe_config.no_fallback) + die("Userspace fallback disallowed - exiting"); + goto fallback; + } } if (!kernel_setup_table(rtpe_config.kernel_table)) { diff --git a/daemon/nftables.c b/daemon/nftables.c index e200dc938..c07288910 100644 --- a/daemon/nftables.c +++ b/daemon/nftables.c @@ -62,6 +62,8 @@ struct add_rule_callbacks { int table; bool append; bool xtables; + bool may_exist; + bool *created; }; @@ -501,6 +503,15 @@ static const char *target_base_nft_expr(nfapi_buf *b, struct add_rule_callbacks nfapi_add_u32_attr(b, RTPEA_RTPENGINE_TABLE, callbacks->table, "table %u", callbacks->table); + if (!*callbacks->created) { + nfapi_add_attr(b, RTPEA_RTPENGINE_CREAT, NULL, 0, "creat"); + + if (!callbacks->may_exist) + nfapi_add_attr(b, RTPEA_RTPENGINE_EXCL, NULL, 0, "excl"); + + *callbacks->created = true; + } + nfapi_nested_end(b); nfapi_nested_end(b); @@ -772,6 +783,8 @@ static char *nftables_setup_family(nfapi_socket *nl, int family, .table = args->table, .append = args->append, .xtables = args->xtables, + .created = &args->created, + .may_exist = args->may_exist, }); if (err) return err; @@ -797,6 +810,8 @@ static char *nftables_setup_family(nfapi_socket *nl, int family, .table = args->table, .append = args->append, .xtables = args->xtables, + .created = &args->created, + .may_exist = args->may_exist, }); if (err) return err; diff --git a/include/nftables.h b/include/nftables.h index 75964bddc..6d15fda28 100644 --- a/include/nftables.h +++ b/include/nftables.h @@ -8,6 +8,8 @@ typedef struct { int family; bool append; bool xtables; + bool may_exist; + bool created; } nftables_args; char *nftables_setup(const char *chain, const char *base_chain, nftables_args); diff --git a/kernel-module/nft_rtpengine.c b/kernel-module/nft_rtpengine.c index ab47e03db..9a40dd196 100644 --- a/kernel-module/nft_rtpengine.c +++ b/kernel-module/nft_rtpengine.c @@ -7465,9 +7465,24 @@ static int rtpengine_expr_init(const struct nft_ctx *ctx, const struct nft_expr if (table >= MAX_ID) return -ERANGE; + bool crt = !!tb[RTPEA_RTPENGINE_CREAT]; + bool excl = !!tb[RTPEA_RTPENGINE_EXCL]; + info->table = get_table(table); - if (!info->table) - return -ENOENT; + if (!info->table) { + if (!crt) + return -ENOENT; + info->table = new_table_link(table); + if (!info->table) + return -EBUSY; + } + else { + if (excl) { + table_put(info->table); + info->table = NULL; + return -EEXIST; + } + } return 0; } @@ -7547,6 +7562,8 @@ static const struct nft_expr_ops rtpengine_ipv6_ops = { static const struct nla_policy rtpengine_policy[RTPEA_RTPENGINE_MAX + 1] = { [RTPEA_RTPENGINE_TABLE] = { .type = NLA_U32 }, + [RTPEA_RTPENGINE_CREAT] = { .type = NLA_FLAG }, + [RTPEA_RTPENGINE_EXCL] = { .type = NLA_FLAG }, }; static struct nft_expr_type rtpengine_inet_expr __read_mostly = { diff --git a/kernel-module/nft_rtpengine.h b/kernel-module/nft_rtpengine.h index e9f4553ab..eceeabbbb 100644 --- a/kernel-module/nft_rtpengine.h +++ b/kernel-module/nft_rtpengine.h @@ -22,6 +22,8 @@ struct xt_rtpengine_info { enum rtpengine_nft_attributes { RTPEA_RTPENGINE_UNSPEC, RTPEA_RTPENGINE_TABLE, + RTPEA_RTPENGINE_CREAT, + RTPEA_RTPENGINE_EXCL, __RTPEA_RTPENGINE_MAX }; #define RTPEA_RTPENGINE_MAX (__RTPEA_RTPENGINE_MAX - 1)