netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH nf-next v3 0/4] Support for shifted port-ranges in NAT
@ 2023-03-24 19:04 Jeremy Sowden
  2023-03-24 19:04 ` [PATCH nf-next v3 1/4] netfilter: nat: extend core support for shifted port-ranges Jeremy Sowden
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Jeremy Sowden @ 2023-03-24 19:04 UTC (permalink / raw)
  To: Netfilter Devel

Commit 2eb0f624b709 ("netfilter: add NAT support for shifted portmap
ranges") introduced support for shifting port-ranges in DNAT.  This
allows one to redirect packets intended for one port to another in a
range in such a way that the new port chosen has the same offset in the
range as the original port had from a specified base value.

For example, by using the base value 2000, one could redirect packets
intended for 10.0.0.1:2000-3000 to 10.10.0.1:12000-13000 so that the old
and new ports were at the same offset in their respective ranges, i.e.:

  10.0.0.1:2345 -> 10.10.0.1:12345

However, while support for this was added to the common DNAT infra-
structure, only the xt_nat module was updated to make use of it.  This
patch-set extends the core support and updates all the nft NAT modules
to support it too.

Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=970672
Link: https://bugzilla.netfilter.org/show_bug.cgi?id=1501

* Patch 1 extends the core NAT support for shifted port-ranges to SNAT.
* Patch 2 adds shifted port-range support to nft_nat.
* Patch 3 adds shifted port-range support to nft_masq.
* Patch 4 adds shifted port-range support to nft_redir.

Changes since v2.

  * All the remaining patches not directly related to the new
    functionality have been submitted separately.

Changes since v1.

  * Four patches containing bug-fixes have been removed.
  * Missing `if (priv->sreg_proto_base)` checks have been added to
    patches 4, 6, & 9.
  * In patch 8, `range.flags` in `nft_redir_eval` is initialized by
    simple assignment.

Jeremy Sowden (4):
  netfilter: nat: extend core support for shifted port-ranges
  netfilter: nft_nat: add support for shifted port-ranges
  netfilter: nft_masq: add support for shifted port-ranges
  netfilter: nft_redir: add support for shifted port-ranges

 include/uapi/linux/netfilter/nf_tables.h |  6 ++++
 net/netfilter/nf_nat_core.c              |  3 ++
 net/netfilter/nf_nat_masquerade.c        |  2 ++
 net/netfilter/nf_nat_redirect.c          |  1 +
 net/netfilter/nft_masq.c                 | 25 ++++++++++++++-
 net/netfilter/nft_nat.c                  | 41 ++++++++++++++++++------
 net/netfilter/nft_redir.c                | 23 ++++++++++++-
 7 files changed, 89 insertions(+), 12 deletions(-)

-- 
2.39.2


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

* [PATCH nf-next v3 1/4] netfilter: nat: extend core support for shifted port-ranges
  2023-03-24 19:04 [PATCH nf-next v3 0/4] Support for shifted port-ranges in NAT Jeremy Sowden
@ 2023-03-24 19:04 ` Jeremy Sowden
  2023-03-24 19:04 ` [PATCH nf-next v3 2/4] netfilter: nft_nat: add " Jeremy Sowden
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Jeremy Sowden @ 2023-03-24 19:04 UTC (permalink / raw)
  To: Netfilter Devel

Commit 2eb0f624b709 ("netfilter: add NAT support for shifted portmap
ranges") makes changes in the NAT core to add support for shifted
port-ranges to iptables DNAT.  Before adding support for these to the
nft NAT modules extend the core changes to support SNAT as well.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 net/netfilter/nf_nat_core.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index ce829d434f13..9e3a9472df2f 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -255,6 +255,9 @@ static int in_range(const struct nf_conntrack_tuple *tuple,
 	if (!(range->flags & NF_NAT_RANGE_PROTO_SPECIFIED))
 		return 1;
 
+	if (range->flags & NF_NAT_RANGE_PROTO_OFFSET)
+		return 0;
+
 	return l4proto_in_range(tuple, NF_NAT_MANIP_SRC,
 				&range->min_proto, &range->max_proto);
 }
-- 
2.39.2


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

* [PATCH nf-next v3 2/4] netfilter: nft_nat: add support for shifted port-ranges
  2023-03-24 19:04 [PATCH nf-next v3 0/4] Support for shifted port-ranges in NAT Jeremy Sowden
  2023-03-24 19:04 ` [PATCH nf-next v3 1/4] netfilter: nat: extend core support for shifted port-ranges Jeremy Sowden
