mirror of
https://github.com/Ysurac/openmptcprouter.git
synced 2025-03-09 15:40:20 +00:00
Add nft fullcone support
This commit is contained in:
parent
d9b6c05d1e
commit
3feeae5315
6 changed files with 921 additions and 0 deletions
76
6.1/package/libs/libnftnl/Makefile
Normal file
76
6.1/package/libs/libnftnl/Makefile
Normal file
|
@ -0,0 +1,76 @@
|
|||
#
|
||||
# Copyright (C) 2014 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=libnftnl
|
||||
PKG_CPE_ID:=cpe:/a:netfilter:libnftnl
|
||||
PKG_VERSION:=1.2.5
|
||||
PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=https://netfilter.org/projects/$(PKG_NAME)/files
|
||||
PKG_HASH:=966de0a8120c8a53db859889749368bfb2cba0c4f0b4c1a30d264eccc45f1226
|
||||
|
||||
PKG_MAINTAINER:=Steven Barth <steven@midlink.org>
|
||||
PKG_LICENSE:=GPL-2.0-or-later
|
||||
PKG_LICENSE_FILES:=COPYING
|
||||
|
||||
PKG_INSTALL:=1
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_BUILD_FLAGS:=lto
|
||||
PKG_FIXUP:=autoreconf
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
DISABLE_NLS:=
|
||||
|
||||
define Package/libnftnl
|
||||
SECTION:=libs
|
||||
CATEGORY:=Libraries
|
||||
DEPENDS:=+libmnl
|
||||
TITLE:=Low-level netlink library for the nf_tables subsystem
|
||||
URL:=http://www.netfilter.org/projects/libnftnl
|
||||
ABI_VERSION:=11
|
||||
endef
|
||||
|
||||
define Package/libnftnl/description
|
||||
libnftnl is a userspace library providing a low-level netlink
|
||||
programming interface (API) to the in-kernel nf_tables subsystem.
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS += $(FPIC)
|
||||
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-static \
|
||||
--enable-shared
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_DIR) $(1)/usr/include/libnftnl
|
||||
$(CP) \
|
||||
$(PKG_INSTALL_DIR)/usr/include/libnftnl/*.h \
|
||||
$(1)/usr/include/libnftnl/
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) \
|
||||
$(PKG_INSTALL_DIR)/usr/lib/libnftnl.{so*,a,la} \
|
||||
$(1)/usr/lib/
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
|
||||
$(CP) \
|
||||
$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libnftnl.pc \
|
||||
$(1)/usr/lib/pkgconfig/
|
||||
endef
|
||||
|
||||
define Package/libnftnl/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) \
|
||||
$(PKG_INSTALL_DIR)/usr/lib/libnftnl.so.* \
|
||||
$(1)/usr/lib/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,libnftnl))
|
|
@ -0,0 +1,267 @@
|
|||
From 6c39f04febd7cfdbd474233379416babcd0fc341 Mon Sep 17 00:00:00 2001
|
||||
From: Syrone Wong <wong.syrone@gmail.com>
|
||||
Date: Fri, 8 Apr 2022 23:52:11 +0800
|
||||
Subject: [PATCH] libnftnl: add fullcone expression support
|
||||
|
||||
Signed-off-by: Syrone Wong <wong.syrone@gmail.com>
|
||||
---
|
||||
include/libnftnl/expr.h | 6 +
|
||||
include/linux/netfilter/nf_tables.h | 16 +++
|
||||
src/Makefile.am | 1 +
|
||||
src/expr/fullcone.c | 167 ++++++++++++++++++++++++++++
|
||||
src/expr_ops.c | 2 +
|
||||
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,
|
||||
};
|
||||
|
||||
+enum {
|
||||
+ NFTNL_EXPR_FULLCONE_FLAGS = NFTNL_EXPR_BASE,
|
||||
+ NFTNL_EXPR_FULLCONE_REG_PROTO_MIN,
|
||||
+ NFTNL_EXPR_FULLCONE_REG_PROTO_MAX,
|
||||
+};
|
||||
+
|
||||
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
|
||||
--- a/include/linux/netfilter/nf_tables.h
|
||||
+++ b/include/linux/netfilter/nf_tables.h
|
||||
@@ -1433,6 +1433,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)
|
||||
+ * @NFTA_FULLCONE_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers)
|
||||
+ * @NFTA_FULLCONE_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers)
|
||||
+ */
|
||||
+enum nft_fullcone_attributes {
|
||||
+ NFTA_FULLCONE_UNSPEC,
|
||||
+ NFTA_FULLCONE_FLAGS,
|
||||
+ NFTA_FULLCONE_REG_PROTO_MIN,
|
||||
+ NFTA_FULLCONE_REG_PROTO_MAX,
|
||||
+ __NFTA_FULLCONE_MAX
|
||||
+};
|
||||
+#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
|
||||
--- a/src/Makefile.am
|
||||
+++ b/src/Makefile.am
|
||||
@@ -54,6 +54,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 @@
|
||||
+/*
|
||||
+ * (C) 2022 wongsyrone
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published
|
||||
+ * by the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdint.h>
|
||||
+#include <arpa/inet.h>
|
||||
+#include <errno.h>
|
||||
+#include <inttypes.h>
|
||||
+
|
||||
+#include <linux/netfilter/nf_tables.h>
|
||||
+
|
||||
+#include "internal.h"
|
||||
+#include <libmnl/libmnl.h>
|
||||
+#include <libnftnl/expr.h>
|
||||
+#include <libnftnl/rule.h>
|
||||
+
|
||||
+struct nftnl_expr_fullcone {
|
||||
+ uint32_t flags;
|
||||
+ enum nft_registers sreg_proto_min;
|
||||
+ enum nft_registers sreg_proto_max;
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+nftnl_expr_fullcone_set(struct nftnl_expr *e, uint16_t type,
|
||||
+ const void *data, uint32_t data_len)
|
||||
+{
|
||||
+ struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e);
|
||||
+
|
||||
+ switch (type) {
|
||||
+ case NFTNL_EXPR_FULLCONE_FLAGS:
|
||||
+ memcpy(&fullcone->flags, data, sizeof(fullcone->flags));
|
||||
+ break;
|
||||
+ case NFTNL_EXPR_FULLCONE_REG_PROTO_MIN:
|
||||
+ memcpy(&fullcone->sreg_proto_min, data, sizeof(fullcone->sreg_proto_min));
|
||||
+ break;
|
||||
+ case NFTNL_EXPR_FULLCONE_REG_PROTO_MAX:
|
||||
+ memcpy(&fullcone->sreg_proto_max, data, sizeof(fullcone->sreg_proto_max));
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const void *
|
||||
+nftnl_expr_fullcone_get(const struct nftnl_expr *e, uint16_t type,
|
||||
+ uint32_t *data_len)
|
||||
+{
|
||||
+ struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e);
|
||||
+
|
||||
+ switch (type) {
|
||||
+ case NFTNL_EXPR_FULLCONE_FLAGS:
|
||||
+ *data_len = sizeof(fullcone->flags);
|
||||
+ return &fullcone->flags;
|
||||
+ case NFTNL_EXPR_FULLCONE_REG_PROTO_MIN:
|
||||
+ *data_len = sizeof(fullcone->sreg_proto_min);
|
||||
+ return &fullcone->sreg_proto_min;
|
||||
+ case NFTNL_EXPR_FULLCONE_REG_PROTO_MAX:
|
||||
+ *data_len = sizeof(fullcone->sreg_proto_max);
|
||||
+ return &fullcone->sreg_proto_max;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int nftnl_expr_fullcone_cb(const struct nlattr *attr, void *data)
|
||||
+{
|
||||
+ const struct nlattr **tb = data;
|
||||
+ int type = mnl_attr_get_type(attr);
|
||||
+
|
||||
+ if (mnl_attr_type_valid(attr, NFTA_FULLCONE_MAX) < 0)
|
||||
+ return MNL_CB_OK;
|
||||
+
|
||||
+ switch (type) {
|
||||
+ case NFTA_FULLCONE_REG_PROTO_MIN:
|
||||
+ case NFTA_FULLCONE_REG_PROTO_MAX:
|
||||
+ case NFTA_FULLCONE_FLAGS:
|
||||
+ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
|
||||
+ abi_breakage();
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ tb[type] = attr;
|
||||
+ return MNL_CB_OK;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+nftnl_expr_fullcone_build(struct nlmsghdr *nlh, const struct nftnl_expr *e)
|
||||
+{
|
||||
+ struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e);
|
||||
+
|
||||
+ if (e->flags & (1 << NFTNL_EXPR_FULLCONE_FLAGS))
|
||||
+ mnl_attr_put_u32(nlh, NFTA_FULLCONE_FLAGS, htobe32(fullcone->flags));
|
||||
+ if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MIN))
|
||||
+ mnl_attr_put_u32(nlh, NFTA_FULLCONE_REG_PROTO_MIN,
|
||||
+ htobe32(fullcone->sreg_proto_min));
|
||||
+ if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MAX))
|
||||
+ mnl_attr_put_u32(nlh, NFTA_FULLCONE_REG_PROTO_MAX,
|
||||
+ htobe32(fullcone->sreg_proto_max));
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+nftnl_expr_fullcone_parse(struct nftnl_expr *e, struct nlattr *attr)
|
||||
+{
|
||||
+ struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e);
|
||||
+ struct nlattr *tb[NFTA_FULLCONE_MAX+1] = {};
|
||||
+
|
||||
+ if (mnl_attr_parse_nested(attr, nftnl_expr_fullcone_cb, tb) < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (tb[NFTA_FULLCONE_FLAGS]) {
|
||||
+ fullcone->flags = be32toh(mnl_attr_get_u32(tb[NFTA_FULLCONE_FLAGS]));
|
||||
+ e->flags |= (1 << NFTNL_EXPR_FULLCONE_FLAGS);
|
||||
+ }
|
||||
+ if (tb[NFTA_FULLCONE_REG_PROTO_MIN]) {
|
||||
+ fullcone->sreg_proto_min =
|
||||
+ be32toh(mnl_attr_get_u32(tb[NFTA_FULLCONE_REG_PROTO_MIN]));
|
||||
+ e->flags |= (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MIN);
|
||||
+ }
|
||||
+ if (tb[NFTA_FULLCONE_REG_PROTO_MAX]) {
|
||||
+ fullcone->sreg_proto_max =
|
||||
+ be32toh(mnl_attr_get_u32(tb[NFTA_FULLCONE_REG_PROTO_MAX]));
|
||||
+ e->flags |= (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MAX);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int nftnl_expr_fullcone_snprintf(char *buf, size_t remain,
|
||||
+ uint32_t flags, const struct nftnl_expr *e)
|
||||
+{
|
||||
+ struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e);
|
||||
+ int offset = 0, ret = 0;
|
||||
+
|
||||
+ if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MIN)) {
|
||||
+ ret = snprintf(buf + offset, remain, "proto_min reg %u ",
|
||||
+ fullcone->sreg_proto_min);
|
||||
+ SNPRINTF_BUFFER_SIZE(ret, remain, offset);
|
||||
+ }
|
||||
+ if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MAX)) {
|
||||
+ ret = snprintf(buf + offset, remain, "proto_max reg %u ",
|
||||
+ fullcone->sreg_proto_max);
|
||||
+ SNPRINTF_BUFFER_SIZE(ret, remain, offset);
|
||||
+ }
|
||||
+ if (e->flags & (1 << NFTNL_EXPR_FULLCONE_FLAGS)) {
|
||||
+ ret = snprintf(buf + offset, remain, "flags 0x%x ", fullcone->flags);
|
||||
+ SNPRINTF_BUFFER_SIZE(ret, remain, offset);
|
||||
+ }
|
||||
+
|
||||
+ return offset;
|
||||
+}
|
||||
+
|
||||
+struct expr_ops expr_ops_fullcone = {
|
||||
+ .name = "fullcone",
|
||||
+ .alloc_len = sizeof(struct nftnl_expr_fullcone),
|
||||
+ .max_attr = NFTA_FULLCONE_MAX,
|
||||
+ .set = nftnl_expr_fullcone_set,
|
||||
+ .get = nftnl_expr_fullcone_get,
|
||||
+ .parse = nftnl_expr_fullcone_parse,
|
||||
+ .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;
|
||||
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[] = {
|
||||
&expr_ops_log,
|
||||
&expr_ops_lookup,
|
||||
&expr_ops_masq,
|
||||
+ &expr_ops_fullcone,
|
||||
&expr_ops_match,
|
||||
&expr_ops_meta,
|
||||
&expr_ops_ng,
|
||||
--
|
||||
2.35.1
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
--- a/root/usr/share/firewall4/templates/ruleset.uc 2023-07-28 18:55:05.492297782 +0200
|
||||
+++ b/root/usr/share/firewall4/templates/ruleset.uc 2023-07-28 18:58:52.300598623 +0200
|
||||
@@ -218,9 +218,7 @@
|
||||
{% for (let rule in fw4.rules(`input_${zone.name}`)): %}
|
||||
{%+ include("rule.uc", { fw4, rule }) %}
|
||||
{% endfor %}
|
||||
-{% if (zone.dflags.dnat): %}
|
||||
ct status dnat accept comment "!fw4: Accept port redirections"
|
||||
-{% endif %}
|
||||
{% fw4.includes('chain-append', `input_${zone.name}`) %}
|
||||
jump {{ zone.input }}_from_{{ zone.name }}
|
||||
}
|
||||
@@ -239,9 +237,7 @@
|
||||
{% for (let rule in fw4.rules(`forward_${zone.name}`)): %}
|
||||
{%+ include("rule.uc", { fw4, rule }) %}
|
||||
{% endfor %}
|
||||
-{% if (zone.dflags.dnat): %}
|
||||
ct status dnat accept comment "!fw4: Accept port forwards"
|
||||
-{% endif %}
|
||||
{% fw4.includes('chain-append', `forward_${zone.name}`) %}
|
||||
jump {{ zone.forward }}_to_{{ zone.name }}
|
||||
{% if (fw4.forward_policy() != "accept" && (zone.log & 1)): %}
|
|
@ -0,0 +1,248 @@
|
|||
From d4081c498ddca184578903fe5199d390bbc0707b 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
|
||||
|
||||
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.
|
||||
---
|
||||
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(-)
|
||||
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
|
||||
option forward REJECT
|
||||
# Uncomment this line to disable ipv6 rules
|
||||
# option disable_ipv6 1
|
||||
+ option fullcone '1'
|
||||
|
||||
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 '1'
|
||||
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 {
|
||||
{% for (let redirect in fw4.redirects(`dstnat_${zone.name}`)): %}
|
||||
{%+ include("redirect.uc", { fw4, redirect }) %}
|
||||
{% endfor %}
|
||||
+{% if (zone.fullcone4): %}
|
||||
+ {%+ include("zone-fullcone.uc", { fw4, zone, family: 4, direction: "dstnat" }) %}
|
||||
+{% endif %}
|
||||
+{% if (zone.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 {
|
||||
{% for (let redirect in fw4.redirects(`srcnat_${zone.name}`)): %}
|
||||
{%+ include("redirect.uc", { fw4, redirect }) %}
|
||||
{% endfor %}
|
||||
-{% if (zone.masq): %}
|
||||
+{% if (zone.masq && !zone.fullcone4): %}
|
||||
{% 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): %}
|
||||
{% 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): %}
|
||||
+ {%+ include("zone-fullcone.uc", { fw4, zone, family: 4, direction: "srcnat" }) %}
|
||||
+{% endif %}
|
||||
+{% if (zone.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 @@
|
||||
+// /usr/share/ucode/fw4.uc
|
||||
+
|
||||
const fs = require("fs");
|
||||
const uci = require("uci");
|
||||
const ubus = require("ubus");
|
||||
@@ -428,6 +430,25 @@ function nft_try_hw_offload(devices) {
|
||||
return (rc == 0);
|
||||
}
|
||||
|
||||
+function nft_try_fullcone() {
|
||||
+ let nft_test =
|
||||
+ 'add table inet fw4-fullcone-test; ' +
|
||||
+ 'add chain inet fw4-fullcone-test dstnat { ' +
|
||||
+ 'type nat hook prerouting priority -100; policy accept; ' +
|
||||
+ 'fullcone; ' +
|
||||
+ '}; ' +
|
||||
+ 'add chain inet fw4-fullcone-test srcnat { ' +
|
||||
+ 'type nat hook postrouting priority -100; policy accept; ' +
|
||||
+ 'fullcone; ' +
|
||||
+ '}; ';
|
||||
+ let cmd = sprintf("/usr/sbin/nft -c '%s' 2>/dev/null", replace(nft_test, "'", "'\\''"));
|
||||
+ let ok = system(cmd) == 0;
|
||||
+ if (!ok) {
|
||||
+ warn("nft_try_fullcone: cmd "+ cmd + "\n");
|
||||
+ }
|
||||
+ return ok;
|
||||
+}
|
||||
+
|
||||
|
||||
return {
|
||||
read_kernel_version: function() {
|
||||
@@ -765,6 +786,18 @@ return {
|
||||
warn(`[!] ${msg}\n`);
|
||||
},
|
||||
|
||||
+ myinfo: function(fmt, ...args) {
|
||||
+ if (getenv("QUIET"))
|
||||
+ return;
|
||||
+
|
||||
+ let msg = sprintf(fmt, ...args);
|
||||
+
|
||||
+ if (getenv("TTY"))
|
||||
+ warn(`\033[32m${msg}\033[m\n`);
|
||||
+ else
|
||||
+ warn(`[I] ${msg}\n`);
|
||||
+ },
|
||||
+
|
||||
get: function(sid, opt) {
|
||||
return this.cursor.get("firewall", sid, opt);
|
||||
},
|
||||
@@ -946,6 +979,21 @@ return {
|
||||
}
|
||||
},
|
||||
|
||||
+ myinfo_section: function(s, msg) {
|
||||
+ if (s[".name"]) {
|
||||
+ if (s.name)
|
||||
+ this.myinfo("Section %s (%s) %s", this.section_id(s[".name"]), s.name, msg);
|
||||
+ else
|
||||
+ this.myinfo("Section %s %s", this.section_id(s[".name"]), msg);
|
||||
+ }
|
||||
+ else {
|
||||
+ if (s.name)
|
||||
+ this.myinfo("ubus %s (%s) %s", s.type || "rule", s.name, msg);
|
||||
+ else
|
||||
+ this.myinfo("ubus %s %s", s.type || "rule", msg);
|
||||
+ }
|
||||
+ },
|
||||
+
|
||||
parse_policy: function(val) {
|
||||
return this.parse_enum(val, [
|
||||
"accept",
|
||||
@@ -1385,6 +1433,7 @@ return {
|
||||
"dnat",
|
||||
"snat",
|
||||
"masquerade",
|
||||
+ "fullcone",
|
||||
"accept",
|
||||
"reject",
|
||||
"drop"
|
||||
@@ -1852,6 +1901,7 @@ return {
|
||||
}
|
||||
|
||||
let defs = this.parse_options(data, {
|
||||
+ fullcone: [ "bool", "0" ],
|
||||
input: [ "policy", "drop" ],
|
||||
output: [ "policy", "drop" ],
|
||||
forward: [ "policy", "drop" ],
|
||||
@@ -1884,6 +1934,11 @@ return {
|
||||
|
||||
delete defs.syn_flood;
|
||||
|
||||
+ if (!nft_try_fullcone()) {
|
||||
+ delete defs.fullcone;
|
||||
+ warn("nft_try_fullcone failed, disable fullcone globally\n");
|
||||
+ }
|
||||
+
|
||||
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 {
|
||||
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)
|
||||
zone.dflags.snat = true;
|
||||
|
||||
- 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)) {
|
||||
zone.dflags.helper = true;
|
||||
|
||||
for (let helper in (length(zone.helper) ? zone.helper : this.state.helpers)) {
|
85
6.1/package/network/utils/nftables/Makefile
Normal file
85
6.1/package/network/utils/nftables/Makefile
Normal file
|
@ -0,0 +1,85 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Copyright (C) 2015 OpenWrt.org
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=nftables
|
||||
PKG_VERSION:=1.0.7
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=https://netfilter.org/projects/$(PKG_NAME)/files
|
||||
PKG_HASH:=c12ac941fff9adaedf17367d5ce213789b98a0d314277bc22b3d71e10891f412
|
||||
|
||||
PKG_MAINTAINER:=
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
PKG_LICENSE_FILES:=COPYING
|
||||
|
||||
PKG_FIXUP:=autoreconf
|
||||
PKG_INSTALL:=1
|
||||
|
||||
PKG_BUILD_FLAGS:=lto
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
DISABLE_NLS:=
|
||||
|
||||
CONFIGURE_ARGS += \
|
||||
--disable-debug \
|
||||
--disable-man-doc \
|
||||
--with-mini-gmp \
|
||||
--without-cli \
|
||||
--disable-python
|
||||
|
||||
define Package/nftables/Default
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=Firewall
|
||||
TITLE:=nftables userspace utility
|
||||
DEPENDS:=+kmod-nft-core +libnftnl
|
||||
URL:=http://netfilter.org/projects/nftables/
|
||||
PROVIDES:=nftables
|
||||
endef
|
||||
|
||||
define Package/nftables-nojson
|
||||
$(Package/nftables/Default)
|
||||
TITLE+= no JSON support
|
||||
VARIANT:=nojson
|
||||
DEFAULT_VARIANT:=1
|
||||
CONFLICTS:=nftables-json
|
||||
endef
|
||||
|
||||
define Package/nftables-json
|
||||
$(Package/nftables/Default)
|
||||
TITLE+= with JSON support
|
||||
VARIANT:=json
|
||||
DEPENDS+=+jansson
|
||||
endef
|
||||
|
||||
ifeq ($(BUILD_VARIANT),json)
|
||||
CONFIGURE_ARGS += --with-json
|
||||
endif
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_DIR) $(1)/usr/lib $(1)/usr/include
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/include/nftables $(1)/usr/include/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libnftables.pc \
|
||||
$(1)/usr/lib/pkgconfig/
|
||||
endef
|
||||
|
||||
define Package/nftables/install/Default
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/sbin/nft $(1)/usr/sbin/
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
|
||||
endef
|
||||
|
||||
Package/nftables-nojson/install = $(Package/nftables/install/Default)
|
||||
Package/nftables-json/install = $(Package/nftables/install/Default)
|
||||
|
||||
$(eval $(call BuildPackage,nftables-nojson))
|
||||
$(eval $(call BuildPackage,nftables-json))
|
|
@ -0,0 +1,223 @@
|
|||
From 58c89e8768711a959fdc6e953df3ea2254ff93c1 Mon Sep 17 00:00:00 2001
|
||||
From: Syrone Wong <wong.syrone@gmail.com>
|
||||
Date: Sat, 9 Apr 2022 00:38:51 +0800
|
||||
Subject: [PATCH] nftables: add fullcone expression support
|
||||
|
||||
Signed-off-by: Syrone Wong <wong.syrone@gmail.com>
|
||||
---
|
||||
include/linux/netfilter/nf_tables.h | 16 ++++++++++
|
||||
include/statement.h | 1 +
|
||||
src/netlink_delinearize.c | 48 +++++++++++++++++++++++++++++
|
||||
src/netlink_linearize.c | 7 +++++
|
||||
src/parser_bison.y | 28 +++++++++++++++--
|
||||
src/scanner.l | 1 +
|
||||
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 {
|
||||
};
|
||||
#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)
|
||||
+ * @NFTA_FULLCONE_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers)
|
||||
+ * @NFTA_FULLCONE_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers)
|
||||
+ */
|
||||
+enum nft_fullcone_attributes {
|
||||
+ NFTA_FULLCONE_UNSPEC,
|
||||
+ NFTA_FULLCONE_FLAGS,
|
||||
+ NFTA_FULLCONE_REG_PROTO_MIN,
|
||||
+ NFTA_FULLCONE_REG_PROTO_MAX,
|
||||
+ __NFTA_FULLCONE_MAX
|
||||
+};
|
||||
+#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
|
||||
--- a/include/statement.h
|
||||
+++ b/include/statement.h
|
||||
@@ -122,6 +122,7 @@ enum nft_nat_etypes {
|
||||
__NFT_NAT_SNAT = NFT_NAT_SNAT,
|
||||
__NFT_NAT_DNAT = NFT_NAT_DNAT,
|
||||
NFT_NAT_MASQ,
|
||||
+ NFT_NAT_FULLCONE,
|
||||
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,
|
||||
stmt_free(stmt);
|
||||
}
|
||||
|
||||
+static void netlink_parse_fullcone(struct netlink_parse_ctx *ctx,
|
||||
+ const struct location *loc,
|
||||
+ const struct nftnl_expr *nle)
|
||||
+{
|
||||
+ enum nft_registers reg1, reg2;
|
||||
+ struct expr *proto;
|
||||
+ struct stmt *stmt;
|
||||
+ uint32_t flags = 0;
|
||||
+
|
||||
+ if (nftnl_expr_is_set(nle, NFTNL_EXPR_FULLCONE_FLAGS))
|
||||
+ flags = nftnl_expr_get_u32(nle, NFTNL_EXPR_FULLCONE_FLAGS);
|
||||
+
|
||||
+ stmt = nat_stmt_alloc(loc, NFT_NAT_FULLCONE);
|
||||
+ stmt->nat.flags = flags;
|
||||
+
|
||||
+ reg1 = netlink_parse_register(nle, NFTNL_EXPR_FULLCONE_REG_PROTO_MIN);
|
||||
+ if (reg1) {
|
||||
+ proto = netlink_get_register(ctx, loc, reg1);
|
||||
+ if (proto == NULL) {
|
||||
+ netlink_error(ctx, loc,
|
||||
+ "fullcone statement has no proto expression");
|
||||
+ goto out_err;
|
||||
+ }
|
||||
+ expr_set_type(proto, &inet_service_type, BYTEORDER_BIG_ENDIAN);
|
||||
+ stmt->nat.proto = proto;
|
||||
+ }
|
||||
+
|
||||
+ reg2 = netlink_parse_register(nle, NFTNL_EXPR_FULLCONE_REG_PROTO_MAX);
|
||||
+ if (reg2 && reg2 != reg1) {
|
||||
+ proto = netlink_get_register(ctx, loc, reg2);
|
||||
+ if (proto == NULL) {
|
||||
+ netlink_error(ctx, loc,
|
||||
+ "fullcone statement has no proto expression");
|
||||
+ goto out_err;
|
||||
+ }
|
||||
+ expr_set_type(proto, &inet_service_type, BYTEORDER_BIG_ENDIAN);
|
||||
+ if (stmt->nat.proto != NULL)
|
||||
+ proto = range_expr_alloc(loc, stmt->nat.proto, proto);
|
||||
+ stmt->nat.proto = proto;
|
||||
+ }
|
||||
+
|
||||
+ ctx->stmt = stmt;
|
||||
+ return;
|
||||
+out_err:
|
||||
+ stmt_free(stmt);
|
||||
+}
|
||||
+
|
||||
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[] = {
|
||||
{ .name = "tproxy", .parse = netlink_parse_tproxy },
|
||||
{ .name = "notrack", .parse = netlink_parse_notrack },
|
||||
{ .name = "masq", .parse = netlink_parse_masq },
|
||||
+ { .name = "fullcone", .parse = netlink_parse_fullcone },
|
||||
{ .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,
|
||||
nftnl_reg_pmin = NFTNL_EXPR_MASQ_REG_PROTO_MIN;
|
||||
nftnl_reg_pmax = NFTNL_EXPR_MASQ_REG_PROTO_MAX;
|
||||
break;
|
||||
+ case NFT_NAT_FULLCONE:
|
||||
+ nle = alloc_nft_expr("fullcone");
|
||||
+
|
||||
+ nftnl_flag_attr = NFTNL_EXPR_FULLCONE_FLAGS;
|
||||
+ nftnl_reg_pmin = NFTNL_EXPR_FULLCONE_REG_PROTO_MIN;
|
||||
+ nftnl_reg_pmax = NFTNL_EXPR_FULLCONE_REG_PROTO_MAX;
|
||||
+ break;
|
||||
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 *);
|
||||
%token SNAT "snat"
|
||||
%token DNAT "dnat"
|
||||
%token MASQUERADE "masquerade"
|
||||
+%token FULLCONE "fullcone"
|
||||
%token REDIRECT "redirect"
|
||||
%token RANDOM "random"
|
||||
%token FULLY_RANDOM "fully-random"
|
||||
@@ -703,8 +704,8 @@ int nft_lex(void *, void *, void *);
|
||||
%type <val> limit_burst_pkts limit_burst_bytes limit_mode limit_bytes time_unit quota_mode
|
||||
%type <stmt> reject_stmt reject_stmt_alloc
|
||||
%destructor { stmt_free($$); } reject_stmt reject_stmt_alloc
|
||||
-%type <stmt> nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc redir_stmt redir_stmt_alloc
|
||||
-%destructor { stmt_free($$); } nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc redir_stmt redir_stmt_alloc
|
||||
+%type <stmt> nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc fullcone_stmt fullcone_stmt_alloc redir_stmt redir_stmt_alloc
|
||||
+%destructor { stmt_free($$); } nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc fullcone_stmt fullcone_stmt_alloc redir_stmt redir_stmt_alloc
|
||||
%type <val> nf_nat_flags nf_nat_flag offset_opt
|
||||
%type <stmt> tproxy_stmt
|
||||
%destructor { stmt_free($$); } tproxy_stmt
|
||||
@@ -2853,6 +2854,7 @@ stmt : verdict_stmt
|
||||
| queue_stmt
|
||||
| ct_stmt
|
||||
| masq_stmt close_scope_nat
|
||||
+ | fullcone_stmt close_scope_nat
|
||||
| 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
|
||||
}
|
||||
;
|
||||
|
||||
+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
|
||||
+ {
|
||||
+ $<stmt>0->nat.proto = $3;
|
||||
+ }
|
||||
+ | TO COLON stmt_expr nf_nat_flags
|
||||
+ {
|
||||
+ $<stmt>0->nat.proto = $3;
|
||||
+ $<stmt>0->nat.flags = $4;
|
||||
+ }
|
||||
+ | nf_nat_flags
|
||||
+ {
|
||||
+ $<stmt>0->nat.flags = $1;
|
||||
+ }
|
||||
+ ;
|
||||
+
|
||||
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
|
||||
--- a/src/scanner.l
|
||||
+++ b/src/scanner.l
|
||||
@@ -453,6 +453,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; }
|
||||
+"fullcone" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return FULLCONE; }
|
||||
"redirect" { scanner_push_start_cond(yyscanner, SCANSTATE_STMT_NAT); return REDIRECT; }
|
||||
"random" { return RANDOM; }
|
||||
<SCANSTATE_STMT_NAT>{
|
||||
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)
|
||||
[NFT_NAT_SNAT] = "snat",
|
||||
[NFT_NAT_DNAT] = "dnat",
|
||||
[NFT_NAT_MASQ] = "masquerade",
|
||||
+ [NFT_NAT_FULLCONE] = "fullcone",
|
||||
[NFT_NAT_REDIR] = "redirect",
|
||||
};
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue