netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] extensions: add IPv6 NAT support
@ 2012-08-09 20:11 kaber
  2012-08-09 20:11 ` [PATCH 1/7] extensions: convert NAT target to use nf_nat.h kaber
                   ` (6 more replies)
  0 siblings, 7 replies; 14+ messages in thread
From: kaber @ 2012-08-09 20:11 UTC (permalink / raw)
  To: netfilter-devel

The following patches contain userspace support for IPv6 NAT and
stateless prefix translation. The NAT extensions are based on
their IPv4 counterparts.


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

* [PATCH 1/7] extensions: convert NAT target to use nf_nat.h
  2012-08-09 20:11 [PATCH 0/7] extensions: add IPv6 NAT support kaber
@ 2012-08-09 20:11 ` kaber
  2012-08-09 20:11 ` [PATCH 2/7] extensions: add IPv6 MASQUERADE extension kaber
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: kaber @ 2012-08-09 20:11 UTC (permalink / raw)
  To: netfilter-devel

From: Patrick McHardy <kaber@trash.net>

Convert the NAT targets to use the kernel supplied nf_nat.h header.

Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 extensions/libipt_DNAT.c                           |   36 +++---
 extensions/libipt_MASQUERADE.c                     |   32 +++---
 extensions/libipt_NETMAP.c                         |   18 ++--
 extensions/libipt_REDIRECT.c                       |   34 +++---
 extensions/libipt_SAME.c                           |   21 +++--
 extensions/libipt_SNAT.c                           |   36 +++---
 .../linux/netfilter/nf_conntrack_tuple_common.h    |   27 +++++
 include/linux/netfilter/nf_nat.h                   |   25 +++++
 include/linux/netfilter_ipv4/ipt_SAME.h            |    2 +-
 include/net/netfilter/nf_conntrack_tuple.h         |  114 --------------------
 include/net/netfilter/nf_nat.h                     |   55 ----------
 11 files changed, 144 insertions(+), 256 deletions(-)
 create mode 100644 include/linux/netfilter/nf_nat.h
 delete mode 100644 include/net/netfilter/nf_conntrack_tuple.h
 delete mode 100644 include/net/netfilter/nf_nat.h

diff --git a/extensions/libipt_DNAT.c b/extensions/libipt_DNAT.c
index 466c9de..ff18799 100644
--- a/extensions/libipt_DNAT.c
+++ b/extensions/libipt_DNAT.c
@@ -6,7 +6,7 @@
 #include <iptables.h> /* get_kernel_version */
 #include <limits.h> /* INT_MAX in ip_tables.h */
 #include <linux/netfilter_ipv4/ip_tables.h>
-#include <net/netfilter/nf_nat.h>
+#include <linux/netfilter/nf_nat.h>
 
 enum {
 	O_TO_DEST = 0,
@@ -23,7 +23,7 @@ enum {
 struct ipt_natinfo
 {
 	struct xt_entry_target t;
-	struct nf_nat_multi_range mr;
+	struct nf_nat_ipv4_multi_range_compat mr;
 };
 
 static void DNAT_help(void)
@@ -44,7 +44,7 @@ static const struct xt_option_entry DNAT_opts[] = {
 };
 
 static struct ipt_natinfo *
-append_range(struct ipt_natinfo *info, const struct nf_nat_range *range)
+append_range(struct ipt_natinfo *info, const struct nf_nat_ipv4_range *range)
 {
 	unsigned int size;
 
@@ -66,7 +66,7 @@ append_range(struct ipt_natinfo *info, const struct nf_nat_range *range)
 static struct xt_entry_target *
 parse_to(const char *orig_arg, int portok, struct ipt_natinfo *info)
 {
-	struct nf_nat_range range;
+	struct nf_nat_ipv4_range range;
 	char *arg, *colon, *dash, *error;
 	const struct in_addr *ip;
 
@@ -83,7 +83,7 @@ parse_to(const char *orig_arg, int portok, struct ipt_natinfo *info)
 			xtables_error(PARAMETER_PROBLEM,
 				   "Need TCP, UDP, SCTP or DCCP with port specification");
 
-		range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
+		range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
 
 		port = atoi(colon+1);
 		if (port <= 0 || port > 65535)
@@ -122,7 +122,7 @@ parse_to(const char *orig_arg, int portok, struct ipt_natinfo *info)
 		*colon = '\0';
 	}
 
-	range.flags |= IP_NAT_RANGE_MAP_IPS;
+	range.flags |= NF_NAT_RANGE_MAP_IPS;
 	dash = strchr(arg, '-');
 	if (colon && dash && dash > colon)
 		dash = NULL;
@@ -177,7 +177,7 @@ static void DNAT_parse(struct xt_option_call *cb)
 		cb->xflags |= F_X_TO_DEST;
 		break;
 	case O_PERSISTENT:
-		info->mr.range[0].flags |= IP_NAT_RANGE_PERSISTENT;
+		info->mr.range[0].flags |= NF_NAT_RANGE_PERSISTENT;
 		break;
 	}
 }
@@ -185,15 +185,15 @@ static void DNAT_parse(struct xt_option_call *cb)
 static void DNAT_fcheck(struct xt_fcheck_call *cb)
 {
 	static const unsigned int f = F_TO_DEST | F_RANDOM;
-	struct nf_nat_multi_range *mr = cb->data;
+	struct nf_nat_ipv4_multi_range_compat *mr = cb->data;
 
 	if ((cb->xflags & f) == f)
-		mr->range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
+		mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM;
 }
 
-static void print_range(const struct nf_nat_range *r)
+static void print_range(const struct nf_nat_ipv4_range *r)
 {
-	if (r->flags & IP_NAT_RANGE_MAP_IPS) {
+	if (r->flags & NF_NAT_RANGE_MAP_IPS) {
 		struct in_addr a;
 
 		a.s_addr = r->min_ip;
@@ -203,7 +203,7 @@ static void print_range(const struct nf_nat_range *r)
 			printf("-%s", xtables_ipaddr_to_numeric(&a));
 		}
 	}
-	if (r->flags & IP_NAT_RANGE_PROTO_SPECIFIED) {
+	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
 		printf(":");
 		printf("%hu", ntohs(r->min.tcp.port));
 		if (r->max.tcp.port != r->min.tcp.port)
@@ -220,9 +220,9 @@ static void DNAT_print(const void *ip, const struct xt_entry_target *target,
 	printf(" to:");
 	for (i = 0; i < info->mr.rangesize; i++) {
 		print_range(&info->mr.range[i]);
-		if (info->mr.range[i].flags & IP_NAT_RANGE_PROTO_RANDOM)
+		if (info->mr.range[i].flags & NF_NAT_RANGE_PROTO_RANDOM)
 			printf(" random");
-		if (info->mr.range[i].flags & IP_NAT_RANGE_PERSISTENT)
+		if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT)
 			printf(" persistent");
 	}
 }
@@ -235,9 +235,9 @@ static void DNAT_save(const void *ip, const struct xt_entry_target *target)
 	for (i = 0; i < info->mr.rangesize; i++) {
 		printf(" --to-destination ");
 		print_range(&info->mr.range[i]);
-		if (info->mr.range[i].flags & IP_NAT_RANGE_PROTO_RANDOM)
+		if (info->mr.range[i].flags & NF_NAT_RANGE_PROTO_RANDOM)
 			printf(" --random");
-		if (info->mr.range[i].flags & IP_NAT_RANGE_PERSISTENT)
+		if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT)
 			printf(" --persistent");
 	}
 }
@@ -246,8 +246,8 @@ static struct xtables_target dnat_tg_reg = {
 	.name		= "DNAT",
 	.version	= XTABLES_VERSION,
 	.family		= NFPROTO_IPV4,
-	.size		= XT_ALIGN(sizeof(struct nf_nat_multi_range)),
-	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_multi_range)),
+	.size		= XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
+	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
 	.help		= DNAT_help,
 	.x6_parse	= DNAT_parse,
 	.x6_fcheck	= DNAT_fcheck,
diff --git a/extensions/libipt_MASQUERADE.c b/extensions/libipt_MASQUERADE.c
index 7ba42df..ea07445 100644
--- a/extensions/libipt_MASQUERADE.c
+++ b/extensions/libipt_MASQUERADE.c
@@ -6,7 +6,7 @@
 #include <xtables.h>
 #include <limits.h> /* INT_MAX in ip_tables.h */
 #include <linux/netfilter_ipv4/ip_tables.h>
