OSDN Git Service

nftables: add fullcone expression support
authorSyrone Wong <wong.syrone@gmail.com>
Wed, 20 Apr 2022 05:55:32 +0000 (13:55 +0800)
committerZiMing Mo <msylgj@immortalwrt.org>
Fri, 22 Apr 2022 07:25:20 +0000 (15:25 +0800)
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
Signed-off-by: ZiMing Mo <msylgj@immortalwrt.org>
package/network/utils/nftables/Makefile
package/network/utils/nftables/patches/002-nftables-add-fullcone-expression-support.patch [new file with mode: 0644]

index 8f0fdda..2221da2 100644 (file)
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=nftables
 PKG_VERSION:=1.0.2
-PKG_RELEASE:=2
+PKG_RELEASE:=3
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=https://netfilter.org/projects/$(PKG_NAME)/files
diff --git a/package/network/utils/nftables/patches/002-nftables-add-fullcone-expression-support.patch b/package/network/utils/nftables/patches/002-nftables-add-fullcone-expression-support.patch
new file mode 100644 (file)
index 0000000..55e5412
--- /dev/null
@@ -0,0 +1,222 @@
+From b6e3ad4c0bb845a05d73ef1be46ffb73517d1565 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 0622104..481cc3b 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 6619b41..6d9a262 100644
+--- a/src/netlink_delinearize.c
++++ b/src/netlink_delinearize.c
+@@ -1365,6 +1365,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)
+@@ -1783,6 +1830,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 34a6e1a..261dc75 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 d67d16b..f8d8d22 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
+@@ -2821,6 +2822,7 @@ stmt                     :       verdict_stmt
+                       |       queue_stmt
+                       |       ct_stmt
+                       |       masq_stmt
++                      |       fullcone_stmt
+                       |       redir_stmt
+                       |       dup_stmt
+                       |       fwd_stmt
+@@ -3720,6 +3722,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 9a189ec..929ed0f 100644
+--- a/src/scanner.l
++++ b/src/scanner.l
+@@ -409,6 +409,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
+ "snat"                        { return SNAT; }
+ "dnat"                        { return DNAT; }
+ "masquerade"          { return MASQUERADE; }
++"fullcone"            { return FULLCONE; }
+ "redirect"            { return REDIRECT; }
+ "random"              { return RANDOM; }
+ "fully-random"                { return FULLY_RANDOM; }
+diff --git a/src/statement.c b/src/statement.c
+index 03c0acf..1d57323 100644
+--- a/src/statement.c
++++ b/src/statement.c
+@@ -649,6 +649,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",
+       };