OSDN Git Service

libnftnl: add fullcone expression support
authorSyrone Wong <wong.syrone@gmail.com>
Thu, 21 Apr 2022 09:40:47 +0000 (17:40 +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/libs/libnftnl/Makefile
package/libs/libnftnl/patches/001-libnftnl-add-fullcone-expression-support.patch [new file with mode: 0644]

index 37835b4..e2e7791 100644 (file)
@@ -19,6 +19,7 @@ PKG_MAINTAINER:=Steven Barth <steven@midlink.org>
 PKG_LICENSE:=GPL-2.0-or-later
 PKG_LICENSE_FILES:=COPYING
 
+PKG_FIXUP:=autoreconf
 PKG_INSTALL:=1
 PKG_BUILD_PARALLEL:=1
 
diff --git a/package/libs/libnftnl/patches/001-libnftnl-add-fullcone-expression-support.patch b/package/libs/libnftnl/patches/001-libnftnl-add-fullcone-expression-support.patch
new file mode 100644 (file)
index 0000000..cab40ec
--- /dev/null
@@ -0,0 +1,264 @@
+From 6c39f04febd7cfdbd474233379416babcd0fc341 Mon Sep 17 00:00:00 2001
+From: Syrone Wong <wong.syrone@gmail.com>
+Date: Fri, 8 Apr 2022 23:52:11 +0800
+Subject: [PATCH] libnftnl: add fullcone expression support
+
+Signed-off-by: Syrone Wong <wong.syrone@gmail.com>
+---
+ include/libnftnl/expr.h             |   6 +
+ include/linux/netfilter/nf_tables.h |  16 +++
+ src/Makefile.am                     |   1 +
+ src/expr/fullcone.c                 | 167 ++++++++++++++++++++++++++++
+ src/expr_ops.c                      |   2 +
+ 5 files changed, 192 insertions(+)
+ create mode 100644 src/expr/fullcone.c
+
+diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
+index 00c63ab..7dcf403 100644
+--- a/include/libnftnl/expr.h
++++ b/include/libnftnl/expr.h
+@@ -244,6 +244,12 @@ enum {
+       NFTNL_EXPR_MASQ_REG_PROTO_MAX,
+ };
++enum {
++      NFTNL_EXPR_FULLCONE_FLAGS               = NFTNL_EXPR_BASE,
++      NFTNL_EXPR_FULLCONE_REG_PROTO_MIN,
++      NFTNL_EXPR_FULLCONE_REG_PROTO_MAX,
++};
++
+ enum {
+       NFTNL_EXPR_REDIR_REG_PROTO_MIN  = NFTNL_EXPR_BASE,
+       NFTNL_EXPR_REDIR_REG_PROTO_MAX,
+diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
+index 0ae9120..8b8ae38 100644
+--- a/include/linux/netfilter/nf_tables.h
++++ b/include/linux/netfilter/nf_tables.h
+@@ -1433,6 +1433,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/src/Makefile.am b/src/Makefile.am
+index c3b0ab9..2718218 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -54,6 +54,7 @@ libnftnl_la_SOURCES = utils.c                \
+                     expr/target.c     \
+                     expr/tunnel.c     \
+                     expr/masq.c       \
++                    expr/fullcone.c   \
+                     expr/redir.c      \
+                     expr/hash.c       \
+                     expr/socket.c     \
+diff --git a/src/expr/fullcone.c b/src/expr/fullcone.c
+new file mode 100644
+index 0000000..aaedd83
+--- /dev/null
++++ b/src/expr/fullcone.c
+@@ -0,0 +1,167 @@
++/*
++ * (C) 2022 wongsyrone
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published
++ * by the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#include <stdio.h>
++#include <stdint.h>
++#include <arpa/inet.h>
++#include <errno.h>
++#include <inttypes.h>
++
++#include <linux/netfilter/nf_tables.h>
++
++#include "internal.h"
++#include <libmnl/libmnl.h>
++#include <libnftnl/expr.h>
++#include <libnftnl/rule.h>
++
++struct nftnl_expr_fullcone {
++      uint32_t                flags;
++      enum nft_registers      sreg_proto_min;
++      enum nft_registers      sreg_proto_max;
++};
++
++static int
++nftnl_expr_fullcone_set(struct nftnl_expr *e, uint16_t type,
++                     const void *data, uint32_t data_len)
++{
++      struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e);
++
++      switch (type) {
++      case NFTNL_EXPR_FULLCONE_FLAGS:
++              memcpy(&fullcone->flags, data, sizeof(fullcone->flags));
++              break;
++      case NFTNL_EXPR_FULLCONE_REG_PROTO_MIN:
++              memcpy(&fullcone->sreg_proto_min, data, sizeof(fullcone->sreg_proto_min));
++              break;
++      case NFTNL_EXPR_FULLCONE_REG_PROTO_MAX:
++              memcpy(&fullcone->sreg_proto_max, data, sizeof(fullcone->sreg_proto_max));
++              break;
++      default:
++              return -1;
++      }
++      return 0;
++}
++
++static const void *
++nftnl_expr_fullcone_get(const struct nftnl_expr *e, uint16_t type,
++                     uint32_t *data_len)
++{
++      struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e);
++
++      switch (type) {
++      case NFTNL_EXPR_FULLCONE_FLAGS:
++              *data_len = sizeof(fullcone->flags);
++              return &fullcone->flags;
++      case NFTNL_EXPR_FULLCONE_REG_PROTO_MIN:
++              *data_len = sizeof(fullcone->sreg_proto_min);
++              return &fullcone->sreg_proto_min;
++      case NFTNL_EXPR_FULLCONE_REG_PROTO_MAX:
++              *data_len = sizeof(fullcone->sreg_proto_max);
++              return &fullcone->sreg_proto_max;
++      }
++      return NULL;
++}
++
++static int nftnl_expr_fullcone_cb(const struct nlattr *attr, void *data)
++{
++      const struct nlattr **tb = data;
++      int type = mnl_attr_get_type(attr);
++
++      if (mnl_attr_type_valid(attr, NFTA_FULLCONE_MAX) < 0)
++              return MNL_CB_OK;
++
++      switch (type) {
++      case NFTA_FULLCONE_REG_PROTO_MIN:
++      case NFTA_FULLCONE_REG_PROTO_MAX:
++      case NFTA_FULLCONE_FLAGS:
++              if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
++                      abi_breakage();
++              break;
++      }
++
++      tb[type] = attr;
++      return MNL_CB_OK;
++}
++
++static void
++nftnl_expr_fullcone_build(struct nlmsghdr *nlh, const struct nftnl_expr *e)
++{
++      struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e);
++
++      if (e->flags & (1 << NFTNL_EXPR_FULLCONE_FLAGS))
++              mnl_attr_put_u32(nlh, NFTA_FULLCONE_FLAGS, htobe32(fullcone->flags));
++      if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MIN))
++              mnl_attr_put_u32(nlh, NFTA_FULLCONE_REG_PROTO_MIN,
++                               htobe32(fullcone->sreg_proto_min));
++      if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MAX))
++              mnl_attr_put_u32(nlh, NFTA_FULLCONE_REG_PROTO_MAX,
++                               htobe32(fullcone->sreg_proto_max));
++}
++
++static int
++nftnl_expr_fullcone_parse(struct nftnl_expr *e, struct nlattr *attr)
++{
++      struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e);
++      struct nlattr *tb[NFTA_FULLCONE_MAX+1] = {};
++
++      if (mnl_attr_parse_nested(attr, nftnl_expr_fullcone_cb, tb) < 0)
++              return -1;
++
++      if (tb[NFTA_FULLCONE_FLAGS]) {
++              fullcone->flags = be32toh(mnl_attr_get_u32(tb[NFTA_FULLCONE_FLAGS]));
++              e->flags |= (1 << NFTNL_EXPR_FULLCONE_FLAGS);
++        }
++      if (tb[NFTA_FULLCONE_REG_PROTO_MIN]) {
++              fullcone->sreg_proto_min =
++                      be32toh(mnl_attr_get_u32(tb[NFTA_FULLCONE_REG_PROTO_MIN]));
++              e->flags |= (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MIN);
++      }
++      if (tb[NFTA_FULLCONE_REG_PROTO_MAX]) {
++              fullcone->sreg_proto_max =
++                      be32toh(mnl_attr_get_u32(tb[NFTA_FULLCONE_REG_PROTO_MAX]));
++              e->flags |= (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MAX);
++      }
++
++      return 0;
++}
++
++static int nftnl_expr_fullcone_snprintf(char *buf, size_t remain,
++                                  uint32_t flags, const struct nftnl_expr *e)
++{
++      struct nftnl_expr_fullcone *fullcone = nftnl_expr_data(e);
++      int offset = 0, ret = 0;
++
++      if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MIN)) {
++              ret = snprintf(buf + offset, remain, "proto_min reg %u ",
++                             fullcone->sreg_proto_min);
++              SNPRINTF_BUFFER_SIZE(ret, remain, offset);
++      }
++      if (e->flags & (1 << NFTNL_EXPR_FULLCONE_REG_PROTO_MAX)) {
++              ret = snprintf(buf + offset, remain, "proto_max reg %u ",
++                             fullcone->sreg_proto_max);
++              SNPRINTF_BUFFER_SIZE(ret, remain, offset);
++      }
++      if (e->flags & (1 << NFTNL_EXPR_FULLCONE_FLAGS)) {
++              ret = snprintf(buf + offset, remain, "flags 0x%x ", fullcone->flags);
++              SNPRINTF_BUFFER_SIZE(ret, remain, offset);
++      }
++
++      return offset;
++}
++
++struct expr_ops expr_ops_fullcone = {
++      .name           = "fullcone",
++      .alloc_len      = sizeof(struct nftnl_expr_fullcone),
++      .max_attr       = NFTA_FULLCONE_MAX,
++      .set            = nftnl_expr_fullcone_set,
++      .get            = nftnl_expr_fullcone_get,
++      .parse          = nftnl_expr_fullcone_parse,
++      .build          = nftnl_expr_fullcone_build,
++      .snprintf       = nftnl_expr_fullcone_snprintf,
++};
+diff --git a/src/expr_ops.c b/src/expr_ops.c
+index 7248e4f..9dee9f8 100644
+--- a/src/expr_ops.c
++++ b/src/expr_ops.c
+@@ -19,6 +19,7 @@ extern struct expr_ops expr_ops_limit;
+ extern struct expr_ops expr_ops_log;
+ extern struct expr_ops expr_ops_lookup;
+ extern struct expr_ops expr_ops_masq;
++extern struct expr_ops expr_ops_fullcone;
+ extern struct expr_ops expr_ops_match;
+ extern struct expr_ops expr_ops_meta;
+ extern struct expr_ops expr_ops_ng;
+@@ -63,6 +64,7 @@ static struct expr_ops *expr_ops[] = {
+       &expr_ops_log,
+       &expr_ops_lookup,
+       &expr_ops_masq,
++      &expr_ops_fullcone,
+       &expr_ops_match,
+       &expr_ops_meta,
+       &expr_ops_ng,