-#include <net/netfilter/nf_nat.h>
+#include <linux/netfilter/nf_nat.h>
 
 enum {
 	O_TO_PORTS = 0,
@@ -31,7 +31,7 @@ static const struct xt_option_entry MASQUERADE_opts[] = {
 
 static void MASQUERADE_init(struct xt_entry_target *t)
 {
-	struct nf_nat_multi_range *mr = (struct nf_nat_multi_range *)t->data;
+	struct nf_nat_ipv4_multi_range_compat *mr = (struct nf_nat_ipv4_multi_range_compat *)t->data;
 
 	/* Actually, it's 0, but it's ignored at the moment. */
 	mr->rangesize = 1;
@@ -39,12 +39,12 @@ static void MASQUERADE_init(struct xt_entry_target *t)
 
 /* Parses ports */
 static void
-parse_ports(const char *arg, struct nf_nat_multi_range *mr)
+parse_ports(const char *arg, struct nf_nat_ipv4_multi_range_compat *mr)
 {
 	char *end;
 	unsigned int port, maxport;
 
-	mr->range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
+	mr->range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
 
 	if (!xtables_strtoui(arg, &end, &port, 0, UINT16_MAX))
 		xtables_param_act(XTF_BAD_VALUE, "MASQUERADE", "--to-ports", arg);
@@ -75,7 +75,7 @@ static void MASQUERADE_parse(struct xt_option_call *cb)
 {
 	const struct ipt_entry *entry = cb->xt_entry;
 	int portok;
-	struct nf_nat_multi_range *mr = cb->data;
+	struct nf_nat_ipv4_multi_range_compat *mr = cb->data;
 
 	if (entry->ip.proto == IPPROTO_TCP
 	    || entry->ip.proto == IPPROTO_UDP
@@ -95,7 +95,7 @@ static void MASQUERADE_parse(struct xt_option_call *cb)
 		parse_ports(cb->arg, mr);
 		break;
 	case O_RANDOM:
-		mr->range[0].flags |=  IP_NAT_RANGE_PROTO_RANDOM;
+		mr->range[0].flags |=  NF_NAT_RANGE_PROTO_RANDOM;
 		break;
 	}
 }
@@ -104,33 +104,33 @@ static void
 MASQUERADE_print(const void *ip, const struct xt_entry_target *target,
                  int numeric)
 {
-	const struct nf_nat_multi_range *mr = (const void *)target->data;
-	const struct nf_nat_range *r = &mr->range[0];
+	const struct nf_nat_ipv4_multi_range_compat *mr = (const void *)target->data;
+	const struct nf_nat_ipv4_range *r = &mr->range[0];
 
-	if (r->flags & IP_NAT_RANGE_PROTO_SPECIFIED) {
+	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
 		printf(" masq ports: ");
 		printf("%hu", ntohs(r->min.tcp.port));
 		if (r->max.tcp.port != r->min.tcp.port)
 			printf("-%hu", ntohs(r->max.tcp.port));
 	}
 
-	if (r->flags & IP_NAT_RANGE_PROTO_RANDOM)
+	if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
 		printf(" random");
 }
 
 static void
 MASQUERADE_save(const void *ip, const struct xt_entry_target *target)
 {
-	const struct nf_nat_multi_range *mr = (const void *)target->data;
-	const struct nf_nat_range *r = &mr->range[0];
+	const struct nf_nat_ipv4_multi_range_compat *mr = (const void *)target->data;
+	const struct nf_nat_ipv4_range *r = &mr->range[0];
 
-	if (r->flags & IP_NAT_RANGE_PROTO_SPECIFIED) {
+	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
 		printf(" --to-ports %hu", ntohs(r->min.tcp.port));
 		if (r->max.tcp.port != r->min.tcp.port)
 			printf("-%hu", ntohs(r->max.tcp.port));
 	}
 
-	if (r->flags & IP_NAT_RANGE_PROTO_RANDOM)
+	if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
 		printf(" --random");
 }
 
@@ -138,8 +138,8 @@ static struct xtables_target masquerade_tg_reg = {
 	.name		= "MASQUERADE",
 	.version	= XTABLES_VERSION,
 	.family		= NFPROTO_IPV4,
-	.size		= XT_ALIGN(sizeof(struct nf_nat_multi_range)),
-	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_multi_range)),
+	.size		= XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
+	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
 	.help		= MASQUERADE_help,
 	.init		= MASQUERADE_init,
 	.x6_parse	= MASQUERADE_parse,
diff --git a/extensions/libipt_NETMAP.c b/extensions/libipt_NETMAP.c
index 5c4471a..dee7b01 100644
--- a/extensions/libipt_NETMAP.c
+++ b/extensions/libipt_NETMAP.c
@@ -7,7 +7,7 @@
 #include <stdlib.h>
 #include <getopt.h>
 #include <xtables.h>
-#include <net/netfilter/nf_nat.h>
+#include <linux/netfilter/nf_nat.h>
 
 #define MODULENAME "NETMAP"
 
@@ -45,7 +45,7 @@ netmask2bits(uint32_t netmask)
 
 static void NETMAP_init(struct xt_entry_target *t)
 {
-	struct nf_nat_multi_range *mr = (struct nf_nat_multi_range *)t->data;
+	struct nf_nat_ipv4_multi_range_compat *mr = (struct nf_nat_ipv4_multi_range_compat *)t->data;
 
 	/* Actually, it's 0, but it's ignored at the moment. */
 	mr->rangesize = 1;
@@ -53,11 +53,11 @@ static void NETMAP_init(struct xt_entry_target *t)
 
 static void NETMAP_parse(struct xt_option_call *cb)
 {
-	struct nf_nat_multi_range *mr = cb->data;
-	struct nf_nat_range *range = &mr->range[0];
+	struct nf_nat_ipv4_multi_range_compat *mr = cb->data;
+	struct nf_nat_ipv4_range *range = &mr->range[0];
 
 	xtables_option_parse(cb);
-	range->flags |= IP_NAT_RANGE_MAP_IPS;
+	range->flags |= NF_NAT_RANGE_MAP_IPS;
 	range->min_ip = cb->val.haddr.ip & cb->val.hmask.ip;
 	range->max_ip = range->min_ip | ~cb->val.hmask.ip;
 }
@@ -65,8 +65,8 @@ static void NETMAP_parse(struct xt_option_call *cb)
 static void NETMAP_print(const void *ip, const struct xt_entry_target *target,
                          int numeric)
 {
-	const struct nf_nat_multi_range *mr = (const void *)target->data;
-	const struct nf_nat_range *r = &mr->range[0];
+	const struct nf_nat_ipv4_multi_range_compat *mr = (const void *)target->data;
+	const struct nf_nat_ipv4_range *r = &mr->range[0];
 	struct in_addr a;
 	int bits;
 
@@ -90,8 +90,8 @@ static struct xtables_target netmap_tg_reg = {
 	.name		= MODULENAME,
 	.version	= XTABLES_VERSION,
 	.family		= NFPROTO_IPV4,
-	.size		= XT_ALIGN(sizeof(struct nf_nat_multi_range)),
-	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_multi_range)),
+	.size		= XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
+	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
 	.help		= NETMAP_help,
 	.init		= NETMAP_init,
 	.x6_parse	= NETMAP_parse,
diff --git a/extensions/libipt_REDIRECT.c b/extensions/libipt_REDIRECT.c
index e67360a..610a949 100644
--- a/extensions/libipt_REDIRECT.c
+++ b/extensions/libipt_REDIRECT.c
@@ -4,7 +4,7 @@
 #include <xtables.h>
 #include <limits.h> /* INT_MAX in ip_tables.h */
 #include <linux/netfilter_ipv4/ip_tables.h>
-#include <net/netfilter/nf_nat.h>
+#include <linux/netfilter/nf_nat.h>
 
 enum {
 	O_TO_PORTS = 0,
@@ -30,7 +30,7 @@ static const struct xt_option_entry REDIRECT_opts[] = {
 
 static void REDIRECT_init(struct xt_entry_target *t)
 {
-	struct nf_nat_multi_range *mr = (struct nf_nat_multi_range *)t->data;
+	struct nf_nat_ipv4_multi_range_compat *mr = (struct nf_nat_ipv4_multi_range_compat *)t->data;
 
 	/* Actually, it's 0, but it's ignored at the moment. */
 	mr->rangesize = 1;
@@ -38,12 +38,12 @@ static void REDIRECT_init(struct xt_entry_target *t)
 
 /* Parses ports */
 static void
-parse_ports(const char *arg, struct nf_nat_multi_range *mr)
+parse_ports(const char *arg, struct nf_nat_ipv4_multi_range_compat *mr)
 {
 	char *end = "";
 	unsigned int port, maxport;
 
-	mr->range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
+	mr->range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
 
 	if (!xtables_strtoui(arg, &end, &port, 0, UINT16_MAX) &&
 	    (port = xtables_service_to_port(arg, NULL)) == (unsigned)-1)
@@ -75,7 +75,7 @@ parse_ports(const char *arg, struct nf_nat_multi_range *mr)
 static void REDIRECT_parse(struct xt_option_call *cb)
 {
 	const struct ipt_entry *entry = cb->xt_entry;
-	struct nf_nat_multi_range *mr = (void *)(*cb->target)->data;
+	struct nf_nat_ipv4_multi_range_compat *mr = (void *)(*cb->target)->data;
 	int portok;
 
 	if (entry->ip.proto == IPPROTO_TCP
@@ -95,11 +95,11 @@ static void REDIRECT_parse(struct xt_option_call *cb)
 				   "Need TCP, UDP, SCTP or DCCP with port specification");
 		parse_ports(cb->arg, mr);
 		if (cb->xflags & F_RANDOM)
-			mr->range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
+			mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM;
 		break;
 	case O_RANDOM:
 		if (cb->xflags & F_TO_PORTS)
-			mr->range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
+			mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM;
 		break;
 	}
 }
@@ -107,30 +107,30 @@ static void REDIRECT_parse(struct xt_option_call *cb)
 static void REDIRECT_print(const void *ip, const struct xt_entry_target *target,
                            int numeric)
 {
-	const struct nf_nat_multi_range *mr = (const void *)target->data;
-	const struct nf_nat_range *r = &mr->range[0];
+	const struct nf_nat_ipv4_multi_range_compat *mr = (const void *)target->data;
+	const struct nf_nat_ipv4_range *r = &mr->range[0];
 
-	if (r->flags & IP_NAT_RANGE_PROTO_SPECIFIED) {
+	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
 		printf(" redir ports ");
 		printf("%hu", ntohs(r->min.tcp.port));
 		if (r->max.tcp.port != r->min.tcp.port)
 			printf("-%hu", ntohs(r->max.tcp.port));
-		if (mr->range[0].flags & IP_NAT_RANGE_PROTO_RANDOM)
+		if (mr->range[0].flags & NF_NAT_RANGE_PROTO_RANDOM)
 			printf(" random");
 	}
 }
 
 static void REDIRECT_save(const void *ip, const struct xt_entry_target *target)
 {
-	const struct nf_nat_multi_range *mr = (const void *)target->data;
-	const struct nf_nat_range *r = &mr->range[0];
+	const struct nf_nat_ipv4_multi_range_compat *mr = (const void *)target->data;
+	const struct nf_nat_ipv4_range *r = &mr->range[0];
 
-	if (r->flags & IP_NAT_RANGE_PROTO_SPECIFIED) {
+	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
 		printf(" --to-ports ");
 		printf("%hu", ntohs(r->min.tcp.port));
 		if (r->max.tcp.port != r->min.tcp.port)
 			printf("-%hu", ntohs(r->max.tcp.port));
-		if (mr->range[0].flags & IP_NAT_RANGE_PROTO_RANDOM)
+		if (mr->range[0].flags & NF_NAT_RANGE_PROTO_RANDOM)
 			printf(" --random");
 	}
 }
@@ -139,8 +139,8 @@ static struct xtables_target redirect_tg_reg = {
 	.name		= "REDIRECT",
 	.version	= XTABLES_VERSION,
 	.family		= NFPROTO_IPV4,
-	.size		= XT_ALIGN(sizeof(struct nf_nat_multi_range)),
-	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_multi_range)),
+	.size		= XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
+	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
 	.help		= REDIRECT_help,
 	.init		= REDIRECT_init,
  	.x6_parse	= REDIRECT_parse,
diff --git a/extensions/libipt_SAME.c b/extensions/libipt_SAME.c
index e603ef6..5d5bf63 100644
--- a/extensions/libipt_SAME.c
+++ b/extensions/libipt_SAME.c
@@ -2,7 +2,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <xtables.h>
-#include <net/netfilter/nf_nat.h>
+#include <linux/netfilter/nf_nat.h>
 #include <linux/netfilter_ipv4/ipt_SAME.h>
 
 enum {
@@ -37,7 +37,7 @@ static const struct xt_option_entry SAME_opts[] = {
 };
 
 /* Parses range of IPs */
-static void parse_to(const char *orig_arg, struct nf_nat_range *range)
+static void parse_to(const char *orig_arg, struct nf_nat_ipv4_range *range)
 {
 	char *dash, *arg;
 	const struct in_addr *ip;
@@ -45,7 +45,7 @@ static void parse_to(const char *orig_arg, struct nf_nat_range *range)
 	arg = strdup(orig_arg);
 	if (arg == NULL)
 		xtables_error(RESOURCE_PROBLEM, "strdup");
-	range->flags |= IP_NAT_RANGE_MAP_IPS;
+	range->flags |= NF_NAT_RANGE_MAP_IPS;
 	dash = strchr(arg, '-');
 
 	if (dash)
@@ -74,6 +74,7 @@ static void parse_to(const char *orig_arg, struct nf_nat_range *range)
 static void SAME_parse(struct xt_option_call *cb)
 {
 	struct ipt_same_info *mr = cb->data;
+	unsigned int count;
 
 	xtables_option_parse(cb);
 	switch (cb->entry->id) {
@@ -89,6 +90,10 @@ static void SAME_parse(struct xt_option_call *cb)
 	case O_NODST:
 		mr->info |= IPT_SAME_NODST;
 		break;
+	case O_RANDOM:
+		for (count=0; count < mr->rangesize; count++)
+			mr->range[count].flags |= NF_NAT_RANGE_PROTO_RANDOM;
+		break;
 	}
 }
 
@@ -100,7 +105,7 @@ static void SAME_fcheck(struct xt_fcheck_call *cb)
 
 	if ((cb->xflags & f) == f)
 		for (count = 0; count < mr->rangesize; ++count)
-			mr->range[count].flags |= IP_NAT_RANGE_PROTO_RANDOM;
+			mr->range[count].flags |= NF_NAT_RANGE_PROTO_RANDOM;
 }
 
 static void SAME_print(const void *ip, const struct xt_entry_target *target,
@@ -113,7 +118,7 @@ static void SAME_print(const void *ip, const struct xt_entry_target *target,
 	printf(" same:");
 
 	for (count = 0; count < mr->rangesize; count++) {
-		const struct nf_nat_range *r = &mr->range[count];
+		const struct nf_nat_ipv4_range *r = &mr->range[count];
 		struct in_addr a;
 
 		a.s_addr = r->min_ip;
@@ -123,7 +128,7 @@ static void SAME_print(const void *ip, const struct xt_entry_target *target,
 		
 		if (r->min_ip != r->max_ip)
 			printf("-%s", xtables_ipaddr_to_numeric(&a));
-		if (r->flags & IP_NAT_RANGE_PROTO_RANDOM) 
+		if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
 			random_selection = 1;
 	}
 	
@@ -141,7 +146,7 @@ static void SAME_save(const void *ip, const struct xt_entry_target *target)
 	int random_selection = 0;
 
 	for (count = 0; count < mr->rangesize; count++) {
-		const struct nf_nat_range *r = &mr->range[count];
+		const struct nf_nat_ipv4_range *r = &mr->range[count];
 		struct in_addr a;
 
 		a.s_addr = r->min_ip;
@@ -150,7 +155,7 @@ static void SAME_save(const void *ip, const struct xt_entry_target *target)
 
 		if (r->min_ip != r->max_ip)
 			printf("-%s", xtables_ipaddr_to_numeric(&a));
-		if (r->flags & IP_NAT_RANGE_PROTO_RANDOM) 
+		if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
 			random_selection = 1;
 	}
 	
diff --git a/extensions/libipt_SNAT.c b/extensions/libipt_SNAT.c
index c8cb26d..1a24f3d 100644
--- a/extensions/libipt_SNAT.c
+++ b/extensions/libipt_SNAT.c
@@ -6,7 +6,7 @@
 #include <iptables.h>
 #include <limits.h> /* INT_MAX in ip_tables.h */
 #include <linux/netfilter_ipv4/ip_tables.h>
-#include <net/netfilter/nf_nat.h>
+#include <linux/netfilter/nf_nat.h>
 
 enum {
 	O_TO_SRC = 0,
@@ -23,7 +23,7 @@ enum {
 struct ipt_natinfo
 {
 	struct xt_entry_target t;
-	struct nf_nat_multi_range mr;
+	struct nf_nat_ipv4_multi_range_compat mr;
 };
 
 static void SNAT_help(void)
@@ -44,7 +44,7 @@ static const struct xt_option_entry SNAT_opts[] = {
 };
 
 static struct ipt_natinfo *
-append_range(struct ipt_natinfo *info, const struct nf_nat_range *range)
+append_range(struct ipt_natinfo *info, const struct nf_nat_ipv4_range *range)
 {
 	unsigned int size;
 
@@ -66,7 +66,7 @@ append_range(struct ipt_natinfo *info, const struct nf_nat_range *range)
 static struct xt_entry_target *
 parse_to(const char *orig_arg, int portok, struct ipt_natinfo *info)
 {
-	struct nf_nat_range range;
+	struct nf_nat_ipv4_range range;
 	char *arg, *colon, *dash, *error;
 	const struct in_addr *ip;
 
@@ -83,7 +83,7 @@ parse_to(const char *orig_arg, int portok, struct ipt_natinfo *info)
 			xtables_error(PARAMETER_PROBLEM,
 				   "Need TCP, UDP, SCTP or DCCP with port specification");
 
-		range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
+		range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
 
 		port = atoi(colon+1);
 		if (port <= 0 || port > 65535)
@@ -122,7 +122,7 @@ parse_to(const char *orig_arg, int portok, struct ipt_natinfo *info)
 		*colon = '\0';
 	}
 
-	range.flags |= IP_NAT_RANGE_MAP_IPS;
+	range.flags |= NF_NAT_RANGE_MAP_IPS;
 	dash = strchr(arg, '-');
 	if (colon && dash && dash > colon)
 		dash = NULL;
@@ -177,7 +177,7 @@ static void SNAT_parse(struct xt_option_call *cb)
 		cb->xflags |= F_X_TO_SRC;
 		break;
 	case O_PERSISTENT:
-		info->mr.range[0].flags |= IP_NAT_RANGE_PERSISTENT;
+		info->mr.range[0].flags |= NF_NAT_RANGE_PERSISTENT;
 		break;
 	}
 }
@@ -185,15 +185,15 @@ static void SNAT_parse(struct xt_option_call *cb)
 static void SNAT_fcheck(struct xt_fcheck_call *cb)
 {
 	static const unsigned int f = F_TO_SRC | F_RANDOM;
-	struct nf_nat_multi_range *mr = cb->data;
+	struct nf_nat_ipv4_multi_range_compat *mr = cb->data;
 
 	if ((cb->xflags & f) == f)
-		mr->range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
+		mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM;
 }
 
-static void print_range(const struct nf_nat_range *r)
+static void print_range(const struct nf_nat_ipv4_range *r)
 {
-	if (r->flags & IP_NAT_RANGE_MAP_IPS) {
+	if (r->flags & NF_NAT_RANGE_MAP_IPS) {
 		struct in_addr a;
 
 		a.s_addr = r->min_ip;
@@ -203,7 +203,7 @@ static void print_range(const struct nf_nat_range *r)
 			printf("-%s", xtables_ipaddr_to_numeric(&a));
 		}
 	}
-	if (r->flags & IP_NAT_RANGE_PROTO_SPECIFIED) {
+	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
 		printf(":");
 		printf("%hu", ntohs(r->min.tcp.port));
 		if (r->max.tcp.port != r->min.tcp.port)
@@ -220,9 +220,9 @@ static void SNAT_print(const void *ip, const struct xt_entry_target *target,
 	printf(" to:");
 	for (i = 0; i < info->mr.rangesize; i++) {
 		print_range(&info->mr.range[i]);
-		if (info->mr.range[i].flags & IP_NAT_RANGE_PROTO_RANDOM)
+		if (info->mr.range[i].flags & NF_NAT_RANGE_PROTO_RANDOM)
 			printf(" random");
-		if (info->mr.range[i].flags & IP_NAT_RANGE_PERSISTENT)
+		if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT)
 			printf(" persistent");
 	}
 }
@@ -235,9 +235,9 @@ static void SNAT_save(const void *ip, const struct xt_entry_target *target)
 	for (i = 0; i < info->mr.rangesize; i++) {
 		printf(" --to-source ");
 		print_range(&info->mr.range[i]);
-		if (info->mr.range[i].flags & IP_NAT_RANGE_PROTO_RANDOM)
+		if (info->mr.range[i].flags & NF_NAT_RANGE_PROTO_RANDOM)
 			printf(" --random");
-		if (info->mr.range[i].flags & IP_NAT_RANGE_PERSISTENT)
+		if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT)
 			printf(" --persistent");
 	}
 }
@@ -246,8 +246,8 @@ static struct xtables_target snat_tg_reg = {
 	.name		= "SNAT",
 	.version	= XTABLES_VERSION,
 	.family		= NFPROTO_IPV4,
-	.size		= XT_ALIGN(sizeof(struct nf_nat_multi_range)),
-	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_multi_range)),
+	.size		= XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
+	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
 	.help		= SNAT_help,
 	.x6_parse	= SNAT_parse,
 	.x6_fcheck	= SNAT_fcheck,
diff --git a/include/linux/netfilter/nf_conntrack_tuple_common.h b/include/linux/netfilter/nf_conntrack_tuple_common.h
index 2ea22b0..2f6bbc5 100644
--- a/include/linux/netfilter/nf_conntrack_tuple_common.h
+++ b/include/linux/netfilter/nf_conntrack_tuple_common.h
@@ -7,6 +7,33 @@ enum ip_conntrack_dir {
 	IP_CT_DIR_MAX
 };
 
+/* The protocol-specific manipulable parts of the tuple: always in
+ * network order
+ */
+union nf_conntrack_man_proto {
+	/* Add other protocols here. */
+	__be16 all;
+
+	struct {
+		__be16 port;
+	} tcp;
+	struct {
+		__be16 port;
+	} udp;
+	struct {
+		__be16 id;
+	} icmp;
+	struct {
+		__be16 port;
+	} dccp;
+	struct {
+		__be16 port;
+	} sctp;
+	struct {
+		__be16 key;	/* GRE key is 32bit, PPtP only uses 16bit */
+	} gre;
+};
+
 #define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL)
 
 #endif /* _NF_CONNTRACK_TUPLE_COMMON_H */
diff --git a/include/linux/netfilter/nf_nat.h b/include/linux/netfilter/nf_nat.h
new file mode 100644
index 0000000..8df2d13
--- /dev/null
+++ b/include/linux/netfilter/nf_nat.h
@@ -0,0 +1,25 @@
+#ifndef _NETFILTER_NF_NAT_H
+#define _NETFILTER_NF_NAT_H
+
+#include <linux/netfilter.h>
+#include <linux/netfilter/nf_conntrack_tuple_common.h>
+
+#define NF_NAT_RANGE_MAP_IPS		1
+#define NF_NAT_RANGE_PROTO_SPECIFIED	2
+#define NF_NAT_RANGE_PROTO_RANDOM	4
+#define NF_NAT_RANGE_PERSISTENT		8
+
+struct nf_nat_ipv4_range {
+	unsigned int			flags;
+	__be32				min_ip;
+	__be32				max_ip;
+	union nf_conntrack_man_proto	min;
+	union nf_conntrack_man_proto	max;
+};
+
+struct nf_nat_ipv4_multi_range_compat {
+	unsigned int			rangesize;
+	struct nf_nat_ipv4_range	range[1];
+};
+
+#endif /* _NETFILTER_NF_NAT_H */
diff --git a/include/linux/netfilter_ipv4/ipt_SAME.h b/include/linux/netfilter_ipv4/ipt_SAME.h
index 5bca782..a855167 100644
--- a/include/linux/netfilter_ipv4/ipt_SAME.h
+++ b/include/linux/netfilter_ipv4/ipt_SAME.h
@@ -14,7 +14,7 @@ struct ipt_same_info {
 	__u32 *iparray;
 
 	/* hangs off end. */
-	struct nf_nat_range range[IPT_SAME_MAX_RANGE];
+	struct nf_nat_ipv4_range range[IPT_SAME_MAX_RANGE];
 };
 
 #endif /*_IPT_SAME_H*/
diff --git a/include/net/netfilter/nf_conntrack_tuple.h b/include/net/netfilter/nf_conntrack_tuple.h
deleted file mode 100644
index c40e0b4..0000000
--- a/include/net/netfilter/nf_conntrack_tuple.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* This file was manually copied from the Linux kernel source
- * and manually stripped from __KERNEL__ sections and unused functions.
- */
-
-/*
- * Definitions and Declarations for tuple.
- *
- * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
- *	- generalize L3 protocol dependent part.
- *
- * Derived from include/linux/netfiter_ipv4/ip_conntrack_tuple.h
- */
-
-#ifndef _NF_CONNTRACK_TUPLE_H
-#define _NF_CONNTRACK_TUPLE_H
-
-#include <linux/netfilter/x_tables.h>
-#include <linux/netfilter/nf_conntrack_tuple_common.h>
-
-/* A `tuple' is a structure containing the information to uniquely
-  identify a connection.  ie. if two packets have the same tuple, they
-  are in the same connection; if not, they are not.
-
-  We divide the structure along "manipulatable" and
-  "non-manipulatable" lines, for the benefit of the NAT code.
-*/
-
-#define NF_CT_TUPLE_L3SIZE	ARRAY_SIZE(((union nf_inet_addr *)NULL)->all)
-
-/* The protocol-specific manipulable parts of the tuple: always in
-   network order! */
-union nf_conntrack_man_proto
-{
-	/* Add other protocols here. */
-	__be16 all;
-
-	struct {
-		__be16 port;
-	} tcp;
-	struct {
-		__be16 port;
-	} udp;
-	struct {
-		__be16 id;
-	} icmp;
-	struct {
-		__be16 port;
-	} dccp;
-	struct {
-		__be16 port;
-	} sctp;
-	struct {
-		__be16 key;	/* GRE key is 32bit, PPtP only uses 16bit */
-	} gre;
-};
-
-/* The manipulable part of the tuple. */
-struct nf_conntrack_man
-{
-	union nf_inet_addr u3;
-	union nf_conntrack_man_proto u;
-	/* Layer 3 protocol */
-	u_int16_t l3num;
-};
-
-/* This contains the information to distinguish a connection. */
-struct nf_conntrack_tuple
-{
-	struct nf_conntrack_man src;
-
-	/* These are the parts of the tuple which are fixed. */
-	struct {
-		union nf_inet_addr u3;
-		union {
-			/* Add other protocols here. */
-			__be16 all;
-
-			struct {
-				__be16 port;
-			} tcp;
-			struct {
-				__be16 port;
-			} udp;
-			struct {
-				u_int8_t type, code;
-			} icmp;
-			struct {
-				__be16 port;
-			} dccp;
-			struct {
-				__be16 port;
-			} sctp;
-			struct {
-				__be16 key;
-			} gre;
-		} u;
-
-		/* The protocol. */
-		u_int8_t protonum;
-
-		/* The direction (for tuplehash) */
-		u_int8_t dir;
-	} dst;
-};
-
-struct nf_conntrack_tuple_mask
-{
-	struct {
-		union nf_inet_addr u3;
-		union nf_conntrack_man_proto u;
-	} src;
-};
-
-#endif /* _NF_CONNTRACK_TUPLE_H */
diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h
deleted file mode 100644
index c3e2060..0000000
--- a/include/net/netfilter/nf_nat.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef _NF_NAT_H
-#define _NF_NAT_H
-#include <linux/netfilter_ipv4.h>
-#include <net/netfilter/nf_conntrack_tuple.h>
-
-#define NF_NAT_MAPPING_TYPE_MAX_NAMELEN 16
-
-enum nf_nat_manip_type
-{
-	IP_NAT_MANIP_SRC,
-	IP_NAT_MANIP_DST
-};
-
-/* SRC manip occurs POST_ROUTING or LOCAL_IN */
-#define HOOK2MANIP(hooknum) ((hooknum) != NF_INET_POST_ROUTING && \
-			     (hooknum) != NF_INET_LOCAL_IN)
-
-#define IP_NAT_RANGE_MAP_IPS 1
-#define IP_NAT_RANGE_PROTO_SPECIFIED 2
-#define IP_NAT_RANGE_PROTO_RANDOM 4
-#define IP_NAT_RANGE_PERSISTENT 8
-
-/* NAT sequence number modifications */
-struct nf_nat_seq {
-	/* position of the last TCP sequence number modification (if any) */
-	u_int32_t correction_pos;
-
-	/* sequence number offset before and after last modification */
-	int16_t offset_before, offset_after;
-};
-
-/* Single range specification. */
-struct nf_nat_range
-{
-	/* Set to OR of flags above. */
-	unsigned int flags;
-
-	/* Inclusive: network order. */
-	__be32 min_ip, max_ip;
-
-	/* Inclusive: network order */
-	union nf_conntrack_man_proto min, max;
-};
-
-/* For backwards compat: don't use in modern code. */
-struct nf_nat_multi_range_compat
-{
-	unsigned int rangesize; /* Must be 1. */
-
-	/* hangs off end. */
-	struct nf_nat_range range[1];
-};
-
-#define nf_nat_multi_range nf_nat_multi_range_compat
-#endif
-- 
1.7.1


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

* [PATCH 2/7] extensions: add IPv6 MASQUERADE extension
  2012-08-09 20:11 [PATCH 0/7] extensions: add IPv6 NAT support kaber
  2012-08-09 20:11 ` [PATCH 1/7] extensions: convert NAT target to use nf_nat.h kaber
@ 2012-08-09 20:11 ` kaber
  2012-08-09 21:18   ` Jan Engelhardt
  2012-08-09 20:11 ` [PATCH 3/7] extensions: add IPv6 SNAT extension kaber
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: kaber @ 2012-08-09 20:11 UTC (permalink / raw)
  To: netfilter-devel

From: Patrick McHardy <kaber@trash.net>

Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 extensions/libip6t_MASQUERADE.c   |  150 +++++++++++++++++++++++++++++++++++++
 extensions/libip6t_MASQUERADE.man |   30 ++++++++
 include/linux/netfilter/nf_nat.h  |    8 ++
 3 files changed, 188 insertions(+), 0 deletions(-)
 create mode 100644 extensions/libip6t_MASQUERADE.c
 create mode 100644 extensions/libip6t_MASQUERADE.man

diff --git a/extensions/libip6t_MASQUERADE.c b/extensions/libip6t_MASQUERADE.c
new file mode 100644
index 0000000..eb9213e
--- /dev/null
+++ b/extensions/libip6t_MASQUERADE.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
+ *
+ * Based on Rusty Russell's IPv4 MASQUERADE target. Development of IPv6 NAT
+ * funded by Astaro.
+ */
+
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <xtables.h>
+#include <limits.h> /* INT_MAX in ip_tables.h */
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter/nf_nat.h>
+
+enum {
+	O_TO_PORTS = 0,
+	O_RANDOM,
+};
+
+static void MASQUERADE_help(void)
+{
+	printf(
+"MASQUERADE target options:\n"
+" --to-ports <port>[-<port>]\n"
+"				Port (range) to map to.\n"
+" --random\n"
+"				Randomize source port.\n");
+}
+
+static const struct xt_option_entry MASQUERADE_opts[] = {
+	{.name = "to-ports", .id = O_TO_PORTS, .type = XTTYPE_STRING},
+	{.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
+	XTOPT_TABLEEND,
+};
+
+/* Parses ports */
+static void
+parse_ports(const char *arg, struct nf_nat_range *r)
+{
+	char *end;
+	unsigned int port, maxport;
+
+	r->flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
+
+	if (!xtables_strtoui(arg, &end, &port, 0, UINT16_MAX))
+		xtables_param_act(XTF_BAD_VALUE, "MASQUERADE", "--to-ports", arg);
+
+	switch (*end) {
+	case '\0':
+		r->min_proto.tcp.port
+			= r->max_proto.tcp.port
+			= htons(port);
+		return;
+	case '-':
+		if (!xtables_strtoui(end + 1, NULL, &maxport, 0, UINT16_MAX))
+			break;
+
+		if (maxport < port)
+			break;
+
+		r->min_proto.tcp.port = htons(port);
+		r->max_proto.tcp.port = htons(maxport);
+		return;
+	default:
+		break;
+	}
+	xtables_param_act(XTF_BAD_VALUE, "MASQUERADE", "--to-ports", arg);
+}
+
+static void MASQUERADE_parse(struct xt_option_call *cb)
+{
+	const struct ip6t_entry *entry = cb->xt_entry;
+	struct nf_nat_range *r = cb->data;
+	int portok;
+
+	if (entry->ipv6.proto == IPPROTO_TCP ||
+	    entry->ipv6.proto == IPPROTO_UDP ||
+	    entry->ipv6.proto == IPPROTO_SCTP ||
+	    entry->ipv6.proto == IPPROTO_DCCP ||
+	    entry->ipv6.proto == IPPROTO_ICMP)
+		portok = 1;
+	else
+		portok = 0;
+
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_TO_PORTS:
+		if (!portok)
+			xtables_error(PARAMETER_PROBLEM,
+				   "Need TCP, UDP, SCTP or DCCP with port specification");
+		parse_ports(cb->arg, r);
+		break;
+	case O_RANDOM:
+		r->flags |=  NF_NAT_RANGE_PROTO_RANDOM;
+		break;
+	}
+}
+
+static void
+MASQUERADE_print(const void *ip, const struct xt_entry_target *target,
+                 int numeric)
+{
+	const struct nf_nat_range *r = (const void *)target->data;
+
+	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
+		printf(" masq ports: ");
+		printf("%hu", ntohs(r->min_proto.tcp.port));
+		if (r->max_proto.tcp.port != r->min_proto.tcp.port)
+			printf("-%hu", ntohs(r->max_proto.tcp.port));
+	}
+
+	if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
+		printf(" random");
+}
+
+static void
+MASQUERADE_save(const void *ip, const struct xt_entry_target *target)
+{
+	const struct nf_nat_range *r = (const void *)target->data;
+
+	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
+		printf(" --to-ports %hu", ntohs(r->min_proto.tcp.port));
+		if (r->max_proto.tcp.port != r->min_proto.tcp.port)
+			printf("-%hu", ntohs(r->max_proto.tcp.port));
+	}
+
+	if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
+		printf(" --random");
+}
+
+static struct xtables_target masquerade_tg_reg = {
+	.name		= "MASQUERADE",
+	.version	= XTABLES_VERSION,
+	.family		= NFPROTO_IPV6,
+	.size		= XT_ALIGN(sizeof(struct nf_nat_range)),
+	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_range)),
+	.help		= MASQUERADE_help,
+	.x6_parse	= MASQUERADE_parse,
+	.print		= MASQUERADE_print,
+	.save		= MASQUERADE_save,
+	.x6_options	= MASQUERADE_opts,
+};
+
+void _init(void)
+{
+	xtables_register_target(&masquerade_tg_reg);
+}
diff --git a/extensions/libip6t_MASQUERADE.man b/extensions/libip6t_MASQUERADE.man
new file mode 100644
index 0000000..c63d826
--- /dev/null
+++ b/extensions/libip6t_MASQUERADE.man
@@ -0,0 +1,30 @@
+This target is only valid in the
+.B nat
+table, in the
+.B POSTROUTING
+chain.  It should only be used with dynamically assigned IPv6 (dialup)
+connections: if you have a static IP address, you should use the SNAT
+target.  Masquerading is equivalent to specifying a mapping to the IP
+address of the interface the packet is going out, but also has the
+effect that connections are
+.I forgotten
+when the interface goes down.  This is the correct behavior when the
+next dialup is unlikely to have the same interface address (and hence
+any established connections are lost anyway).
+.TP
+\fB\-\-to\-ports\fP \fIport\fP[\fB\-\fP\fIport\fP]
+This specifies a range of source ports to use, overriding the default
+.B SNAT
+source port-selection heuristics (see above).  This is only valid
+if the rule also specifies
+\fB\-p tcp\fP
+or
+\fB\-p udp\fP.
+.TP
+\fB\-\-random\fP
+Randomize source port mapping
+If option
+\fB\-\-random\fP
+is used then port mapping will be randomized.
+.RS
+.PP
diff --git a/include/linux/netfilter/nf_nat.h b/include/linux/netfilter/nf_nat.h
index 8df2d13..bf0cc37 100644
--- a/include/linux/netfilter/nf_nat.h
+++ b/include/linux/netfilter/nf_nat.h
@@ -22,4 +22,12 @@ struct nf_nat_ipv4_multi_range_compat {
 	struct nf_nat_ipv4_range	range[1];
 };
 
+struct nf_nat_range {
+	unsigned int			flags;
+	union nf_inet_addr		min_addr;
+	union nf_inet_addr		max_addr;
+	union nf_conntrack_man_proto	min_proto;
+	union nf_conntrack_man_proto	max_proto;
+};
+
 #endif /* _NETFILTER_NF_NAT_H */
-- 
1.7.1


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

* [PATCH 3/7] extensions: add IPv6 SNAT extension
  2012-08-09 20:11 [PATCH 0/7] extensions: add IPv6 NAT support kaber
  2012-08-09 20:11 ` [PATCH 1/7] extensions: convert NAT target to use nf_nat.h kaber
  2012-08-09 20:11 ` [PATCH 2/7] extensions: add IPv6 MASQUERADE extension kaber
@ 2012-08-09 20:11 ` kaber
  2012-08-09 21:28   ` Jan Engelhardt
  2012-08-09 20:11 ` [PATCH 4/7] extensions: add IPv6 DNAT target kaber
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: kaber @ 2012-08-09 20:11 UTC (permalink / raw)
  To: netfilter-devel

From: Patrick McHardy <kaber@trash.net>

Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 extensions/libip6t_SNAT.c |  247 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 247 insertions(+), 0 deletions(-)
 create mode 100644 extensions/libip6t_SNAT.c

diff --git a/extensions/libip6t_SNAT.c b/extensions/libip6t_SNAT.c
new file mode 100644
index 0000000..307be70
--- /dev/null
+++ b/extensions/libip6t_SNAT.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
+ *
+ * Based on Rusty Russell's IPv4 SNAT target. Development of IPv6 NAT
+ * funded by Astaro.
+ */
+
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <xtables.h>
+#include <iptables.h>
+#include <limits.h> /* INT_MAX in ip_tables.h */
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter/nf_nat.h>
+
+enum {
+	O_TO_SRC = 0,
+	O_RANDOM,
+	O_PERSISTENT,
+	O_X_TO_SRC,
+	F_TO_SRC   = 1 << O_TO_SRC,
+	F_RANDOM   = 1 << O_RANDOM,
+	F_X_TO_SRC = 1 << O_X_TO_SRC,
+};
+
+static void SNAT_help(void)
+{
+	printf(
+"SNAT target options:\n"
+" --to-source [<ipaddr>[-<ipaddr>]][:port[-port]]\n"
+"				Address to map source to.\n"
+"[--random] [--persistent]\n");
+}
+
+static const struct xt_option_entry SNAT_opts[] = {
+	{.name = "to-source", .id = O_TO_SRC, .type = XTTYPE_STRING,
+	 .flags = XTOPT_MAND | XTOPT_MULTI},
+	{.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
+	{.name = "persistent", .id = O_PERSISTENT, .type = XTTYPE_NONE},
+	XTOPT_TABLEEND,
+};
+
+/* Ranges expected in network order. */
+static void
+parse_to(const char *orig_arg, int portok, struct nf_nat_range *range)
+{
+	char *arg, *start, *end = NULL, *colon = NULL, *dash, *error;
+	const struct in6_addr *ip;
+
+	arg = strdup(orig_arg);
+	if (arg == NULL)
+		xtables_error(RESOURCE_PROBLEM, "strdup");
+
+	start = strchr(arg, '[');
+	if (start == NULL)
+		start = arg;
+	else {
+		start++;
+		end = strchr(start, ']');
+		if (end == NULL)
+			xtables_error(PARAMETER_PROBLEM,
+				      "Invalid address format");
+
+		*end = '\0';
+		colon = strchr(end + 1, ':');
+	}
+
+	if (colon) {
+		int port;
+
+		if (!portok)
+			xtables_error(PARAMETER_PROBLEM,
+				   "Need TCP, UDP, SCTP or DCCP with port specification");
+
+		range->flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
+
+		port = atoi(colon+1);
+		if (port <= 0 || port > 65535)
+			xtables_error(PARAMETER_PROBLEM,
+				   "Port `%s' not valid\n", colon+1);
+
+		error = strchr(colon+1, ':');
+		if (error)
+			xtables_error(PARAMETER_PROBLEM,
+				   "Invalid port:port syntax - use dash\n");
+
+		dash = strchr(colon, '-');
+		if (!dash) {
+			range->min_proto.tcp.port
+				= range->max_proto.tcp.port
+				= htons(port);
+		} else {
+			int maxport;
+
+			maxport = atoi(dash + 1);
+			if (maxport <= 0 || maxport > 65535)
+				xtables_error(PARAMETER_PROBLEM,
+					   "Port `%s' not valid\n", dash+1);
+			if (maxport < port)
+				/* People are stupid. */
+				xtables_error(PARAMETER_PROBLEM,
+					   "Port range `%s' funky\n", colon+1);
+			range->min_proto.tcp.port = htons(port);
+			range->max_proto.tcp.port = htons(maxport);
+		}
+		/* Starts with a colon? No IP info...*/
+		if (colon == arg) {
+			free(arg);
+			return;
+		}
+		*colon = '\0';
+	}
+
+	range->flags |= NF_NAT_RANGE_MAP_IPS;
+	dash = strchr(start, '-');
+	if (colon && dash && dash > colon)
+		dash = NULL;
+
+	if (dash)
+		*dash = '\0';
+
+	ip = xtables_numeric_to_ip6addr(start);
+	if (!ip)
+		xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
+			      start);
+	range->min_addr.in6 = *ip;
+	if (dash) {
+		ip = xtables_numeric_to_ip6addr(dash + 1);
+		if (!ip)
+			xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
+				      dash+1);
+		range->max_addr.in6 = *ip;
+	} else
+		range->max_addr = range->min_addr;
+
+	free(arg);
+	return;
+}
+
+static void SNAT_parse(struct xt_option_call *cb)
+{
+	const struct ip6t_entry *entry = cb->xt_entry;
+	struct nf_nat_range *range = cb->data;
+	int portok;
+
+	if (entry->ipv6.proto == IPPROTO_TCP ||
+	    entry->ipv6.proto == IPPROTO_UDP ||
+	    entry->ipv6.proto == IPPROTO_SCTP ||
+	    entry->ipv6.proto == IPPROTO_DCCP ||
+	    entry->ipv6.proto == IPPROTO_ICMP)
+		portok = 1;
+	else
+		portok = 0;
+
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_TO_SRC:
+		if (cb->xflags & F_X_TO_SRC) {
+			if (!kernel_version)
+				get_kernel_version();
+			if (kernel_version > LINUX_VERSION(2, 6, 10))
+				xtables_error(PARAMETER_PROBLEM,
+					   "SNAT: Multiple --to-source not supported");
+		}
+		parse_to(cb->arg, portok, range);
+		break;
+	case O_PERSISTENT:
+		range->flags |= NF_NAT_RANGE_PERSISTENT;
+		break;
+	}
+}
+
+static void SNAT_fcheck(struct xt_fcheck_call *cb)
+{
+	static const unsigned int f = F_TO_SRC | F_RANDOM;
+	struct nf_nat_range *range = cb->data;
+
+	if ((cb->xflags & f) == f)
+		range->flags |= NF_NAT_RANGE_PROTO_RANDOM;
+}
+
+static void print_range(const struct nf_nat_range *range)
+{
+	if (range->flags & NF_NAT_RANGE_MAP_IPS) {
+		if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)
+			printf("[");
+		printf("%s", xtables_ip6addr_to_numeric(&range->min_addr.in6));
+		if (memcmp(&range->min_addr, &range->max_addr,
+			   sizeof(range->min_addr)))
+			printf("-%s", xtables_ip6addr_to_numeric(&range->max_addr.in6));
+		if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)
+			printf("]");
+	}
+	if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
+		printf(":");
+		printf("%hu", ntohs(range->min_proto.tcp.port));
+		if (range->max_proto.tcp.port != range->min_proto.tcp.port)
+			printf("-%hu", ntohs(range->max_proto.tcp.port));
+	}
+}
+
+static void SNAT_print(const void *ip, const struct xt_entry_target *target,
+                       int numeric)
+{
+	const struct nf_nat_range *range = (const void *)target->data;
+
+	printf(" to:");
+	print_range(range);
+	if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
+		printf(" random");
+	if (range->flags & NF_NAT_RANGE_PERSISTENT)
+		printf(" persistent");
+}
+
+static void SNAT_save(const void *ip, const struct xt_entry_target *target)
+{
+	const struct nf_nat_range *range = (const void *)target->data;
+
+	printf(" --to-source ");
+	print_range(range);
+	if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
+		printf(" --random");
+	if (range->flags & NF_NAT_RANGE_PERSISTENT)
+		printf(" --persistent");
+}
+
+static struct xtables_target snat_tg_reg = {
+	.name		= "SNAT",
+	.version	= XTABLES_VERSION,
+	.family		= NFPROTO_IPV6,
+	.revision	= 1,
+	.size		= XT_ALIGN(sizeof(struct nf_nat_range)),
+	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_range)),
+	.help		= SNAT_help,
+	.x6_parse	= SNAT_parse,
+	.x6_fcheck	= SNAT_fcheck,
+	.print		= SNAT_print,
+	.save		= SNAT_save,
+	.x6_options	= SNAT_opts,
+};
+
+void _init(void)
+{
+	xtables_register_target(&snat_tg_reg);
+}
-- 
1.7.1


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

