OSDN Git Service

libnftnl: add fullcone expression support
[immortalwrt/immortalwrt.git] / package / libs / libnftnl / patches / 001-libnftnl-add-fullcone-expression-support.patch
1 From 6c39f04febd7cfdbd474233379416babcd0fc341 Mon Sep 17 00:00:00 2001
2 From: Syrone Wong <wong.syrone@gmail.com>
3 Date: Fri, 8 Apr 2022 23:52:11 +0800
4 Subject: [PATCH] libnftnl: add fullcone expression support
5
6 Signed-off-by: Syrone Wong <wong.syrone@gmail.com>
7 ---
8  include/libnftnl/expr.h             |   6 +
9  include/linux/netfilter/nf_tables.h |  16 +++
10  src/Makefile.am                     |   1 +
11  src/expr/fullcone.c                 | 167 ++++++++++++++++++++++++++++
12  src/expr_ops.c                      |   2 +
13  5 files changed, 192 insertions(+)
14  create mode 100644 src/expr/fullcone.c
15
16 diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
17 index 00c63ab..7dcf403 100644
18 --- a/include/libnftnl/expr.h
19 +++ b/include/libnftnl/expr.h
20 @@ -244,6 +244,12 @@ enum {
21         NFTNL_EXPR_MASQ_REG_PROTO_MAX,
22  };
23  
24 +enum {
25 +       NFTNL_EXPR_FULLCONE_FLAGS               = NFTNL_EXPR_BASE,
26 +       NFTNL_EXPR_FULLCONE_REG_PROTO_MIN,
27 +       NFTNL_EXPR_FULLCONE_REG_PROTO_MAX,
28 +};
29 +
30  enum {
31         NFTNL_EXPR_REDIR_REG_PROTO_MIN  = NFTNL_EXPR_BASE,
32         NFTNL_EXPR_REDIR_REG_PROTO_MAX,
33 diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
34 index 0ae9120..8b8ae38 100644
35 --- a/include/linux/netfilter/nf_tables.h
36 +++ b/include/linux/netfilter/nf_tables.h
37 @@ -1433,6 +1433,22 @@ enum nft_masq_attributes {
38  };
39  #define NFTA_MASQ_MAX          (__NFTA_MASQ_MAX - 1)
40  
41 +/**
42 + * enum nft_fullcone_attributes - nf_tables fullcone expression attributes
43 + *
44 + * @NFTA_FULLCONE_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32)
45 + * @NFTA_FULLCONE_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers)
46 + * @NFTA_FULLCONE_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers)
47 + */
48 +enum nft_fullcone_attributes {
49 +       NFTA_FULLCONE_UNSPEC,
50 +       NFTA_FULLCONE_FLAGS,
51 +       NFTA_FULLCONE_REG_PROTO_MIN,
52 +       NFTA_FULLCONE_REG_PROTO_MAX,
53 +       __NFTA_FULLCONE_MAX
54 +};
55 +#define NFTA_FULLCONE_MAX              (__NFTA_FULLCONE_MAX - 1)
56 +
57  /**
58   * enum nft_redir_attributes - nf_tables redirect expression netlink attributes
59   *
60 diff --git a/src/Makefile.am b/src/Makefile.am
61 index c3b0ab9..2718218 100644
62 --- a/src/Makefile.am
63 +++ b/src/Makefile.am
64 @@ -54,6 +54,7 @@ libnftnl_la_SOURCES = utils.c         \
65                       expr/target.c     \
66                       expr/tunnel.c     \
67                       expr/masq.c       \
68 +                     expr/fullcone.c   \
69                       expr/redir.c      \
70                       expr/hash.c       \
71                       expr/socket.c     \
72 diff --git a/src/expr/fullcone.c b/src/expr/fullcone.c
73 new file mode 100644
74 index 0000000..aaedd83
75 --- /dev/null
76 +++ b/src/expr/fullcone.c
77 @@ -0,0 +1,167 @@
78 +/*
79 + * (C) 2022 wongsyrone
80 + *
81 + * This program is free software; you can redistribute it and/or modify
82 + * it under the terms of the GNU General Public License as published
83 + * by the Free Software Foundation; either version 2 of the License, or
84 + * (at your option) any later version.
85 + */
86 +
87 +#include <stdio.h>
88 +#include <stdint.h>
89 +#include <arpa/inet.h>
90 +#include <errno.h>
91 +#include <inttypes.h>
92 +
93 +#include <linux/netfilter/nf_tables.h>
94 +
95 +#include "internal.h"
96 +#include <libmnl/libmnl.h>
97 +#include <libnftnl/expr.h>
98 +#include <libnftnl/rule.h>
99 +
100 +struct nftnl_expr_fullcone {
101 +       uint32_t                flags;
102 +       enum nft_registers      sreg_proto_min;
103 +       enum nft_registers      sreg_proto_max;
104 +};
105 +
106 +static int
107 +nftnl_expr_fullcone_set(struct nftnl_expr *e, uint16_t type,
108 +                      const void *data, uint32_t data_len)
109 +{
110 +       struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e);
111 +
112 +       switch (type) {
113 +       case NFTNL_EXPR_FULLCONE_FLAGS:
114 +               memcpy(&fullcone->flags, data, sizeof(fullcone->flags));
115 +               break;
116 +       case NFTNL_EXPR_FULLCONE_REG_PROTO_MIN:
117 +               memcpy(&fullcone->sreg_proto_min, data, sizeof(fullcone->sreg_proto_min));
118 +               break;
119 +       case NFTNL_EXPR_FULLCONE_REG_PROTO_MAX:
120 +               memcpy(&fullcone->sreg_proto_max, data, sizeof(fullcone->sreg_proto_max));
121 +               break;
122 +       default:
123 +               return -1;
124 +       }
125 +       return 0;
126 +}
127 +
128 +static const void *
129 +nftnl_expr_fullcone_get(const struct nftnl_expr *e, uint16_t type,
130 +                      uint32_t *data_len)
131 +{
132 +       struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e);
133 +
134 +       switch (type) {
135 +       case NFTNL_EXPR_FULLCONE_FLAGS:
136 +               *data_len = sizeof(fullcone->flags);
137 +               return &fullcone->flags;
138 +       case NFTNL_EXPR_FULLCONE_REG_PROTO_MIN:
139 +               *data_len = sizeof(fullcone->sreg_proto_min);
140 +               return &fullcone->sreg_proto_min;
141 +       case NFTNL_EXPR_FULLCONE_REG_PROTO_MAX:
142 +               *data_len = sizeof(fullcone->sreg_proto_max);
143 +               return &fullcone->sreg_proto_max;
144 +       }
145 +       return NULL;
146 +}
147 +
148 +static int nftnl_expr_fullcone_cb(const struct nlattr *attr, void *data)
149 +{
150 +       const struct nlattr **tb = data;
151 +       int type = mnl_attr_get_type(attr);
152 +
153 +       if (mnl_attr_type_valid(attr, NFTA_FULLCONE_MAX) < 0)
154 +               return MNL_CB_OK;
155 +
156 +       switch (type) {
157 +       case NFTA_FULLCONE_REG_PROTO_MIN:
158 +       case NFTA_FULLCONE_REG_PROTO_MAX:
159 +       case NFTA_FULLCONE_FLAGS:
160 +               if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
161 +                       abi_breakage();
162 +               break;
163 +       }
164 +
165 +       tb[type] = attr;
166 +       return MNL_CB_OK;
167 +}
168 +
169 +static void
170 +nftnl_expr_fullcone_build(struct nlmsghdr *nlh, const struct nftnl_expr *e)
171 +{
172 +       struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e);
173 +
174 +       if (e->flags & (1 << NFTNL_EXPR_FULLCONE_FLAGS))
175 +               mnl_attr_put_u32(nlh, NFTA_FULLCONE_FLAGS, htobe32(fullcone->flags));
176 +       if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MIN))
177 +               mnl_attr_put_u32(nlh, NFTA_FULLCONE_REG_PROTO_MIN,
178 +                                htobe32(fullcone->sreg_proto_min));
179 +       if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MAX))
180 +               mnl_attr_put_u32(nlh, NFTA_FULLCONE_REG_PROTO_MAX,
181 +                                htobe32(fullcone->sreg_proto_max));
182 +}
183 +
184 +static int
185 +nftnl_expr_fullcone_parse(struct nftnl_expr *e, struct nlattr *attr)
186 +{
187 +       struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e);
188 +       struct nlattr *tb[NFTA_FULLCONE_MAX+1] = {};
189 +
190 +       if (mnl_attr_parse_nested(attr, nftnl_expr_fullcone_cb, tb) < 0)
191 +               return -1;
192 +
193 +       if (tb[NFTA_FULLCONE_FLAGS]) {
194 +               fullcone->flags = be32toh(mnl_attr_get_u32(tb[NFTA_FULLCONE_FLAGS]));
195 +               e->flags |= (1 << NFTNL_EXPR_FULLCONE_FLAGS);
196 +        }
197 +       if (tb[NFTA_FULLCONE_REG_PROTO_MIN]) {
198 +               fullcone->sreg_proto_min =
199 +                       be32toh(mnl_attr_get_u32(tb[NFTA_FULLCONE_REG_PROTO_MIN]));
200 +               e->flags |= (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MIN);
201 +       }
202 +       if (tb[NFTA_FULLCONE_REG_PROTO_MAX]) {
203 +               fullcone->sreg_proto_max =
204 +                       be32toh(mnl_attr_get_u32(tb[NFTA_FULLCONE_REG_PROTO_MAX]));
205 +               e->flags |= (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MAX);
206 +       }
207 +
208 +       return 0;
209 +}
210 +
211 +static int nftnl_expr_fullcone_snprintf(char *buf, size_t remain,
212 +                                   uint32_t flags, const struct nftnl_expr *e)
213 +{
214 +       struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e);
215 +       int offset = 0, ret = 0;
216 +
217 +       if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MIN)) {
218 +               ret = snprintf(buf + offset, remain, "proto_min reg %u ",
219 +                              fullcone->sreg_proto_min);
220 +               SNPRINTF_BUFFER_SIZE(ret, remain, offset);
221 +       }
222 +       if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MAX)) {
223 +               ret = snprintf(buf + offset, remain, "proto_max reg %u ",
224 +                              fullcone->sreg_proto_max);
225 +               SNPRINTF_BUFFER_SIZE(ret, remain, offset);
226 +       }
227 +       if (e->flags & (1 << NFTNL_EXPR_FULLCONE_FLAGS)) {
228 +               ret = snprintf(buf + offset, remain, "flags 0x%x ", fullcone->flags);
229 +               SNPRINTF_BUFFER_SIZE(ret, remain, offset);
230 +       }
231 +
232 +       return offset;
233 +}
234 +
235 +struct expr_ops expr_ops_fullcone = {
236 +       .name           = "fullcone",
237 +       .alloc_len      = sizeof(struct nftnl_expr_fullcone),
238 +       .max_attr       = NFTA_FULLCONE_MAX,
239 +       .set            = nftnl_expr_fullcone_set,
240 +       .get            = nftnl_expr_fullcone_get,
241 +       .parse          = nftnl_expr_fullcone_parse,
242 +       .build          = nftnl_expr_fullcone_build,
243 +       .snprintf       = nftnl_expr_fullcone_snprintf,
244 +};
245 diff --git a/src/expr_ops.c b/src/expr_ops.c
246 index 7248e4f..9dee9f8 100644
247 --- a/src/expr_ops.c
248 +++ b/src/expr_ops.c
249 @@ -19,6 +19,7 @@ extern struct expr_ops expr_ops_limit;
250  extern struct expr_ops expr_ops_log;
251  extern struct expr_ops expr_ops_lookup;
252  extern struct expr_ops expr_ops_masq;
253 +extern struct expr_ops expr_ops_fullcone;
254  extern struct expr_ops expr_ops_match;
255  extern struct expr_ops expr_ops_meta;
256  extern struct expr_ops expr_ops_ng;
257 @@ -63,6 +64,7 @@ static struct expr_ops *expr_ops[] = {
258         &expr_ops_log,
259         &expr_ops_lookup,
260         &expr_ops_masq,
261 +       &expr_ops_fullcone,
262         &expr_ops_match,
263         &expr_ops_meta,
264         &expr_ops_ng,