* [iptables PATCH 0/6] Merge NAT extensions
@ 2022-11-03 1:41 Phil Sutter
2022-11-03 1:41 ` [iptables PATCH 1/6] extensions: DNAT: Fix bad IP address error reporting Phil Sutter
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Phil Sutter @ 2022-11-03 1:41 UTC (permalink / raw)
To: netfilter-devel
Besides the three different data structures in use to store different
revisions' extensions data, the actual code is pretty similar in all the
different NAT "flavors".
Patch 1 fixes a minor bug introduced by a previous commit. Patch 2
eliminates some needless checks and some that seem not necessary.
Patches 3 to 5 prepare DNAT extension code for the actual merge
happening in patch 6.
Phil Sutter (6):
extensions: DNAT: Fix bad IP address error reporting
extensions: *NAT: Drop NF_NAT_RANGE_PROTO_RANDOM* flag checks
extensions: DNAT: Use __DNAT_xlate for REDIRECT, too
extensions: DNAT: Generate print, save and xlate callbacks
extensions: DNAT: Rename some symbols
extensions: Merge SNAT, DNAT, REDIRECT and MASQUERADE
extensions/GNUmakefile.in | 10 +-
extensions/libip6t_MASQUERADE.c | 188 ----------
extensions/libip6t_MASQUERADE.txlate | 9 +
extensions/libip6t_SNAT.c | 308 ----------------
extensions/libip6t_SNAT.t | 6 +
extensions/libipt_MASQUERADE.c | 190 ----------
extensions/libipt_MASQUERADE.txlate | 9 +
extensions/libipt_SNAT.c | 280 ---------------
extensions/libipt_SNAT.t | 6 +
extensions/{libxt_DNAT.c => libxt_NAT.c} | 440 +++++++++++------------
extensions/libxt_REDIRECT.t | 1 +
extensions/libxt_REDIRECT.txlate | 3 +
12 files changed, 262 insertions(+), 1188 deletions(-)
delete mode 100644 extensions/libip6t_MASQUERADE.c
delete mode 100644 extensions/libip6t_SNAT.c
delete mode 100644 extensions/libipt_MASQUERADE.c
delete mode 100644 extensions/libipt_SNAT.c
rename extensions/{libxt_DNAT.c => libxt_NAT.c} (59%)
--
2.38.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [iptables PATCH 1/6] extensions: DNAT: Fix bad IP address error reporting
2022-11-03 1:41 [iptables PATCH 0/6] Merge NAT extensions Phil Sutter
@ 2022-11-03 1:41 ` Phil Sutter
2022-11-03 1:41 ` [iptables PATCH 2/6] extensions: *NAT: Drop NF_NAT_RANGE_PROTO_RANDOM* flag checks Phil Sutter
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Phil Sutter @ 2022-11-03 1:41 UTC (permalink / raw)
To: netfilter-devel
When introducing 'start' variable to cover for IPv6 addresses enclosed
in brackets, this single spot was missed.
Fixes: 14d77c8aa29a7 ("extensions: Merge IPv4 and IPv6 DNAT targets")
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
extensions/libxt_DNAT.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/extensions/libxt_DNAT.c b/extensions/libxt_DNAT.c
index 5696d31f2b0c5..7bfefc7961fac 100644
--- a/extensions/libxt_DNAT.c
+++ b/extensions/libxt_DNAT.c
@@ -197,7 +197,7 @@ parse_to(const char *orig_arg, bool portok,
if (!inet_pton(family, start, &range->min_addr))
xtables_error(PARAMETER_PROBLEM,
- "Bad IP address \"%s\"", arg);
+ "Bad IP address \"%s\"", start);
if (dash) {
if (!inet_pton(family, dash + 1, &range->max_addr))
xtables_error(PARAMETER_PROBLEM,
--
2.38.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [iptables PATCH 2/6] extensions: *NAT: Drop NF_NAT_RANGE_PROTO_RANDOM* flag checks
2022-11-03 1:41 [iptables PATCH 0/6] Merge NAT extensions Phil Sutter
2022-11-03 1:41 ` [iptables PATCH 1/6] extensions: DNAT: Fix bad IP address error reporting Phil Sutter
@ 2022-11-03 1:41 ` Phil Sutter
2022-11-03 1:41 ` [iptables PATCH 3/6] extensions: DNAT: Use __DNAT_xlate for REDIRECT, too Phil Sutter
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Phil Sutter @ 2022-11-03 1:41 UTC (permalink / raw)
To: netfilter-devel
SNAT, DNAT and REDIRECT extensions tried to prevent
NF_NAT_RANGE_PROTO_RANDOM flag from being set if no port or address was
also given.
With SNAT and DNAT, this is not possible as the respective
--to-destination or --to-source parameters are mandatory anyway.
Looking at the kernel code, doing so with REDIRECT seems harmless.
Moreover, nftables supports 'redirect random' without specifying a
port-range.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
extensions/libip6t_SNAT.c | 20 +++++---------------
extensions/libipt_SNAT.c | 16 ++++++----------
extensions/libxt_DNAT.c | 28 ++++------------------------
extensions/libxt_REDIRECT.t | 1 +
extensions/libxt_REDIRECT.txlate | 3 +++
5 files changed, 19 insertions(+), 49 deletions(-)
diff --git a/extensions/libip6t_SNAT.c b/extensions/libip6t_SNAT.c
index 4fe272b262a3d..8bf7b035f84b6 100644
--- a/extensions/libip6t_SNAT.c
+++ b/extensions/libip6t_SNAT.c
@@ -20,9 +20,6 @@ enum {
O_RANDOM,
O_RANDOM_FULLY,
O_PERSISTENT,
- F_TO_SRC = 1 << O_TO_SRC,
- F_RANDOM = 1 << O_RANDOM,
- F_RANDOM_FULLY = 1 << O_RANDOM_FULLY,
};
static void SNAT_help(void)
@@ -166,19 +163,13 @@ static void SNAT_parse(struct xt_option_call *cb)
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;
- static const unsigned int r = F_TO_SRC | F_RANDOM_FULLY;
- struct nf_nat_range *range = cb->data;
-
- if ((cb->xflags & f) == f)
+ case O_RANDOM:
range->flags |= NF_NAT_RANGE_PROTO_RANDOM;
- if ((cb->xflags & r) == r)
+ break;
+ case O_RANDOM_FULLY:
range->flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY;
+ break;
+ }
}
static void print_range(const struct nf_nat_range *range)
@@ -295,7 +286,6 @@ static struct xtables_target snat_tg_reg = {
.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,
diff --git a/extensions/libipt_SNAT.c b/extensions/libipt_SNAT.c
index 211a20bc45bfe..9c8cdb46a1585 100644
--- a/extensions/libipt_SNAT.c
+++ b/extensions/libipt_SNAT.c
@@ -13,9 +13,6 @@ enum {
O_RANDOM,
O_RANDOM_FULLY,
O_PERSISTENT,
- F_TO_SRC = 1 << O_TO_SRC,
- F_RANDOM = 1 << O_RANDOM,
- F_RANDOM_FULLY = 1 << O_RANDOM_FULLY,
};
static void SNAT_help(void)
@@ -141,20 +138,19 @@ static void SNAT_parse(struct xt_option_call *cb)
case O_PERSISTENT:
mr->range->flags |= NF_NAT_RANGE_PERSISTENT;
break;
+ case O_RANDOM:
+ mr->range->flags |= NF_NAT_RANGE_PROTO_RANDOM;
+ break;
+ case O_RANDOM_FULLY:
+ mr->range->flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY;
+ break;
}
}
static void SNAT_fcheck(struct xt_fcheck_call *cb)
{
- static const unsigned int f = F_TO_SRC | F_RANDOM;
- static const unsigned int r = F_TO_SRC | F_RANDOM_FULLY;
struct nf_nat_ipv4_multi_range_compat *mr = cb->data;
- if ((cb->xflags & f) == f)
- mr->range->flags |= NF_NAT_RANGE_PROTO_RANDOM;
- if ((cb->xflags & r) == r)
- mr->range->flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY;
-
mr->rangesize = 1;
}
diff --git a/extensions/libxt_DNAT.c b/extensions/libxt_DNAT.c
index 7bfefc7961fac..af44518798aef 100644
--- a/extensions/libxt_DNAT.c
+++ b/extensions/libxt_DNAT.c
@@ -31,9 +31,6 @@ enum {
O_TO_PORTS,
O_RANDOM,
O_PERSISTENT,
- F_TO_DEST = 1 << O_TO_DEST,
- F_TO_PORTS = 1 << O_TO_PORTS,
- F_RANDOM = 1 << O_RANDOM,
};
static void DNAT_help(void)
@@ -229,6 +226,9 @@ static void __DNAT_parse(struct xt_option_call *cb, __u16 proto,
case O_PERSISTENT:
range->flags |= NF_NAT_RANGE_PERSISTENT;
break;
+ case O_RANDOM:
+ range->flags |= NF_NAT_RANGE_PROTO_RANDOM;
+ break;
}
}
@@ -250,21 +250,12 @@ static void DNAT_parse(struct xt_option_call *cb)
mr->range->max = range.max_proto;
/* fall through */
case O_PERSISTENT:
+ case O_RANDOM:
mr->range->flags |= range.flags;
break;
}
}
-static void __DNAT_fcheck(struct xt_fcheck_call *cb, unsigned int *flags)
-{
- static const unsigned int redir_f = F_TO_PORTS | F_RANDOM;
- static const unsigned int dnat_f = F_TO_DEST | F_RANDOM;
-
- if ((cb->xflags & redir_f) == redir_f ||
- (cb->xflags & dnat_f) == dnat_f)
- *flags |= NF_NAT_RANGE_PROTO_RANDOM;
-}
-
static void DNAT_fcheck(struct xt_fcheck_call *cb)
{
struct nf_nat_ipv4_multi_range_compat *mr = cb->data;
@@ -274,8 +265,6 @@ static void DNAT_fcheck(struct xt_fcheck_call *cb)
if (mr->range[0].flags & NF_NAT_RANGE_PROTO_OFFSET)
xtables_error(PARAMETER_PROBLEM,
"Shifted portmap ranges not supported with this kernel");
-
- __DNAT_fcheck(cb, &mr->range[0].flags);
}
static char *sprint_range(const struct nf_nat_range2 *r, int family)
@@ -388,11 +377,6 @@ static void DNAT_parse_v2(struct xt_option_call *cb)
__DNAT_parse(cb, entry->ip.proto, cb->data, AF_INET);
}
-static void DNAT_fcheck_v2(struct xt_fcheck_call *cb)
-{
- __DNAT_fcheck(cb, &((struct nf_nat_range2 *)cb->data)->flags);
-}
-
static void DNAT_print_v2(const void *ip, const struct xt_entry_target *target,
int numeric)
{
@@ -428,8 +412,6 @@ static void DNAT_fcheck6(struct xt_fcheck_call *cb)
if (range->flags & NF_NAT_RANGE_PROTO_OFFSET)
xtables_error(PARAMETER_PROBLEM,
"Shifted portmap ranges not supported with this kernel");
-
- __DNAT_fcheck(cb, &range->flags);
}
static void DNAT_print6(const void *ip, const struct xt_entry_target *target,
@@ -619,7 +601,6 @@ static struct xtables_target dnat_tg_reg[] = {
.print = DNAT_print_v2,
.save = DNAT_save_v2,
.x6_parse = DNAT_parse_v2,
- .x6_fcheck = DNAT_fcheck_v2,
.x6_options = DNAT_opts,
.xlate = DNAT_xlate_v2,
},
@@ -634,7 +615,6 @@ static struct xtables_target dnat_tg_reg[] = {
.print = DNAT_print6_v2,
.save = DNAT_save6_v2,
.x6_parse = DNAT_parse6_v2,
- .x6_fcheck = DNAT_fcheck_v2,
.x6_options = DNAT_opts,
.xlate = DNAT_xlate6_v2,
},
diff --git a/extensions/libxt_REDIRECT.t b/extensions/libxt_REDIRECT.t
index f607dd0a12c51..362efa8428ed4 100644
--- a/extensions/libxt_REDIRECT.t
+++ b/extensions/libxt_REDIRECT.t
@@ -14,3 +14,4 @@
-p tcp -j REDIRECT --to-ports ftp-ssh;;FAIL
-p tcp -j REDIRECT --to-ports 10-ssh;;FAIL
-j REDIRECT --to-ports 42;;FAIL
+-j REDIRECT --random;=;OK
diff --git a/extensions/libxt_REDIRECT.txlate b/extensions/libxt_REDIRECT.txlate
index 2c536495b35a2..36419a46bb366 100644
--- a/extensions/libxt_REDIRECT.txlate
+++ b/extensions/libxt_REDIRECT.txlate
@@ -16,6 +16,9 @@ nft add rule ip nat prerouting tcp dport 80 counter redirect to :10-22
iptables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT --to-ports 8080 --random
nft add rule ip nat prerouting tcp dport 80 counter redirect to :8080 random
+iptables-translate -t nat -A prerouting -j REDIRECT --random
+nft add rule ip nat prerouting counter redirect random
+
ip6tables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT
nft add rule ip6 nat prerouting tcp dport 80 counter redirect
--
2.38.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [iptables PATCH 3/6] extensions: DNAT: Use __DNAT_xlate for REDIRECT, too
2022-11-03 1:41 [iptables PATCH 0/6] Merge NAT extensions Phil Sutter
2022-11-03 1:41 ` [iptables PATCH 1/6] extensions: DNAT: Fix bad IP address error reporting Phil Sutter
2022-11-03 1:41 ` [iptables PATCH 2/6] extensions: *NAT: Drop NF_NAT_RANGE_PROTO_RANDOM* flag checks Phil Sutter
@ 2022-11-03 1:41 ` Phil Sutter
2022-11-03 1:41 ` [iptables PATCH 4/6] extensions: DNAT: Generate print, save and xlate callbacks Phil Sutter
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Phil Sutter @ 2022-11-03 1:41 UTC (permalink / raw)
To: netfilter-devel
Make the common function a bit more versatile and give it a more
generic name, then use it for REDIRECT target, too.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
extensions/libxt_DNAT.c | 33 +++++++++++----------------------
1 file changed, 11 insertions(+), 22 deletions(-)
diff --git a/extensions/libxt_DNAT.c b/extensions/libxt_DNAT.c
index af44518798aef..9b94062512c09 100644
--- a/extensions/libxt_DNAT.c
+++ b/extensions/libxt_DNAT.c
@@ -338,7 +338,8 @@ static void DNAT_save(const void *ip, const struct xt_entry_target *target)
}
static int
-__DNAT_xlate(struct xt_xlate *xl, const struct nf_nat_range2 *r, int family)
+__NAT_xlate(struct xt_xlate *xl, const struct nf_nat_range2 *r,
+ int family, const char *tgt)
{
char *range_str = sprint_range(r, family);
const char *sep = " ";
@@ -347,7 +348,7 @@ __DNAT_xlate(struct xt_xlate *xl, const struct nf_nat_range2 *r, int family)
if (r->flags & NF_NAT_RANGE_PROTO_OFFSET)
return 0;
- xt_xlate_add(xl, "dnat");
+ xt_xlate_add(xl, tgt);
if (strlen(range_str))
xt_xlate_add(xl, " to %s", range_str);
if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) {
@@ -367,7 +368,7 @@ static int DNAT_xlate(struct xt_xlate *xl,
struct nf_nat_range2 range =
RANGE2_INIT_FROM_IPV4_MRC(params->target->data);
- return __DNAT_xlate(xl, &range, AF_INET);
+ return __NAT_xlate(xl, &range, AF_INET, "dnat");
}
static void DNAT_parse_v2(struct xt_option_call *cb)
@@ -391,7 +392,8 @@ static void DNAT_save_v2(const void *ip, const struct xt_entry_target *target)
static int DNAT_xlate_v2(struct xt_xlate *xl,
const struct xt_xlate_tg_params *params)
{
- return __DNAT_xlate(xl, (const void *)params->target->data, AF_INET);
+ return __NAT_xlate(xl, (const void *)params->target->data,
+ AF_INET, "dnat");
}
static void DNAT_parse6(struct xt_option_call *cb)
@@ -438,7 +440,7 @@ static int DNAT_xlate6(struct xt_xlate *xl,
memcpy(&range, (const void *)params->target->data,
sizeof(struct nf_nat_range));
- return __DNAT_xlate(xl, &range, AF_INET6);
+ return __NAT_xlate(xl, &range, AF_INET6, "dnat");
}
static void DNAT_parse6_v2(struct xt_option_call *cb)
@@ -462,21 +464,8 @@ static void DNAT_save6_v2(const void *ip, const struct xt_entry_target *target)
static int DNAT_xlate6_v2(struct xt_xlate *xl,
const struct xt_xlate_tg_params *params)
{
- return __DNAT_xlate(xl, (const void *)params->target->data, AF_INET6);
-}
-
-static int __REDIRECT_xlate(struct xt_xlate *xl,
- const struct nf_nat_range2 *range)
-{
- char *range_str = sprint_range(range, AF_INET);
-
- xt_xlate_add(xl, "redirect");
- if (strlen(range_str))
- xt_xlate_add(xl, " to %s", range_str);
- if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
- xt_xlate_add(xl, " random");
-
- return 1;
+ return __NAT_xlate(xl, (const void *)params->target->data,
+ AF_INET6, "dnat");
}
static void REDIRECT_print(const void *ip, const struct xt_entry_target *target,
@@ -500,7 +489,7 @@ static int REDIRECT_xlate(struct xt_xlate *xl,
struct nf_nat_range2 range =
RANGE2_INIT_FROM_IPV4_MRC(params->target->data);
- return __REDIRECT_xlate(xl, &range);
+ return __NAT_xlate(xl, &range, AF_INET, "redirect");
}
static void REDIRECT_print6(const void *ip, const struct xt_entry_target *target,
@@ -527,7 +516,7 @@ static int REDIRECT_xlate6(struct xt_xlate *xl,
memcpy(&range, (const void *)params->target->data,
sizeof(struct nf_nat_range));
- return __REDIRECT_xlate(xl, &range);
+ return __NAT_xlate(xl, &range, AF_INET6, "redirect");
}
static struct xtables_target dnat_tg_reg[] = {
--
2.38.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [iptables PATCH 4/6] extensions: DNAT: Generate print, save and xlate callbacks
2022-11-03 1:41 [iptables PATCH 0/6] Merge NAT extensions Phil Sutter
` (2 preceding siblings ...)
2022-11-03 1:41 ` [iptables PATCH 3/6] extensions: DNAT: Use __DNAT_xlate for REDIRECT, too Phil Sutter
@ 2022-11-03 1:41 ` Phil Sutter
2022-11-03 1:41 ` [iptables PATCH 5/6] extensions: DNAT: Rename some symbols Phil Sutter
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Phil Sutter @ 2022-11-03 1:41 UTC (permalink / raw)
To: netfilter-devel
Each extension's callbacks follow the same scheme so introduce a
generator which accepts the specifics as parameter - including the
method to transform from per-extension data into struct nf_nat_range2.
Also move the different parser frontends and fcheck callbacks in one
spot for clarity.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
extensions/libxt_DNAT.c | 266 +++++++++++++---------------------------
1 file changed, 86 insertions(+), 180 deletions(-)
diff --git a/extensions/libxt_DNAT.c b/extensions/libxt_DNAT.c
index 9b94062512c09..e53002541ee03 100644
--- a/extensions/libxt_DNAT.c
+++ b/extensions/libxt_DNAT.c
@@ -25,6 +25,14 @@
.min_proto = TO_IPV4_MRC(ptr)->range[0].min, \
.max_proto = TO_IPV4_MRC(ptr)->range[0].max, \
};
+#define TO_NF_NAT_RANGE(ptr) ((const struct nf_nat_range *)(ptr))
+#define RANGE2_INIT_FROM_RANGE(ptr) { \
+ .flags = TO_NF_NAT_RANGE(ptr)->flags, \
+ .min_addr = TO_NF_NAT_RANGE(ptr)->min_addr, \
+ .max_addr = TO_NF_NAT_RANGE(ptr)->max_addr, \
+ .min_proto = TO_NF_NAT_RANGE(ptr)->min_proto, \
+ .max_proto = TO_NF_NAT_RANGE(ptr)->max_proto, \
+};
enum {
O_TO_DEST = 0,
@@ -256,6 +264,30 @@ static void DNAT_parse(struct xt_option_call *cb)
}
}
+static void DNAT_parse6(struct xt_option_call *cb)
+{
+ struct nf_nat_range2 range = RANGE2_INIT_FROM_RANGE(cb->data);
+ struct nf_nat_range *range_v1 = (void *)cb->data;
+ const struct ip6t_entry *entry = cb->xt_entry;
+
+ __DNAT_parse(cb, entry->ipv6.proto, &range, AF_INET6);
+ memcpy(range_v1, &range, sizeof(*range_v1));
+}
+
+static void DNAT_parse_v2(struct xt_option_call *cb)
+{
+ const struct ipt_entry *entry = cb->xt_entry;
+
+ __DNAT_parse(cb, entry->ip.proto, cb->data, AF_INET);
+}
+
+static void DNAT_parse6_v2(struct xt_option_call *cb)
+{
+ const struct ip6t_entry *entry = cb->xt_entry;
+
+ __DNAT_parse(cb, entry->ipv6.proto, cb->data, AF_INET6);
+}
+
static void DNAT_fcheck(struct xt_fcheck_call *cb)
{
struct nf_nat_ipv4_multi_range_compat *mr = cb->data;
@@ -267,6 +299,15 @@ static void DNAT_fcheck(struct xt_fcheck_call *cb)
"Shifted portmap ranges not supported with this kernel");
}
+static void DNAT_fcheck6(struct xt_fcheck_call *cb)
+{
+ struct nf_nat_range *range = (void *)cb->data;
+
+ if (range->flags & NF_NAT_RANGE_PROTO_OFFSET)
+ xtables_error(PARAMETER_PROBLEM,
+ "Shifted portmap ranges not supported with this kernel");
+}
+
static char *sprint_range(const struct nf_nat_range2 *r, int family)
{
bool brackets = family == AF_INET6 &&
@@ -317,25 +358,6 @@ static void __NAT_print(const struct nf_nat_range2 *r, int family,
if (r->flags & NF_NAT_RANGE_PERSISTENT)
printf(" %spersistent", flag_pfx);
}
-#define __DNAT_print(r, family) __NAT_print(r, family, "to:", "", false)
-#define __DNAT_save(r, family) __NAT_print(r, family, "--to-destination ", "--", false)
-#define __REDIRECT_print(r) __NAT_print(r, AF_INET, "redir ports ", "", true)
-#define __REDIRECT_save(r) __NAT_print(r, AF_INET, "--to-ports ", "--", true)
-
-static void DNAT_print(const void *ip, const struct xt_entry_target *target,
- int numeric)
-{
- struct nf_nat_range2 range = RANGE2_INIT_FROM_IPV4_MRC(target->data);
-
- __DNAT_print(&range, AF_INET);
-}
-
-static void DNAT_save(const void *ip, const struct xt_entry_target *target)
-{
- struct nf_nat_range2 range = RANGE2_INIT_FROM_IPV4_MRC(target->data);
-
- __DNAT_save(&range, AF_INET);
-}
static int
__NAT_xlate(struct xt_xlate *xl, const struct nf_nat_range2 *r,
@@ -362,162 +384,46 @@ __NAT_xlate(struct xt_xlate *xl, const struct nf_nat_range2 *r,
return 1;
}
-static int DNAT_xlate(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- struct nf_nat_range2 range =
- RANGE2_INIT_FROM_IPV4_MRC(params->target->data);
-
- return __NAT_xlate(xl, &range, AF_INET, "dnat");
-}
-
-static void DNAT_parse_v2(struct xt_option_call *cb)
-{
- const struct ipt_entry *entry = cb->xt_entry;
-
- __DNAT_parse(cb, entry->ip.proto, cb->data, AF_INET);
-}
-
-static void DNAT_print_v2(const void *ip, const struct xt_entry_target *target,
- int numeric)
-{
- __DNAT_print((const void *)target->data, AF_INET);
-}
-
-static void DNAT_save_v2(const void *ip, const struct xt_entry_target *target)
-{
- __DNAT_save((const void *)target->data, AF_INET);
-}
-
-static int DNAT_xlate_v2(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- return __NAT_xlate(xl, (const void *)params->target->data,
- AF_INET, "dnat");
-}
-
-static void DNAT_parse6(struct xt_option_call *cb)
-{
- const struct ip6t_entry *entry = cb->xt_entry;
- struct nf_nat_range *range_v1 = (void *)cb->data;
- struct nf_nat_range2 range = {};
-
- memcpy(&range, range_v1, sizeof(*range_v1));
- __DNAT_parse(cb, entry->ipv6.proto, &range, AF_INET6);
- memcpy(range_v1, &range, sizeof(*range_v1));
-}
-
-static void DNAT_fcheck6(struct xt_fcheck_call *cb)
-{
- struct nf_nat_range *range = (void *)cb->data;
-
- if (range->flags & NF_NAT_RANGE_PROTO_OFFSET)
- xtables_error(PARAMETER_PROBLEM,
- "Shifted portmap ranges not supported with this kernel");
+#define PSX_GEN(name, converter, family, \
+ print_rangeopt, save_rangeopt, skip_colon, xlate) \
+static void name##_print(const void *ip, const struct xt_entry_target *target, \
+ int numeric) \
+{ \
+ struct nf_nat_range2 range = converter(target->data); \
+ \
+ __NAT_print(&range, family, print_rangeopt, "", skip_colon); \
+} \
+static void name##_save(const void *ip, const struct xt_entry_target *target) \
+{ \
+ struct nf_nat_range2 range = converter(target->data); \
+ \
+ __NAT_print(&range, family, save_rangeopt, "--", skip_colon); \
+} \
+static int name##_xlate(struct xt_xlate *xl, \
+ const struct xt_xlate_tg_params *params) \
+{ \
+ struct nf_nat_range2 range = converter(params->target->data); \
+ \
+ return __NAT_xlate(xl, &range, family, xlate); \
}
-static void DNAT_print6(const void *ip, const struct xt_entry_target *target,
- int numeric)
-{
- struct nf_nat_range2 range = {};
+PSX_GEN(DNAT, RANGE2_INIT_FROM_IPV4_MRC, \
+ AF_INET, "to:", "--to-destination ", false, "dnat")
- memcpy(&range, (const void *)target->data, sizeof(struct nf_nat_range));
- __DNAT_print(&range, AF_INET6);
-}
+PSX_GEN(DNATv2, *(struct nf_nat_range2 *), \
+ AF_INET, "to:", "--to-destination ", false, "dnat")
-static void DNAT_save6(const void *ip, const struct xt_entry_target *target)
-{
- struct nf_nat_range2 range = {};
-
- memcpy(&range, (const void *)target->data, sizeof(struct nf_nat_range));
- __DNAT_save(&range, AF_INET6);
-}
-
-static int DNAT_xlate6(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- struct nf_nat_range2 range = {};
-
- memcpy(&range, (const void *)params->target->data,
- sizeof(struct nf_nat_range));
- return __NAT_xlate(xl, &range, AF_INET6, "dnat");
-}
+PSX_GEN(DNAT6, RANGE2_INIT_FROM_RANGE, \
+ AF_INET6, "to:", "--to-destination ", false, "dnat")
-static void DNAT_parse6_v2(struct xt_option_call *cb)
-{
- const struct ip6t_entry *entry = cb->xt_entry;
-
- __DNAT_parse(cb, entry->ipv6.proto, cb->data, AF_INET6);
-}
+PSX_GEN(DNAT6v2, *(struct nf_nat_range2 *), \
+ AF_INET6, "to:", "--to-destination ", false, "dnat")
-static void DNAT_print6_v2(const void *ip, const struct xt_entry_target *target,
- int numeric)
-{
- __DNAT_print((const void *)target->data, AF_INET6);
-}
+PSX_GEN(REDIRECT, RANGE2_INIT_FROM_IPV4_MRC, \
+ AF_INET, "redir ports ", "--to-ports ", true, "redirect")
-static void DNAT_save6_v2(const void *ip, const struct xt_entry_target *target)
-{
- __DNAT_save((const void *)target->data, AF_INET6);
-}
-
-static int DNAT_xlate6_v2(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- return __NAT_xlate(xl, (const void *)params->target->data,
- AF_INET6, "dnat");
-}
-
-static void REDIRECT_print(const void *ip, const struct xt_entry_target *target,
- int numeric)
-{
- struct nf_nat_range2 range = RANGE2_INIT_FROM_IPV4_MRC(target->data);
-
- __REDIRECT_print(&range);
-}
-
-static void REDIRECT_save(const void *ip, const struct xt_entry_target *target)
-{
- struct nf_nat_range2 range = RANGE2_INIT_FROM_IPV4_MRC(target->data);
-
- __REDIRECT_save(&range);
-}
-
-static int REDIRECT_xlate(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- struct nf_nat_range2 range =
- RANGE2_INIT_FROM_IPV4_MRC(params->target->data);
-
- return __NAT_xlate(xl, &range, AF_INET, "redirect");
-}
-
-static void REDIRECT_print6(const void *ip, const struct xt_entry_target *target,
- int numeric)
-{
- struct nf_nat_range2 range = {};
-
- memcpy(&range, (const void *)target->data, sizeof(struct nf_nat_range));
- __REDIRECT_print(&range);
-}
-
-static void REDIRECT_save6(const void *ip, const struct xt_entry_target *target)
-{
- struct nf_nat_range2 range = {};
-
- memcpy(&range, (const void *)target->data, sizeof(struct nf_nat_range));
- __REDIRECT_save(&range);
-}
-
-static int REDIRECT_xlate6(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- struct nf_nat_range2 range = {};
-
- memcpy(&range, (const void *)params->target->data,
- sizeof(struct nf_nat_range));
- return __NAT_xlate(xl, &range, AF_INET6, "redirect");
-}
+PSX_GEN(REDIRECT6, RANGE2_INIT_FROM_RANGE, \
+ AF_INET6, "redir ports ", "--to-ports ", true, "redirect")
static struct xtables_target dnat_tg_reg[] = {
{
@@ -558,12 +464,12 @@ static struct xtables_target dnat_tg_reg[] = {
.size = XT_ALIGN(sizeof(struct nf_nat_range)),
.userspacesize = XT_ALIGN(sizeof(struct nf_nat_range)),
.help = DNAT_help,
- .print = DNAT_print6,
- .save = DNAT_save6,
+ .print = DNAT6_print,
+ .save = DNAT6_save,
.x6_parse = DNAT_parse6,
.x6_fcheck = DNAT_fcheck6,
.x6_options = DNAT_opts,
- .xlate = DNAT_xlate6,
+ .xlate = DNAT6_xlate,
},
{
.name = "REDIRECT",
@@ -572,12 +478,12 @@ static struct xtables_target dnat_tg_reg[] = {
.size = XT_ALIGN(sizeof(struct nf_nat_range)),
.userspacesize = XT_ALIGN(sizeof(struct nf_nat_range)),
.help = REDIRECT_help,
- .print = REDIRECT_print6,
- .save = REDIRECT_save6,
+ .print = REDIRECT6_print,
+ .save = REDIRECT6_save,
.x6_parse = DNAT_parse6,
.x6_fcheck = DNAT_fcheck6,
.x6_options = REDIRECT_opts,
- .xlate = REDIRECT_xlate6,
+ .xlate = REDIRECT6_xlate,
},
{
.name = "DNAT",
@@ -587,11 +493,11 @@ static struct xtables_target dnat_tg_reg[] = {
.size = XT_ALIGN(sizeof(struct nf_nat_range2)),
.userspacesize = XT_ALIGN(sizeof(struct nf_nat_range2)),
.help = DNAT_help_v2,
- .print = DNAT_print_v2,
- .save = DNAT_save_v2,
+ .print = DNATv2_print,
+ .save = DNATv2_save,
.x6_parse = DNAT_parse_v2,
.x6_options = DNAT_opts,
- .xlate = DNAT_xlate_v2,
+ .xlate = DNATv2_xlate,
},
{
.name = "DNAT",
@@ -601,11 +507,11 @@ static struct xtables_target dnat_tg_reg[] = {
.size = XT_ALIGN(sizeof(struct nf_nat_range2)),
.userspacesize = XT_ALIGN(sizeof(struct nf_nat_range2)),
.help = DNAT_help_v2,
- .print = DNAT_print6_v2,
- .save = DNAT_save6_v2,
+ .print = DNAT6v2_print,
+ .save = DNAT6v2_save,
.x6_parse = DNAT_parse6_v2,
.x6_options = DNAT_opts,
- .xlate = DNAT_xlate6_v2,
+ .xlate = DNAT6v2_xlate,
},
};
--
2.38.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [iptables PATCH 5/6] extensions: DNAT: Rename some symbols
2022-11-03 1:41 [iptables PATCH 0/6] Merge NAT extensions Phil Sutter
` (3 preceding siblings ...)
2022-11-03 1:41 ` [iptables PATCH 4/6] extensions: DNAT: Generate print, save and xlate callbacks Phil Sutter
@ 2022-11-03 1:41 ` Phil Sutter
2022-11-03 1:41 ` [iptables PATCH 6/6] extensions: Merge SNAT, DNAT, REDIRECT and MASQUERADE Phil Sutter
2022-11-11 18:16 ` [iptables PATCH 0/6] Merge NAT extensions Phil Sutter
6 siblings, 0 replies; 8+ messages in thread
From: Phil Sutter @ 2022-11-03 1:41 UTC (permalink / raw)
To: netfilter-devel
No functional change intended, just a more generic name for some symbols
which won't be DNAT-specific soon.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
extensions/libxt_DNAT.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/extensions/libxt_DNAT.c b/extensions/libxt_DNAT.c
index e53002541ee03..fbb10e410a221 100644
--- a/extensions/libxt_DNAT.c
+++ b/extensions/libxt_DNAT.c
@@ -214,8 +214,8 @@ parse_to(const char *orig_arg, bool portok,
return;
}
-static void __DNAT_parse(struct xt_option_call *cb, __u16 proto,
- struct nf_nat_range2 *range, int family)
+static void __NAT_parse(struct xt_option_call *cb, __u16 proto,
+ struct nf_nat_range2 *range, int family)
{
bool portok = proto == IPPROTO_TCP ||
proto == IPPROTO_UDP ||
@@ -240,13 +240,13 @@ static void __DNAT_parse(struct xt_option_call *cb, __u16 proto,
}
}
-static void DNAT_parse(struct xt_option_call *cb)
+static void NAT_parse(struct xt_option_call *cb)
{
struct nf_nat_ipv4_multi_range_compat *mr = (void *)cb->data;
const struct ipt_entry *entry = cb->xt_entry;
struct nf_nat_range2 range = {};
- __DNAT_parse(cb, entry->ip.proto, &range, AF_INET);
+ __NAT_parse(cb, entry->ip.proto, &range, AF_INET);
switch (cb->entry->id) {
case O_TO_DEST:
@@ -264,13 +264,13 @@ static void DNAT_parse(struct xt_option_call *cb)
}
}
-static void DNAT_parse6(struct xt_option_call *cb)
+static void NAT_parse6(struct xt_option_call *cb)
{
struct nf_nat_range2 range = RANGE2_INIT_FROM_RANGE(cb->data);
struct nf_nat_range *range_v1 = (void *)cb->data;
const struct ip6t_entry *entry = cb->xt_entry;
- __DNAT_parse(cb, entry->ipv6.proto, &range, AF_INET6);
+ __NAT_parse(cb, entry->ipv6.proto, &range, AF_INET6);
memcpy(range_v1, &range, sizeof(*range_v1));
}
@@ -278,14 +278,14 @@ static void DNAT_parse_v2(struct xt_option_call *cb)
{
const struct ipt_entry *entry = cb->xt_entry;
- __DNAT_parse(cb, entry->ip.proto, cb->data, AF_INET);
+ __NAT_parse(cb, entry->ip.proto, cb->data, AF_INET);
}
static void DNAT_parse6_v2(struct xt_option_call *cb)
{
const struct ip6t_entry *entry = cb->xt_entry;
- __DNAT_parse(cb, entry->ipv6.proto, cb->data, AF_INET6);
+ __NAT_parse(cb, entry->ipv6.proto, cb->data, AF_INET6);
}
static void DNAT_fcheck(struct xt_fcheck_call *cb)
@@ -425,7 +425,7 @@ PSX_GEN(REDIRECT, RANGE2_INIT_FROM_IPV4_MRC, \
PSX_GEN(REDIRECT6, RANGE2_INIT_FROM_RANGE, \
AF_INET6, "redir ports ", "--to-ports ", true, "redirect")
-static struct xtables_target dnat_tg_reg[] = {
+static struct xtables_target nat_tg_reg[] = {
{
.name = "DNAT",
.version = XTABLES_VERSION,
@@ -436,7 +436,7 @@ static struct xtables_target dnat_tg_reg[] = {
.help = DNAT_help,
.print = DNAT_print,
.save = DNAT_save,
- .x6_parse = DNAT_parse,
+ .x6_parse = NAT_parse,
.x6_fcheck = DNAT_fcheck,
.x6_options = DNAT_opts,
.xlate = DNAT_xlate,
@@ -451,7 +451,7 @@ static struct xtables_target dnat_tg_reg[] = {
.help = REDIRECT_help,
.print = REDIRECT_print,
.save = REDIRECT_save,
- .x6_parse = DNAT_parse,
+ .x6_parse = NAT_parse,
.x6_fcheck = DNAT_fcheck,
.x6_options = REDIRECT_opts,
.xlate = REDIRECT_xlate,
@@ -466,7 +466,7 @@ static struct xtables_target dnat_tg_reg[] = {
.help = DNAT_help,
.print = DNAT6_print,
.save = DNAT6_save,
- .x6_parse = DNAT_parse6,
+ .x6_parse = NAT_parse6,
.x6_fcheck = DNAT_fcheck6,
.x6_options = DNAT_opts,
.xlate = DNAT6_xlate,
@@ -480,7 +480,7 @@ static struct xtables_target dnat_tg_reg[] = {
.help = REDIRECT_help,
.print = REDIRECT6_print,
.save = REDIRECT6_save,
- .x6_parse = DNAT_parse6,
+ .x6_parse = NAT_parse6,
.x6_fcheck = DNAT_fcheck6,
.x6_options = REDIRECT_opts,
.xlate = REDIRECT6_xlate,
@@ -517,5 +517,5 @@ static struct xtables_target dnat_tg_reg[] = {
void _init(void)
{
- xtables_register_targets(dnat_tg_reg, ARRAY_SIZE(dnat_tg_reg));
+ xtables_register_targets(nat_tg_reg, ARRAY_SIZE(nat_tg_reg));
}
--
2.38.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [iptables PATCH 6/6] extensions: Merge SNAT, DNAT, REDIRECT and MASQUERADE
2022-11-03 1:41 [iptables PATCH 0/6] Merge NAT extensions Phil Sutter
` (4 preceding siblings ...)
2022-11-03 1:41 ` [iptables PATCH 5/6] extensions: DNAT: Rename some symbols Phil Sutter
@ 2022-11-03 1:41 ` Phil Sutter
2022-11-11 18:16 ` [iptables PATCH 0/6] Merge NAT extensions Phil Sutter
6 siblings, 0 replies; 8+ messages in thread
From: Phil Sutter @ 2022-11-03 1:41 UTC (permalink / raw)
To: netfilter-devel
REDIRECT was already merged into DNAT. Given the callback generator and
generalized inner parsing routines, merging the other "flavors" is
relatively simple. Rename the extension into "libxt_NAT.so" while doing
so and turn the old DSOs into symlinks.
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
extensions/GNUmakefile.in | 10 +-
extensions/libip6t_MASQUERADE.c | 188 --------------
extensions/libip6t_MASQUERADE.txlate | 9 +
extensions/libip6t_SNAT.c | 298 -----------------------
extensions/libip6t_SNAT.t | 6 +
extensions/libipt_MASQUERADE.c | 190 ---------------
extensions/libipt_MASQUERADE.txlate | 9 +
extensions/libipt_SNAT.c | 276 ---------------------
extensions/libipt_SNAT.t | 6 +
extensions/{libxt_DNAT.c => libxt_NAT.c} | 125 ++++++++++
10 files changed, 163 insertions(+), 954 deletions(-)
delete mode 100644 extensions/libip6t_MASQUERADE.c
delete mode 100644 extensions/libip6t_SNAT.c
delete mode 100644 extensions/libipt_MASQUERADE.c
delete mode 100644 extensions/libipt_SNAT.c
rename extensions/{libxt_DNAT.c => libxt_NAT.c} (80%)
diff --git a/extensions/GNUmakefile.in b/extensions/GNUmakefile.in
index 3c68f8decd13f..0239a06a90cd1 100644
--- a/extensions/GNUmakefile.in
+++ b/extensions/GNUmakefile.in
@@ -42,7 +42,7 @@ endif
pfx_build_mod := $(patsubst ${srcdir}/libxt_%.c,%,$(sort $(wildcard ${srcdir}/libxt_*.c)))
@ENABLE_NFTABLES_TRUE@ pfb_build_mod := $(patsubst ${srcdir}/libebt_%.c,%,$(sort $(wildcard ${srcdir}/libebt_*.c)))
@ENABLE_NFTABLES_TRUE@ pfa_build_mod := $(patsubst ${srcdir}/libarpt_%.c,%,$(sort $(wildcard ${srcdir}/libarpt_*.c)))
-pfx_symlinks := NOTRACK state REDIRECT
+pfx_symlinks := NOTRACK state REDIRECT MASQUERADE SNAT DNAT
@ENABLE_IPV4_TRUE@ pf4_build_mod := $(patsubst ${srcdir}/libipt_%.c,%,$(sort $(wildcard ${srcdir}/libipt_*.c)))
@ENABLE_IPV6_TRUE@ pf6_build_mod := $(patsubst ${srcdir}/libip6t_%.c,%,$(sort $(wildcard ${srcdir}/libip6t_*.c)))
pfx_build_mod := $(filter-out @blacklist_modules@ @blacklist_x_modules@,${pfx_build_mod})
@@ -130,7 +130,13 @@ libxt_NOTRACK.so: libxt_CT.so
ln -fs $< $@
libxt_state.so: libxt_conntrack.so
ln -fs $< $@
-libxt_REDIRECT.so: libxt_DNAT.so
+libxt_REDIRECT.so: libxt_NAT.so
+ ln -fs $< $@
+libxt_MASQUERADE.so: libxt_NAT.so
+ ln -fs $< $@
+libxt_SNAT.so: libxt_NAT.so
+ ln -fs $< $@
+libxt_DNAT.so: libxt_NAT.so
ln -fs $< $@
# Need the LIBADDs in iptables/Makefile.am too for libxtables_la_LIBADD
diff --git a/extensions/libip6t_MASQUERADE.c b/extensions/libip6t_MASQUERADE.c
deleted file mode 100644
index f28f071b047e1..0000000000000
--- a/extensions/libip6t_MASQUERADE.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * 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,
- O_RANDOM_FULLY,
-};
-
-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"
-" --random-fully\n"
-" Fully 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},
- {.name = "random-fully", .id = O_RANDOM_FULLY, .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;
- case O_RANDOM_FULLY:
- r->flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY;
- 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");
-
- if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
- printf(" random-fully");
-}
-
-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");
-
- if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
- printf(" --random-fully");
-}
-
-static int MASQUERADE_xlate(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- const struct nf_nat_range *r = (const void *)params->target->data;
-
- xt_xlate_add(xl, "masquerade");
-
- if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
- xt_xlate_add(xl, " to :%hu", ntohs(r->min_proto.tcp.port));
- if (r->max_proto.tcp.port != r->min_proto.tcp.port)
- xt_xlate_add(xl, "-%hu", ntohs(r->max_proto.tcp.port));
- }
-
- xt_xlate_add(xl, " ");
- if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
- xt_xlate_add(xl, "random ");
-
- xt_xlate_add(xl, " ");
- if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
- xt_xlate_add(xl, "fully-random ");
-
- return 1;
-}
-
-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,
- .xlate = MASQUERADE_xlate,
-};
-
-void _init(void)
-{
- xtables_register_target(&masquerade_tg_reg);
-}
diff --git a/extensions/libip6t_MASQUERADE.txlate b/extensions/libip6t_MASQUERADE.txlate
index 6c289c2bdaee3..a2f9808036ebf 100644
--- a/extensions/libip6t_MASQUERADE.txlate
+++ b/extensions/libip6t_MASQUERADE.txlate
@@ -6,3 +6,12 @@ nft add rule ip6 nat POSTROUTING meta l4proto tcp counter masquerade to :10
ip6tables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --to-ports 10-20 --random
nft add rule ip6 nat POSTROUTING meta l4proto tcp counter masquerade to :10-20 random
+
+ip6tables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --random
+nft add rule ip6 nat POSTROUTING meta l4proto tcp counter masquerade random
+
+ip6tables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --random-fully
+nft add rule ip6 nat POSTROUTING meta l4proto tcp counter masquerade fully-random
+
+ip6tables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --random --random-fully
+nft add rule ip6 nat POSTROUTING meta l4proto tcp counter masquerade random,fully-random
diff --git a/extensions/libip6t_SNAT.c b/extensions/libip6t_SNAT.c
deleted file mode 100644
index 8bf7b035f84b6..0000000000000
--- a/extensions/libip6t_SNAT.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * 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_RANDOM_FULLY,
- O_PERSISTENT,
-};
-
-static void SNAT_help(void)
-{
- printf(
-"SNAT target options:\n"
-" --to-source [<ipaddr>[-<ipaddr>]][:port[-port]]\n"
-" Address to map source to.\n"
-"[--random] [--random-fully] [--persistent]\n");
-}
-
-static const struct xt_option_entry SNAT_opts[] = {
- {.name = "to-source", .id = O_TO_SRC, .type = XTTYPE_STRING,
- .flags = XTOPT_MAND},
- {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
- {.name = "random-fully", .id = O_RANDOM_FULLY, .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 = xtables_strdup(orig_arg);
-
- start = strchr(arg, '[');
- if (start == NULL) {
- start = arg;
- /* Lets assume one colon is port information. Otherwise its an IPv6 address */
- colon = strchr(arg, ':');
- if (colon && strchr(colon+1, ':'))
- colon = NULL;
- }
- 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 colon or [] colon? No IP info...*/
- if (colon == arg || colon == arg+2) {
- 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:
- parse_to(cb->arg, portok, range);
- break;
- case O_PERSISTENT:
- range->flags |= NF_NAT_RANGE_PERSISTENT;
- break;
- case O_RANDOM:
- range->flags |= NF_NAT_RANGE_PROTO_RANDOM;
- break;
- case O_RANDOM_FULLY:
- range->flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY;
- break;
- }
-}
-
-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_PROTO_RANDOM_FULLY)
- printf(" random-fully");
- 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_PROTO_RANDOM_FULLY)
- printf(" --random-fully");
- if (range->flags & NF_NAT_RANGE_PERSISTENT)
- printf(" --persistent");
-}
-
-static void print_range_xlate(const struct nf_nat_range *range,
- struct xt_xlate *xl)
-{
- bool proto_specified = range->flags & NF_NAT_RANGE_PROTO_SPECIFIED;
-
- if (range->flags & NF_NAT_RANGE_MAP_IPS) {
- xt_xlate_add(xl, "%s%s%s",
- proto_specified ? "[" : "",
- xtables_ip6addr_to_numeric(&range->min_addr.in6),
- proto_specified ? "]" : "");
-
- if (memcmp(&range->min_addr, &range->max_addr,
- sizeof(range->min_addr))) {
- xt_xlate_add(xl, "-%s%s%s",
- proto_specified ? "[" : "",
- xtables_ip6addr_to_numeric(&range->max_addr.in6),
- proto_specified ? "]" : "");
- }
- }
- if (proto_specified) {
- xt_xlate_add(xl, ":%hu", ntohs(range->min_proto.tcp.port));
-
- if (range->max_proto.tcp.port != range->min_proto.tcp.port)
- xt_xlate_add(xl, "-%hu",
- ntohs(range->max_proto.tcp.port));
- }
-}
-
-static int SNAT_xlate(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- const struct nf_nat_range *range = (const void *)params->target->data;
- bool sep_need = false;
- const char *sep = " ";
-
- xt_xlate_add(xl, "snat to ");
- print_range_xlate(range, xl);
- if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) {
- xt_xlate_add(xl, " random");
- sep_need = true;
- }
- if (range->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) {
- if (sep_need)
- sep = ",";
- xt_xlate_add(xl, "%sfully-random", sep);
- sep_need = true;
- }
- if (range->flags & NF_NAT_RANGE_PERSISTENT) {
- if (sep_need)
- sep = ",";
- xt_xlate_add(xl, "%spersistent", sep);
- }
-
- return 1;
-}
-
-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,
- .print = SNAT_print,
- .save = SNAT_save,
- .x6_options = SNAT_opts,
- .xlate = SNAT_xlate,
-};
-
-void _init(void)
-{
- xtables_register_target(&snat_tg_reg);
-}
diff --git a/extensions/libip6t_SNAT.t b/extensions/libip6t_SNAT.t
index d188a6bb3d559..98aa7602e784f 100644
--- a/extensions/libip6t_SNAT.t
+++ b/extensions/libip6t_SNAT.t
@@ -4,6 +4,12 @@
-j SNAT --to-source dead::beef-dead::fee7;=;OK
-j SNAT --to-source [dead::beef]:1025-65535;;FAIL
-j SNAT --to-source [dead::beef] --to-source [dead::fee7];;FAIL
+-j SNAT --to-source dead::beef --random;=;OK
+-j SNAT --to-source dead::beef --random-fully;=;OK
+-j SNAT --to-source dead::beef --persistent;=;OK
+-j SNAT --to-source dead::beef --random --persistent;=;OK
+-j SNAT --to-source dead::beef --random --random-fully;=;OK
+-j SNAT --to-source dead::beef --random --random-fully --persistent;=;OK
-p tcp -j SNAT --to-source [dead::beef]:1025-65535;=;OK
-p tcp -j SNAT --to-source [dead::beef-dead::fee7]:1025-65535;=;OK
-p tcp -j SNAT --to-source [dead::beef-dead::fee7]:1025-65536;;FAIL
diff --git a/extensions/libipt_MASQUERADE.c b/extensions/libipt_MASQUERADE.c
deleted file mode 100644
index 90bf60659c4f4..0000000000000
--- a/extensions/libipt_MASQUERADE.c
+++ /dev/null
@@ -1,190 +0,0 @@
-#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_ipv4/ip_tables.h>
-#include <linux/netfilter/nf_nat.h>
-
-enum {
- O_TO_PORTS = 0,
- O_RANDOM,
- O_RANDOM_FULLY,
-};
-
-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"
-" --random-fully\n"
-" Fully 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},
- {.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE},
- XTOPT_TABLEEND,
-};
-
-static void MASQUERADE_init(struct xt_entry_target *t)
-{
- 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;
-}
-
-/* Parses ports */
-static void
-parse_ports(const char *arg, struct nf_nat_ipv4_multi_range_compat *mr)
-{
- char *end;
- unsigned int port, maxport;
-
- 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);
-
- switch (*end) {
- case '\0':
- mr->range[0].min.tcp.port
- = mr->range[0].max.tcp.port
- = htons(port);
- return;
- case '-':
- if (!xtables_strtoui(end + 1, NULL, &maxport, 0, UINT16_MAX))
- break;
-
- if (maxport < port)
- break;
-
- mr->range[0].min.tcp.port = htons(port);
- mr->range[0].max.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 ipt_entry *entry = cb->xt_entry;
- int portok;
- struct nf_nat_ipv4_multi_range_compat *mr = cb->data;
-
- if (entry->ip.proto == IPPROTO_TCP
- || entry->ip.proto == IPPROTO_UDP
- || entry->ip.proto == IPPROTO_SCTP
- || entry->ip.proto == IPPROTO_DCCP
- || entry->ip.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, mr);
- break;
- case O_RANDOM:
- mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM;
- break;
- case O_RANDOM_FULLY:
- mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY;
- break;
- }
-}
-
-static void
-MASQUERADE_print(const void *ip, const struct xt_entry_target *target,
- int numeric)
-{
- 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 & 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 & NF_NAT_RANGE_PROTO_RANDOM)
- printf(" random");
-
- if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
- printf(" random-fully");
-}
-
-static void
-MASQUERADE_save(const void *ip, const struct xt_entry_target *target)
-{
- 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 & 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 & NF_NAT_RANGE_PROTO_RANDOM)
- printf(" --random");
-
- if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
- printf(" --random-fully");
-}
-
-static int MASQUERADE_xlate(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- const struct nf_nat_ipv4_multi_range_compat *mr =
- (const void *)params->target->data;
- const struct nf_nat_ipv4_range *r = &mr->range[0];
-
- xt_xlate_add(xl, "masquerade");
-
- if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
- xt_xlate_add(xl, " to :%hu", ntohs(r->min.tcp.port));
- if (r->max.tcp.port != r->min.tcp.port)
- xt_xlate_add(xl, "-%hu", ntohs(r->max.tcp.port));
- }
-
- xt_xlate_add(xl, " ");
- if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
- xt_xlate_add(xl, "random ");
-
- return 1;
-}
-
-static struct xtables_target masquerade_tg_reg = {
- .name = "MASQUERADE",
- .version = XTABLES_VERSION,
- .family = NFPROTO_IPV4,
- .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,
- .print = MASQUERADE_print,
- .save = MASQUERADE_save,
- .x6_options = MASQUERADE_opts,
- .xlate = MASQUERADE_xlate,
-};
-
-void _init(void)
-{
- xtables_register_target(&masquerade_tg_reg);
-}
diff --git a/extensions/libipt_MASQUERADE.txlate b/extensions/libipt_MASQUERADE.txlate
index 40b6958a55cad..49f79d33dcfa8 100644
--- a/extensions/libipt_MASQUERADE.txlate
+++ b/extensions/libipt_MASQUERADE.txlate
@@ -6,3 +6,12 @@ nft add rule ip nat POSTROUTING ip protocol tcp counter masquerade to :10
iptables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --to-ports 10-20 --random
nft add rule ip nat POSTROUTING ip protocol tcp counter masquerade to :10-20 random
+
+iptables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --random
+nft add rule ip nat POSTROUTING ip protocol tcp counter masquerade random
+
+iptables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --random-fully
+nft add rule ip nat POSTROUTING ip protocol tcp counter masquerade fully-random
+
+iptables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --random --random-fully
+nft add rule ip nat POSTROUTING ip protocol tcp counter masquerade random,fully-random
diff --git a/extensions/libipt_SNAT.c b/extensions/libipt_SNAT.c
deleted file mode 100644
index 9c8cdb46a1585..0000000000000
--- a/extensions/libipt_SNAT.c
+++ /dev/null
@@ -1,276 +0,0 @@
-#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_ipv4/ip_tables.h>
-#include <linux/netfilter/nf_nat.h>
-
-enum {
- O_TO_SRC = 0,
- O_RANDOM,
- O_RANDOM_FULLY,
- O_PERSISTENT,
-};
-
-static void SNAT_help(void)
-{
- printf(
-"SNAT target options:\n"
-" --to-source [<ipaddr>[-<ipaddr>]][:port[-port]]\n"
-" Address to map source to.\n"
-"[--random] [--random-fully] [--persistent]\n");
-}
-
-static const struct xt_option_entry SNAT_opts[] = {
- {.name = "to-source", .id = O_TO_SRC, .type = XTTYPE_STRING,
- .flags = XTOPT_MAND},
- {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
- {.name = "random-fully", .id = O_RANDOM_FULLY, .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_ipv4_range *range)
-{
- char *arg, *colon, *dash, *error;
- const struct in_addr *ip;
-
- arg = xtables_strdup(orig_arg);
- colon = strchr(arg, ':');
-
- 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.tcp.port
- = range->max.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.tcp.port = htons(port);
- range->max.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(arg, '-');
- if (colon && dash && dash > colon)
- dash = NULL;
-
- if (dash)
- *dash = '\0';
-
- ip = xtables_numeric_to_ipaddr(arg);
- if (!ip)
- xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
- arg);
- range->min_ip = ip->s_addr;
- if (dash) {
- ip = xtables_numeric_to_ipaddr(dash+1);
- if (!ip)
- xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
- dash+1);
- range->max_ip = ip->s_addr;
- } else
- range->max_ip = range->min_ip;
-
- free(arg);
- return;
-}
-
-static void SNAT_parse(struct xt_option_call *cb)
-{
- struct nf_nat_ipv4_multi_range_compat *mr = cb->data;
- const struct ipt_entry *entry = cb->xt_entry;
- int portok;
-
- if (entry->ip.proto == IPPROTO_TCP
- || entry->ip.proto == IPPROTO_UDP
- || entry->ip.proto == IPPROTO_SCTP
- || entry->ip.proto == IPPROTO_DCCP
- || entry->ip.proto == IPPROTO_ICMP)
- portok = 1;
- else
- portok = 0;
-
- xtables_option_parse(cb);
- switch (cb->entry->id) {
- case O_TO_SRC:
- parse_to(cb->arg, portok, mr->range);
- break;
- case O_PERSISTENT:
- mr->range->flags |= NF_NAT_RANGE_PERSISTENT;
- break;
- case O_RANDOM:
- mr->range->flags |= NF_NAT_RANGE_PROTO_RANDOM;
- break;
- case O_RANDOM_FULLY:
- mr->range->flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY;
- break;
- }
-}
-
-static void SNAT_fcheck(struct xt_fcheck_call *cb)
-{
- struct nf_nat_ipv4_multi_range_compat *mr = cb->data;
-
- mr->rangesize = 1;
-}
-
-static void print_range(const struct nf_nat_ipv4_range *r)
-{
- if (r->flags & NF_NAT_RANGE_MAP_IPS) {
- struct in_addr a;
-
- a.s_addr = r->min_ip;
- printf("%s", xtables_ipaddr_to_numeric(&a));
- if (r->max_ip != r->min_ip) {
- a.s_addr = r->max_ip;
- printf("-%s", xtables_ipaddr_to_numeric(&a));
- }
- }
- 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)
- printf("-%hu", ntohs(r->max.tcp.port));
- }
-}
-
-static void SNAT_print(const void *ip, const struct xt_entry_target *target,
- int numeric)
-{
- const struct nf_nat_ipv4_multi_range_compat *mr =
- (const void *)target->data;
-
- printf(" to:");
- print_range(mr->range);
- if (mr->range->flags & NF_NAT_RANGE_PROTO_RANDOM)
- printf(" random");
- if (mr->range->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
- printf(" random-fully");
- if (mr->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_ipv4_multi_range_compat *mr =
- (const void *)target->data;
-
- printf(" --to-source ");
- print_range(mr->range);
- if (mr->range->flags & NF_NAT_RANGE_PROTO_RANDOM)
- printf(" --random");
- if (mr->range->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
- printf(" --random-fully");
- if (mr->range->flags & NF_NAT_RANGE_PERSISTENT)
- printf(" --persistent");
-}
-
-static void print_range_xlate(const struct nf_nat_ipv4_range *r,
- struct xt_xlate *xl)
-{
- if (r->flags & NF_NAT_RANGE_MAP_IPS) {
- struct in_addr a;
-
- a.s_addr = r->min_ip;
- xt_xlate_add(xl, "%s", xtables_ipaddr_to_numeric(&a));
- if (r->max_ip != r->min_ip) {
- a.s_addr = r->max_ip;
- xt_xlate_add(xl, "-%s", xtables_ipaddr_to_numeric(&a));
- }
- }
- if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
- xt_xlate_add(xl, ":");
- xt_xlate_add(xl, "%hu", ntohs(r->min.tcp.port));
- if (r->max.tcp.port != r->min.tcp.port)
- xt_xlate_add(xl, "-%hu", ntohs(r->max.tcp.port));
- }
-}
-
-static int SNAT_xlate(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- const struct nf_nat_ipv4_multi_range_compat *mr =
- (const void *)params->target->data;
- bool sep_need = false;
- const char *sep = " ";
-
- xt_xlate_add(xl, "snat to ");
- print_range_xlate(mr->range, xl);
- if (mr->range->flags & NF_NAT_RANGE_PROTO_RANDOM) {
- xt_xlate_add(xl, " random");
- sep_need = true;
- }
- if (mr->range->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) {
- if (sep_need)
- sep = ",";
- xt_xlate_add(xl, "%sfully-random", sep);
- sep_need = true;
- }
- if (mr->range->flags & NF_NAT_RANGE_PERSISTENT) {
- if (sep_need)
- sep = ",";
- xt_xlate_add(xl, "%spersistent", sep);
- }
-
- return 1;
-}
-
-static struct xtables_target snat_tg_reg = {
- .name = "SNAT",
- .version = XTABLES_VERSION,
- .family = NFPROTO_IPV4,
- .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,
- .print = SNAT_print,
- .save = SNAT_save,
- .x6_options = SNAT_opts,
- .xlate = SNAT_xlate,
-};
-
-void _init(void)
-{
- xtables_register_target(&snat_tg_reg);
-}
diff --git a/extensions/libipt_SNAT.t b/extensions/libipt_SNAT.t
index 186e1cb82c3f3..c31d6e7c2cce8 100644
--- a/extensions/libipt_SNAT.t
+++ b/extensions/libipt_SNAT.t
@@ -4,6 +4,12 @@
-j SNAT --to-source 1.1.1.1-1.1.1.10;=;OK
-j SNAT --to-source 1.1.1.1:1025-65535;;FAIL
-j SNAT --to-source 1.1.1.1 --to-source 2.2.2.2;;FAIL
+-j SNAT --to-source 1.1.1.1 --random;=;OK
+-j SNAT --to-source 1.1.1.1 --random-fully;=;OK
+-j SNAT --to-source 1.1.1.1 --persistent;=;OK
+-j SNAT --to-source 1.1.1.1 --random --persistent;=;OK
+-j SNAT --to-source 1.1.1.1 --random --random-fully;=;OK
+-j SNAT --to-source 1.1.1.1 --random --random-fully --persistent;=;OK
-p tcp -j SNAT --to-source 1.1.1.1:1025-65535;=;OK
-p tcp -j SNAT --to-source 1.1.1.1-1.1.1.10:1025-65535;=;OK
-p tcp -j SNAT --to-source 1.1.1.1-1.1.1.10:1025-65536;;FAIL
diff --git a/extensions/libxt_DNAT.c b/extensions/libxt_NAT.c
similarity index 80%
rename from extensions/libxt_DNAT.c
rename to extensions/libxt_NAT.c
index fbb10e410a221..da9f22012c5d6 100644
--- a/extensions/libxt_DNAT.c
+++ b/extensions/libxt_NAT.c
@@ -36,11 +36,34 @@
enum {
O_TO_DEST = 0,
+ O_TO_SRC,
O_TO_PORTS,
O_RANDOM,
+ O_RANDOM_FULLY,
O_PERSISTENT,
};
+static void SNAT_help(void)
+{
+ printf(
+"SNAT target options:\n"
+" --to-source [<ipaddr>[-<ipaddr>]][:port[-port]]\n"
+" Address to map source to.\n"
+"[--random] [--random-fully] [--persistent]\n");
+}
+
+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"
+" --random-fully\n"
+" Fully randomize source port.\n");
+}
+
static void DNAT_help(void)
{
printf(
@@ -68,6 +91,22 @@ static void REDIRECT_help(void)
" [--random]\n");
}
+static const struct xt_option_entry SNAT_opts[] = {
+ {.name = "to-source", .id = O_TO_SRC, .type = XTTYPE_STRING,
+ .flags = XTOPT_MAND},
+ {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
+ {.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE},
+ {.name = "persistent", .id = O_PERSISTENT, .type = XTTYPE_NONE},
+ XTOPT_TABLEEND,
+};
+
+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},
+ {.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE},
+ XTOPT_TABLEEND,
+};
+
static const struct xt_option_entry DNAT_opts[] = {
{.name = "to-destination", .id = O_TO_DEST, .type = XTTYPE_STRING,
.flags = XTOPT_MAND},
@@ -226,6 +265,7 @@ static void __NAT_parse(struct xt_option_call *cb, __u16 proto,
xtables_option_parse(cb);
switch (cb->entry->id) {
case O_TO_DEST:
+ case O_TO_SRC:
parse_to(cb->arg, portok, range, family);
break;
case O_TO_PORTS:
@@ -237,6 +277,9 @@ static void __NAT_parse(struct xt_option_call *cb, __u16 proto,
case O_RANDOM:
range->flags |= NF_NAT_RANGE_PROTO_RANDOM;
break;
+ case O_RANDOM_FULLY:
+ range->flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY;
+ break;
}
}
@@ -250,6 +293,7 @@ static void NAT_parse(struct xt_option_call *cb)
switch (cb->entry->id) {
case O_TO_DEST:
+ case O_TO_SRC:
mr->range->min_ip = range.min_addr.ip;
mr->range->max_ip = range.max_addr.ip;
/* fall through */
@@ -259,6 +303,7 @@ static void NAT_parse(struct xt_option_call *cb)
/* fall through */
case O_PERSISTENT:
case O_RANDOM:
+ case O_RANDOM_FULLY:
mr->range->flags |= range.flags;
break;
}
@@ -288,6 +333,13 @@ static void DNAT_parse6_v2(struct xt_option_call *cb)
__NAT_parse(cb, entry->ipv6.proto, cb->data, AF_INET6);
}
+static void SNAT_fcheck(struct xt_fcheck_call *cb)
+{
+ struct nf_nat_ipv4_multi_range_compat *mr = cb->data;
+
+ mr->rangesize = 1;
+}
+
static void DNAT_fcheck(struct xt_fcheck_call *cb)
{
struct nf_nat_ipv4_multi_range_compat *mr = cb->data;
@@ -355,6 +407,8 @@ static void __NAT_print(const struct nf_nat_range2 *r, int family,
}
if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
printf(" %srandom", flag_pfx);
+ if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
+ printf(" %srandom-fully", flag_pfx);
if (r->flags & NF_NAT_RANGE_PERSISTENT)
printf(" %spersistent", flag_pfx);
}
@@ -377,6 +431,10 @@ __NAT_xlate(struct xt_xlate *xl, const struct nf_nat_range2 *r,
xt_xlate_add(xl, "%srandom", sep);
sep = ",";
}
+ if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) {
+ xt_xlate_add(xl, "%sfully-random", sep);
+ sep = ",";
+ }
if (r->flags & NF_NAT_RANGE_PERSISTENT) {
xt_xlate_add(xl, "%spersistent", sep);
sep = ",";
@@ -425,7 +483,33 @@ PSX_GEN(REDIRECT, RANGE2_INIT_FROM_IPV4_MRC, \
PSX_GEN(REDIRECT6, RANGE2_INIT_FROM_RANGE, \
AF_INET6, "redir ports ", "--to-ports ", true, "redirect")
+PSX_GEN(SNAT, RANGE2_INIT_FROM_IPV4_MRC, \
+ AF_INET, "to:", "--to-source ", false, "snat")
+
+PSX_GEN(SNAT6, RANGE2_INIT_FROM_RANGE, \
+ AF_INET6, "to:", "--to-source ", false, "snat")
+
+PSX_GEN(MASQUERADE, RANGE2_INIT_FROM_IPV4_MRC, \
+ AF_INET, "masq ports: ", "--to-ports ", true, "masquerade")
+
+PSX_GEN(MASQUERADE6, RANGE2_INIT_FROM_RANGE, \
+ AF_INET6, "masq ports: ", "--to-ports ", true, "masquerade")
+
static struct xtables_target nat_tg_reg[] = {
+ {
+ .name = "SNAT",
+ .version = XTABLES_VERSION,
+ .family = NFPROTO_IPV4,
+ .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 = NAT_parse,
+ .x6_fcheck = SNAT_fcheck,
+ .print = SNAT_print,
+ .save = SNAT_save,
+ .x6_options = SNAT_opts,
+ .xlate = SNAT_xlate,
+ },
{
.name = "DNAT",
.version = XTABLES_VERSION,
@@ -441,6 +525,33 @@ static struct xtables_target nat_tg_reg[] = {
.x6_options = DNAT_opts,
.xlate = DNAT_xlate,
},
+ {
+ .name = "MASQUERADE",
+ .version = XTABLES_VERSION,
+ .family = NFPROTO_IPV4,
+ .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,
+ .x6_parse = NAT_parse,
+ .x6_fcheck = SNAT_fcheck,
+ .print = MASQUERADE_print,
+ .save = MASQUERADE_save,
+ .x6_options = MASQUERADE_opts,
+ .xlate = MASQUERADE_xlate,
+ },
+ {
+ .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 = NAT_parse6,
+ .print = MASQUERADE6_print,
+ .save = MASQUERADE6_save,
+ .x6_options = MASQUERADE_opts,
+ .xlate = MASQUERADE6_xlate,
+ },
{
.name = "REDIRECT",
.version = XTABLES_VERSION,
@@ -456,6 +567,20 @@ static struct xtables_target nat_tg_reg[] = {
.x6_options = REDIRECT_opts,
.xlate = REDIRECT_xlate,
},
+ {
+ .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 = NAT_parse6,
+ .print = SNAT6_print,
+ .save = SNAT6_save,
+ .x6_options = SNAT_opts,
+ .xlate = SNAT6_xlate,
+ },
{
.name = "DNAT",
.version = XTABLES_VERSION,
--
2.38.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [iptables PATCH 0/6] Merge NAT extensions
2022-11-03 1:41 [iptables PATCH 0/6] Merge NAT extensions Phil Sutter
` (5 preceding siblings ...)
2022-11-03 1:41 ` [iptables PATCH 6/6] extensions: Merge SNAT, DNAT, REDIRECT and MASQUERADE Phil Sutter
@ 2022-11-11 18:16 ` Phil Sutter
6 siblings, 0 replies; 8+ messages in thread
From: Phil Sutter @ 2022-11-11 18:16 UTC (permalink / raw)
To: netfilter-devel
On Thu, Nov 03, 2022 at 02:41:07AM +0100, Phil Sutter wrote:
> Besides the three different data structures in use to store different
> revisions' extensions data, the actual code is pretty similar in all the
> different NAT "flavors".
>
> Patch 1 fixes a minor bug introduced by a previous commit. Patch 2
> eliminates some needless checks and some that seem not necessary.
> Patches 3 to 5 prepare DNAT extension code for the actual merge
> happening in patch 6.
>
> Phil Sutter (6):
> extensions: DNAT: Fix bad IP address error reporting
> extensions: *NAT: Drop NF_NAT_RANGE_PROTO_RANDOM* flag checks
> extensions: DNAT: Use __DNAT_xlate for REDIRECT, too
> extensions: DNAT: Generate print, save and xlate callbacks
> extensions: DNAT: Rename some symbols
> extensions: Merge SNAT, DNAT, REDIRECT and MASQUERADE
Series applied.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2022-11-11 18:16 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-11-03 1:41 [iptables PATCH 0/6] Merge NAT extensions Phil Sutter
2022-11-03 1:41 ` [iptables PATCH 1/6] extensions: DNAT: Fix bad IP address error reporting Phil Sutter
2022-11-03 1:41 ` [iptables PATCH 2/6] extensions: *NAT: Drop NF_NAT_RANGE_PROTO_RANDOM* flag checks Phil Sutter
2022-11-03 1:41 ` [iptables PATCH 3/6] extensions: DNAT: Use __DNAT_xlate for REDIRECT, too Phil Sutter
2022-11-03 1:41 ` [iptables PATCH 4/6] extensions: DNAT: Generate print, save and xlate callbacks Phil Sutter
2022-11-03 1:41 ` [iptables PATCH 5/6] extensions: DNAT: Rename some symbols Phil Sutter
2022-11-03 1:41 ` [iptables PATCH 6/6] extensions: Merge SNAT, DNAT, REDIRECT and MASQUERADE Phil Sutter
2022-11-11 18:16 ` [iptables PATCH 0/6] Merge NAT extensions Phil Sutter
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).