* [PATCH 4/7] extensions: add IPv6 DNAT target
  2012-08-09 20:11 [PATCH 0/7] extensions: add IPv6 NAT support kaber
                   ` (2 preceding siblings ...)
  2012-08-09 20:11 ` [PATCH 3/7] extensions: add IPv6 SNAT extension kaber
@ 2012-08-09 20:11 ` kaber
  2012-08-09 20:11 ` [PATCH 5/7] extensions: add IPv6 REDIRECT extension kaber
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: kaber @ 2012-08-09 20:11 UTC (permalink / raw)
  To: netfilter-devel

From: Patrick McHardy <kaber@trash.net>

Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 extensions/libip6t_DNAT.c |  247 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 247 insertions(+), 0 deletions(-)
 create mode 100644 extensions/libip6t_DNAT.c

diff --git a/extensions/libip6t_DNAT.c b/extensions/libip6t_DNAT.c
new file mode 100644
index 0000000..a5969c3
--- /dev/null
+++ b/extensions/libip6t_DNAT.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
+ *
+ * Based on Rusty Russell's IPv4 DNAT target. Development of IPv6 NAT
+ * funded by Astaro.
+ */
+
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <xtables.h>
+#include <iptables.h>
+#include <limits.h> /* INT_MAX in ip_tables.h */
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter/nf_nat.h>
+
+enum {
+	O_TO_DEST = 0,
+	O_RANDOM,
+	O_PERSISTENT,
+	O_X_TO_DEST,
+	F_TO_DEST   = 1 << O_TO_DEST,
+	F_RANDOM   = 1 << O_RANDOM,
+	F_X_TO_DEST = 1 << O_X_TO_DEST,
+};
+
+static void DNAT_help(void)
+{
+	printf(
+"DNAT target options:\n"
+" --to-dest [<ipaddr>[-<ipaddr>]][:port[-port]]\n"
+"				Address to map source to.\n"
+"[--random] [--persistent]\n");
+}
+
+static const struct xt_option_entry DNAT_opts[] = {
+	{.name = "to-dest", .id = O_TO_DEST, .type = XTTYPE_STRING,
+	 .flags = XTOPT_MAND | XTOPT_MULTI},
+	{.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
+	{.name = "persistent", .id = O_PERSISTENT, .type = XTTYPE_NONE},
+	XTOPT_TABLEEND,
+};
+
+/* Ranges expected in network order. */
+static void
+parse_to(const char *orig_arg, int portok, struct nf_nat_range *range)
+{
+	char *arg, *start, *end = NULL, *colon = NULL, *dash, *error;
+	const struct in6_addr *ip;
+
+	arg = strdup(orig_arg);
+	if (arg == NULL)
+		xtables_error(RESOURCE_PROBLEM, "strdup");
+
+	start = strchr(arg, '[');
+	if (start == NULL)
+		start = arg;
+	else {
+		start++;
+		end = strchr(start, ']');
+		if (end == NULL)
+			xtables_error(PARAMETER_PROBLEM,
+				      "Invalid address format");
+
+		*end = '\0';
+		colon = strchr(end + 1, ':');
+	}
+
+	if (colon) {
+		int port;
+
+		if (!portok)
+			xtables_error(PARAMETER_PROBLEM,
+				   "Need TCP, UDP, SCTP or DCCP with port specification");
+
+		range->flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
+
+		port = atoi(colon+1);
+		if (port <= 0 || port > 65535)
+			xtables_error(PARAMETER_PROBLEM,
+				   "Port `%s' not valid\n", colon+1);
+
+		error = strchr(colon+1, ':');
+		if (error)
+			xtables_error(PARAMETER_PROBLEM,
+				   "Invalid port:port syntax - use dash\n");
+
+		dash = strchr(colon, '-');
+		if (!dash) {
+			range->min_proto.tcp.port
+				= range->max_proto.tcp.port
+				= htons(port);
+		} else {
+			int maxport;
+
+			maxport = atoi(dash + 1);
+			if (maxport <= 0 || maxport > 65535)
+				xtables_error(PARAMETER_PROBLEM,
+					   "Port `%s' not valid\n", dash+1);
+			if (maxport < port)
+				/* People are stupid. */
+				xtables_error(PARAMETER_PROBLEM,
+					   "Port range `%s' funky\n", colon+1);
+			range->min_proto.tcp.port = htons(port);
+			range->max_proto.tcp.port = htons(maxport);
+		}
+		/* Starts with a colon? No IP info...*/
+		if (colon == arg) {
+			free(arg);
+			return;
+		}
+		*colon = '\0';
+	}
+
+	range->flags |= NF_NAT_RANGE_MAP_IPS;
+	dash = strchr(start, '-');
+	if (colon && dash && dash > colon)
+		dash = NULL;
+
+	if (dash)
+		*dash = '\0';
+
+	ip = xtables_numeric_to_ip6addr(start);
+	if (!ip)
+		xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
+			      start);
+	range->min_addr.in6 = *ip;
+	if (dash) {
+		ip = xtables_numeric_to_ip6addr(dash + 1);
+		if (!ip)
+			xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
+				      dash+1);
+		range->max_addr.in6 = *ip;
+	} else
+		range->max_addr = range->min_addr;
+
+	free(arg);
+	return;
+}
+
+static void DNAT_parse(struct xt_option_call *cb)
+{
+	const struct ip6t_entry *entry = cb->xt_entry;
+	struct nf_nat_range *range = cb->data;
+	int portok;
+
+	if (entry->ipv6.proto == IPPROTO_TCP ||
+	    entry->ipv6.proto == IPPROTO_UDP ||
+	    entry->ipv6.proto == IPPROTO_SCTP ||
+	    entry->ipv6.proto == IPPROTO_DCCP ||
+	    entry->ipv6.proto == IPPROTO_ICMP)
+		portok = 1;
+	else
+		portok = 0;
+
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_TO_DEST:
+		if (cb->xflags & F_X_TO_DEST) {
+			if (!kernel_version)
+				get_kernel_version();
+			if (kernel_version > LINUX_VERSION(2, 6, 10))
+				xtables_error(PARAMETER_PROBLEM,
+					   "DNAT: Multiple --to-source not supported");
+		}
+		parse_to(cb->arg, portok, range);
+		break;
+	case O_PERSISTENT:
+		range->flags |= NF_NAT_RANGE_PERSISTENT;
+		break;
+	}
+}
+
+static void DNAT_fcheck(struct xt_fcheck_call *cb)
+{
+	static const unsigned int f = F_TO_DEST | F_RANDOM;
+	struct nf_nat_range *mr = cb->data;
+
+	if ((cb->xflags & f) == f)
+		mr->flags |= NF_NAT_RANGE_PROTO_RANDOM;
+}
+
+static void print_range(const struct nf_nat_range *range)
+{
+	if (range->flags & NF_NAT_RANGE_MAP_IPS) {
+		if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)
+			printf("[");
+		printf("%s", xtables_ip6addr_to_numeric(&range->min_addr.in6));
+		if (memcmp(&range->min_addr, &range->max_addr,
+			   sizeof(range->min_addr)))
+			printf("-%s", xtables_ip6addr_to_numeric(&range->max_addr.in6));
+		if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)
+			printf("]");
+	}
+	if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
+		printf(":");
+		printf("%hu", ntohs(range->min_proto.tcp.port));
+		if (range->max_proto.tcp.port != range->min_proto.tcp.port)
+			printf("-%hu", ntohs(range->max_proto.tcp.port));
+	}
+}
+
+static void DNAT_print(const void *ip, const struct xt_entry_target *target,
+                       int numeric)
+{
+	const struct nf_nat_range *range = (const void *)target->data;
+
+	printf(" to:");
+	print_range(range);
+	if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
+		printf(" random");
+	if (range->flags & NF_NAT_RANGE_PERSISTENT)
+		printf(" persistent");
+}
+
+static void DNAT_save(const void *ip, const struct xt_entry_target *target)
+{
+	const struct nf_nat_range *range = (const void *)target->data;
+
+	printf(" --to-source ");
+	print_range(range);
+	if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
+		printf(" --random");
+	if (range->flags & NF_NAT_RANGE_PERSISTENT)
+		printf(" --persistent");
+}
+
+static struct xtables_target snat_tg_reg = {
+	.name		= "DNAT",
+	.version	= XTABLES_VERSION,
+	.family		= NFPROTO_IPV6,
+	.revision	= 1,
+	.size		= XT_ALIGN(sizeof(struct nf_nat_range)),
+	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_range)),
+	.help		= DNAT_help,
+	.x6_parse	= DNAT_parse,
+	.x6_fcheck	= DNAT_fcheck,
+	.print		= DNAT_print,
+	.save		= DNAT_save,
+	.x6_options	= DNAT_opts,
+};
+
+void _init(void)
+{
+	xtables_register_target(&snat_tg_reg);
+}
-- 
1.7.1


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