@ 2023-03-24 19:04 ` Jeremy Sowden
  2023-03-24 19:04 ` [PATCH nf-next v3 3/4] netfilter: nft_masq: " Jeremy Sowden
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Jeremy Sowden @ 2023-03-24 19:04 UTC (permalink / raw)
  To: Netfilter Devel

Commit 2eb0f624b709 ("netfilter: add NAT support for shifted portmap
ranges") introduced support for shifting port-ranges in NAT.  This
allows one to redirect packets intended for one port to another in a
range in such a way that the new port chosen has the same offset in the
range as the original port had from a specified base value.

For example, by using the base value 2000, one could redirect packets
intended for 10.0.0.1:2000-3000 to 10.10.0.1:12000-13000 so that the old
and new ports were at the same offset in their respective ranges, i.e.:

  10.0.0.1:2345 -> 10.10.0.1:12345

However, while support for this was added to the common NAT infra-
structure, only the xt_nat module was updated to make use of it.  This
commit updates the nft_nat module to allow shifted port-ranges to be
used by nftables.

In contrast to xt_nat, where shifting is only available for DNAT, both
DNAT and SNAT are supported.

Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=970672
Link: https://bugzilla.netfilter.org/show_bug.cgi?id=1501
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 include/uapi/linux/netfilter/nf_tables.h |  2 ++
 net/netfilter/nft_nat.c                  | 41 ++++++++++++++++++------
 2 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 9c6f02c26054..2938e878d3fd 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1434,6 +1434,7 @@ enum nft_nat_types {
  * @NFTA_NAT_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers)
  * @NFTA_NAT_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers)
  * @NFTA_NAT_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32)
