netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [libnetfilter_conntrack PATCH v2 1/3] src: add support for IPv6 to struct __nfct_nat
@ 2016-05-18  8:56 Arturo Borrero Gonzalez
  2016-05-18  8:56 ` [libnetfilter_conntrack PATCH v2 2/3] src: add support for IPv6 NAT Arturo Borrero Gonzalez
  2016-05-20  9:34 ` [libnetfilter_conntrack PATCH v2 1/3] src: add support for IPv6 to struct __nfct_nat Pablo Neira Ayuso
  0 siblings, 2 replies; 5+ messages in thread
From: Arturo Borrero Gonzalez @ 2016-05-18  8:56 UTC (permalink / raw)
  To: netfilter-devel; +Cc: fw, pablo

The conntrackd daemon lacks support for syncing IPv6 NATed connections.

This patch prepares the ground to give support to such operations:
 * replace uint32_t with union __nfct_address in struct __nfct_nat.
 * update all users of the former uint32_t to support the new struct

A follow-up patch gives support to actually manage the IPv6 NAT.

Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
---
v2: untangle code. don't add AF_INET6 case.

 include/internal/object.h |    2 +-
 src/conntrack/build.c     |   33 ++++++++++++++++---------
 src/conntrack/build_mnl.c |   29 ++++++++++++++--------
 src/conntrack/copy.c      |    4 ++-
 src/conntrack/getter.c    |    4 ++-
 src/conntrack/objopt.c    |   59 +++++++++++++++++++++++++++++++++------------
 src/conntrack/setter.c    |    4 ++-
 7 files changed, 90 insertions(+), 45 deletions(-)

diff --git a/include/internal/object.h b/include/internal/object.h
index ffbcb1f..bb14dc8 100644
--- a/include/internal/object.h
+++ b/include/internal/object.h
@@ -144,7 +144,7 @@ struct __nfct_counters {
 };
 
 struct __nfct_nat {
-	uint32_t 		min_ip, max_ip;
+	union __nfct_address	min_ip, max_ip;
 	union __nfct_l4_src 	l4min, l4max;
 };
 
diff --git a/src/conntrack/build.c b/src/conntrack/build.c
index 01bdefb..8ba6b16 100644
--- a/src/conntrack/build.c
+++ b/src/conntrack/build.c
@@ -275,20 +275,28 @@ static void __build_protonat(struct nfnlhdr *req,
 
 static void __build_nat(struct nfnlhdr *req,
 			size_t size,
-			const struct __nfct_nat *nat)
+			const struct __nfct_nat *nat,
+			uint8_t l3protonum)
 {
-	nfnl_addattr_l(&req->nlh, size, CTA_NAT_MINIP,
-		       &nat->min_ip, sizeof(uint32_t));
+	switch (l3protonum) {
+	case AF_INET:
+		nfnl_addattr_l(&req->nlh, size, CTA_NAT_MINIP,
+			       &nat->min_ip.v4, sizeof(uint32_t));
+		break;
+	default:
+		break;
+	}
 }
 
 static void __build_snat(struct nfnlhdr *req,
 			 size_t size,
-			 const struct nf_conntrack *ct)
+			 const struct nf_conntrack *ct,
+			 uint8_t l3protonum)
 {
 	struct nfattr *nest;
 
 	nest = nfnl_nest(&req->nlh, size, CTA_NAT_SRC);
-	__build_nat(req, size, &ct->snat);
+	__build_nat(req, size, &ct->snat, l3protonum);
 	__build_protonat(req, size, ct, &ct->snat);
 	nfnl_nest_end(&req->nlh, nest);
 }
@@ -300,7 +308,7 @@ static void __build_snat_ipv4(struct nfnlhdr *req,
 	struct nfattr *nest;
 
 	nest = nfnl_nest(&req->nlh, size, CTA_NAT_SRC);
-	__build_nat(req, size, &ct->snat);
+	__build_nat(req, size, &ct->snat, AF_INET);
 	nfnl_nest_end(&req->nlh, nest);
 }
 
@@ -317,12 +325,13 @@ static void __build_snat_port(struct nfnlhdr *req,
 
 static void __build_dnat(struct nfnlhdr *req,
 			 size_t size,
-			 const struct nf_conntrack *ct)
+			 const struct nf_conntrack *ct,
+			 uint8_t l3protonum)
 {
 	struct nfattr *nest;
 
 	nest = nfnl_nest(&req->nlh, size, CTA_NAT_DST);
-	__build_nat(req, size, &ct->dnat);
+	__build_nat(req, size, &ct->dnat, l3protonum);
 	__build_protonat(req, size, ct, &ct->dnat);
 	nfnl_nest_end(&req->nlh, nest);
 }
@@ -334,7 +343,7 @@ static void __build_dnat_ipv4(struct nfnlhdr *req,
 	struct nfattr *nest;
 
 	nest = nfnl_nest(&req->nlh, size, CTA_NAT_DST);
-	__build_nat(req, size, &ct->dnat);
+	__build_nat(req, size, &ct->dnat, AF_INET);
 	nfnl_nest_end(&req->nlh, nest);
 }
 
