Skip to content

Commit

Permalink
Fix firewall4 fullcone-nat
Browse files Browse the repository at this point in the history
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 <nicholas-sun@outlook.com>
  • Loading branch information
3 people committed Aug 25, 2023
1 parent 52e0329 commit 0f05bb9
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 152 deletions.
126 changes: 47 additions & 79 deletions PATCH/firewall/999-01-firewall4-add-fullcone-support.patch
Original file line number Diff line number Diff line change
@@ -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 <wong.syrone@gmail.com>
Date: Sat, 9 Apr 2022 13:24:19 +0800
Subject: [PATCH] firewall4: add fullcone support
Expand All @@ -8,96 +8,82 @@ 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 <msylgj@immortalwrt.org>
---
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 }) %}
{% endfor %}
{% 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 @@
+{# /usr/share/firewall4/templates/zone-fullcone.uc #}
+ 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 @@
Expand All @@ -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);
}

Expand All @@ -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`);
},

Expand All @@ -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 {
}
},

Expand All @@ -173,23 +159,24 @@ 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",
+ "fullcone",
"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;

Expand All @@ -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)) {
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,27 @@ Signed-off-by: Syrone Wong <wong.syrone@gmail.com>
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)
Expand All @@ -54,24 +49,20 @@ 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 \
+ expr/fullcone.c \
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 @@
Expand Down Expand Up @@ -242,26 +233,21 @@ 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;
+extern struct expr_ops expr_ops_fullcone;
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,
Loading

0 comments on commit 0f05bb9

Please sign in to comment.