diff --git a/package/libs/libnftnl/Makefile b/package/libs/libnftnl/Makefile index 37835b4338..e2e7791bf1 100644 --- a/package/libs/libnftnl/Makefile +++ b/package/libs/libnftnl/Makefile @@ -19,6 +19,7 @@ PKG_MAINTAINER:=Steven Barth 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 index 0000000000..cab40ec6c1 --- /dev/null +++ b/package/libs/libnftnl/patches/001-libnftnl-add-fullcone-expression-support.patch @@ -0,0 +1,264 @@ +From 6c39f04febd7cfdbd474233379416babcd0fc341 Mon Sep 17 00:00:00 2001 +From: Syrone Wong +Date: Fri, 8 Apr 2022 23:52:11 +0800 +Subject: [PATCH] libnftnl: add fullcone expression support + +Signed-off-by: Syrone Wong +--- + 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 ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "internal.h" ++#include ++#include ++#include ++ ++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,