nftables: mini-bump and patch cleanup
[openwrt/staging/lynxis/omap.git] / package / network / utils / nftables / patches / 201-make-nftables-usable-with-mini-gmp.patch
diff --git a/package/network/utils/nftables/patches/201-make-nftables-usable-with-mini-gmp.patch b/package/network/utils/nftables/patches/201-make-nftables-usable-with-mini-gmp.patch
new file mode 100644 (file)
index 0000000..4533e31
--- /dev/null
@@ -0,0 +1,357 @@
+From d559314e3e3debe1ff8c2c1372701df6154a53ef Mon Sep 17 00:00:00 2001
+From: Steven Barth <steven@midlink.org>
+Date: Mon, 15 Dec 2014 10:13:39 +0100
+Subject: [PATCH 2/3] build: make nftables usable with mini-gmp
+
+libgmp usually compiles to >400KB which can put a burden on embedded
+device firmware especially if libgmp isn't used for other purposes.
+mini-gmp in contrast adds only ~30KB to the nft-binary itself.
+
+However mini-gmp does not support gmp_sscanf and gmp_printf.
+
+This patch:
+* Adds a configure flag --without-libgmp to select mini-gmp
+* Replaces the single gmp_sscanf occurence with mpz_set_str
+* Replaces calls to gmp_printf outside of pr_debug with
+  a minimalistic mpz_printf usable to format one mpz_t
+* Replaces gmp_vasprintf in erec_vcreate with vasprintf
+  and rewrites the single user of the gmp format-flags
+* Changes the parser token VERSION to IPHDRVERSION to avoid
+  clashes with the VERSION-define in config.h
+
+Signed-off-by: Steven Barth <cyrus@openwrt.org>
+---
+ configure.ac         | 17 ++++++++++++++---
+ include/expression.h |  2 +-
+ include/gmputil.h    | 10 ++++++++++
+ include/utils.h      |  3 +--
+ src/Makefile.am      |  4 ++++
+ src/ct.c             |  2 +-
+ src/datatype.c       |  8 +++-----
+ src/erec.c           |  6 +++++-
+ src/evaluate.c       |  8 ++++++--
+ src/gmputil.c        | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++-
+ src/parser_bison.y   |  6 +++---
+ src/scanner.l        |  2 +-
+ 12 files changed, 102 insertions(+), 20 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index b55b2b1..1e3729d 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -73,8 +73,18 @@ AM_CONDITIONAL([BUILD_PDF], [test "$DBLATEX" == "found"])
+ PKG_CHECK_MODULES([LIBMNL], [libmnl >= 1.0.3])
+ PKG_CHECK_MODULES([LIBNFTNL], [libnftnl >= 1.0.2])
+-AC_CHECK_LIB([gmp], [__gmpz_init], ,
+-           AC_MSG_ERROR([No suitable version of libgmp found]))
++AC_ARG_WITH([libgmp], [AS_HELP_STRING([--without-libgmp],
++            [Disable libgmp support (use builtin mini-gmp)])], [],
++            [with_libgmp=yes])
++AS_IF([test "x$with_libgmp" != xno], [
++AC_CHECK_LIB([gmp],[__gmpz_init], , AC_MSG_ERROR([No suitable version of libgmp found]))
++])
++AM_CONDITIONAL([BUILD_MINIGMP], [test "x$with_libgmp" == xno])
++
++
++AS_IF([test "x$with_libgmp" != xyes -a "x$CONFIG_DEBUG" = xy], [
++AC_MSG_ERROR([--without-libgmp MUST be used with --disable-debug])
++])
+ AC_ARG_WITH([cli], [AS_HELP_STRING([--without-cli],
+             [disable interactive CLI (libreadline support)])],
+@@ -130,4 +140,5 @@ AC_OUTPUT
+ echo "
+ nft configuration:
+   cli support:                        ${with_cli}
+-  enable debugging:           ${with_debug}"
++  enable debugging:           ${with_debug}
++  use shared libgmp:          ${with_libgmp}"
+diff --git a/include/expression.h b/include/expression.h
+index 4b96879..7477c3e 100644
+--- a/include/expression.h
++++ b/include/expression.h
+@@ -2,7 +2,7 @@
+ #define NFTABLES_EXPRESSION_H
+ #include <stdbool.h>
+-#include <gmp.h>
++#include <gmputil.h>
+ #include <linux/netfilter/nf_tables.h>
+ #include <nftables.h>
+diff --git a/include/gmputil.h b/include/gmputil.h
+index 63eb0ba..b9ced6d 100644
+--- a/include/gmputil.h
++++ b/include/gmputil.h
+@@ -1,9 +1,17 @@
+ #ifndef NFTABLES_GMPUTIL_H
+ #define NFTABLES_GMPUTIL_H
++#include <config.h>
++
++#ifdef HAVE_LIBGMP
+ #include <gmp.h>
++#else
++#include <mini-gmp.h>
++#endif
++
+ #include <asm/byteorder.h>
++
+ enum mpz_word_order {
+       MPZ_MSWF                = 1,
+       MPZ_LSWF                = -1,
+@@ -48,4 +56,6 @@ extern void mpz_import_data(mpz_t rop, const void *data,
+                           unsigned int len);
+ extern void mpz_switch_byteorder(mpz_t rop, unsigned int len);
++extern int mpz_printf(const char *format, const mpz_t value);
++
+ #endif /* NFTABLES_GMPUTIL_H */
+diff --git a/include/utils.h b/include/utils.h
+index 15b2e39..3c436ba 100644
+--- a/include/utils.h
++++ b/include/utils.h
+@@ -9,14 +9,13 @@
+ #include <unistd.h>
+ #include <assert.h>
+ #include <list.h>
+-#include <gmp.h>
+ #define BITS_PER_BYTE 8
+ #ifdef DEBUG
+ #define pr_debug(fmt, arg...) gmp_printf(fmt, ##arg)
+ #else
+-#define pr_debug(fmt, arg...) ({ if (false) gmp_printf(fmt, ##arg); 0; })
++#define pr_debug(fmt, arg...) ({ if (false) {}; 0; })
+ #endif
+ #define __fmtstring(x, y)     __attribute__((format(printf, x, y)))
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 378424d..099052a 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -51,4 +51,8 @@ if BUILD_CLI
+ nft_SOURCES +=        cli.c
+ endif
++if BUILD_MINIGMP
++nft_SOURCES +=        mini-gmp.c
++endif
++
+ nft_LDADD     = ${LIBMNL_LIBS} ${LIBNFTNL_LIBS}
+diff --git a/src/ct.c b/src/ct.c
+index 2eb85ea..759e65d 100644
+--- a/src/ct.c
++++ b/src/ct.c
+@@ -110,7 +110,7 @@ static void ct_label_type_print(const struct expr *expr)
+               return;
+       }
+       /* can happen when connlabel.conf is altered after rules were added */
+-      gmp_printf("0x%Zx", expr->value);
++      mpz_printf("0x%Zx", expr->value);
+ }
+ static struct error_record *ct_label_type_parse(const struct expr *sym,
+diff --git a/src/datatype.c b/src/datatype.c
+index 4519d87..40ce898 100644
+--- a/src/datatype.c
++++ b/src/datatype.c
+@@ -186,7 +186,7 @@ void symbol_table_print(const struct symbol_table *tbl,
+ static void invalid_type_print(const struct expr *expr)
+ {
+-      gmp_printf("0x%Zx [invalid type]", expr->value);
++      mpz_printf("0x%Zx [invalid type]", expr->value);
+ }
+ const struct datatype invalid_type = {
+@@ -268,18 +268,16 @@ static void integer_type_print(const struct expr *expr)
+       if (expr->dtype->basefmt != NULL)
+               fmt = expr->dtype->basefmt;
+-      gmp_printf(fmt, expr->value);
++      mpz_printf(fmt, expr->value);
+ }
+ static struct error_record *integer_type_parse(const struct expr *sym,
+                                              struct expr **res)
+ {
+       mpz_t v;
+-      int len;
+       mpz_init(v);
+-      if (gmp_sscanf(sym->identifier, "%Zu%n", v, &len) != 1 ||
+-          (int)strlen(sym->identifier) != len) {
++      if (mpz_set_str(v, sym->identifier, 0)) {
+               mpz_clear(v);
+               return error(&sym->location, "Could not parse %s",
+                            sym->dtype->desc);
+diff --git a/src/erec.c b/src/erec.c
+index 82543e6..810e9bf 100644
+--- a/src/erec.c
++++ b/src/erec.c
+@@ -44,6 +44,7 @@ static void erec_destroy(struct error_record *erec)
+       xfree(erec);
+ }
++__attribute__((format(printf, 3, 0)))
+ struct error_record *erec_vcreate(enum error_record_types type,
+                                 const struct location *loc,
+                                 const char *fmt, va_list ap)
+@@ -55,10 +56,13 @@ struct error_record *erec_vcreate(enum error_record_types type,
+       erec->num_locations     = 0;
+       erec_add_location(erec, loc);
+-      gmp_vasprintf(&erec->msg, fmt, ap);
++      if (vasprintf(&erec->msg, fmt, ap) < 0)
++              erec->msg = NULL;
++
+       return erec;
+ }
++__attribute__((format(printf, 3, 4)))
+ struct error_record *erec_create(enum error_record_types type,
+                                const struct location *loc,
+                                const char *fmt, ...)
+diff --git a/src/evaluate.c b/src/evaluate.c
+index 0732660..3cb5cca 100644
+--- a/src/evaluate.c
++++ b/src/evaluate.c
+@@ -232,9 +232,13 @@ static int expr_evaluate_value(struct eval_ctx *ctx, struct expr **expr)
+       case TYPE_INTEGER:
+               mpz_init_bitmask(mask, ctx->ectx.len);
+               if (mpz_cmp((*expr)->value, mask) > 0) {
++                      char *valstr = mpz_get_str(NULL, 10, (*expr)->value);
++                      char *rangestr = mpz_get_str(NULL, 10, mask);
+                       expr_error(ctx->msgs, *expr,
+-                                 "Value %Zu exceeds valid range 0-%Zu",
+-                                 (*expr)->value, mask);
++                                 "Value %s exceeds valid range 0-%s",
++                                 valstr, rangestr);
++                      free(valstr);
++                      free(rangestr);
+                       mpz_clear(mask);
+                       return -1;
+               }
+diff --git a/src/gmputil.c b/src/gmputil.c
+index cb46445..acbf369 100644
+--- a/src/gmputil.c
++++ b/src/gmputil.c
+@@ -14,7 +14,6 @@
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <string.h>
+-#include <gmp.h>
+ #include <nftables.h>
+ #include <datatype.h>
+@@ -148,6 +147,59 @@ void mpz_switch_byteorder(mpz_t rop, unsigned int len)
+       mpz_import_data(rop, data, BYTEORDER_HOST_ENDIAN, len);
+ }
++int mpz_printf(const char *f, const mpz_t value)
++{
++      /* minimalistic gmp_printf replacement to format a single mpz_t
++       * using only mini-gmp functions */
++      int n = 0;
++      while (*f) {
++              if (*f != '%') {
++                      if (fputc(*f, stdout) != *f)
++                              return -1;
++
++                      ++n;
++              } else {
++                      unsigned long prec = 0;
++                      int base;
++                      size_t len;
++                      char *str;
++                      bool ok;
++
++                      if (*++f == '.')
++                              prec = strtoul(++f, (char**)&f, 10);
++
++                      if (*f++ != 'Z')
++                              return -1;
++
++                      if (*f == 'u')
++                              base = 10;
++                      else if (*f == 'x')
++                              base = 16;
++                      else
++                              return -1;
++
++                      len = mpz_sizeinbase(value, base);
++                      while (prec-- > len) {
++                              if (fputc('0', stdout) != '0')
++                                      return -1;
++
++                              ++n;
++                      }
++
++                      str = mpz_get_str(NULL, base, value);
++                      ok = str && fwrite(str, 1, len, stdout) == len;
++                      free(str);
++
++                      if (!ok)
++                              return -1;
++
++                      n += len;
++              }
++              ++f;
++      }
++      return n;
++}
++
+ static void *gmp_xrealloc(void *ptr, size_t old_size, size_t new_size)
+ {
+       return xrealloc(ptr, new_size);
+diff --git a/src/parser_bison.y b/src/parser_bison.y
+index 99dbd08..eb5cf90 100644
+--- a/src/parser_bison.y
++++ b/src/parser_bison.y
+@@ -237,7 +237,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
+ %token OPERATION              "operation"
+ %token IP                     "ip"
+-%token VERSION                        "version"
++%token IPHDRVERSION           "version"
+ %token HDRLENGTH              "hdrlength"
+ %token TOS                    "tos"
+ %token LENGTH                 "length"
+@@ -1947,7 +1947,7 @@ ip_hdr_expr              :       IP      ip_hdr_field
+                       }
+                       ;
+-ip_hdr_field          :       VERSION         { $$ = IPHDR_VERSION; }
++ip_hdr_field          :       IPHDRVERSION    { $$ = IPHDR_VERSION; }
+                       |       HDRLENGTH       { $$ = IPHDR_HDRLENGTH; }
+                       |       TOS             { $$ = IPHDR_TOS; }
+                       |       LENGTH          { $$ = IPHDR_LENGTH; }
+@@ -1994,7 +1994,7 @@ ip6_hdr_expr             :       IP6     ip6_hdr_field
+                       }
+                       ;
+-ip6_hdr_field         :       VERSION         { $$ = IP6HDR_VERSION; }
++ip6_hdr_field         :       IPHDRVERSION    { $$ = IP6HDR_VERSION; }
+                       |       PRIORITY        { $$ = IP6HDR_PRIORITY; }
+                       |       FLOWLABEL       { $$ = IP6HDR_FLOWLABEL; }
+                       |       LENGTH          { $$ = IP6HDR_LENGTH; }
+diff --git a/src/scanner.l b/src/scanner.l
+index ed87da6..92b6a10 100644
+--- a/src/scanner.l
++++ b/src/scanner.l
+@@ -349,7 +349,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
+ "operation"           { return OPERATION; }
+ "ip"                  { return IP; }
+-"version"             { return VERSION; }
++"version"             { return IPHDRVERSION; }
+ "hdrlength"           { return HDRLENGTH; }
+ "tos"                 { return TOS; }
+ "length"              { return LENGTH; }
+-- 
+2.1.3
+