* [PATCH 5/7] extensions: add IPv6 REDIRECT extension
  2012-08-09 20:11 [PATCH 0/7] extensions: add IPv6 NAT support kaber
                   ` (3 preceding siblings ...)
  2012-08-09 20:11 ` [PATCH 4/7] extensions: add IPv6 DNAT target kaber
@ 2012-08-09 20:11 ` kaber
  2012-08-09 20:11 ` [PATCH 6/7] extensions: add IPv6 NETMAP extension kaber
  2012-08-09 20:11 ` [PATCH 7/7] extensions: add NPT extension kaber
  6 siblings, 0 replies; 14+ messages in thread
From: kaber @ 2012-08-09 20:11 UTC (permalink / raw)
  To: netfilter-devel

From: Patrick McHardy <kaber@trash.net>

Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 extensions/libip6t_REDIRECT.c |  151 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 151 insertions(+), 0 deletions(-)
 create mode 100644 extensions/libip6t_REDIRECT.c

diff --git a/extensions/libip6t_REDIRECT.c b/extensions/libip6t_REDIRECT.c
new file mode 100644
index 0000000..1724aa6
--- /dev/null
+++ b/extensions/libip6t_REDIRECT.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
+ *
+ * Based on Rusty Russell's IPv4 REDIRECT target. Development of IPv6 NAT
+ * funded by Astaro.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <xtables.h>
+#include <limits.h> /* INT_MAX in ip_tables.h */
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter/nf_nat.h>
+
+enum {
+	O_TO_PORTS = 0,
+	O_RANDOM,
+	F_TO_PORTS = 1 << O_TO_PORTS,
+	F_RANDOM   = 1 << O_RANDOM,
+};
+
+static void REDIRECT_help(void)
+{
+	printf(
+"REDIRECT target options:\n"
+" --to-ports <port>[-<port>]\n"
+"				Port (range) to map to.\n"
+" [--random]\n");
+}
+
+static const struct xt_option_entry REDIRECT_opts[] = {
+	{.name = "to-ports", .id = O_TO_PORTS, .type = XTTYPE_STRING},
+	{.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
+	XTOPT_TABLEEND,
+};
+
+/* Parses ports */
+static void
+parse_ports(const char *arg, struct nf_nat_range *range)
+{
+	char *end = "";
+	unsigned int port, maxport;
+
+	range->flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
+
+	if (!xtables_strtoui(arg, &end, &port, 0, UINT16_MAX) &&
+	    (port = xtables_service_to_port(arg, NULL)) == (unsigned)-1)
+		xtables_param_act(XTF_BAD_VALUE, "REDIRECT", "--to-ports", arg);
+
+	switch (*end) {
+	case '\0':
+		range->min_proto.tcp.port
+			= range->max_proto.tcp.port
+			= htons(port);
+		return;
+	case '-':
+		if (!xtables_strtoui(end + 1, NULL, &maxport, 0, UINT16_MAX) &&
+		    (maxport = xtables_service_to_port(end + 1, NULL)) == (unsigned)-1)
+			break;
+
+		if (maxport < port)
+			break;
+
+		range->min_proto.tcp.port = htons(port);
+		range->max_proto.tcp.port = htons(maxport);
+		return;
+	default:
+		break;
+	}
+	xtables_param_act(XTF_BAD_VALUE, "REDIRECT", "--to-ports", arg);
+}
+
+static void REDIRECT_parse(struct xt_option_call *cb)
+{
+	const struct ip6t_entry *entry = cb->xt_entry;
+	struct nf_nat_range *range = (void *)(*cb->target)->data;
+	int portok;
+
+	if (entry->ipv6.proto == IPPROTO_TCP
+	    || entry->ipv6.proto == IPPROTO_UDP
+	    || entry->ipv6.proto == IPPROTO_SCTP
+	    || entry->ipv6.proto == IPPROTO_DCCP
+	    || entry->ipv6.proto == IPPROTO_ICMP)
+		portok = 1;
+	else
+		portok = 0;
+
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_TO_PORTS:
+		if (!portok)
+			xtables_error(PARAMETER_PROBLEM,
+				   "Need TCP, UDP, SCTP or DCCP with port specification");
+		parse_ports(cb->arg, range);
+		if (cb->xflags & F_RANDOM)
+			range->flags |= NF_NAT_RANGE_PROTO_RANDOM;
+		break;
+	case O_RANDOM:
+		if (cb->xflags & F_TO_PORTS)
+			range->flags |= NF_NAT_RANGE_PROTO_RANDOM;
+		break;
+	}
+}
+
+static void REDIRECT_print(const void *ip, const struct xt_entry_target *target,
+                           int numeric)
+{
+	const struct nf_nat_range *range = (const void *)target->data;
+
+	if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
+		printf(" redir ports ");
+		printf("%hu", ntohs(range->min_proto.tcp.port));
+		if (range->max_proto.tcp.port != range->min_proto.tcp.port)
+			printf("-%hu", ntohs(range->max_proto.tcp.port));
+		if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
+			printf(" random");
+	}
+}
+
+static void REDIRECT_save(const void *ip, const struct xt_entry_target *target)
+{
+	const struct nf_nat_range *range = (const void *)target->data;
+
+	if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
+		printf(" --to-ports ");
+		printf("%hu", ntohs(range->min_proto.tcp.port));
+		if (range->max_proto.tcp.port != range->min_proto.tcp.port)
+			printf("-%hu", ntohs(range->max_proto.tcp.port));
+		if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
+			printf(" --random");
+	}
+}
+
+static struct xtables_target redirect_tg_reg = {
+	.name		= "REDIRECT",
+	.version	= XTABLES_VERSION,
+	.family		= NFPROTO_IPV6,
+	.size		= XT_ALIGN(sizeof(struct nf_nat_range)),
+	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_range)),
+	.help		= REDIRECT_help,
+	.x6_parse	= REDIRECT_parse,
+	.print		= REDIRECT_print,
+	.save		= REDIRECT_save,
+	.x6_options	= REDIRECT_opts,
+};
+
+void _init(void)
+{
+	xtables_register_target(&redirect_tg_reg);
+}
-- 
1.7.1


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

* [PATCH 6/7] extensions: add IPv6 NETMAP extension
  2012-08-09 20:11 [PATCH 0/7] extensions: add IPv6 NAT support kaber
                   ` (4 preceding siblings ...)
  2012-08-09 20:11 ` [PATCH 5/7] extensions: add IPv6 REDIRECT extension kaber
@ 2012-08-09 20:11 ` kaber
  2012-08-09 20:11 ` [PATCH 7/7] extensions: add NPT extension kaber
  6 siblings, 0 replies; 14+ messages in thread
From: kaber @ 2012-08-09 20:11 UTC (permalink / raw)
  To: netfilter-devel

From: Patrick McHardy <kaber@trash.net>

Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 extensions/GNUmakefile.in   |    2 +-
 extensions/libip6t_NETMAP.c |   93 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 94 insertions(+), 1 deletions(-)
 create mode 100644 extensions/libip6t_NETMAP.c

diff --git a/extensions/GNUmakefile.in b/extensions/GNUmakefile.in
index 218dc3a..2492d18 100644
--- a/extensions/GNUmakefile.in
+++ b/extensions/GNUmakefile.in
@@ -97,10 +97,10 @@ lib%.oo: ${srcdir}/lib%.c
 	${AM_VERBOSE_CC} ${CC} ${AM_CPPFLAGS} ${AM_DEPFLAGS} ${AM_CFLAGS} -D_INIT=lib$*_init -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
 
 # Need the LIBADDs in iptables/Makefile.am too for libxtables_la_LIBADD
+ip6t_NETMAP_LIBADD  = -lip6tc
 xt_RATEEST_LIBADD   = -lm
 xt_statistic_LIBADD = -lm
 
-
 #
 #	Static bits
 #
diff --git a/extensions/libip6t_NETMAP.c b/extensions/libip6t_NETMAP.c
new file mode 100644
index 0000000..d14dece
--- /dev/null
+++ b/extensions/libip6t_NETMAP.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
+ *
+ * Based on Svenning Soerensen's IPv4 NETMAP target. Development of IPv6 NAT
+ * funded by Astaro.
+ */
+
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <xtables.h>
+#include <libiptc/libip6tc.h>
+#include <linux/netfilter/nf_nat.h>
+
+#define MODULENAME "NETMAP"
+
+enum {
+	O_TO = 0,
+};
+
+static const struct xt_option_entry NETMAP_opts[] = {
+	{.name = "to", .id = O_TO, .type = XTTYPE_HOSTMASK,
+	 .flags = XTOPT_MAND},
+	XTOPT_TABLEEND,
+};
+
+static void NETMAP_help(void)
+{
+	printf(MODULENAME" target options:\n"
+	       "  --%s address[/mask]\n"
+	       "				Network address to map to.\n\n",
+	       NETMAP_opts[0].name);
+}
+
+static void NETMAP_parse(struct xt_option_call *cb)
+{
+	struct nf_nat_range *range = cb->data;
+	unsigned int i;
+
+	xtables_option_parse(cb);
+	range->flags |= NF_NAT_RANGE_MAP_IPS;
+	for (i = 0; i < 4; i++) {
+		range->min_addr.ip6[i] = cb->val.haddr.ip6[i] &
+					 cb->val.hmask.ip6[i];
+		range->max_addr.ip6[i] = range->min_addr.ip6[i] |
+					 ~cb->val.hmask.ip6[i];
+	}
+}
+
+static void NETMAP_print(const void *ip, const struct xt_entry_target *target,
+                         int numeric)
+{
+	const struct nf_nat_range *r = (const void *)target->data;
+	struct in6_addr a;
+	unsigned int i;
+	int bits;
+
+	a = r->min_addr.in6;
+	printf("%s", xtables_ip6addr_to_numeric(&a));
+	for (i = 0; i < 4; i++)
+		a.s6_addr32[i] = ~(r->min_addr.ip6[i] ^ r->max_addr.ip6[i]);
+	bits = ipv6_prefix_length(&a);
+	if (bits < 0)
+		printf("/%s", xtables_ip6addr_to_numeric(&a));
+	else
+		printf("/%d", bits);
+}
+
+static void NETMAP_save(const void *ip, const struct xt_entry_target *target)
+{
+	printf(" --%s ", NETMAP_opts[0].name);
+	NETMAP_print(ip, target, 0);
+}
+
+static struct xtables_target netmap_tg_reg = {
+	.name		= MODULENAME,
+	.version	= XTABLES_VERSION,
+	.family		= NFPROTO_IPV6,
+	.size		= XT_ALIGN(sizeof(struct nf_nat_range)),
+	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_range)),
+	.help		= NETMAP_help,
+	.x6_parse	= NETMAP_parse,
+	.print		= NETMAP_print,
+	.save		= NETMAP_save,
+	.x6_options	= NETMAP_opts,
+};
+
+void _init(void)
+{
+	xtables_register_target(&netmap_tg_reg);
+}
-- 
1.7.1


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

* [PATCH 7/7] extensions: add NPT extension
  2012-08-09 20:11 [PATCH 0/7] extensions: add IPv6 NAT support kaber
                   ` (5 preceding siblings ...)
  2012-08-09 20:11 ` [PATCH 6/7] extensions: add IPv6 NETMAP extension kaber
@ 2012-08-09 20:11 ` kaber
  6 siblings, 0 replies; 14+ messages in thread
