All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH iptables 1/2] libxtables: extend xlate infrastructure
@ 2021-06-02 23:16 Pablo Neira Ayuso
  2021-06-02 23:16 ` [PATCH iptables 2/2] extensions: libxt_connlimit: add translation Pablo Neira Ayuso
  0 siblings, 1 reply; 2+ messages in thread
From: Pablo Neira Ayuso @ 2021-06-02 23:16 UTC (permalink / raw)
  To: netfilter-devel

This infrastructure extends the existing xlate infrastructure:

- Extensions can define set dependencies through .xlate. The resulting
  set definition can be obtained through xt_xlate_set_get().
- Add xl_xlate_set_family() and xl_xlate_get_family() to store/fetch
  the family.

The first client of this new xlate API is the connlimit extension,
which is added in a follow up patch.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 configure.ac                 |  4 +-
 include/xtables.h            |  6 +++
 iptables/xtables-translate.c | 35 ++++++++++-----
 libxtables/xtables.c         | 82 ++++++++++++++++++++++++++++--------
 4 files changed, 96 insertions(+), 31 deletions(-)

diff --git a/configure.ac b/configure.ac
index 6864378a3fcb..00ae60c5cfa1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,8 +2,8 @@
 AC_INIT([iptables], [1.8.7])
 
 # See libtool.info "Libtool's versioning system"
-libxtables_vcurrent=16
-libxtables_vage=4
+libxtables_vcurrent=17
+libxtables_vage=5
 
 AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_HEADERS([config.h])
diff --git a/include/xtables.h b/include/xtables.h
index df1eaee32664..347f4bd7aa98 100644
--- a/include/xtables.h
+++ b/include/xtables.h
@@ -632,9 +632,15 @@ extern const char *xtables_lmap_id2name(const struct xtables_lmap *, int);
 struct xt_xlate *xt_xlate_alloc(int size);
 void xt_xlate_free(struct xt_xlate *xl);
 void xt_xlate_add(struct xt_xlate *xl, const char *fmt, ...) __attribute__((format(printf,2,3)));
+#define xt_xlate_rule_add xt_xlate_add
+void xt_xlate_set_add(struct xt_xlate *xl, const char *fmt, ...) __attribute__((format(printf,2,3)));
 void xt_xlate_add_comment(struct xt_xlate *xl, const char *comment);
 const char *xt_xlate_get_comment(struct xt_xlate *xl);
+void xl_xlate_set_family(struct xt_xlate *xl, uint8_t family);
+uint8_t xt_xlate_get_family(struct xt_xlate *xl);
 const char *xt_xlate_get(struct xt_xlate *xl);
+#define xt_xlate_rule_get xt_xlate_get
+const char *xt_xlate_set_get(struct xt_xlate *xl);
 
 #ifdef XTABLES_INTERNAL
 
diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c
index 575fb320dc40..9cfcd4d44167 100644
--- a/iptables/xtables-translate.c
+++ b/iptables/xtables-translate.c
@@ -155,20 +155,36 @@ static int nft_rule_xlate_add(struct nft_handle *h,
 			      bool append)
 {
 	struct xt_xlate *xl = xt_xlate_alloc(10240);
+	const char *set;
 	int ret;
 
+	xl_xlate_set_family(xl, h->family);
+	ret = h->ops->xlate(cs, xl);
+	if (!ret)
+		goto err_out;
+
+	set = xt_xlate_set_get(xl);
+	if (set[0]) {
+		if (!cs->restore && p->command != CMD_NONE)
+			printf("nft ");
+
+		printf("add set %s %s %s\n", family2str[h->family], p->table,
+		       xt_xlate_set_get(xl));
+	}
+
+	if (!cs->restore && p->command != CMD_NONE)
+		printf("nft ");
+
 	if (append) {
-		xt_xlate_add(xl, "add rule %s %s %s ",
-			   family2str[h->family], p->table, p->chain);
+		printf("add rule %s %s %s ",
+		       family2str[h->family], p->table, p->chain);
 	} else {
-		xt_xlate_add(xl, "insert rule %s %s %s ",
-			   family2str[h->family], p->table, p->chain);
+		printf("insert rule %s %s %s ",
+		       family2str[h->family], p->table, p->chain);
 	}
+	printf("%s\n", xt_xlate_rule_get(xl));
 
-	ret = h->ops->xlate(cs, xl);
-	if (ret)
-		printf("%s\n", xt_xlate_get(xl));
-
+err_out:
 	xt_xlate_free(xl);
 	return ret;
 }
@@ -249,9 +265,6 @@ static int do_command_xlate(struct nft_handle *h, int argc, char *argv[],
 
 	cs.restore = restore;
 
-	if (!restore && p.command != CMD_NONE)
-		printf("nft ");
-
 	switch (p.command) {
 	case CMD_APPEND:
 		ret = 1;
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
index e6edfb5b4946..d7aab834b998 100644
--- a/libxtables/xtables.c
+++ b/libxtables/xtables.c
@@ -2319,32 +2319,42 @@ void get_kernel_version(void)
 
 #include <linux/netfilter/nf_tables.h>
 
+enum xt_xlate_type {
+	XT_XLATE_RULE = 0,
+	XT_XLATE_SET,
+	__XT_XLATE_MAX
+};
+
 struct xt_xlate {
-	struct {
+	struct xt_xlate_buf {
 		char	*data;
 		int	size;
 		int	rem;
 		int	off;
-	} buf;
+	} buf[__XT_XLATE_MAX];
 	char comment[NFT_USERDATA_MAXLEN];
+	int family;
 };
 
 struct xt_xlate *xt_xlate_alloc(int size)
 {
 	struct xt_xlate *xl;
+	int i;
 
 	xl = malloc(sizeof(struct xt_xlate));
 	if (xl == NULL)
 		xtables_error(RESOURCE_PROBLEM, "OOM");
 
-	xl->buf.data = malloc(size);
-	if (xl->buf.data == NULL)
-		xtables_error(RESOURCE_PROBLEM, "OOM");
+	for (i = 0; i < __XT_XLATE_MAX; i++) {
+		xl->buf[i].data = malloc(size);
+		if (xl->buf[i].data == NULL)
+			xtables_error(RESOURCE_PROBLEM, "OOM");
 
-	xl->buf.data[0] = '\0';
-	xl->buf.size = size;
-	xl->buf.rem = size;
-	xl->buf.off = 0;
+		xl->buf[i].data[0] = '\0';
+		xl->buf[i].size = size;
+		xl->buf[i].rem = size;
+		xl->buf[i].off = 0;
+	}
 	xl->comment[0] = '\0';
 
 	return xl;
@@ -2352,23 +2362,44 @@ struct xt_xlate *xt_xlate_alloc(int size)
 
 void xt_xlate_free(struct xt_xlate *xl)
 {
-	free(xl->buf.data);
+	int i;
+
+	for (i = 0; i < __XT_XLATE_MAX; i++)
+		free(xl->buf[i].data);
+
 	free(xl);
 }
 
-void xt_xlate_add(struct xt_xlate *xl, const char *fmt, ...)
+static void __xt_xlate_add(struct xt_xlate *xl, enum xt_xlate_type type,
+			   const char *fmt, va_list ap)
 {
-	va_list ap;
+	struct xt_xlate_buf *buf = &xl->buf[type];
 	int len;
 
-	va_start(ap, fmt);
-	len = vsnprintf(xl->buf.data + xl->buf.off, xl->buf.rem, fmt, ap);
-	if (len < 0 || len >= xl->buf.rem)
+	len = vsnprintf(buf->data + buf->off, buf->rem, fmt, ap);
+	if (len < 0 || len >= buf->rem)
 		xtables_error(RESOURCE_PROBLEM, "OOM");
 
+	buf->rem -= len;
+	buf->off += len;
+}
+
+void xt_xlate_rule_add(struct xt_xlate *xl, const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	__xt_xlate_add(xl, XT_XLATE_RULE, fmt, ap);
+	va_end(ap);
+}
+
+void xt_xlate_set_add(struct xt_xlate *xl, const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	__xt_xlate_add(xl, XT_XLATE_SET, fmt, ap);
 	va_end(ap);
-	xl->buf.rem -= len;
-	xl->buf.off += len;
 }
 
 void xt_xlate_add_comment(struct xt_xlate *xl, const char *comment)
@@ -2382,7 +2413,22 @@ const char *xt_xlate_get_comment(struct xt_xlate *xl)
 	return xl->comment[0] ? xl->comment : NULL;
 }
 
+void xl_xlate_set_family(struct xt_xlate *xl, uint8_t family)
+{
+	xl->family = family;
+}
+
+uint8_t xt_xlate_get_family(struct xt_xlate *xl)
+{
+	return xl->family;
+}
+
 const char *xt_xlate_get(struct xt_xlate *xl)
 {
-	return xl->buf.data;
+	return xl->buf[XT_XLATE_RULE].data;
+}
+
+const char *xt_xlate_set_get(struct xt_xlate *xl)
+{
+	return xl->buf[XT_XLATE_SET].data;
 }
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH iptables 2/2] extensions: libxt_connlimit: add translation
  2021-06-02 23:16 [PATCH iptables 1/2] libxtables: extend xlate infrastructure Pablo Neira Ayuso
@ 2021-06-02 23:16 ` Pablo Neira Ayuso
  0 siblings, 0 replies; 2+ messages in thread
