From 0f05bb9840a6d3d5e2bc6e0f9b7f72d38e2cb826 Mon Sep 17 00:00:00 2001 From: Nicholas Sun Date: Sat, 26 Aug 2023 06:12:00 +0800 Subject: [PATCH] Fix firewall4 fullcone-nat Refresh patches Co-authored-by: QiuSimons <45143996+QiuSimons@users.noreply.github.com> Co-authored-by: SiYao Mo <1388852+msylgj@users.noreply.github.com> Signed-off-by: Nicholas Sun --- ...99-01-firewall4-add-fullcone-support.patch | 126 +++++++----------- ...ftnl-add-fullcone-expression-support.patch | 38 ++---- ...bles-add-fullcone-expression-support.patch | 76 +++++------ SCRIPTS/switch | 4 +- 4 files changed, 92 insertions(+), 152 deletions(-) diff --git a/PATCH/firewall/999-01-firewall4-add-fullcone-support.patch b/PATCH/firewall/999-01-firewall4-add-fullcone-support.patch index 9538b06..d82a78a 100644 --- a/PATCH/firewall/999-01-firewall4-add-fullcone-support.patch +++ b/PATCH/firewall/999-01-firewall4-add-fullcone-support.patch @@ -1,4 +1,4 @@ -From d4081c498ddca184578903fe5199d390bbc0707b Mon Sep 17 00:00:00 2001 +From aa3b56e289fba7425e649a608c333622ffd9c367 Mon Sep 17 00:00:00 2001 From: Syrone Wong Date: Sat, 9 Apr 2022 13:24:19 +0800 Subject: [PATCH] firewall4: add fullcone support @@ -8,61 +8,52 @@ fullcone is drop-in replacement of masq for non-udp traffic add runtime fullcone rule check, disable it globally if fullcone expr is invalid -defaults.fullcone is the global switch, while zone.fullcone4 and -zone.fullcone6 are switches for IPv4 and IPv6 respectively, most -IPv6 traffic do NOT need this FullCone NAT functionality. +defaults.fullcone and defaults.fullcone6 are switches for IPv4 and IPv6 +respectively, most IPv6 traffic do NOT need this FullCone NAT functionality. + +Renew: ZiMing Mo --- - root/etc/config/firewall | 3 + - root/usr/share/firewall4/templates/ruleset.uc | 16 +++- - .../firewall4/templates/zone-fullcone.uc | 4 + - root/usr/share/ucode/fw4.uc | 76 ++++++++++++++++++- - 4 files changed, 96 insertions(+), 3 deletions(-) + root/etc/config/firewall | 2 ++ + root/usr/share/firewall4/templates/ruleset.uc | 16 ++++++++++++++-- + .../firewall4/templates/zone-fullcone.uc | 4 ++++ + root/usr/share/ucode/fw4.uc | 69 ++++++++++++++++++- + 4 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 root/usr/share/firewall4/templates/zone-fullcone.uc -diff --git a/root/etc/config/firewall b/root/etc/config/firewall -index b9a4647..7187723 100644 --- a/root/etc/config/firewall +++ b/root/etc/config/firewall -@@ -5,6 +5,7 @@ config defaults +@@ -5,6 +5,10 @@ config defaults option forward REJECT # Uncomment this line to disable ipv6 rules # option disable_ipv6 1 -+ option fullcone '1' ++ option flow_offloading 0 ++ option flow_offloading_hw 0 ++ option fullcone 1 ++ option fullcone6 0 config zone option name lan -@@ -20,6 +21,8 @@ config zone - option input REJECT - option output ACCEPT - option forward REJECT -+ option fullcone4 '1' -+ option fullcone6 '0' - option masq 1 - option mtu_fix 1 - -diff --git a/root/usr/share/firewall4/templates/ruleset.uc b/root/usr/share/firewall4/templates/ruleset.uc -index eaa1f04..e29eae6 100644 --- a/root/usr/share/firewall4/templates/ruleset.uc +++ b/root/usr/share/firewall4/templates/ruleset.uc -@@ -310,6 +310,12 @@ table inet fw4 { +@@ -320,6 +320,12 @@ table inet fw4 { {% for (let redirect in fw4.redirects(`dstnat_${zone.name}`)): %} {%+ include("redirect.uc", { fw4, redirect }) %} {% endfor %} -+{% if (zone.fullcone4): %} ++{% if (zone.masq && fw4.default_option("fullcone")): %} + {%+ include("zone-fullcone.uc", { fw4, zone, family: 4, direction: "dstnat" }) %} +{% endif %} -+{% if (zone.fullcone6): %} ++{% if (zone.masq6 && fw4.default_option("fullcone6")): %} + {%+ include("zone-fullcone.uc", { fw4, zone, family: 6, direction: "dstnat" }) %} +{% endif %} {% fw4.includes('chain-append', `dstnat_${zone.name}`) %} } -@@ -320,20 +326,26 @@ table inet fw4 { +@@ -330,20 +336,26 @@ table inet fw4 { {% for (let redirect in fw4.redirects(`srcnat_${zone.name}`)): %} {%+ include("redirect.uc", { fw4, redirect }) %} {% endfor %} -{% if (zone.masq): %} -+{% if (zone.masq && !zone.fullcone4): %} ++{% if (zone.masq && !fw4.default_option("fullcone")): %} {% for (let saddrs in zone.masq4_src_subnets): %} {% for (let daddrs in zone.masq4_dest_subnets): %} {%+ include("zone-masq.uc", { fw4, zone, family: 4, saddrs, daddrs }) %} @@ -70,25 +61,22 @@ index eaa1f04..e29eae6 100644 {% endfor %} {% endif %} -{% if (zone.masq6): %} -+{% if (zone.masq6 && !zone.fullcone6): %} ++{% if (zone.masq6 && !fw4.default_option("fullcone6")): %} {% for (let saddrs in zone.masq6_src_subnets): %} {% for (let daddrs in zone.masq6_dest_subnets): %} {%+ include("zone-masq.uc", { fw4, zone, family: 6, saddrs, daddrs }) %} {% endfor %} {% endfor %} {% endif %} -+{% if (zone.fullcone4): %} ++{% if (zone.masq && fw4.default_option("fullcone")): %} + {%+ include("zone-fullcone.uc", { fw4, zone, family: 4, direction: "srcnat" }) %} +{% endif %} -+{% if (zone.fullcone6): %} ++{% if (zone.masq6 && fw4.default_option("fullcone6")): %} + {%+ include("zone-fullcone.uc", { fw4, zone, family: 6, direction: "srcnat" }) %} +{% endif %} {% fw4.includes('chain-append', `srcnat_${zone.name}`) %} } -diff --git a/root/usr/share/firewall4/templates/zone-fullcone.uc b/root/usr/share/firewall4/templates/zone-fullcone.uc -new file mode 100644 -index 0000000..77d9806 --- /dev/null +++ b/root/usr/share/firewall4/templates/zone-fullcone.uc @@ -0,0 +1,4 @@ @@ -96,8 +84,6 @@ index 0000000..77d9806 + meta nfproto {{ fw4.nfproto(family) }} fullcone comment "!fw4: Handle {{ + zone.name +}} {{ fw4.nfproto(family, true) }} fullcone NAT {{ direction }} traffic" -diff --git a/root/usr/share/ucode/fw4.uc b/root/usr/share/ucode/fw4.uc -index 1b4764c..c5716da 100644 --- a/root/usr/share/ucode/fw4.uc +++ b/root/usr/share/ucode/fw4.uc @@ -1,3 +1,5 @@ @@ -106,7 +92,7 @@ index 1b4764c..c5716da 100644 const fs = require("fs"); const uci = require("uci"); const ubus = require("ubus"); -@@ -428,6 +430,25 @@ function nft_try_hw_offload(devices) { +@@ -490,6 +492,25 @@ function nft_try_hw_offload(devices) { return (rc == 0); } @@ -132,7 +118,7 @@ index 1b4764c..c5716da 100644 return { read_kernel_version: function() { -@@ -765,6 +786,18 @@ return { +@@ -840,6 +861,18 @@ return { warn(`[!] ${msg}\n`); }, @@ -151,7 +137,7 @@ index 1b4764c..c5716da 100644 get: function(sid, opt) { return this.cursor.get("firewall", sid, opt); }, -@@ -946,6 +979,21 @@ return { +@@ -1021,6 +1054,21 @@ return { } }, @@ -173,7 +159,7 @@ index 1b4764c..c5716da 100644 parse_policy: function(val) { return this.parse_enum(val, [ "accept", -@@ -1385,6 +1433,7 @@ return { +@@ -1460,6 +1508,7 @@ return { "dnat", "snat", "masquerade", @@ -181,15 +167,16 @@ index 1b4764c..c5716da 100644 "accept", "reject", "drop" -@@ -1852,6 +1901,7 @@ return { +@@ -1927,6 +1976,8 @@ return { } let defs = this.parse_options(data, { + fullcone: [ "bool", "0" ], ++ fullcone6: [ "bool", "0" ], input: [ "policy", "drop" ], output: [ "policy", "drop" ], forward: [ "policy", "drop" ], -@@ -1884,6 +1934,11 @@ return { +@@ -1961,6 +2012,11 @@ return { delete defs.syn_flood; @@ -201,48 +188,29 @@ index 1b4764c..c5716da 100644 this.state.defaults = defs; }, -@@ -1908,6 +1963,8 @@ return { - masq_dest: [ "network", null, PARSE_LIST ], - - masq6: [ "bool" ], -+ fullcone4: [ "bool", "0" ], -+ fullcone6: [ "bool", "0" ], - - extra: [ "string", null, UNSUPPORTED ], - extra_src: [ "string", null, UNSUPPORTED ], -@@ -1940,6 +1997,18 @@ return { - } - } - -+ if (this.state.defaults && !this.state.defaults.fullcone) { -+ this.warn_section(data, "fullcone in defaults not enabled, ignore zone fullcone settings"); -+ zone.fullcone4 = false; -+ zone.fullcone6 = false; -+ } -+ if (zone.fullcone4) { -+ this.myinfo_section(data, "IPv4 fullcone enabled for zone '" + zone.name + "'"); -+ } -+ if (zone.fullcone6) { -+ this.myinfo_section(data, "IPv6 fullcone enabled for zone '" + zone.name + "'"); -+ } -+ - if (zone.mtu_fix && this.kernel < 0x040a0000) { - this.warn_section(data, "option 'mtu_fix' requires kernel 4.10 or later"); - return; -@@ -2110,10 +2179,15 @@ return { +@@ -2186,10 +2242,23 @@ return { zone.related_subnets = related_subnets; zone.related_physdevs = related_physdevs; -+ if (zone.fullcone4 || zone.fullcone6) { -+ zone.dflags.snat = true; -+ zone.dflags.dnat = true; +- if (zone.masq || zone.masq6) ++ if (zone.masq) { + zone.dflags.snat = true; ++ if (this.state.defaults.fullcone) { ++ zone.dflags.dnat = true; ++ this.myinfo_section(data, "IPv4 fullcone enabled for zone '" + zone.name + "'"); ++ } + } + - if (zone.masq || zone.masq6) - zone.dflags.snat = true; ++ if (zone.masq6) { ++ zone.dflags.snat = true; ++ if (this.state.defaults.fullcone6) { ++ zone.dflags.dnat = true; ++ this.myinfo_section(data, "IPv6 fullcone enabled for zone '" + zone.name + "'"); ++ } ++ } - if ((zone.auto_helper && !(zone.masq || zone.masq6)) || length(zone.helper)) { -+ if ((zone.auto_helper && !(zone.masq || zone.masq6 || zone.fullcone4 || zone.fullcone6)) || length(zone.helper)) { ++ if ((zone.auto_helper && !(zone.masq || zone.masq6 || this.state.defaults.fullcone || this.state.defaults.fullcone6)) || length(zone.helper)) { zone.dflags.helper = true; - for (let helper in (length(zone.helper) ? zone.helper : this.state.helpers)) { + for (let helper in (length(zone.helper) ? zone.helper : this.state.helpers)) { \ No newline at end of file diff --git a/PATCH/firewall/libnftnl/001-libnftnl-add-fullcone-expression-support.patch b/PATCH/firewall/libnftnl/001-libnftnl-add-fullcone-expression-support.patch index d8fcfc9..02983cd 100644 --- a/PATCH/firewall/libnftnl/001-libnftnl-add-fullcone-expression-support.patch +++ b/PATCH/firewall/libnftnl/001-libnftnl-add-fullcone-expression-support.patch @@ -13,32 +13,27 @@ Signed-off-by: Syrone Wong 5 files changed, 192 insertions(+) create mode 100644 src/expr/fullcone.c -diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h -index 00c63ab..7dcf403 100644 --- a/include/libnftnl/expr.h +++ b/include/libnftnl/expr.h -@@ -244,6 +244,12 @@ enum { - NFTNL_EXPR_MASQ_REG_PROTO_MAX, +@@ -245,6 +245,12 @@ enum { }; -+enum { + enum { + NFTNL_EXPR_FULLCONE_FLAGS = NFTNL_EXPR_BASE, + NFTNL_EXPR_FULLCONE_REG_PROTO_MIN, + NFTNL_EXPR_FULLCONE_REG_PROTO_MAX, +}; + - enum { ++enum { NFTNL_EXPR_REDIR_REG_PROTO_MIN = NFTNL_EXPR_BASE, NFTNL_EXPR_REDIR_REG_PROTO_MAX, -diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h -index 0ae9120..8b8ae38 100644 + NFTNL_EXPR_REDIR_FLAGS, --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h -@@ -1433,6 +1433,22 @@ enum nft_masq_attributes { - }; +@@ -1464,6 +1464,22 @@ enum nft_masq_attributes { #define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1) -+/** + /** + * enum nft_fullcone_attributes - nf_tables fullcone expression attributes + * + * @NFTA_FULLCONE_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32) @@ -54,14 +49,13 @@ index 0ae9120..8b8ae38 100644 +}; +#define NFTA_FULLCONE_MAX (__NFTA_FULLCONE_MAX - 1) + - /** ++/** * enum nft_redir_attributes - nf_tables redirect expression netlink attributes * -diff --git a/src/Makefile.am b/src/Makefile.am -index c3b0ab9..2718218 100644 + * @NFTA_REDIR_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers) --- a/src/Makefile.am +++ b/src/Makefile.am -@@ -54,6 +54,7 @@ libnftnl_la_SOURCES = utils.c \ +@@ -55,6 +55,7 @@ libnftnl_la_SOURCES = utils.c \ expr/target.c \ expr/tunnel.c \ expr/masq.c \ @@ -69,9 +63,6 @@ index c3b0ab9..2718218 100644 expr/redir.c \ expr/hash.c \ expr/socket.c \ -diff --git a/src/expr/fullcone.c b/src/expr/fullcone.c -new file mode 100644 -index 0000000..aaedd83 --- /dev/null +++ b/src/expr/fullcone.c @@ -0,0 +1,167 @@ @@ -242,11 +233,9 @@ index 0000000..aaedd83 + .build = nftnl_expr_fullcone_build, + .output = nftnl_expr_fullcone_snprintf, +}; -diff --git a/src/expr_ops.c b/src/expr_ops.c -index 7248e4f..9dee9f8 100644 --- a/src/expr_ops.c +++ b/src/expr_ops.c -@@ -19,6 +19,7 @@ extern struct expr_ops expr_ops_limit; +@@ -20,6 +20,7 @@ extern struct expr_ops expr_ops_limit; extern struct expr_ops expr_ops_log; extern struct expr_ops expr_ops_lookup; extern struct expr_ops expr_ops_masq; @@ -254,14 +243,11 @@ index 7248e4f..9dee9f8 100644 extern struct expr_ops expr_ops_match; extern struct expr_ops expr_ops_meta; extern struct expr_ops expr_ops_ng; -@@ -63,6 +64,7 @@ static struct expr_ops *expr_ops[] = { +@@ -65,6 +66,7 @@ static struct expr_ops *expr_ops[] = { &expr_ops_log, &expr_ops_lookup, &expr_ops_masq, + &expr_ops_fullcone, &expr_ops_match, &expr_ops_meta, - &expr_ops_ng, --- -2.35.1 - + &expr_ops_ng, \ No newline at end of file diff --git a/PATCH/firewall/nftables/002-nftables-add-fullcone-expression-support.patch b/PATCH/firewall/nftables/002-nftables-add-fullcone-expression-support.patch index 8a7c57e..1d787d5 100644 --- a/PATCH/firewall/nftables/002-nftables-add-fullcone-expression-support.patch +++ b/PATCH/firewall/nftables/002-nftables-add-fullcone-expression-support.patch @@ -14,15 +14,12 @@ Signed-off-by: Syrone Wong src/statement.c | 1 + 7 files changed, 100 insertions(+), 2 deletions(-) -diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h -index 75df968..beab9d8 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h -@@ -1409,6 +1409,22 @@ enum nft_masq_attributes { - }; +@@ -1485,6 +1485,22 @@ enum nft_masq_attributes { #define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1) -+/** + /** + * enum nft_fullcone_attributes - nf_tables fullcone expression attributes + * + * @NFTA_FULLCONE_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32) @@ -38,14 +35,13 @@ index 75df968..beab9d8 100644 +}; +#define NFTA_FULLCONE_MAX (__NFTA_FULLCONE_MAX - 1) + - /** ++/** * enum nft_redir_attributes - nf_tables redirect expression netlink attributes * -diff --git a/include/statement.h b/include/statement.h -index 2a2d300..cbd48dd 100644 + * @NFTA_REDIR_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers) --- a/include/statement.h +++ b/include/statement.h -@@ -122,6 +122,7 @@ enum nft_nat_etypes { +@@ -129,6 +129,7 @@ enum nft_nat_etypes { __NFT_NAT_SNAT = NFT_NAT_SNAT, __NFT_NAT_DNAT = NFT_NAT_DNAT, NFT_NAT_MASQ, @@ -53,11 +49,9 @@ index 2a2d300..cbd48dd 100644 NFT_NAT_REDIR, }; -diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c -index 068c3bb..8513113 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c -@@ -1369,6 +1369,53 @@ static void netlink_parse_masq(struct netlink_parse_ctx *ctx, +@@ -1473,6 +1473,53 @@ out_err: stmt_free(stmt); } @@ -111,7 +105,7 @@ index 068c3bb..8513113 100644 static void netlink_parse_redir(struct netlink_parse_ctx *ctx, const struct location *loc, const struct nftnl_expr *nle) -@@ -1787,6 +1834,7 @@ static const struct expr_handler netlink_parsers[] = { +@@ -1901,6 +1948,7 @@ static const struct expr_handler netlink { .name = "tproxy", .parse = netlink_parse_tproxy }, { .name = "notrack", .parse = netlink_parse_notrack }, { .name = "masq", .parse = netlink_parse_masq }, @@ -119,11 +113,9 @@ index 068c3bb..8513113 100644 { .name = "redir", .parse = netlink_parse_redir }, { .name = "dup", .parse = netlink_parse_dup }, { .name = "queue", .parse = netlink_parse_queue }, -diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c -index c8bbcb7..505eafa 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c -@@ -1140,6 +1140,13 @@ static void netlink_gen_nat_stmt(struct netlink_linearize_ctx *ctx, +@@ -1221,6 +1221,13 @@ static void netlink_gen_nat_stmt(struct nftnl_reg_pmin = NFTNL_EXPR_MASQ_REG_PROTO_MIN; nftnl_reg_pmax = NFTNL_EXPR_MASQ_REG_PROTO_MAX; break; @@ -137,11 +129,9 @@ index c8bbcb7..505eafa 100644 case NFT_NAT_REDIR: nle = alloc_nft_expr("redir"); -diff --git a/src/parser_bison.y b/src/parser_bison.y -index ca5c488..ec9fc9b 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y -@@ -571,6 +571,7 @@ int nft_lex(void *, void *, void *); +@@ -621,6 +621,7 @@ int nft_lex(void *, void *, void *); %token SNAT "snat" %token DNAT "dnat" %token MASQUERADE "masquerade" @@ -149,7 +139,7 @@ index ca5c488..ec9fc9b 100644 %token REDIRECT "redirect" %token RANDOM "random" %token FULLY_RANDOM "fully-random" -@@ -703,8 +704,8 @@ int nft_lex(void *, void *, void *); +@@ -755,8 +756,8 @@ int nft_lex(void *, void *, void *); %type limit_burst_pkts limit_burst_bytes limit_mode limit_bytes time_unit quota_mode %type reject_stmt reject_stmt_alloc %destructor { stmt_free($$); } reject_stmt reject_stmt_alloc @@ -160,7 +150,7 @@ index ca5c488..ec9fc9b 100644 %type nf_nat_flags nf_nat_flag offset_opt %type tproxy_stmt %destructor { stmt_free($$); } tproxy_stmt -@@ -2853,6 +2854,7 @@ stmt : verdict_stmt +@@ -3064,6 +3065,7 @@ stmt : verdict_stmt | queue_stmt | ct_stmt | masq_stmt close_scope_nat @@ -168,21 +158,10 @@ index ca5c488..ec9fc9b 100644 | redir_stmt close_scope_nat | dup_stmt close_scope_dup | fwd_stmt close_scope_fwd -@@ -3753,6 +3755,28 @@ masq_stmt_args : TO COLON stmt_expr +@@ -3976,6 +3978,28 @@ masq_stmt_args : TO COLON stmt_expr + { + $0->nat.proto = $3; } - ; - -+fullcone_stmt : fullcone_stmt_alloc fullcone_stmt_args -+ | fullcone_stmt_alloc -+ ; -+ -+fullcone_stmt_alloc : FULLCONE { $$ = nat_stmt_alloc(&@$, NFT_NAT_FULLCONE); } -+ ; -+ -+fullcone_stmt_args : TO COLON stmt_expr -+ { -+ $0->nat.proto = $3; -+ } + | TO COLON stmt_expr nf_nat_flags + { + $0->nat.proto = $3; @@ -194,14 +173,23 @@ index ca5c488..ec9fc9b 100644 + } + ; + - redir_stmt : redir_stmt_alloc redir_stmt_arg - | redir_stmt_alloc - ; -diff --git a/src/scanner.l b/src/scanner.l -index 2154281..c389860 100644 ++fullcone_stmt : fullcone_stmt_alloc fullcone_stmt_args ++ | fullcone_stmt_alloc ++ ; ++ ++fullcone_stmt_alloc : FULLCONE { $$ = nat_stmt_alloc(&@$, NFT_NAT_FULLCONE); } ++ ; ++ ++fullcone_stmt_args : TO COLON stmt_expr ++ { ++ $0->nat.proto = $3; ++ } + | TO COLON stmt_expr nf_nat_flags + { + $0->nat.proto = $3; --- a/src/scanner.l +++ b/src/scanner.l -@@ -453,6 +453,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) +@@ -460,6 +460,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr "snat" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return SNAT; } "dnat" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return DNAT; } "masquerade" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return MASQUERADE; } @@ -209,15 +197,13 @@ index 2154281..c389860 100644 "redirect" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return REDIRECT; } "random" { return RANDOM; } { -diff --git a/src/statement.c b/src/statement.c -index 30caf9c..f4866c2 100644 --- a/src/statement.c +++ b/src/statement.c -@@ -650,6 +650,7 @@ const char *nat_etype2str(enum nft_nat_etypes type) +@@ -681,6 +681,7 @@ const char *nat_etype2str(enum nft_nat_e [NFT_NAT_SNAT] = "snat", [NFT_NAT_DNAT] = "dnat", [NFT_NAT_MASQ] = "masquerade", + [NFT_NAT_FULLCONE] = "fullcone", [NFT_NAT_REDIR] = "redirect", }; - + \ No newline at end of file diff --git a/SCRIPTS/switch b/SCRIPTS/switch index cc8fe06..74344d3 100644 --- a/SCRIPTS/switch +++ b/SCRIPTS/switch @@ -1,6 +1,6 @@ # This is a useless file # -# v23.05.0-rc2 has released! +# v23.05.0-rc3 has released! # # A # B @@ -8,4 +8,4 @@ # # Change Lines # -# 15 Aug +# 26 Aug