Skip to content

Commit

Permalink
nft, fw4: add fullcone support
Browse files Browse the repository at this point in the history
  • Loading branch information
911gt3 authored and lawrencetg committed Sep 5, 2022
1 parent 5afa326 commit 315135a
Show file tree
Hide file tree
Showing 4 changed files with 703 additions and 0 deletions.
1 change: 1 addition & 0 deletions package/libs/libnftnl/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ PKG_LICENSE_FILES:=COPYING

PKG_INSTALL:=1
PKG_BUILD_PARALLEL:=1
PKG_FIXUP:=autoreconf

include $(INCLUDE_DIR)/package.mk

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
From 6c39f04febd7cfdbd474233379416babcd0fc341 Mon Sep 17 00:00:00 2001
From: Syrone Wong <[email protected]>
Date: Fri, 8 Apr 2022 23:52:11 +0800
Subject: [PATCH] libnftnl: add fullcone expression support

Signed-off-by: Syrone Wong <[email protected]>
---
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

--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -245,6 +245,12 @@ enum {
};

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,
NFTNL_EXPR_REDIR_FLAGS,
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1434,6 +1434,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
*
* @NFTA_REDIR_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers)
--- 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 \
--- /dev/null
+++ b/src/expr/fullcone.c
@@ -0,0 +1,168 @@
+/*
+ * (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,
+ .output = nftnl_expr_fullcone_snprintf,
+};
+
--- 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,
Loading

0 comments on commit 315135a

Please sign in to comment.