From: kaber @ 2012-08-09 20:11 UTC (permalink / raw)
  To: netfilter-devel

From: Patrick McHardy <kaber@trash.net>

Add extensions for the SNPT and DNPT stateless IPv6-to-IPv6 Network Prefix
Translation targets.

Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 extensions/libip6t_DNPT.c               |   71 +++++++++++++++++++++++++++++++
 extensions/libip6t_SNPT.c               |   71 +++++++++++++++++++++++++++++++
 include/linux/netfilter_ipv6/ip6t_NPT.h |   16 +++++++
 3 files changed, 158 insertions(+), 0 deletions(-)
 create mode 100644 extensions/libip6t_DNPT.c
 create mode 100644 extensions/libip6t_SNPT.c
 create mode 100644 include/linux/netfilter_ipv6/ip6t_NPT.h

diff --git a/extensions/libip6t_DNPT.c b/extensions/libip6t_DNPT.c
new file mode 100644
index 0000000..9e4dc5c
--- /dev/null
+++ b/extensions/libip6t_DNPT.c
@@ -0,0 +1,71 @@
+#include <stdio.h>
+#include <xtables.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter_ipv6/ip6t_NPT.h>
+
+enum {
+	O_SRC_PFX	= 1 << 0,
+	O_DST_PFX	= 1 << 1,
+};
+
+static const struct xt_option_entry SNPT_options[] = {
+	{ .name = "src-pfx", .id = O_SRC_PFX, .type = XTTYPE_HOSTMASK,
+	  .flags = XTOPT_MAND },
+	{ .name = "dst-pfx", .id = O_DST_PFX, .type = XTTYPE_HOSTMASK,
+	  .flags = XTOPT_MAND },
+	{ }
+};
+
+static void SNPT_help(void)
+{
+	printf("SNPT target options:"
+	       "\n"
+	       " --src-pfx prefix/length\n"
+	       " --dst-pfx prefix/length\n"
+	       "\n");
+}
+
+static void SNPT_parse(struct xt_option_call *cb)
+{
+	struct ip6t_npt_tginfo *npt = cb->data;
+
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_SRC_PFX:
+		npt->src_pfx = cb->val.haddr;
+		npt->src_pfx_len = cb->val.hlen;
+		break;
+	case O_DST_PFX:
+		npt->dst_pfx = cb->val.haddr;
+		npt->dst_pfx_len = cb->val.hlen;
+		break;
+	}
+}
+
+static void SNPT_print(const void *ip, const struct xt_entry_target *target,
+		       int numeric)
+{
+	const struct ip6t_npt_tginfo *npt = (const void *)target->data;
+
+	printf("src-pfx %s/%u ", xtables_ip6addr_to_numeric(&npt->src_pfx.in6),
+				 npt->src_pfx_len);
+	printf("dst-pfx %s/%u ", xtables_ip6addr_to_numeric(&npt->dst_pfx.in6),
+				 npt->dst_pfx_len);
+}
+
+static struct xtables_target snpt_tg_reg = {
+	.name		= "DNPT",
+	.version	= XTABLES_VERSION,
+	.family		= NFPROTO_IPV6,
+	.size		= XT_ALIGN(sizeof(struct ip6t_npt_tginfo)),
+	.userspacesize	= offsetof(struct ip6t_npt_tginfo, adjustment),
+	.help		= SNPT_help,
+	.x6_parse	= SNPT_parse,
+	.print		= SNPT_print,
+	.x6_options	= SNPT_options,
+};
+
+void _init(void)
+{
+	xtables_register_target(&snpt_tg_reg);
+}
diff --git a/extensions/libip6t_SNPT.c b/extensions/libip6t_SNPT.c
new file mode 100644
index 0000000..26a86c5
--- /dev/null
+++ b/extensions/libip6t_SNPT.c
@@ -0,0 +1,71 @@
+#include <stdio.h>
+#include <xtables.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter_ipv6/ip6t_NPT.h>
+
+enum {
+	O_SRC_PFX	= 1 << 0,
+	O_DST_PFX	= 1 << 1,
+};
+
+static const struct xt_option_entry SNPT_options[] = {
+	{ .name = "src-pfx", .id = O_SRC_PFX, .type = XTTYPE_HOSTMASK,
+	  .flags = XTOPT_MAND },
+	{ .name = "dst-pfx", .id = O_DST_PFX, .type = XTTYPE_HOSTMASK,
+	  .flags = XTOPT_MAND },
+	{ }
+};
+
+static void SNPT_help(void)
+{
+	printf("SNPT target options:"
+	       "\n"
+	       " --src-pfx prefix/length\n"
+	       " --dst-pfx prefix/length\n"
+	       "\n");
+}
+
+static void SNPT_parse(struct xt_option_call *cb)
+{
+	struct ip6t_npt_tginfo *npt = cb->data;
+
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_SRC_PFX:
+		npt->src_pfx = cb->val.haddr;
+		npt->src_pfx_len = cb->val.hlen;
+		break;
+	case O_DST_PFX:
+		npt->dst_pfx = cb->val.haddr;
+		npt->dst_pfx_len = cb->val.hlen;
+		break;
+	}
+}
+
+static void SNPT_print(const void *ip, const struct xt_entry_target *target,
+		       int numeric)
+{
+	const struct ip6t_npt_tginfo *npt = (const void *)target->data;
+
+	printf("src-pfx %s/%u ", xtables_ip6addr_to_numeric(&npt->src_pfx.in6),
+				 npt->src_pfx_len);
+	printf("dst-pfx %s/%u ", xtables_ip6addr_to_numeric(&npt->dst_pfx.in6),
+				 npt->dst_pfx_len);
+}
+
+static struct xtables_target snpt_tg_reg = {
+	.name		= "SNPT",
+	.version	= XTABLES_VERSION,
+	.family		= NFPROTO_IPV6,
+	.size		= XT_ALIGN(sizeof(struct ip6t_npt_tginfo)),
+	.userspacesize	= offsetof(struct ip6t_npt_tginfo, adjustment),
+	.help		= SNPT_help,
+	.x6_parse	= SNPT_parse,
+	.print		= SNPT_print,
+	.x6_options	= SNPT_options,
+};
+
+void _init(void)
+{
+	xtables_register_target(&snpt_tg_reg);
+}
diff --git a/include/linux/netfilter_ipv6/ip6t_NPT.h b/include/linux/netfilter_ipv6/ip6t_NPT.h
new file mode 100644
index 0000000..f763355
--- /dev/null
+++ b/include/linux/netfilter_ipv6/ip6t_NPT.h
@@ -0,0 +1,16 @@
+#ifndef __NETFILTER_IP6T_NPT
+#define __NETFILTER_IP6T_NPT
+
+#include <linux/types.h>
+#include <linux/netfilter.h>
+
+struct ip6t_npt_tginfo {
+	union nf_inet_addr	src_pfx;
+	union nf_inet_addr	dst_pfx;
+	__u8			src_pfx_len;
+	__u8			dst_pfx_len;
+	/* Used internally by the kernel */
+	__sum16			adjustment;
+};
+
+#endif /* __NETFILTER_IP6T_NPT */
-- 
1.7.1


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