@@ -514,9 +523,9 @@ int __build_conntrack(struct nfnl_subsys_handle *ssh,
 
 	__build_protoinfo(req, size, ct);
 
-	if (test_bit(ATTR_SNAT_IPV4, ct->head.set) && 
+	if (test_bit(ATTR_SNAT_IPV4, ct->head.set) &&
 	    test_bit(ATTR_SNAT_PORT, ct->head.set))
-		__build_snat(req, size, ct);
+		__build_snat(req, size, ct, AF_INET);
 	else if (test_bit(ATTR_SNAT_IPV4, ct->head.set))
 		__build_snat_ipv4(req, size, ct);
 	else if (test_bit(ATTR_SNAT_PORT, ct->head.set))
@@ -524,7 +533,7 @@ int __build_conntrack(struct nfnl_subsys_handle *ssh,
 
 	if (test_bit(ATTR_DNAT_IPV4, ct->head.set) &&
 	    test_bit(ATTR_DNAT_PORT, ct->head.set))
-		__build_dnat(req, size, ct);
+		__build_dnat(req, size, ct, AF_INET);
 	else if (test_bit(ATTR_DNAT_IPV4, ct->head.set))
 		__build_dnat_ipv4(req, size, ct);
 	else if (test_bit(ATTR_DNAT_PORT, ct->head.set))
diff --git a/src/conntrack/build_mnl.c b/src/conntrack/build_mnl.c
index 8ed0690..f4bb287 100644
--- a/src/conntrack/build_mnl.c
+++ b/src/conntrack/build_mnl.c
@@ -264,19 +264,27 @@ nfct_build_protonat(struct nlmsghdr *nlh, const struct nf_conntrack *ct,
 }
 
 static int
-nfct_build_nat(struct nlmsghdr *nlh, const struct __nfct_nat *nat)
+nfct_build_nat(struct nlmsghdr *nlh, const struct __nfct_nat *nat,
+	       uint8_t l3protonum)
 {
-	mnl_attr_put_u32(nlh, CTA_NAT_MINIP, nat->min_ip);
+	switch (l3protonum) {
+	case AF_INET:
+		mnl_attr_put_u32(nlh, CTA_NAT_MINIP, nat->min_ip.v4);
+		break;
+	default:
+		break;
+	}
 	return 0;
 }
 
 static int
-nfct_build_snat(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
+nfct_build_snat(struct nlmsghdr *nlh, const struct nf_conntrack *ct,
+		uint8_t l3protonum)
 {
 	struct nlattr *nest;
 
 	nest = mnl_attr_nest_start(nlh, CTA_NAT_SRC);
-	nfct_build_nat(nlh, &ct->snat);
+	nfct_build_nat(nlh, &ct->snat, l3protonum);
 	nfct_build_protonat(nlh, ct, &ct->snat);
 	mnl_attr_nest_end(nlh, nest);
 	return 0;
@@ -288,7 +296,7 @@ nfct_build_snat_ipv4(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
 	struct nlattr *nest;
 
 	nest = mnl_attr_nest_start(nlh, CTA_NAT_SRC);
-	nfct_build_nat(nlh, &ct->snat);
+	nfct_build_nat(nlh, &ct->snat, AF_INET);
 	mnl_attr_nest_end(nlh, nest);
 	return 0;
 }
@@ -305,12 +313,13 @@ nfct_build_snat_port(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
 }
 
 static int
-nfct_build_dnat(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
+nfct_build_dnat(struct nlmsghdr *nlh, const struct nf_conntrack *ct,
+		uint8_t l3protonum)
 {
 	struct nlattr *nest;
 
 	nest = mnl_attr_nest_start(nlh, CTA_NAT_DST);
-	nfct_build_nat(nlh, &ct->dnat);
+	nfct_build_nat(nlh, &ct->dnat, l3protonum);
 	nfct_build_protonat(nlh, ct, &ct->dnat);
 	mnl_attr_nest_end(nlh, nest);
 	return 0;
@@ -322,7 +331,7 @@ nfct_build_dnat_ipv4(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
 	struct nlattr *nest;
 
 	nest = mnl_attr_nest_start(nlh, CTA_NAT_DST);
-	nfct_build_nat(nlh, &ct->dnat);
+	nfct_build_nat(nlh, &ct->dnat, AF_INET);
 	mnl_attr_nest_end(nlh, nest);
 	return 0;
 }
@@ -498,7 +507,7 @@ nfct_nlmsg_build(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
 
 	if (test_bit(ATTR_SNAT_IPV4, ct->head.set) &&
 	    test_bit(ATTR_SNAT_PORT, ct->head.set)) {
-		nfct_build_snat(nlh, ct);
+		nfct_build_snat(nlh, ct, AF_INET);
 	} else if (test_bit(ATTR_SNAT_IPV4, ct->head.set)) {
 		nfct_build_snat_ipv4(nlh, ct);
 	} else if (test_bit(ATTR_SNAT_PORT, ct->head.set)) {
@@ -507,7 +516,7 @@ nfct_nlmsg_build(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
 
 	if (test_bit(ATTR_DNAT_IPV4, ct->head.set) &&
 	    test_bit(ATTR_DNAT_PORT, ct->head.set)) {
-		nfct_build_dnat(nlh, ct);
+		nfct_build_dnat(nlh, ct, AF_INET);
 	} else if (test_bit(ATTR_DNAT_IPV4, ct->head.set)) {
 		nfct_build_dnat_ipv4(nlh, ct);
 	} else if (test_bit(ATTR_DNAT_PORT, ct->head.set)) {
diff --git a/src/conntrack/copy.c b/src/conntrack/copy.c
index 249e7e0..eac977b 100644
--- a/src/conntrack/copy.c
+++ b/src/conntrack/copy.c
@@ -287,13 +287,13 @@ static void copy_attr_dccp_handshake_seq(struct nf_conntrack *dest,
 static void copy_attr_snat_ipv4(struct nf_conntrack *dest,
 				const struct nf_conntrack *orig)
 {
-	dest->snat.min_ip = orig->snat.min_ip;
+	dest->snat.min_ip.v4 = orig->snat.min_ip.v4;
 }
 
 static void copy_attr_dnat_ipv4(struct nf_conntrack *dest,
 				const struct nf_conntrack *orig)
 {
-	dest->dnat.min_ip = orig->dnat.min_ip;
+	dest->dnat.min_ip.v4 = orig->dnat.min_ip.v4;
 }
 
 static void copy_attr_snat_port(struct nf_conntrack *dest,
diff --git a/src/conntrack/getter.c b/src/conntrack/getter.c
index ef4ec1d..20dd905 100644
--- a/src/conntrack/getter.c
+++ b/src/conntrack/getter.c
@@ -206,12 +206,12 @@ static const void *get_attr_sctp_vtag_repl(const struct nf_conntrack *ct)
 
 static const void *get_attr_snat_ipv4(const struct nf_conntrack *ct)
 {
-	return &ct->snat.min_ip;
+	return &ct->snat.min_ip.v4;
 }
 
 static const void *get_attr_dnat_ipv4(const struct nf_conntrack *ct)
 {
-	return &ct->dnat.min_ip;
+	return &ct->dnat.min_ip.v4;
 }
 
 static const void *get_attr_snat_port(const struct nf_conntrack *ct)
diff --git a/src/conntrack/objopt.c b/src/conntrack/objopt.c
index 5898746..ab0b1a3 100644
--- a/src/conntrack/objopt.c
+++ b/src/conntrack/objopt.c
@@ -52,18 +52,29 @@ static void __autocomplete(struct nf_conntrack *ct, int dir)
 
 static void setobjopt_undo_snat(struct nf_conntrack *ct)
 {
-	ct->snat.min_ip = ct->repl.dst.v4;
-	ct->snat.max_ip = ct->snat.min_ip;
-	ct->repl.dst.v4 = ct->head.orig.src.v4;
-	set_bit(ATTR_SNAT_IPV4, ct->head.set);
+	switch (ct->head.orig.l3protonum) {
+	case AF_INET:
+		ct->snat.min_ip.v4 = ct->repl.dst.v4;
+		ct->snat.max_ip.v4 = ct->snat.min_ip.v4;
+		ct->repl.dst.v4 = ct->head.orig.src.v4;
+		set_bit(ATTR_SNAT_IPV4, ct->head.set);
+		break;
+	default:
+		break;
+	}
 }
 
 static void setobjopt_undo_dnat(struct nf_conntrack *ct)
 {
-	ct->dnat.min_ip = ct->repl.src.v4;
-	ct->dnat.max_ip = ct->dnat.min_ip;
-	ct->repl.src.v4 = ct->head.orig.dst.v4;
-	set_bit(ATTR_DNAT_IPV4, ct->head.set);
+	switch (ct->head.orig.l3protonum) {
+	case AF_INET:
+		ct->dnat.min_ip.v4 = ct->repl.src.v4;
+		ct->dnat.max_ip.v4 = ct->dnat.min_ip.v4;
+		ct->repl.src.v4 = ct->head.orig.dst.v4;
+		set_bit(ATTR_DNAT_IPV4, ct->head.set);
+	default:
+		break;
+	}
 }
 
 static void setobjopt_undo_spat(struct nf_conntrack *ct)
@@ -114,18 +125,34 @@ int __setobjopt(struct nf_conntrack *ct, unsigned int option)
 
 static int getobjopt_is_snat(const struct nf_conntrack *ct)
 {
-	return ((test_bit(ATTR_STATUS, ct->head.set) ?
-		ct->status & IPS_SRC_NAT_DONE : 1) &&
-		ct->repl.dst.v4 != 
-		ct->head.orig.src.v4);
+	if (!(test_bit(ATTR_STATUS, ct->head.set))
+		return 0;
+
+	if (!(ct->status & IPS_SRC_NAT_DONE))
+		return 0;
+
+	switch (ct->head.orig.l3protonum) {
+	case AF_INET:
+		return ct->repl.dst.v4 != ct->head.orig.src.v4;
+	default:
+		return 0;
+	}
 }
 
 static int getobjopt_is_dnat(const struct nf_conntrack *ct)
 {
-	return ((test_bit(ATTR_STATUS, ct->head.set) ?
-		ct->status & IPS_DST_NAT_DONE : 1) &&
-		ct->repl.src.v4 !=
-		ct->head.orig.dst.v4);
+	if (!(test_bit(ATTR_STATUS, ct->head.set))
+		return 0;
+
+	if (!(ct->status & IPS_DST_NAT_DONE))
+		return 0;
+
+	switch (ct->head.orig.l3protonum) {
+	case AF_INET:
+		return ct->repl.src.v4 != ct->head.orig.dst.v4;
+	default:
+		return 0;
+	}
 }
 
 static int getobjopt_is_spat(const struct nf_conntrack *ct)
diff --git a/src/conntrack/setter.c b/src/conntrack/setter.c
index a212461..e103646 100644
--- a/src/conntrack/setter.c
+++ b/src/conntrack/setter.c
@@ -237,13 +237,13 @@ set_attr_sctp_vtag_repl(struct nf_conntrack *ct, const void *value, size_t len)
 static void
 set_attr_snat_ipv4(struct nf_conntrack *ct, const void *value, size_t len)
 {
-	ct->snat.min_ip = ct->snat.max_ip = *((uint32_t *) value);
+	ct->snat.min_ip.v4 = ct->snat.max_ip.v4 = *((uint32_t *) value);
 }
 
 static void
 set_attr_dnat_ipv4(struct nf_conntrack *ct, const void *value, size_t len)
 {
-	ct->dnat.min_ip = ct->dnat.max_ip = *((uint32_t *) value);
+	ct->dnat.min_ip.v4 = ct->dnat.max_ip.v4 = *((uint32_t *) value);
 }
 
 static void


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

* [libnetfilter_conntrack PATCH v2 2/3] src: add support for IPv6 NAT
  2016-05-18  8:56 [libnetfilter_conntrack PATCH v2 1/3] src: add support for IPv6 to struct __nfct_nat Arturo Borrero Gonzalez
@ 2016-05-18  8:56 ` Arturo Borrero Gonzalez
  2016-05-20  9:36   ` Pablo Neira Ayuso
  2016-05-20  9:34 ` [libnetfilter_conntrack PATCH v2 1/3] src: add support for IPv6 to struct __nfct_nat Pablo Neira Ayuso
  1 sibling, 1 reply; 5+ messages in thread
From: Arturo Borrero Gonzalez @ 2016-05-18  8:56 UTC (permalink / raw)
  To: netfilter-devel; +Cc: fw, pablo

The conntrackd daemon lacks support for syncing IPv6 NATed connections.

This patch adds support for managing the IPv6 part of struct __nfct_nat,
also updating the corresponsing symbols.

Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
---
v2: use CTA_NAT_V6_MINIP instead of CTA_NAT_MINIP

 .../libnetfilter_conntrack.h                       |    2 +
 src/conntrack/build.c                              |   36 ++++++++++++++++++++
 src/conntrack/build_mnl.c                          |   36 ++++++++++++++++++++
 src/conntrack/copy.c                               |   16 +++++++++
 src/conntrack/getter.c                             |   12 +++++++
 src/conntrack/objopt.c                             |   34 ++++++++++++++++++-
 src/conntrack/setter.c                             |   16 +++++++++
 7 files changed, 150 insertions(+), 2 deletions(-)

diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack.h b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
index 22af622..6cba578 100644
--- a/include/libnetfilter_conntrack/libnetfilter_conntrack.h
+++ b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
@@ -138,6 +138,8 @@ enum nf_conntrack_attr {
 	ATTR_CONNLABELS_MASK,			/* variable length */
 	ATTR_ORIG_ZONE,				/* u16 bits */
 	ATTR_REPL_ZONE,				/* u16 bits */
+	ATTR_SNAT_IPV6,				/* u128 bits */
+	ATTR_DNAT_IPV6,				/* u128 bits */
 	ATTR_MAX
 };
 
diff --git a/src/conntrack/build.c b/src/conntrack/build.c
index 8ba6b16..cf282e6 100644
--- a/src/conntrack/build.c
+++ b/src/conntrack/build.c
@@ -283,6 +283,10 @@ static void __build_nat(struct nfnlhdr *req,
 		nfnl_addattr_l(&req->nlh, size, CTA_NAT_MINIP,
 			       &nat->min_ip.v4, sizeof(uint32_t));
 		break;
+	case AF_INET6:
+		nfnl_addattr_l(&req->nlh, size, CTA_NAT_V6_MINIP,
+			       &nat->min_ip.v6, sizeof(struct in6_addr));
+		break;
 	default:
 		break;
 	}
@@ -312,6 +316,17 @@ static void __build_snat_ipv4(struct nfnlhdr *req,
 	nfnl_nest_end(&req->nlh, nest);
 }
 
+static void __build_snat_ipv6(struct nfnlhdr *req,
+			      size_t size,
+			      const struct nf_conntrack *ct)
+{
+	struct nfattr *nest;
+
+	nest = nfnl_nest(&req->nlh, size, CTA_NAT_SRC);
+	__build_nat(req, size, &ct->snat, AF_INET6);
+	nfnl_nest_end(&req->nlh, nest);
+}
+
 static void __build_snat_port(struct nfnlhdr *req,
 			      size_t size,
 			      const struct nf_conntrack *ct)
@@ -347,6 +362,17 @@ static void __build_dnat_ipv4(struct nfnlhdr *req,
 	nfnl_nest_end(&req->nlh, nest);
 }
 
+static void __build_dnat_ipv6(struct nfnlhdr *req,
+			      size_t size,
+			      const struct nf_conntrack *ct)
+{
+	struct nfattr *nest;
+
+	nest = nfnl_nest(&req->nlh, size, CTA_NAT_DST);
+	__build_nat(req, size, &ct->dnat, AF_INET6);
+	nfnl_nest_end(&req->nlh, nest);
+}
+
 static void __build_dnat_port(struct nfnlhdr *req,
 			      size_t size,
 			      const struct nf_conntrack *ct)
@@ -526,16 +552,26 @@ int __build_conntrack(struct nfnl_subsys_handle *ssh,
 	if (test_bit(ATTR_SNAT_IPV4, ct->head.set) &&
 	    test_bit(ATTR_SNAT_PORT, ct->head.set))
 		__build_snat(req, size, ct, AF_INET);
+	else if (test_bit(ATTR_SNAT_IPV6, ct->head.set) &&
+		 test_bit(ATTR_SNAT_PORT, ct->head.set))
+		__build_snat(req, size, ct, AF_INET6);
 	else if (test_bit(ATTR_SNAT_IPV4, ct->head.set))
 		__build_snat_ipv4(req, size, ct);
+	else if (test_bit(ATTR_SNAT_IPV6, ct->head.set))
+		__build_snat_ipv6(req, size, ct);
 	else if (test_bit(ATTR_SNAT_PORT, ct->head.set))
 		__build_snat_port(req, size, ct);
 
 	if (test_bit(ATTR_DNAT_IPV4, ct->head.set) &&
 	    test_bit(ATTR_DNAT_PORT, ct->head.set))
 		__build_dnat(req, size, ct, AF_INET);
+	else if (test_bit(ATTR_DNAT_IPV6, ct->head.set) &&
+		 test_bit(ATTR_DNAT_PORT, ct->head.set))
+		__build_dnat(req, size, ct, AF_INET6);
 	else if (test_bit(ATTR_DNAT_IPV4, ct->head.set))
 		__build_dnat_ipv4(req, size, ct);
+	else if (test_bit(ATTR_DNAT_IPV6, ct->head.set))
+		__build_dnat_ipv6(req, size, ct);
 	else if (test_bit(ATTR_DNAT_PORT, ct->head.set))
 		__build_dnat_port(req, size, ct);
 
diff --git a/src/conntrack/build_mnl.c b/src/conntrack/build_mnl.c
index f4bb287..2118bf3 100644
--- a/src/conntrack/build_mnl.c
+++ b/src/conntrack/build_mnl.c
@@ -271,6 +271,10 @@ nfct_build_nat(struct nlmsghdr *nlh, const struct __nfct_nat *nat,
 	case AF_INET:
 		mnl_attr_put_u32(nlh, CTA_NAT_MINIP, nat->min_ip.v4);
 		break;
+	case AF_INET6:
+		mnl_attr_put(nlh, CTA_NAT_V6_MINIP, sizeof(struct in6_addr),
+			     &nat->min_ip.v6);
+		break;
 	default:
 		break;
 	}
@@ -302,6 +306,17 @@ nfct_build_snat_ipv4(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
 }
 
 static int
+nfct_build_snat_ipv6(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
+{
+	struct nlattr *nest;
+
+	nest = mnl_attr_nest_start(nlh, CTA_NAT_SRC);
+	nfct_build_nat(nlh, &ct->snat, AF_INET6);
+	mnl_attr_nest_end(nlh, nest);
+	return 0;
+}
+
+static int
 nfct_build_snat_port(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
 {
 	struct nlattr *nest;
@@ -337,6 +352,17 @@ nfct_build_dnat_ipv4(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
 }
 
 static int
+nfct_build_dnat_ipv6(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
+{
+	struct nlattr *nest;
+
+	nest = mnl_attr_nest_start(nlh, CTA_NAT_DST);
+	nfct_build_nat(nlh, &ct->dnat, AF_INET6);
+	mnl_attr_nest_end(nlh, nest);
+	return 0;
+}
+
+static int
 nfct_build_dnat_port(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
 {
 	struct nlattr *nest;
@@ -508,8 +534,13 @@ nfct_nlmsg_build(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
 	if (test_bit(ATTR_SNAT_IPV4, ct->head.set) &&
 	    test_bit(ATTR_SNAT_PORT, ct->head.set)) {
 		nfct_build_snat(nlh, ct, AF_INET);
+	} else if (test_bit(ATTR_SNAT_IPV6, ct->head.set) &&
+		   test_bit(ATTR_SNAT_PORT, ct->head.set)) {
+		nfct_build_snat(nlh, ct, AF_INET6);
 	} else if (test_bit(ATTR_SNAT_IPV4, ct->head.set)) {
 		nfct_build_snat_ipv4(nlh, ct);
+	} else if (test_bit(ATTR_SNAT_IPV6, ct->head.set)) {
+		nfct_build_snat_ipv6(nlh, ct);
 	} else if (test_bit(ATTR_SNAT_PORT, ct->head.set)) {
 		nfct_build_snat_port(nlh, ct);
 	}
@@ -517,8 +548,13 @@ nfct_nlmsg_build(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
 	if (test_bit(ATTR_DNAT_IPV4, ct->head.set) &&
 	    test_bit(ATTR_DNAT_PORT, ct->head.set)) {
 		nfct_build_dnat(nlh, ct, AF_INET);
+	} else if (test_bit(ATTR_DNAT_IPV6, ct->head.set) &&
+		   test_bit(ATTR_DNAT_PORT, ct->head.set)) {
+		nfct_build_dnat(nlh, ct, AF_INET6);
 	} else if (test_bit(ATTR_DNAT_IPV4, ct->head.set)) {
 		nfct_build_dnat_ipv4(nlh, ct);
+	} else if (test_bit(ATTR_DNAT_IPV6, ct->head.set)) {
+		nfct_build_dnat_ipv6(nlh, ct);
 	} else if (test_bit(ATTR_DNAT_PORT, ct->head.set)) {
 		nfct_build_dnat_port(nlh, ct);
 	}
diff --git a/src/conntrack/copy.c b/src/conntrack/copy.c
index eac977b..e6e4f7a 100644
--- a/src/conntrack/copy.c
+++ b/src/conntrack/copy.c
@@ -296,6 +296,20 @@ static void copy_attr_dnat_ipv4(struct nf_conntrack *dest,
 	dest->dnat.min_ip.v4 = orig->dnat.min_ip.v4;
 }
 
+static void copy_attr_snat_ipv6(struct nf_conntrack *dest,
+				const struct nf_conntrack *orig)
+{
+	memcpy(&dest->snat.min_ip.v6, &orig->snat.min_ip.v6,
+	       sizeof(struct in6_addr));
+}
+
+static void copy_attr_dnat_ipv6(struct nf_conntrack *dest,
+				const struct nf_conntrack *orig)
+{
+	memcpy(&dest->dnat.min_ip.v6, &orig->dnat.min_ip.v6,
+	       sizeof(struct in6_addr));
+}
+
 static void copy_attr_snat_port(struct nf_conntrack *dest,
 				const struct nf_conntrack *orig)
 {
@@ -555,6 +569,8 @@ const copy_attr copy_attr_array[ATTR_MAX] = {
 	[ATTR_HELPER_INFO]		= copy_attr_help_info,
 	[ATTR_CONNLABELS]		= copy_attr_connlabels,
 	[ATTR_CONNLABELS_MASK]		= copy_attr_connlabels_mask,
+	[ATTR_SNAT_IPV6]		= copy_attr_snat_ipv6,
+	[ATTR_DNAT_IPV6]		= copy_attr_dnat_ipv6,
 };
 
 /* this is used by nfct_copy() with the NFCT_CP_OVERRIDE flag set. */
diff --git a/src/conntrack/getter.c b/src/conntrack/getter.c
index 20dd905..e818a05 100644
--- a/src/conntrack/getter.c
+++ b/src/conntrack/getter.c
@@ -214,6 +214,16 @@ static const void *get_attr_dnat_ipv4(const struct nf_conntrack *ct)
 	return &ct->dnat.min_ip.v4;
 }
 
+static const void *get_attr_snat_ipv6(const struct nf_conntrack *ct)
+{
+	return &ct->snat.min_ip.v6;
+}
+
+static const void *get_attr_dnat_ipv6(const struct nf_conntrack *ct)
+{
+	return &ct->dnat.min_ip.v6;
+}
+
 static const void *get_attr_snat_port(const struct nf_conntrack *ct)
 {
 	return &ct->snat.l4min.all;
@@ -430,4 +440,6 @@ const get_attr get_attr_array[ATTR_MAX] = {
 	[ATTR_HELPER_INFO]		= get_attr_helper_info,
 	[ATTR_CONNLABELS]		= get_attr_connlabels,
 	[ATTR_CONNLABELS_MASK]		= get_attr_connlabels_mask,
+	[ATTR_SNAT_IPV6]		= get_attr_snat_ipv6,
+	[ATTR_DNAT_IPV6]		= get_attr_dnat_ipv6,
 };
diff --git a/src/conntrack/objopt.c b/src/conntrack/objopt.c
index ab0b1a3..119a83a 100644
--- a/src/conntrack/objopt.c
+++ b/src/conntrack/objopt.c
@@ -59,6 +59,15 @@ static void setobjopt_undo_snat(struct nf_conntrack *ct)
 		ct->repl.dst.v4 = ct->head.orig.src.v4;
 		set_bit(ATTR_SNAT_IPV4, ct->head.set);
 		break;
+	case AF_INET6:
+		memcpy(&ct->snat.min_ip.v6, &ct->repl.dst.v6,
+		       sizeof(struct in6_addr));
+		memcpy(&ct->snat.max_ip.v6, &ct->snat.min_ip.v6,
+		       sizeof(struct in6_addr));
+		memcpy(&ct->repl.dst.v6, &ct->head.orig.src.v6,
+		       sizeof(struct in6_addr));
+		set_bit(ATTR_SNAT_IPV6, ct->head.set);
+		break;
 	default:
 		break;
 	}
@@ -72,6 +81,15 @@ static void setobjopt_undo_dnat(struct nf_conntrack *ct)
 		ct->dnat.max_ip.v4 = ct->dnat.min_ip.v4;
 		ct->repl.src.v4 = ct->head.orig.dst.v4;
 		set_bit(ATTR_DNAT_IPV4, ct->head.set);
+	case AF_INET6:
+		memcpy(&ct->dnat.min_ip.v6, &ct->repl.src.v6,
+		       sizeof(struct in6_addr));
+		memcpy(&ct->dnat.max_ip.v6, &ct->dnat.min_ip.v6,
+		       sizeof(struct in6_addr));
+		memcpy(&ct->repl.src.v6, &ct->head.orig.dst.v6,
+		       sizeof(struct in6_addr));
+		set_bit(ATTR_DNAT_IPV6, ct->head.set);
+		break;
 	default:
 		break;
 	}
@@ -125,7 +143,7 @@ int __setobjopt(struct nf_conntrack *ct, unsigned int option)
 
 static int getobjopt_is_snat(const struct nf_conntrack *ct)
 {
-	if (!(test_bit(ATTR_STATUS, ct->head.set))
+	if (!(test_bit(ATTR_STATUS, ct->head.set)))
 		return 0;
 
 	if (!(ct->status & IPS_SRC_NAT_DONE))
@@ -134,6 +152,12 @@ static int getobjopt_is_snat(const struct nf_conntrack *ct)
 	switch (ct->head.orig.l3protonum) {
 	case AF_INET:
 		return ct->repl.dst.v4 != ct->head.orig.src.v4;
+	case AF_INET6:
+		if (memcmp(&ct->repl.dst.v6, &ct->head.orig.src.v6,
+			   sizeof(struct in6_addr)) != 0)
+			return 1;
+		else
+			return 0;
 	default:
 		return 0;
 	}
@@ -141,7 +165,7 @@ static int getobjopt_is_snat(const struct nf_conntrack *ct)
 
 static int getobjopt_is_dnat(const struct nf_conntrack *ct)
 {
-	if (!(test_bit(ATTR_STATUS, ct->head.set))
+	if (!(test_bit(ATTR_STATUS, ct->head.set)))
 		return 0;
 
 	if (!(ct->status & IPS_DST_NAT_DONE))
@@ -150,6 +174,12 @@ static int getobjopt_is_dnat(const struct nf_conntrack *ct)
 	switch (ct->head.orig.l3protonum) {
 	case AF_INET:
 		return ct->repl.src.v4 != ct->head.orig.dst.v4;
+	case AF_INET6:
+		if (memcmp(&ct->repl.src.v6, &ct->head.orig.dst.v6,
+			   sizeof(struct in6_addr)) != 0)
+			return 1;
+		else
+			return 0;
 	default:
 		return 0;
 	}
diff --git a/src/conntrack/setter.c b/src/conntrack/setter.c
index e103646..75ab09e 100644
--- a/src/conntrack/setter.c
+++ b/src/conntrack/setter.c
@@ -247,6 +247,20 @@ set_attr_dnat_ipv4(struct nf_conntrack *ct, const void *value, size_t len)
 }
 
 static void
+set_attr_snat_ipv6(struct nf_conntrack *ct, const void *value, size_t len)
+{
+	memcpy(&ct->snat.min_ip.v6, value, sizeof(struct in6_addr));
+	memcpy(&ct->snat.max_ip.v6, value, sizeof(struct in6_addr));
+}
+
+static void
+set_attr_dnat_ipv6(struct nf_conntrack *ct, const void *value, size_t len)
+{
+	memcpy(&ct->dnat.min_ip.v6, value, sizeof(struct in6_addr));
+	memcpy(&ct->dnat.max_ip.v6, value, sizeof(struct in6_addr));
+}
+
+static void
 set_attr_snat_port(struct nf_conntrack *ct, const void *value, size_t len)
 {
 	ct->snat.l4min.all = ct->snat.l4max.all = *((uint16_t *) value);
@@ -527,4 +541,6 @@ const set_attr set_attr_array[ATTR_MAX] = {
 	[ATTR_HELPER_INFO]	= set_attr_helper_info,
 	[ATTR_CONNLABELS]	= set_attr_connlabels,
 	[ATTR_CONNLABELS_MASK]	= set_attr_connlabels_mask,
+	[ATTR_SNAT_IPV6]	= set_attr_snat_ipv6,
+	[ATTR_DNAT_IPV6]	= set_attr_dnat_ipv6,
 };


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

* Re: [libnetfilter_conntrack PATCH v2 1/3] src: add support for IPv6 to struct __nfct_nat
  2016-05-18  8:56 [libnetfilter_conntrack PATCH v2 1/3] src: add support for IPv6 to struct __nfct_nat Arturo Borrero Gonzalez
  2016-05-18  8:56 ` [libnetfilter_conntrack PATCH v2 2/3] src: add support for IPv6 NAT Arturo Borrero Gonzalez
@ 2016-05-20  9:34 ` Pablo Neira Ayuso
  2016-05-20  9:35   ` Pablo Neira Ayuso
  1 sibling, 1 reply; 5+ messages in thread
From: Pablo Neira Ayuso @ 2016-05-20  9:34 UTC (permalink / raw)
  To: Arturo Borrero Gonzalez; +Cc: netfilter-devel, fw

On Wed, May 18, 2016 at 10:56:19AM +0200, Arturo Borrero Gonzalez wrote:
> The conntrackd daemon lacks support for syncing IPv6 NATed connections.
> 
> This patch prepares the ground to give support to such operations:
>  * replace uint32_t with union __nfct_address in struct __nfct_nat.
>  * update all users of the former uint32_t to support the new struct
> 
> A follow-up patch gives support to actually manage the IPv6 NAT.

$ git am
/tmp/libnetfilter_conntrack-v2-1-3-src-add-support-for-IPv6-to-struct-__nfct_nat.patch
Applying: src: add support for IPv6 to struct __nfct_nat
error: patch failed: src/conntrack/setter.c:237
error: src/conntrack/setter.c: patch does not apply
Patch failed at 0001 src: add support for IPv6 to struct __nfct_nat
The copy of the patch that failed is found in:
   /home/pablo/devel/scm/git-netfilter/libnetfilter_conntrack/.git/rebase-apply/patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am
--abort".

This doesn't apply cleanly, please rebase on top of git HEAD and resubmit.

Thanks.

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

* Re: [libnetfilter_conntrack PATCH v2 1/3] src: add support for IPv6 to struct __nfct_nat
  2016-05-20  9:34 ` [libnetfilter_conntrack PATCH v2 1/3] src: add support for IPv6 to struct __nfct_nat Pablo Neira Ayuso
@ 2016-05-20  9:35   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 5+ messages in thread
From: Pablo Neira Ayuso @ 2016-05-20  9:35 UTC (permalink / raw)
  To: Arturo Borrero Gonzalez; +Cc: netfilter-devel, fw

On Fri, May 20, 2016 at 11:34:39AM +0200, Pablo Neira Ayuso wrote:
> This doesn't apply cleanly, please rebase on top of git HEAD and resubmit.

Forget this, sorry. I forgot to pull before applying this.

So now applied, thanks Arturo.

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

* Re: [libnetfilter_conntrack PATCH v2 2/3] src: add support for IPv6 NAT
  2016-05-18  8:56 ` [libnetfilter_conntrack PATCH v2 2/3] src: add support for IPv6 NAT Arturo Borrero Gonzalez
@ 2016-05-20  9:36   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 5+ messages in thread
From: Pablo Neira Ayuso @ 2016-05-20  9:36 UTC (permalink / raw)
  To: Arturo Borrero Gonzalez; +Cc: netfilter-devel, fw

On Wed, May 18, 2016 at 10:56:36AM +0200, Arturo Borrero Gonzalez wrote:
> The conntrackd daemon lacks support for syncing IPv6 NATed connections.
> 
> This patch adds support for managing the IPv6 part of struct __nfct_nat,
> also updating the corresponsing symbols.

Also applied, thanks.

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

end of thread, other threads:[~2016-05-20  9:36 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-05-18  8:56 [libnetfilter_conntrack PATCH v2 1/3] src: add support for IPv6 to struct __nfct_nat Arturo Borrero Gonzalez
2016-05-18  8:56 ` [libnetfilter_conntrack PATCH v2 2/3] src: add support for IPv6 NAT Arturo Borrero Gonzalez
2016-05-20  9:36   ` Pablo Neira Ayuso
2016-05-20  9:34 ` [libnetfilter_conntrack PATCH v2 1/3] src: add support for IPv6 to struct __nfct_nat Pablo Neira Ayuso
2016-05-20  9:35   ` Pablo Neira Ayuso

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).