libnftnl: bump to upstream release 1.0.3
[15.05/openwrt.git] / package / network / utils / nftables / patches / 201-make-nftables-usable-with-mini-gmp.patch
1 From d559314e3e3debe1ff8c2c1372701df6154a53ef Mon Sep 17 00:00:00 2001
2 From: Steven Barth <steven@midlink.org>
3 Date: Mon, 15 Dec 2014 10:13:39 +0100
4 Subject: [PATCH 2/3] build: make nftables usable with mini-gmp
5
6 libgmp usually compiles to >400KB which can put a burden on embedded
7 device firmware especially if libgmp isn't used for other purposes.
8 mini-gmp in contrast adds only ~30KB to the nft-binary itself.
9
10 However mini-gmp does not support gmp_sscanf and gmp_printf.
11
12 This patch:
13 * Adds a configure flag --without-libgmp to select mini-gmp
14 * Replaces the single gmp_sscanf occurence with mpz_set_str
15 * Replaces calls to gmp_printf outside of pr_debug with
16   a minimalistic mpz_printf usable to format one mpz_t
17 * Replaces gmp_vasprintf in erec_vcreate with vasprintf
18   and rewrites the single user of the gmp format-flags
19 * Changes the parser token VERSION to IPHDRVERSION to avoid
20   clashes with the VERSION-define in config.h
21
22 Signed-off-by: Steven Barth <cyrus@openwrt.org>
23 ---
24  configure.ac         | 17 ++++++++++++++---
25  include/expression.h |  2 +-
26  include/gmputil.h    | 10 ++++++++++
27  include/utils.h      |  3 +--
28  src/Makefile.am      |  4 ++++
29  src/ct.c             |  2 +-
30  src/datatype.c       |  8 +++-----
31  src/erec.c           |  6 +++++-
32  src/evaluate.c       |  8 ++++++--
33  src/gmputil.c        | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++-
34  src/parser_bison.y   |  6 +++---
35  src/scanner.l        |  2 +-
36  12 files changed, 102 insertions(+), 20 deletions(-)
37
38 diff --git a/configure.ac b/configure.ac
39 index b55b2b1..1e3729d 100644
40 --- a/configure.ac
41 +++ b/configure.ac
42 @@ -73,8 +73,18 @@ AM_CONDITIONAL([BUILD_PDF], [test "$DBLATEX" == "found"])
43  PKG_CHECK_MODULES([LIBMNL], [libmnl >= 1.0.3])
44  PKG_CHECK_MODULES([LIBNFTNL], [libnftnl >= 1.0.2])
45  
46 -AC_CHECK_LIB([gmp], [__gmpz_init], ,
47 -            AC_MSG_ERROR([No suitable version of libgmp found]))
48 +AC_ARG_WITH([libgmp], [AS_HELP_STRING([--without-libgmp],
49 +            [Disable libgmp support (use builtin mini-gmp)])], [],
50 +            [with_libgmp=yes])
51 +AS_IF([test "x$with_libgmp" != xno], [
52 +AC_CHECK_LIB([gmp],[__gmpz_init], , AC_MSG_ERROR([No suitable version of libgmp found]))
53 +])
54 +AM_CONDITIONAL([BUILD_MINIGMP], [test "x$with_libgmp" == xno])
55 +
56 +
57 +AS_IF([test "x$with_libgmp" != xyes -a "x$CONFIG_DEBUG" = xy], [
58 +AC_MSG_ERROR([--without-libgmp MUST be used with --disable-debug])
59 +])
60  
61  AC_ARG_WITH([cli], [AS_HELP_STRING([--without-cli],
62              [disable interactive CLI (libreadline support)])],
63 @@ -130,4 +140,5 @@ AC_OUTPUT
64  echo "
65  nft configuration:
66    cli support:                 ${with_cli}
67 -  enable debugging:            ${with_debug}"
68 +  enable debugging:            ${with_debug}
69 +  use shared libgmp:           ${with_libgmp}"
70 diff --git a/include/expression.h b/include/expression.h
71 index 4b96879..7477c3e 100644
72 --- a/include/expression.h
73 +++ b/include/expression.h
74 @@ -2,7 +2,7 @@
75  #define NFTABLES_EXPRESSION_H
76  
77  #include <stdbool.h>
78 -#include <gmp.h>
79 +#include <gmputil.h>
80  #include <linux/netfilter/nf_tables.h>
81  
82  #include <nftables.h>
83 diff --git a/include/gmputil.h b/include/gmputil.h
84 index 63eb0ba..b9ced6d 100644
85 --- a/include/gmputil.h
86 +++ b/include/gmputil.h
87 @@ -1,9 +1,17 @@
88  #ifndef NFTABLES_GMPUTIL_H
89  #define NFTABLES_GMPUTIL_H
90  
91 +#include <config.h>
92 +
93 +#ifdef HAVE_LIBGMP
94  #include <gmp.h>
95 +#else
96 +#include <mini-gmp.h>
97 +#endif
98 +
99  #include <asm/byteorder.h>
100  
101 +
102  enum mpz_word_order {
103         MPZ_MSWF                = 1,
104         MPZ_LSWF                = -1,
105 @@ -48,4 +56,6 @@ extern void mpz_import_data(mpz_t rop, const void *data,
106                             unsigned int len);
107  extern void mpz_switch_byteorder(mpz_t rop, unsigned int len);
108  
109 +extern int mpz_printf(const char *format, const mpz_t value);
110 +
111  #endif /* NFTABLES_GMPUTIL_H */
112 diff --git a/include/utils.h b/include/utils.h
113 index 15b2e39..3c436ba 100644
114 --- a/include/utils.h
115 +++ b/include/utils.h
116 @@ -9,14 +9,13 @@
117  #include <unistd.h>
118  #include <assert.h>
119  #include <list.h>
120 -#include <gmp.h>
121  
122  #define BITS_PER_BYTE  8
123  
124  #ifdef DEBUG
125  #define pr_debug(fmt, arg...) gmp_printf(fmt, ##arg)
126  #else
127 -#define pr_debug(fmt, arg...) ({ if (false) gmp_printf(fmt, ##arg); 0; })
128 +#define pr_debug(fmt, arg...) ({ if (false) {}; 0; })
129  #endif
130  
131  #define __fmtstring(x, y)      __attribute__((format(printf, x, y)))
132 diff --git a/src/Makefile.am b/src/Makefile.am
133 index 378424d..099052a 100644
134 --- a/src/Makefile.am
135 +++ b/src/Makefile.am
136 @@ -51,4 +51,8 @@ if BUILD_CLI
137  nft_SOURCES += cli.c
138  endif
139  
140 +if BUILD_MINIGMP
141 +nft_SOURCES += mini-gmp.c
142 +endif
143 +
144  nft_LDADD      = ${LIBMNL_LIBS} ${LIBNFTNL_LIBS}
145 diff --git a/src/ct.c b/src/ct.c
146 index 2eb85ea..759e65d 100644
147 --- a/src/ct.c
148 +++ b/src/ct.c
149 @@ -110,7 +110,7 @@ static void ct_label_type_print(const struct expr *expr)
150                 return;
151         }
152         /* can happen when connlabel.conf is altered after rules were added */
153 -       gmp_printf("0x%Zx", expr->value);
154 +       mpz_printf("0x%Zx", expr->value);
155  }
156  
157  static struct error_record *ct_label_type_parse(const struct expr *sym,
158 diff --git a/src/datatype.c b/src/datatype.c
159 index 4519d87..40ce898 100644
160 --- a/src/datatype.c
161 +++ b/src/datatype.c
162 @@ -186,7 +186,7 @@ void symbol_table_print(const struct symbol_table *tbl,
163  
164  static void invalid_type_print(const struct expr *expr)
165  {
166 -       gmp_printf("0x%Zx [invalid type]", expr->value);
167 +       mpz_printf("0x%Zx [invalid type]", expr->value);
168  }
169  
170  const struct datatype invalid_type = {
171 @@ -268,18 +268,16 @@ static void integer_type_print(const struct expr *expr)
172  
173         if (expr->dtype->basefmt != NULL)
174                 fmt = expr->dtype->basefmt;
175 -       gmp_printf(fmt, expr->value);
176 +       mpz_printf(fmt, expr->value);
177  }
178  
179  static struct error_record *integer_type_parse(const struct expr *sym,
180                                                struct expr **res)
181  {
182         mpz_t v;
183 -       int len;
184  
185         mpz_init(v);
186 -       if (gmp_sscanf(sym->identifier, "%Zu%n", v, &len) != 1 ||
187 -           (int)strlen(sym->identifier) != len) {
188 +       if (mpz_set_str(v, sym->identifier, 0)) {
189                 mpz_clear(v);
190                 return error(&sym->location, "Could not parse %s",
191                              sym->dtype->desc);
192 diff --git a/src/erec.c b/src/erec.c
193 index 82543e6..810e9bf 100644
194 --- a/src/erec.c
195 +++ b/src/erec.c
196 @@ -44,6 +44,7 @@ static void erec_destroy(struct error_record *erec)
197         xfree(erec);
198  }
199  
200 +__attribute__((format(printf, 3, 0)))
201  struct error_record *erec_vcreate(enum error_record_types type,
202                                   const struct location *loc,
203                                   const char *fmt, va_list ap)
204 @@ -55,10 +56,13 @@ struct error_record *erec_vcreate(enum error_record_types type,
205         erec->num_locations     = 0;
206         erec_add_location(erec, loc);
207  
208 -       gmp_vasprintf(&erec->msg, fmt, ap);
209 +       if (vasprintf(&erec->msg, fmt, ap) < 0)
210 +               erec->msg = NULL;
211 +
212         return erec;
213  }
214  
215 +__attribute__((format(printf, 3, 4)))
216  struct error_record *erec_create(enum error_record_types type,
217                                  const struct location *loc,
218                                  const char *fmt, ...)
219 diff --git a/src/evaluate.c b/src/evaluate.c
220 index 0732660..3cb5cca 100644
221 --- a/src/evaluate.c
222 +++ b/src/evaluate.c
223 @@ -232,9 +232,13 @@ static int expr_evaluate_value(struct eval_ctx *ctx, struct expr **expr)
224         case TYPE_INTEGER:
225                 mpz_init_bitmask(mask, ctx->ectx.len);
226                 if (mpz_cmp((*expr)->value, mask) > 0) {
227 +                       char *valstr = mpz_get_str(NULL, 10, (*expr)->value);
228 +                       char *rangestr = mpz_get_str(NULL, 10, mask);
229                         expr_error(ctx->msgs, *expr,
230 -                                  "Value %Zu exceeds valid range 0-%Zu",
231 -                                  (*expr)->value, mask);
232 +                                  "Value %s exceeds valid range 0-%s",
233 +                                  valstr, rangestr);
234 +                       free(valstr);
235 +                       free(rangestr);
236                         mpz_clear(mask);
237                         return -1;
238                 }
239 diff --git a/src/gmputil.c b/src/gmputil.c
240 index cb46445..acbf369 100644
241 --- a/src/gmputil.c
242 +++ b/src/gmputil.c
243 @@ -14,7 +14,6 @@
244  #include <stdio.h>
245  #include <unistd.h>
246  #include <string.h>
247 -#include <gmp.h>
248  
249  #include <nftables.h>
250  #include <datatype.h>
251 @@ -148,6 +147,59 @@ void mpz_switch_byteorder(mpz_t rop, unsigned int len)
252         mpz_import_data(rop, data, BYTEORDER_HOST_ENDIAN, len);
253  }
254  
255 +int mpz_printf(const char *f, const mpz_t value)
256 +{
257 +       /* minimalistic gmp_printf replacement to format a single mpz_t
258 +        * using only mini-gmp functions */
259 +       int n = 0;
260 +       while (*f) {
261 +               if (*f != '%') {
262 +                       if (fputc(*f, stdout) != *f)
263 +                               return -1;
264 +
265 +                       ++n;
266 +               } else {
267 +                       unsigned long prec = 0;
268 +                       int base;
269 +                       size_t len;
270 +                       char *str;
271 +                       bool ok;
272 +
273 +                       if (*++f == '.')
274 +                               prec = strtoul(++f, (char**)&f, 10);
275 +
276 +                       if (*f++ != 'Z')
277 +                               return -1;
278 +
279 +                       if (*f == 'u')
280 +                               base = 10;
281 +                       else if (*f == 'x')
282 +                               base = 16;
283 +                       else
284 +                               return -1;
285 +
286 +                       len = mpz_sizeinbase(value, base);
287 +                       while (prec-- > len) {
288 +                               if (fputc('0', stdout) != '0')
289 +                                       return -1;
290 +
291 +                               ++n;
292 +                       }
293 +
294 +                       str = mpz_get_str(NULL, base, value);
295 +                       ok = str && fwrite(str, 1, len, stdout) == len;
296 +                       free(str);
297 +
298 +                       if (!ok)
299 +                               return -1;
300 +
301 +                       n += len;
302 +               }
303 +               ++f;
304 +       }
305 +       return n;
306 +}
307 +
308  static void *gmp_xrealloc(void *ptr, size_t old_size, size_t new_size)
309  {
310         return xrealloc(ptr, new_size);
311 diff --git a/src/parser_bison.y b/src/parser_bison.y
312 index 99dbd08..eb5cf90 100644
313 --- a/src/parser_bison.y
314 +++ b/src/parser_bison.y
315 @@ -237,7 +237,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
316  %token OPERATION               "operation"
317  
318  %token IP                      "ip"
319 -%token VERSION                 "version"
320 +%token IPHDRVERSION            "version"
321  %token HDRLENGTH               "hdrlength"
322  %token TOS                     "tos"
323  %token LENGTH                  "length"
324 @@ -1947,7 +1947,7 @@ ip_hdr_expr               :       IP      ip_hdr_field
325                         }
326                         ;
327  
328 -ip_hdr_field           :       VERSION         { $$ = IPHDR_VERSION; }
329 +ip_hdr_field           :       IPHDRVERSION    { $$ = IPHDR_VERSION; }
330                         |       HDRLENGTH       { $$ = IPHDR_HDRLENGTH; }
331                         |       TOS             { $$ = IPHDR_TOS; }
332                         |       LENGTH          { $$ = IPHDR_LENGTH; }
333 @@ -1994,7 +1994,7 @@ ip6_hdr_expr              :       IP6     ip6_hdr_field
334                         }
335                         ;
336  
337 -ip6_hdr_field          :       VERSION         { $$ = IP6HDR_VERSION; }
338 +ip6_hdr_field          :       IPHDRVERSION    { $$ = IP6HDR_VERSION; }
339                         |       PRIORITY        { $$ = IP6HDR_PRIORITY; }
340                         |       FLOWLABEL       { $$ = IP6HDR_FLOWLABEL; }
341                         |       LENGTH          { $$ = IP6HDR_LENGTH; }
342 diff --git a/src/scanner.l b/src/scanner.l
343 index ed87da6..92b6a10 100644
344 --- a/src/scanner.l
345 +++ b/src/scanner.l
346 @@ -349,7 +349,7 @@ addrstring  ({macaddr}|{ip4addr}|{ip6addr})
347  "operation"            { return OPERATION; }
348  
349  "ip"                   { return IP; }
350 -"version"              { return VERSION; }
351 +"version"              { return IPHDRVERSION; }
352  "hdrlength"            { return HDRLENGTH; }
353  "tos"                  { return TOS; }
354  "length"               { return LENGTH; }
355 -- 
356 2.1.3
357