* Re: [PATCH 2/7] extensions: add IPv6 MASQUERADE extension
  2012-08-09 20:11 ` [PATCH 2/7] extensions: add IPv6 MASQUERADE extension kaber
@ 2012-08-09 21:18   ` Jan Engelhardt
  2012-08-09 21:22     ` Patrick McHardy
  0 siblings, 1 reply; 14+ messages in thread
From: Jan Engelhardt @ 2012-08-09 21:18 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel


On Thursday 2012-08-09 22:11, kaber@trash.net wrote:
>+static void MASQUERADE_help(void)
>+{
>+	printf(
>+"MASQUERADE target options:\n"
>+" --to-ports <port>[-<port>]\n"
>+"				Port (range) to map to.\n"
>+" --random\n"
>+"				Randomize source port.\n");
>+}
>+
>+static const struct xt_option_entry MASQUERADE_opts[] = {
>+	{.name = "to-ports", .id = O_TO_PORTS, .type = XTTYPE_STRING},
>+	{.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
>+	XTOPT_TABLEEND,
>+};

You could use .type = XTTYPE_PORTRC (port range)...
though arguably iptables already did a bad job at selecting
a suitable syntax for ranges.


>+/* Parses ports */

I don't think such a comment is needed ;)

>+static struct xtables_target masquerade_tg_reg = {
>+	.name		= "MASQUERADE",
>+	.version	= XTABLES_VERSION,
>+	.family		= NFPROTO_IPV6,
>+	.size		= XT_ALIGN(sizeof(struct nf_nat_range)),
>+	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_range)),
>+	.help		= MASQUERADE_help,
>+	.x6_parse	= MASQUERADE_parse,
>+	.print		= MASQUERADE_print,
>+	.save		= MASQUERADE_save,
>+	.x6_options	= MASQUERADE_opts,
>+};

Is it perhaps feasible to rename libipt_DNAT.c to libxt_DNAT.c
and thus have the v4 and v6 parts in the same file? In userspace
we do not have to fear depending on ipv6.ko like for kernel modules.


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

* Re: [PATCH 2/7] extensions: add IPv6 MASQUERADE extension
  2012-08-09 21:18   ` Jan Engelhardt