From: Pablo Neira Ayuso @ 2021-06-02 23:16 UTC (permalink / raw)
  To: netfilter-devel

This patch adds a translation for connlimit matches which requires
the definition of a set and the family context (either IPv4 or IPv6)
which is required to display the netmask accordingly.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 extensions/libxt_connlimit.c | 49 ++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/extensions/libxt_connlimit.c b/extensions/libxt_connlimit.c
index a569f86aa6b2..118faea560f7 100644
--- a/extensions/libxt_connlimit.c
+++ b/extensions/libxt_connlimit.c
@@ -2,6 +2,8 @@
 #include <netdb.h>
 #include <string.h>
 #include <xtables.h>
+#include <arpa/inet.h>
+
 #include <linux/netfilter/xt_connlimit.h>
 
 enum {
@@ -183,6 +185,51 @@ static void connlimit_save6(const void *ip, const struct xt_entry_match *match)
 	}
 }
 
+static int connlimit_xlate(struct xt_xlate *xl,
+			   const struct xt_xlate_mt_params *params)
+{
+	const struct xt_connlimit_info *info = (const void *)params->match->data;
+	static uint32_t connlimit_id;
+	char netmask[128] = {};
+	char addr[64] = {};
+	uint32_t mask;
+
+	switch (xt_xlate_get_family(xl)) {
+	case AF_INET:
+		mask = count_bits4(info->v4_mask);
+		if (mask != 32) {
+			struct in_addr *in = (struct in_addr *)&info->v4_mask;
+
+			inet_ntop(AF_INET, in, addr, sizeof(addr));
+			snprintf(netmask, sizeof(netmask), "and %s ", addr);
+		}
+		break;
+	case AF_INET6:
+		mask = count_bits6(info->v6_mask);
+		if (mask != 128) {
+			struct in6_addr *in6 = (struct in6_addr *)&info->v6_mask;
+
+			inet_ntop(AF_INET6, in6, addr, sizeof(addr));
+			snprintf(netmask, sizeof(netmask), "and %s ", addr);
+		}
+		break;
+	default:
+		return 0;
+	}
+
+	xt_xlate_set_add(xl, "connlimit%u { type ipv4_addr; flags dynamic; }",
+			 connlimit_id);
+	xt_xlate_rule_add(xl, "add @connlimit%u { %s %s %sct count %s%u }",
+			  connlimit_id++,
+			  xt_xlate_get_family(xl) == AF_INET ? "ip" : "ip6",
+			  info->flags & XT_CONNLIMIT_DADDR ? "daddr" : "saddr",
+			  netmask,
+			  info->flags & XT_CONNLIMIT_INVERT ? "" : "over ",
+			  info->limit);
+
+	return 1;
+}
+
 static struct xtables_match connlimit_mt_reg[] = {
 	{
 		.name          = "connlimit",
@@ -228,6 +275,7 @@ static struct xtables_match connlimit_mt_reg[] = {
 		.print         = connlimit_print4,
 		.save          = connlimit_save4,
 		.x6_options    = connlimit_opts,
+		.xlate         = connlimit_xlate,
 	},
 	{
 		.name          = "connlimit",
@@ -243,6 +291,7 @@ static struct xtables_match connlimit_mt_reg[] = {
 		.print         = connlimit_print6,
 		.save          = connlimit_save6,
 		.x6_options    = connlimit_opts,
+		.xlate         = connlimit_xlate,
 	},
 };
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-06-02 23:16 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-02 23:16 [PATCH iptables 1/2] libxtables: extend xlate infrastructure Pablo Neira Ayuso
2021-06-02 23:16 ` [PATCH iptables 2/2] extensions: libxt_connlimit: add translation Pablo Neira Ayuso

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.