+ * @NFTA_NAT_REG_PROTO_BASE: source register of proto range base offset (NLA_U32: nft_registers)
  */
 enum nft_nat_attributes {
 	NFTA_NAT_UNSPEC,
@@ -1444,6 +1445,7 @@ enum nft_nat_attributes {
 	NFTA_NAT_REG_PROTO_MIN,
 	NFTA_NAT_REG_PROTO_MAX,
 	NFTA_NAT_FLAGS,
+	NFTA_NAT_REG_PROTO_BASE,
 	__NFTA_NAT_MAX
 };
 #define NFTA_NAT_MAX		(__NFTA_NAT_MAX - 1)
diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c
index 5c29915ab028..75026c8b36c5 100644
--- a/net/netfilter/nft_nat.c
+++ b/net/netfilter/nft_nat.c
@@ -25,6 +25,7 @@ struct nft_nat {
 	u8			sreg_addr_max;
 	u8			sreg_proto_min;
 	u8			sreg_proto_max;
+	u8			sreg_proto_base;
 	enum nf_nat_manip_type  type:8;
 	u8			family;
 	u16			flags;
@@ -58,6 +59,10 @@ static void nft_nat_setup_proto(struct nf_nat_range2 *range,
 		nft_reg_load16(&regs->data[priv->sreg_proto_min]);
 	range->max_proto.all = (__force __be16)
 		nft_reg_load16(&regs->data[priv->sreg_proto_max]);
+
+	if (priv->sreg_proto_base)
+		range->base_proto.all = (__force __be16)
+			nft_reg_load16(&regs->data[priv->sreg_proto_base]);
 }
 
 static void nft_nat_setup_netmap(struct nf_nat_range2 *range,
@@ -126,13 +131,14 @@ static void nft_nat_eval(const struct nft_expr *expr,
 }
 
 static const struct nla_policy nft_nat_policy[NFTA_NAT_MAX + 1] = {
-	[NFTA_NAT_TYPE]		 = { .type = NLA_U32 },
-	[NFTA_NAT_FAMILY]	 = { .type = NLA_U32 },
-	[NFTA_NAT_REG_ADDR_MIN]	 = { .type = NLA_U32 },
-	[NFTA_NAT_REG_ADDR_MAX]	 = { .type = NLA_U32 },
-	[NFTA_NAT_REG_PROTO_MIN] = { .type = NLA_U32 },
-	[NFTA_NAT_REG_PROTO_MAX] = { .type = NLA_U32 },
-	[NFTA_NAT_FLAGS]	 = { .type = NLA_U32 },
+	[NFTA_NAT_TYPE]		  = { .type = NLA_U32 },
+	[NFTA_NAT_FAMILY]	  = { .type = NLA_U32 },
+	[NFTA_NAT_REG_ADDR_MIN]	  = { .type = NLA_U32 },
+	[NFTA_NAT_REG_ADDR_MAX]	  = { .type = NLA_U32 },
+	[NFTA_NAT_REG_PROTO_MIN]  = { .type = NLA_U32 },
+	[NFTA_NAT_REG_PROTO_MAX]  = { .type = NLA_U32 },
+	[NFTA_NAT_REG_PROTO_BASE] = { .type = NLA_U32 },
+	[NFTA_NAT_FLAGS]	  = { .type = NLA_U32 },
 };
 
 static int nft_nat_validate(const struct nft_ctx *ctx,
@@ -195,10 +201,10 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
 
 	switch (family) {
 	case NFPROTO_IPV4:
-		alen = sizeof_field(struct nf_nat_range, min_addr.ip);
+		alen = sizeof_field(struct nf_nat_range2, min_addr.ip);
 		break;
 	case NFPROTO_IPV6:
-		alen = sizeof_field(struct nf_nat_range, min_addr.ip6);
+		alen = sizeof_field(struct nf_nat_range2, min_addr.ip6);
 		break;
 	default:
 		if (tb[NFTA_NAT_REG_ADDR_MIN])
@@ -226,7 +232,7 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
 		priv->flags |= NF_NAT_RANGE_MAP_IPS;
 	}
 
-	plen = sizeof_field(struct nf_nat_range, min_proto.all);
+	plen = sizeof_field(struct nf_nat_range2, min_proto.all);
 	if (tb[NFTA_NAT_REG_PROTO_MIN]) {
 		err = nft_parse_register_load(tb[NFTA_NAT_REG_PROTO_MIN],
 					      &priv->sreg_proto_min, plen);
@@ -239,6 +245,16 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
 						      plen);
 			if (err < 0)
 				return err;
+
+			if (tb[NFTA_NAT_REG_PROTO_BASE]) {
+				err = nft_parse_register_load
+					(tb[NFTA_NAT_REG_PROTO_BASE],
+					 &priv->sreg_proto_base, plen);
+				if (err < 0)
+					return err;
+
+				priv->flags |= NF_NAT_RANGE_PROTO_OFFSET;
+			}
 		} else {
 			priv->sreg_proto_max = priv->sreg_proto_min;
 		}
@@ -288,6 +304,11 @@ static int nft_nat_dump(struct sk_buff *skb,
 		    nft_dump_register(skb, NFTA_NAT_REG_PROTO_MAX,
 				      priv->sreg_proto_max))
 			goto nla_put_failure;
+
+		if (priv->sreg_proto_base)
+			if (nft_dump_register(skb, NFTA_NAT_REG_PROTO_BASE,
+					      priv->sreg_proto_base))
+				goto nla_put_failure;
 	}
 
 	if (priv->flags != 0) {
-- 
2.39.2


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

* [PATCH nf-next v3 3/4] netfilter: nft_masq: add support for shifted port-ranges
  2023-03-24 19:04 [PATCH nf-next v3 0/4] Support for shifted port-ranges in NAT Jeremy Sowden
  2023-03-24 19:04 ` [PATCH nf-next v3 1/4] netfilter: nat: extend core support for shifted port-ranges Jeremy Sowden
  2023-03-24 19:04 ` [PATCH nf-next v3 2/4] netfilter: nft_nat: add " Jeremy Sowden
@ 2023-03-24 19:04 ` Jeremy Sowden
  2023-03-24 19:04 ` [PATCH nf-next v3 4/4] netfilter: nft_redir: " Jeremy Sowden
  2023-03-24 22:36 ` [PATCH nf-next v3 0/4] Support for shifted port-ranges in NAT Florian Westphal
  4 siblings, 0 replies; 6+ messages in thread
From: Jeremy Sowden @ 2023-03-24 19:04 UTC (permalink / raw)
  To: Netfilter Devel

Support was recently added to nft_nat to allow shifting port-ranges
during NAT.  Extend this support to allow them to used in masquerading
as well.

Set `NF_NAT_RANGE_PROTO_SPECIFIED` flag where appropriate.  `nft_nat`
and `nft_redir` both do this.  It is also set in user space.  However,
it is only ever used internally by the kernel modules, so it would be
good to remove the references to it from user space.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 include/uapi/linux/netfilter/nf_tables.h |  2 ++
 net/netfilter/nf_nat_masquerade.c        |  2 ++
 net/netfilter/nft_masq.c                 | 25 +++++++++++++++++++++++-
 3 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 2938e878d3fd..08780ed008c7 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1472,12 +1472,14 @@ enum nft_tproxy_attributes {
  * @NFTA_MASQ_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32)
  * @NFTA_MASQ_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers)
  * @NFTA_MASQ_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers)
+ * @NFTA_MASQ_REG_PROTO_BASE: source register of proto range base offset (NLA_U32: nft_registers)
  */
 enum nft_masq_attributes {
 	NFTA_MASQ_UNSPEC,
 	NFTA_MASQ_FLAGS,
 	NFTA_MASQ_REG_PROTO_MIN,
 	NFTA_MASQ_REG_PROTO_MAX,
+	NFTA_MASQ_REG_PROTO_BASE,
 	__NFTA_MASQ_MAX
 };
 #define NFTA_MASQ_MAX		(__NFTA_MASQ_MAX - 1)
diff --git a/net/netfilter/nf_nat_masquerade.c b/net/netfilter/nf_nat_masquerade.c
index 1a506b0c6511..8d40b507d4ad 100644
--- a/net/netfilter/nf_nat_masquerade.c
+++ b/net/netfilter/nf_nat_masquerade.c
@@ -69,6 +69,7 @@ nf_nat_masquerade_ipv4(struct sk_buff *skb, unsigned int hooknum,
 	newrange.max_addr.ip = newsrc;
 	newrange.min_proto   = range->min_proto;
 	newrange.max_proto   = range->max_proto;
+	newrange.base_proto  = range->base_proto;
 
 	/* Hand modified range to generic setup. */
 	return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_SRC);
@@ -264,6 +265,7 @@ nf_nat_masquerade_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range,
 	newrange.max_addr.in6	= src;
 	newrange.min_proto	= range->min_proto;
 	newrange.max_proto	= range->max_proto;
+	newrange.base_proto     = range->base_proto;
 
 	return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_SRC);
 }
diff --git a/net/netfilter/nft_masq.c b/net/netfilter/nft_masq.c
index b115d77fbbc7..c9674f5a8c7f 100644
--- a/net/netfilter/nft_masq.c
+++ b/net/netfilter/nft_masq.c
@@ -17,12 +17,14 @@ struct nft_masq {
 	u32			flags;
 	u8			sreg_proto_min;
 	u8			sreg_proto_max;
+	u8			sreg_proto_base;
 };
 
 static const struct nla_policy nft_masq_policy[NFTA_MASQ_MAX + 1] = {
 	[NFTA_MASQ_FLAGS]		= { .type = NLA_U32 },
 	[NFTA_MASQ_REG_PROTO_MIN]	= { .type = NLA_U32 },
 	[NFTA_MASQ_REG_PROTO_MAX]	= { .type = NLA_U32 },
+	[NFTA_MASQ_REG_PROTO_BASE]	= { .type = NLA_U32 },
 };
 
 static int nft_masq_validate(const struct nft_ctx *ctx,
@@ -43,7 +45,7 @@ static int nft_masq_init(const struct nft_ctx *ctx,
 			 const struct nft_expr *expr,
 			 const struct nlattr * const tb[])
 {
-	u32 plen = sizeof_field(struct nf_nat_range, min_proto.all);
+	u32 plen = sizeof_field(struct nf_nat_range2, min_proto.all);
 	struct nft_masq *priv = nft_expr_priv(expr);
 	int err;
 
@@ -65,9 +67,21 @@ static int nft_masq_init(const struct nft_ctx *ctx,
 						      plen);
 			if (err < 0)
 				return err;
+
+			if (tb[NFTA_MASQ_REG_PROTO_BASE]) {
+				err = nft_parse_register_load
+					(tb[NFTA_MASQ_REG_PROTO_BASE],
+					 &priv->sreg_proto_base, plen);
+				if (err < 0)
+					return err;
+
+				priv->flags |= NF_NAT_RANGE_PROTO_OFFSET;
+			}
 		} else {
 			priv->sreg_proto_max = priv->sreg_proto_min;
 		}
+
+		priv->flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
 	}
 
 	return nf_ct_netns_get(ctx->net, ctx->family);
@@ -88,6 +102,11 @@ static int nft_masq_dump(struct sk_buff *skb,
 		    nft_dump_register(skb, NFTA_MASQ_REG_PROTO_MAX,
 				      priv->sreg_proto_max))
 			goto nla_put_failure;
+
+		if (priv->sreg_proto_base)
+			if (nft_dump_register(skb, NFTA_MASQ_REG_PROTO_BASE,
+					      priv->sreg_proto_base))
+				goto nla_put_failure;
 	}
 
 	return 0;
@@ -110,6 +129,10 @@ static void nft_masq_eval(const struct nft_expr *expr,
 			nft_reg_load16(&regs->data[priv->sreg_proto_min]);
 		range.max_proto.all = (__force __be16)
 			nft_reg_load16(&regs->data[priv->sreg_proto_max]);
+
+		if (priv->sreg_proto_base)
+			range.base_proto.all = (__force __be16)
+				nft_reg_load16(&regs->data[priv->sreg_proto_base]);
 	}
 
 	switch (nft_pf(pkt)) {
-- 
2.39.2


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

* [PATCH nf-next v3 4/4] netfilter: nft_redir: add support for shifted port-ranges
  2023-03-24 19:04 [PATCH nf-next v3 0/4] Support for shifted port-ranges in NAT Jeremy Sowden
                   ` (2 preceding siblings ...)
  2023-03-24 19:04 ` [PATCH nf-next v3 3/4] netfilter: nft_masq: " Jeremy Sowden
@ 2023-03-24 19:04 ` Jeremy Sowden
  2023-03-24 22:36 ` [PATCH nf-next v3 0/4] Support for shifted port-ranges in NAT Florian Westphal
  4 siblings, 0 replies; 6+ messages in thread
From: Jeremy Sowden @ 2023-03-24 19:04 UTC (permalink / raw)
  To: Netfilter Devel

Support was recently added to nft_nat to allow shifting port-ranges
during NAT.  Extend this support to allow them to used in redirecting
as well.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
---
 include/uapi/linux/netfilter/nf_tables.h |  2 ++
 net/netfilter/nf_nat_redirect.c          |  1 +
 net/netfilter/nft_redir.c                | 23 ++++++++++++++++++++++-
 3 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 08780ed008c7..c737e8583274 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1490,12 +1490,14 @@ enum nft_masq_attributes {
  * @NFTA_REDIR_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers)
  * @NFTA_REDIR_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers)
  * @NFTA_REDIR_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32)
+ * @NFTA_REDIR_REG_PROTO_BASE: source register of proto range base offset (NLA_U32: nft_registers)
  */
 enum nft_redir_attributes {
 	NFTA_REDIR_UNSPEC,
 	NFTA_REDIR_REG_PROTO_MIN,
 	NFTA_REDIR_REG_PROTO_MAX,
 	NFTA_REDIR_FLAGS,
+	NFTA_REDIR_REG_PROTO_BASE,
 	__NFTA_REDIR_MAX
 };
 #define NFTA_REDIR_MAX		(__NFTA_REDIR_MAX - 1)
diff --git a/net/netfilter/nf_nat_redirect.c b/net/netfilter/nf_nat_redirect.c
index 6616ba5d0b04..ff58b563ef99 100644
--- a/net/netfilter/nf_nat_redirect.c
+++ b/net/netfilter/nf_nat_redirect.c
@@ -42,6 +42,7 @@ nf_nat_redirect(struct sk_buff *skb, const struct nf_nat_range2 *range,
 	newrange.max_addr	= *newdst;
 	newrange.min_proto	= range->min_proto;
 	newrange.max_proto	= range->max_proto;
+	newrange.base_proto	= range->base_proto;
 
 	return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST);
 }
diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c
index a70196ffcb1e..bd9b802c1d64 100644
--- a/net/netfilter/nft_redir.c
+++ b/net/netfilter/nft_redir.c
@@ -16,12 +16,14 @@
 struct nft_redir {
 	u8			sreg_proto_min;
 	u8			sreg_proto_max;
+	u8			sreg_proto_base;
 	u16			flags;
 };
 
 static const struct nla_policy nft_redir_policy[NFTA_REDIR_MAX + 1] = {
 	[NFTA_REDIR_REG_PROTO_MIN]	= { .type = NLA_U32 },
 	[NFTA_REDIR_REG_PROTO_MAX]	= { .type = NLA_U32 },
+	[NFTA_REDIR_REG_PROTO_BASE]	= { .type = NLA_U32 },
 	[NFTA_REDIR_FLAGS]		= { .type = NLA_U32 },
 };
 
@@ -48,7 +50,7 @@ static int nft_redir_init(const struct nft_ctx *ctx,
 	unsigned int plen;
 	int err;
 
-	plen = sizeof_field(struct nf_nat_range, min_proto.all);
+	plen = sizeof_field(struct nf_nat_range2, min_proto.all);
 	if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
 		err = nft_parse_register_load(tb[NFTA_REDIR_REG_PROTO_MIN],
 					      &priv->sreg_proto_min, plen);
@@ -61,6 +63,16 @@ static int nft_redir_init(const struct nft_ctx *ctx,
 						      plen);
 			if (err < 0)
 				return err;
+
+			if (tb[NFTA_REDIR_REG_PROTO_BASE]) {
+				err = nft_parse_register_load
+					(tb[NFTA_REDIR_REG_PROTO_BASE],
+					 &priv->sreg_proto_base, plen);
+				if (err < 0)
+					return err;
+
+				priv->flags |= NF_NAT_RANGE_PROTO_OFFSET;
+			}
 		} else {
 			priv->sreg_proto_max = priv->sreg_proto_min;
 		}
@@ -89,6 +101,11 @@ static int nft_redir_dump(struct sk_buff *skb,
 		if (nft_dump_register(skb, NFTA_REDIR_REG_PROTO_MAX,
 				      priv->sreg_proto_max))
 			goto nla_put_failure;
+
+		if (priv->sreg_proto_base)
+			if (nft_dump_register(skb, NFTA_REDIR_REG_PROTO_BASE,
+					      priv->sreg_proto_base))
+				goto nla_put_failure;
 	}
 
 	if (priv->flags != 0 &&
@@ -115,6 +132,10 @@ static void nft_redir_eval(const struct nft_expr *expr,
 			nft_reg_load16(&regs->data[priv->sreg_proto_min]);
 		range.max_proto.all = (__force __be16)
 			nft_reg_load16(&regs->data[priv->sreg_proto_max]);
+
+		if (priv->sreg_proto_base)
+			range.base_proto.all = (__force __be16)
+				nft_reg_load16(&regs->data[priv->sreg_proto_base]);
 	}
 
 	switch (nft_pf(pkt)) {
-- 
2.39.2


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

* Re: [PATCH nf-next v3 0/4] Support for shifted port-ranges in NAT
  2023-03-24 19:04 [PATCH nf-next v3 0/4] Support for shifted port-ranges in NAT Jeremy Sowden
                   ` (3 preceding siblings ...)
  2023-03-24 19:04 ` [PATCH nf-next v3 4/4] netfilter: nft_redir: " Jeremy Sowden
@ 2023-03-24 22:36 ` Florian Westphal
  4 siblings, 0 replies; 6+ messages in thread
From: Florian Westphal @ 2023-03-24 22:36 UTC (permalink / raw)
  To: Jeremy Sowden; +Cc: Netfilter Devel

Jeremy Sowden <jeremy@azazel.net> wrote:
> Commit 2eb0f624b709 ("netfilter: add NAT support for shifted portmap
> ranges") introduced support for shifting port-ranges in DNAT.  This
> allows one to redirect packets intended for one port to another in a
> range in such a way that the new port chosen has the same offset in the
> range as the original port had from a specified base value.
> 
> For example, by using the base value 2000, one could redirect packets
> intended for 10.0.0.1:2000-3000 to 10.10.0.1:12000-13000 so that the old
> and new ports were at the same offset in their respective ranges, i.e.:
> 
>   10.0.0.1:2345 -> 10.10.0.1:12345
> 
> However, while support for this was added to the common DNAT infra-
> structure, only the xt_nat module was updated to make use of it.  This
> patch-set extends the core support and updates all the nft NAT modules
> to support it too.
> 
> Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=970672
> Link: https://bugzilla.netfilter.org/show_bug.cgi?id=1501

I have no objections to the kernel side.

Pablo, unless you disagree I'm inclined to merge this.

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

end of thread, other threads:[~2023-03-24 22:36 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-24 19:04 [PATCH nf-next v3 0/4] Support for shifted port-ranges in NAT Jeremy Sowden
2023-03-24 19:04 ` [PATCH nf-next v3 1/4] netfilter: nat: extend core support for shifted port-ranges Jeremy Sowden
2023-03-24 19:04 ` [PATCH nf-next v3 2/4] netfilter: nft_nat: add " Jeremy Sowden
2023-03-24 19:04 ` [PATCH nf-next v3 3/4] netfilter: nft_masq: " Jeremy Sowden
2023-03-24 19:04 ` [PATCH nf-next v3 4/4] netfilter: nft_redir: " Jeremy Sowden
2023-03-24 22:36 ` [PATCH nf-next v3 0/4] Support for shifted port-ranges in NAT Florian Westphal

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