@ 2012-08-09 21:22     ` Patrick McHardy
  2012-08-09 21:26       ` Jan Engelhardt
  0 siblings, 1 reply; 14+ messages in thread
From: Patrick McHardy @ 2012-08-09 21:22 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: netfilter-devel

On Thu, 9 Aug 2012, Jan Engelhardt wrote:

>
> On Thursday 2012-08-09 22:11, kaber@trash.net wrote:
>> +static void MASQUERADE_help(void)
>> +{
>> +	printf(
>> +"MASQUERADE target options:\n"
>> +" --to-ports <port>[-<port>]\n"
>> +"				Port (range) to map to.\n"
>> +" --random\n"
>> +"				Randomize source port.\n");
>> +}
>> +
>> +static const struct xt_option_entry MASQUERADE_opts[] = {
>> +	{.name = "to-ports", .id = O_TO_PORTS, .type = XTTYPE_STRING},
>> +	{.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
>> +	XTOPT_TABLEEND,
>> +};
>
> You could use .type = XTTYPE_PORTRC (port range)...
> though arguably iptables already did a bad job at selecting
> a suitable syntax for ranges.

I kept the syntax similar to the IPv4 targets. I think its going to be
confusing to remember which one takes which syntax.

>> +/* Parses ports */
>
> I don't think such a comment is needed ;)

Removed.

>> +static struct xtables_target masquerade_tg_reg = {
>> +	.name		= "MASQUERADE",
>> +	.version	= XTABLES_VERSION,
>> +	.family		= NFPROTO_IPV6,
>> +	.size		= XT_ALIGN(sizeof(struct nf_nat_range)),
>> +	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_range)),
>> +	.help		= MASQUERADE_help,
>> +	.x6_parse	= MASQUERADE_parse,
>> +	.print		= MASQUERADE_print,
>> +	.save		= MASQUERADE_save,
>> +	.x6_options	= MASQUERADE_opts,
>> +};
>
> Is it perhaps feasible to rename libipt_DNAT.c to libxt_DNAT.c
> and thus have the v4 and v6 parts in the same file? In userspace
> we do not have to fear depending on ipv6.ko like for kernel modules.

