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