OSDN Git Service

nftables: add fullcone expression support
[immortalwrt/immortalwrt.git] / package / network / utils / nftables / patches / 002-nftables-add-fullcone-expression-support.patch
1 From b6e3ad4c0bb845a05d73ef1be46ffb73517d1565 Mon Sep 17 00:00:00 2001
2 From: Syrone Wong <wong.syrone@gmail.com>
3 Date: Sat, 9 Apr 2022 00:38:51 +0800
4 Subject: [PATCH] nftables: add fullcone expression support
5
6 Signed-off-by: Syrone Wong <wong.syrone@gmail.com>
7 ---
8  include/linux/netfilter/nf_tables.h | 16 ++++++++++
9  include/statement.h                 |  1 +
10  src/netlink_delinearize.c           | 48 +++++++++++++++++++++++++++++
11  src/netlink_linearize.c             |  7 +++++
12  src/parser_bison.y                  | 28 +++++++++++++++--
13  src/scanner.l                       |  1 +
14  src/statement.c                     |  1 +
15  7 files changed, 100 insertions(+), 2 deletions(-)
16
17 diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
18 index 75df968..beab9d8 100644
19 --- a/include/linux/netfilter/nf_tables.h
20 +++ b/include/linux/netfilter/nf_tables.h
21 @@ -1409,6 +1409,22 @@ enum nft_masq_attributes {
22  };
23  #define NFTA_MASQ_MAX          (__NFTA_MASQ_MAX - 1)
24  
25 +/**
26 + * enum nft_fullcone_attributes - nf_tables fullcone expression attributes
27 + *
28 + * @NFTA_FULLCONE_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32)
29 + * @NFTA_FULLCONE_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers)
30 + * @NFTA_FULLCONE_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers)
31 + */
32 +enum nft_fullcone_attributes {
33 +       NFTA_FULLCONE_UNSPEC,
34 +       NFTA_FULLCONE_FLAGS,
35 +       NFTA_FULLCONE_REG_PROTO_MIN,
36 +       NFTA_FULLCONE_REG_PROTO_MAX,
37 +       __NFTA_FULLCONE_MAX
38 +};
39 +#define NFTA_FULLCONE_MAX              (__NFTA_FULLCONE_MAX - 1)
40 +
41  /**
42   * enum nft_redir_attributes - nf_tables redirect expression netlink attributes
43   *
44 diff --git a/include/statement.h b/include/statement.h
45 index 0622104..481cc3b 100644
46 --- a/include/statement.h
47 +++ b/include/statement.h
48 @@ -122,6 +122,7 @@ enum nft_nat_etypes {
49         __NFT_NAT_SNAT = NFT_NAT_SNAT,
50         __NFT_NAT_DNAT = NFT_NAT_DNAT,
51         NFT_NAT_MASQ,
52 +       NFT_NAT_FULLCONE,
53         NFT_NAT_REDIR,
54  };
55  
56 diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
57 index 6619b41..6d9a262 100644
58 --- a/src/netlink_delinearize.c
59 +++ b/src/netlink_delinearize.c
60 @@ -1365,6 +1365,53 @@ static void netlink_parse_masq(struct netlink_parse_ctx *ctx,
61         stmt_free(stmt);
62  }
63  
64 +static void netlink_parse_fullcone(struct netlink_parse_ctx *ctx,
65 +                              const struct location *loc,
66 +                              const struct nftnl_expr *nle)
67 +{
68 +       enum nft_registers reg1, reg2;
69 +       struct expr *proto;
70 +       struct stmt *stmt;
71 +       uint32_t flags = 0;
72 +
73 +       if (nftnl_expr_is_set(nle, NFTNL_EXPR_FULLCONE_FLAGS))
74 +               flags = nftnl_expr_get_u32(nle, NFTNL_EXPR_FULLCONE_FLAGS);
75 +
76 +       stmt = nat_stmt_alloc(loc, NFT_NAT_FULLCONE);
77 +       stmt->nat.flags = flags;
78 +
79 +       reg1 = netlink_parse_register(nle, NFTNL_EXPR_FULLCONE_REG_PROTO_MIN);
80 +       if (reg1) {
81 +               proto = netlink_get_register(ctx, loc, reg1);
82 +               if (proto == NULL) {
83 +                       netlink_error(ctx, loc,
84 +                                     "fullcone statement has no proto expression");
85 +                       goto out_err;
86 +               }
87 +               expr_set_type(proto, &inet_service_type, BYTEORDER_BIG_ENDIAN);
88 +               stmt->nat.proto = proto;
89 +       }
90 +
91 +       reg2 = netlink_parse_register(nle, NFTNL_EXPR_FULLCONE_REG_PROTO_MAX);
92 +       if (reg2 && reg2 != reg1) {
93 +               proto = netlink_get_register(ctx, loc, reg2);
94 +               if (proto == NULL) {
95 +                       netlink_error(ctx, loc,
96 +                                     "fullcone statement has no proto expression");
97 +                       goto out_err;
98 +               }
99 +               expr_set_type(proto, &inet_service_type, BYTEORDER_BIG_ENDIAN);
100 +               if (stmt->nat.proto != NULL)
101 +                       proto = range_expr_alloc(loc, stmt->nat.proto, proto);
102 +               stmt->nat.proto = proto;
103 +       }
104 +
105 +       ctx->stmt = stmt;
106 +       return;
107 +out_err:
108 +       stmt_free(stmt);
109 +}
110 +
111  static void netlink_parse_redir(struct netlink_parse_ctx *ctx,
112                                 const struct location *loc,
113                                 const struct nftnl_expr *nle)
114 @@ -1783,6 +1830,7 @@ static const struct expr_handler netlink_parsers[] = {
115         { .name = "tproxy",     .parse = netlink_parse_tproxy },
116         { .name = "notrack",    .parse = netlink_parse_notrack },
117         { .name = "masq",       .parse = netlink_parse_masq },
118 +       { .name = "fullcone",   .parse = netlink_parse_fullcone },
119         { .name = "redir",      .parse = netlink_parse_redir },
120         { .name = "dup",        .parse = netlink_parse_dup },
121         { .name = "queue",      .parse = netlink_parse_queue },
122 diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
123 index 34a6e1a..261dc75 100644
124 --- a/src/netlink_linearize.c
125 +++ b/src/netlink_linearize.c
126 @@ -1140,6 +1140,13 @@ static void netlink_gen_nat_stmt(struct netlink_linearize_ctx *ctx,
127                 nftnl_reg_pmin = NFTNL_EXPR_MASQ_REG_PROTO_MIN;
128                 nftnl_reg_pmax = NFTNL_EXPR_MASQ_REG_PROTO_MAX;
129                 break;
130 +       case NFT_NAT_FULLCONE:
131 +               nle = alloc_nft_expr("fullcone");
132 +
133 +               nftnl_flag_attr = NFTNL_EXPR_FULLCONE_FLAGS;
134 +               nftnl_reg_pmin = NFTNL_EXPR_FULLCONE_REG_PROTO_MIN;
135 +               nftnl_reg_pmax = NFTNL_EXPR_FULLCONE_REG_PROTO_MAX;
136 +               break;
137         case NFT_NAT_REDIR:
138                 nle = alloc_nft_expr("redir");
139  
140 diff --git a/src/parser_bison.y b/src/parser_bison.y
141 index d67d16b..f8d8d22 100644
142 --- a/src/parser_bison.y
143 +++ b/src/parser_bison.y
144 @@ -571,6 +571,7 @@ int nft_lex(void *, void *, void *);
145  %token SNAT                    "snat"
146  %token DNAT                    "dnat"
147  %token MASQUERADE              "masquerade"
148 +%token FULLCONE                "fullcone"
149  %token REDIRECT                        "redirect"
150  %token RANDOM                  "random"
151  %token FULLY_RANDOM            "fully-random"
152 @@ -703,8 +704,8 @@ int nft_lex(void *, void *, void *);
153  %type <val>                    limit_burst_pkts limit_burst_bytes limit_mode limit_bytes time_unit quota_mode
154  %type <stmt>                   reject_stmt reject_stmt_alloc
155  %destructor { stmt_free($$); } reject_stmt reject_stmt_alloc
156 -%type <stmt>                   nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc redir_stmt redir_stmt_alloc
157 -%destructor { stmt_free($$); } nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc redir_stmt redir_stmt_alloc
158 +%type <stmt>                   nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc fullcone_stmt fullcone_stmt_alloc redir_stmt redir_stmt_alloc
159 +%destructor { stmt_free($$); } nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc fullcone_stmt fullcone_stmt_alloc redir_stmt redir_stmt_alloc
160  %type <val>                    nf_nat_flags nf_nat_flag offset_opt
161  %type <stmt>                   tproxy_stmt
162  %destructor { stmt_free($$); } tproxy_stmt
163 @@ -2821,6 +2822,7 @@ stmt                      :       verdict_stmt
164                         |       queue_stmt
165                         |       ct_stmt
166                         |       masq_stmt
167 +                       |       fullcone_stmt
168                         |       redir_stmt
169                         |       dup_stmt
170                         |       fwd_stmt
171 @@ -3720,6 +3722,28 @@ masq_stmt_args           :       TO      COLON   stmt_expr
172                         }
173                         ;
174  
175 +fullcone_stmt          :       fullcone_stmt_alloc             fullcone_stmt_args
176 +                       |       fullcone_stmt_alloc
177 +                       ;
178 +
179 +fullcone_stmt_alloc            :       FULLCONE        { $$ = nat_stmt_alloc(&@$, NFT_NAT_FULLCONE); }
180 +                       ;
181 +
182 +fullcone_stmt_args             :       TO      COLON   stmt_expr
183 +                       {
184 +                               $<stmt>0->nat.proto = $3;
185 +                       }
186 +                       |       TO      COLON   stmt_expr       nf_nat_flags
187 +                       {
188 +                               $<stmt>0->nat.proto = $3;
189 +                               $<stmt>0->nat.flags = $4;
190 +                       }
191 +                       |       nf_nat_flags
192 +                       {
193 +                               $<stmt>0->nat.flags = $1;
194 +                       }
195 +                       ;
196 +
197  redir_stmt             :       redir_stmt_alloc        redir_stmt_arg
198                         |       redir_stmt_alloc
199                         ;
200 diff --git a/src/scanner.l b/src/scanner.l
201 index 9a189ec..929ed0f 100644
202 --- a/src/scanner.l
203 +++ b/src/scanner.l
204 @@ -409,6 +409,7 @@ addrstring  ({macaddr}|{ip4addr}|{ip6addr})
205  "snat"                 { return SNAT; }
206  "dnat"                 { return DNAT; }
207  "masquerade"           { return MASQUERADE; }
208 +"fullcone"             { return FULLCONE; }
209  "redirect"             { return REDIRECT; }
210  "random"               { return RANDOM; }
211  "fully-random"         { return FULLY_RANDOM; }
212 diff --git a/src/statement.c b/src/statement.c
213 index 03c0acf..1d57323 100644
214 --- a/src/statement.c
215 +++ b/src/statement.c
216 @@ -649,6 +649,7 @@ const char *nat_etype2str(enum nft_nat_etypes type)
217                 [NFT_NAT_SNAT]  = "snat",
218                 [NFT_NAT_DNAT]  = "dnat",
219                 [NFT_NAT_MASQ]  = "masquerade",
220 +               [NFT_NAT_FULLCONE] = "fullcone",
221                 [NFT_NAT_REDIR] = "redirect",
222         };