I did that at first, but they use different structures 
(nf_nat_ipv4_multi_range_compat vs. nf_nat_range), so there's actually
almost no code which can be shared.

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

* Re: [PATCH 2/7] extensions: add IPv6 MASQUERADE extension
  2012-08-09 21:22     ` Patrick McHardy
@ 2012-08-09 21:26       ` Jan Engelhardt
  2012-08-09 21:30         ` Patrick McHardy
  0 siblings, 1 reply; 14+ messages in thread
From: Jan Engelhardt @ 2012-08-09 21:26 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netfilter-devel


On Thursday 2012-08-09 23:22, Patrick McHardy wrote:
>>
>> Is it perhaps feasible to rename libipt_DNAT.c to libxt_DNAT.c
>> and thus have the v4 and v6 parts in the same file? In userspace
>> we do not have to fear depending on ipv6.ko like for kernel modules.
>
> I did that at first, but they use different structures
> (nf_nat_ipv4_multi_range_compat vs. nf_nat_range), so there's actually
> almost no code which can be shared.

Will we be able to use nf_nat_range for IPv4 NAT parts
in the future as well?

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

* Re: [PATCH 3/7] extensions: add IPv6 SNAT extension
  2012-08-09 20:11 ` [PATCH 3/7] extensions: add IPv6 SNAT extension kaber
@ 2012-08-09 21:28   ` Jan Engelhardt
  2012-08-09 21:31     ` Patrick McHardy
  0 siblings, 1 reply; 14+ messages in thread
From: Jan Engelhardt @ 2012-08-09 21:28 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel


On Thursday 2012-08-09 22:11, kaber@trash.net wrote:
>+
>+static const struct xt_option_entry SNAT_opts[] = {
>+	{.name = "to-source", .id = O_TO_SRC, .type = XTTYPE_STRING,
>+	 .flags = XTOPT_MAND | XTOPT_MULTI},

According to the IPv4 SNAT/DNAT manpage, support for multiple ranges
was removed after 2.6.10. Has this changed?
If not, XTOPT_MULTI seems misplaced.

>+	case O_TO_SRC:
>+		if (cb->xflags & F_X_TO_SRC) {
>+			if (!kernel_version)
>+				get_kernel_version();
>+			if (kernel_version > LINUX_VERSION(2, 6, 10))
>+				xtables_error(PARAMETER_PROBLEM,
>+					   "SNAT: Multiple --to-source not supported");

It certainly is misplaced. IPv6 S/DNAT did not exist in any form in 2.6.10,
so we do not need to do the version check here.


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

* Re: [PATCH 2/7] extensions: add IPv6 MASQUERADE extension
  2012-08-09 21:26       ` Jan Engelhardt
@ 2012-08-09 21:30         ` Patrick McHardy
  0 siblings, 0 replies; 14+ messages in thread
From: Patrick McHardy @ 2012-08-09 21:30 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: netfilter-devel

On Thu, 9 Aug 2012, Jan Engelhardt wrote:

>
> On Thursday 2012-08-09 23:22, Patrick McHardy wrote:
>>>
>>> Is it perhaps feasible to rename libipt_DNAT.c to libxt_DNAT.c
>>> and thus have the v4 and v6 parts in the same file? In userspace
>>> we do not have to fear depending on ipv6.ko like for kernel modules.
>>
>> I did that at first, but they use different structures
>> (nf_nat_ipv4_multi_range_compat vs. nf_nat_range), so there's actually
>> almost no code which can be shared.
>
> Will we be able to use nf_nat_range for IPv4 NAT parts
> in the future as well?

I've added a v1 version of SNAT/DNAT, which use nf_nat_range.
We certainly can do this for MASQUERADE as well.

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

* Re: [PATCH 3/7] extensions: add IPv6 SNAT extension
  2012-08-09 21:28   ` Jan Engelhardt
@ 2012-08-09 21:31     ` Patrick McHardy
  0 siblings, 0 replies; 14+ messages in thread
From: Patrick McHardy @ 2012-08-09 21:31 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: netfilter-devel

On Thu, 9 Aug 2012, Jan Engelhardt wrote:

>
> On Thursday 2012-08-09 22:11, kaber@trash.net wrote:
>> +
>> +static const struct xt_option_entry SNAT_opts[] = {
>> +	{.name = "to-source", .id = O_TO_SRC, .type = XTTYPE_STRING,
>> +	 .flags = XTOPT_MAND | XTOPT_MULTI},
>
> According to the IPv4 SNAT/DNAT manpage, support for multiple ranges
> was removed after 2.6.10. Has this changed?
> If not, XTOPT_MULTI seems misplaced.
>
>> +	case O_TO_SRC:
>> +		if (cb->xflags & F_X_TO_SRC) {
>> +			if (!kernel_version)
>> +				get_kernel_version();
>> +			if (kernel_version > LINUX_VERSION(2, 6, 10))
>> +				xtables_error(PARAMETER_PROBLEM,
>> +					   "SNAT: Multiple --to-source not supported");
>
> It certainly is misplaced. IPv6 S/DNAT did not exist in any form in 2.6.10,
> so we do not need to do the version check here.

Right, I'm going to delete all this.

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

end of thread, other threads:[~2012-08-09 21:31 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-08-09 20:11 [PATCH 0/7] extensions: add IPv6 NAT support kaber
2012-08-09 20:11 ` [PATCH 1/7] extensions: convert NAT target to use nf_nat.h kaber
2012-08-09 20:11 ` [PATCH 2/7] extensions: add IPv6 MASQUERADE extension kaber
2012-08-09 21:18   ` Jan Engelhardt
2012-08-09 21:22     ` Patrick McHardy
2012-08-09 21:26       ` Jan Engelhardt
2012-08-09 21:30         ` Patrick McHardy
2012-08-09 20:11 ` [PATCH 3/7] extensions: add IPv6 SNAT extension kaber
2012-08-09 21:28   ` Jan Engelhardt
2012-08-09 21:31     ` Patrick McHardy
2012-08-09 20:11 ` [PATCH 4/7] extensions: add IPv6 DNAT target kaber
2012-08-09 20:11 ` [PATCH 5/7] extensions: add IPv6 REDIRECT extension kaber
2012-08-09 20:11 ` [PATCH 6/7] extensions: add IPv6 NETMAP extension kaber
2012-08-09 20:11 ` [PATCH 7/7] extensions: add NPT extension kaber

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).