kernel: add support for brcm fullcone NAT1 in fw4 ntfables

This commit is contained in:
coolsnowwolf 2025-11-09 10:22:21 +08:00
parent bd72295d9e
commit 43d8e623be
6 changed files with 390 additions and 0 deletions

View File

@ -0,0 +1,65 @@
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1477,12 +1477,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_FULLCONE: fullcone NAT (NLA_U8)
*/
enum nft_masq_attributes {
NFTA_MASQ_UNSPEC,
NFTA_MASQ_FLAGS,
NFTA_MASQ_REG_PROTO_MIN,
NFTA_MASQ_REG_PROTO_MAX,
+ NFTA_MASQ_REG_FULLCONE,
__NFTA_MASQ_MAX
};
#define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1)
--- a/net/netfilter/nft_masq.c
+++ b/net/netfilter/nft_masq.c
@@ -17,6 +17,7 @@ struct nft_masq {
u32 flags;
u8 sreg_proto_min;
u8 sreg_proto_max;
+ bool fullcone;
};
static const struct nla_policy nft_masq_policy[NFTA_MASQ_MAX + 1] = {
@@ -24,6 +25,7 @@ static const struct nla_policy nft_masq_
NLA_POLICY_MASK(NLA_BE32, NF_NAT_RANGE_MASK),
[NFTA_MASQ_REG_PROTO_MIN] = { .type = NLA_U32 },
[NFTA_MASQ_REG_PROTO_MAX] = { .type = NLA_U32 },
+ [NFTA_MASQ_REG_FULLCONE] = { .type = NLA_U8 },
};
static int nft_masq_validate(const struct nft_ctx *ctx,
@@ -51,6 +53,9 @@ static int nft_masq_init(const struct nf
if (tb[NFTA_MASQ_FLAGS])
priv->flags = ntohl(nla_get_be32(tb[NFTA_MASQ_FLAGS]));
+ if (tb[NFTA_MASQ_REG_FULLCONE])
+ priv->fullcone = nla_get_u8(tb[NFTA_MASQ_REG_FULLCONE]);
+
if (tb[NFTA_MASQ_REG_PROTO_MIN]) {
err = nft_parse_register_load(tb[NFTA_MASQ_REG_PROTO_MIN],
&priv->sreg_proto_min, plen);
@@ -80,6 +85,9 @@ static int nft_masq_dump(struct sk_buff
nla_put_be32(skb, NFTA_MASQ_FLAGS, htonl(priv->flags)))
goto nla_put_failure;
+ if (priv->fullcone && nla_put_u8(skb, NFTA_MASQ_REG_FULLCONE, 1))
+ goto nla_put_failure;
+
if (priv->sreg_proto_min) {
if (nft_dump_register(skb, NFTA_MASQ_REG_PROTO_MIN,
priv->sreg_proto_min) ||
@@ -112,6 +120,9 @@ static void nft_masq_eval(const struct n
{
switch (nft_pf(pkt)) {
case NFPROTO_IPV4:
+ if (priv->fullcone) {
+ range.min_addr.ip = 1;
+ }
return nft_masq_ipv4_eval(expr, regs, pkt);
case NFPROTO_IPV6:
return nft_masq_ipv6_eval(expr, regs, pkt);

View File

@ -0,0 +1,65 @@
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1477,12 +1477,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_FULLCONE: fullcone NAT (NLA_U8)
*/
enum nft_masq_attributes {
NFTA_MASQ_UNSPEC,
NFTA_MASQ_FLAGS,
NFTA_MASQ_REG_PROTO_MIN,
NFTA_MASQ_REG_PROTO_MAX,
+ NFTA_MASQ_REG_FULLCONE,
__NFTA_MASQ_MAX
};
#define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1)
--- a/net/netfilter/nft_masq.c
+++ b/net/netfilter/nft_masq.c
@@ -17,6 +17,7 @@ struct nft_masq {
u32 flags;
u8 sreg_proto_min;
u8 sreg_proto_max;
+ bool fullcone;
};
static const struct nla_policy nft_masq_policy[NFTA_MASQ_MAX + 1] = {
@@ -24,6 +25,7 @@ static const struct nla_policy nft_masq_
NLA_POLICY_MASK(NLA_BE32, NF_NAT_RANGE_MASK),
[NFTA_MASQ_REG_PROTO_MIN] = { .type = NLA_U32 },
[NFTA_MASQ_REG_PROTO_MAX] = { .type = NLA_U32 },
+ [NFTA_MASQ_REG_FULLCONE] = { .type = NLA_U8 },
};
static int nft_masq_validate(const struct nft_ctx *ctx,
@@ -51,6 +53,9 @@ static int nft_masq_init(const struct nf
if (tb[NFTA_MASQ_FLAGS])
priv->flags = ntohl(nla_get_be32(tb[NFTA_MASQ_FLAGS]));
+ if (tb[NFTA_MASQ_REG_FULLCONE])
+ priv->fullcone = nla_get_u8(tb[NFTA_MASQ_REG_FULLCONE]);
+
if (tb[NFTA_MASQ_REG_PROTO_MIN]) {
err = nft_parse_register_load(tb[NFTA_MASQ_REG_PROTO_MIN],
&priv->sreg_proto_min, plen);
@@ -80,6 +85,9 @@ static int nft_masq_dump(struct sk_buff
nla_put_be32(skb, NFTA_MASQ_FLAGS, htonl(priv->flags)))
goto nla_put_failure;
+ if (priv->fullcone && nla_put_u8(skb, NFTA_MASQ_REG_FULLCONE, 1))
+ goto nla_put_failure;
+
if (priv->sreg_proto_min) {
if (nft_dump_register(skb, NFTA_MASQ_REG_PROTO_MIN,
priv->sreg_proto_min) ||
@@ -112,6 +120,9 @@ static void nft_masq_eval(const struct n
{
switch (nft_pf(pkt)) {
case NFPROTO_IPV4:
+ if (priv->fullcone) {
+ range.min_addr.ip = 1;
+ }
return nft_masq_ipv4_eval(expr, regs, pkt);
case NFPROTO_IPV6:
return nft_masq_ipv6_eval(expr, regs, pkt);

View File

@ -0,0 +1,65 @@
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1477,12 +1477,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_FULLCONE: fullcone NAT (NLA_U8)
*/
enum nft_masq_attributes {
NFTA_MASQ_UNSPEC,
NFTA_MASQ_FLAGS,
NFTA_MASQ_REG_PROTO_MIN,
NFTA_MASQ_REG_PROTO_MAX,
+ NFTA_MASQ_REG_FULLCONE,
__NFTA_MASQ_MAX
};
#define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1)
--- a/net/netfilter/nft_masq.c
+++ b/net/netfilter/nft_masq.c
@@ -17,6 +17,7 @@ struct nft_masq {
u32 flags;
u8 sreg_proto_min;
u8 sreg_proto_max;
+ bool fullcone;
};
static const struct nla_policy nft_masq_policy[NFTA_MASQ_MAX + 1] = {
@@ -24,6 +25,7 @@ static const struct nla_policy nft_masq_
NLA_POLICY_MASK(NLA_BE32, NF_NAT_RANGE_MASK),
[NFTA_MASQ_REG_PROTO_MIN] = { .type = NLA_U32 },
[NFTA_MASQ_REG_PROTO_MAX] = { .type = NLA_U32 },
+ [NFTA_MASQ_REG_FULLCONE] = { .type = NLA_U8 },
};
static int nft_masq_validate(const struct nft_ctx *ctx,
@@ -51,6 +53,9 @@ static int nft_masq_init(const struct nf
if (tb[NFTA_MASQ_FLAGS])
priv->flags = ntohl(nla_get_be32(tb[NFTA_MASQ_FLAGS]));
+ if (tb[NFTA_MASQ_REG_FULLCONE])
+ priv->fullcone = nla_get_u8(tb[NFTA_MASQ_REG_FULLCONE]);
+
if (tb[NFTA_MASQ_REG_PROTO_MIN]) {
err = nft_parse_register_load(tb[NFTA_MASQ_REG_PROTO_MIN],
&priv->sreg_proto_min, plen);
@@ -80,6 +85,9 @@ static int nft_masq_dump(struct sk_buff
nla_put_be32(skb, NFTA_MASQ_FLAGS, htonl(priv->flags)))
goto nla_put_failure;
+ if (priv->fullcone && nla_put_u8(skb, NFTA_MASQ_REG_FULLCONE, 1))
+ goto nla_put_failure;
+
if (priv->sreg_proto_min) {
if (nft_dump_register(skb, NFTA_MASQ_REG_PROTO_MIN,
priv->sreg_proto_min) ||
@@ -112,6 +120,9 @@ static void nft_masq_eval(const struct n
{
switch (nft_pf(pkt)) {
case NFPROTO_IPV4:
+ if (priv->fullcone) {
+ range.min_addr.ip = 1;
+ }
return nft_masq_ipv4_eval(expr, regs, pkt);
case NFPROTO_IPV6:
return nft_masq_ipv6_eval(expr, regs, pkt);

View File

@ -0,0 +1,65 @@
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1477,12 +1477,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_FULLCONE: fullcone NAT (NLA_U8)
*/
enum nft_masq_attributes {
NFTA_MASQ_UNSPEC,
NFTA_MASQ_FLAGS,
NFTA_MASQ_REG_PROTO_MIN,
NFTA_MASQ_REG_PROTO_MAX,
+ NFTA_MASQ_REG_FULLCONE,
__NFTA_MASQ_MAX
};
#define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1)
--- a/net/netfilter/nft_masq.c
+++ b/net/netfilter/nft_masq.c
@@ -17,6 +17,7 @@ struct nft_masq {
u32 flags;
u8 sreg_proto_min;
u8 sreg_proto_max;
+ bool fullcone;
};
static const struct nla_policy nft_masq_policy[NFTA_MASQ_MAX + 1] = {
@@ -24,6 +25,7 @@ static const struct nla_policy nft_masq_
NLA_POLICY_MASK(NLA_BE32, NF_NAT_RANGE_MASK),
[NFTA_MASQ_REG_PROTO_MIN] = { .type = NLA_U32 },
[NFTA_MASQ_REG_PROTO_MAX] = { .type = NLA_U32 },
+ [NFTA_MASQ_REG_FULLCONE] = { .type = NLA_U8 },
};
static int nft_masq_validate(const struct nft_ctx *ctx,
@@ -51,6 +53,9 @@ static int nft_masq_init(const struct nf
if (tb[NFTA_MASQ_FLAGS])
priv->flags = ntohl(nla_get_be32(tb[NFTA_MASQ_FLAGS]));
+ if (tb[NFTA_MASQ_REG_FULLCONE])
+ priv->fullcone = nla_get_u8(tb[NFTA_MASQ_REG_FULLCONE]);
+
if (tb[NFTA_MASQ_REG_PROTO_MIN]) {
err = nft_parse_register_load(tb[NFTA_MASQ_REG_PROTO_MIN],
&priv->sreg_proto_min, plen);
@@ -80,6 +85,9 @@ static int nft_masq_dump(struct sk_buff
nla_put_be32(skb, NFTA_MASQ_FLAGS, htonl(priv->flags)))
goto nla_put_failure;
+ if (priv->fullcone && nla_put_u8(skb, NFTA_MASQ_REG_FULLCONE, 1))
+ goto nla_put_failure;
+
if (priv->sreg_proto_min) {
if (nft_dump_register(skb, NFTA_MASQ_REG_PROTO_MIN,
priv->sreg_proto_min) ||
@@ -112,6 +120,9 @@ static void nft_masq_eval(const struct n
{
switch (nft_pf(pkt)) {
case NFPROTO_IPV4:
+ if (priv->fullcone) {
+ range.min_addr.ip = 1;
+ }
return nft_masq_ipv4_eval(expr, regs, pkt);
case NFPROTO_IPV6:
return nft_masq_ipv6_eval(expr, regs, pkt);

View File

@ -0,0 +1,65 @@
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1477,12 +1477,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_FULLCONE: fullcone NAT (NLA_U8)
*/
enum nft_masq_attributes {
NFTA_MASQ_UNSPEC,
NFTA_MASQ_FLAGS,
NFTA_MASQ_REG_PROTO_MIN,
NFTA_MASQ_REG_PROTO_MAX,
+ NFTA_MASQ_REG_FULLCONE,
__NFTA_MASQ_MAX
};
#define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1)
--- a/net/netfilter/nft_masq.c
+++ b/net/netfilter/nft_masq.c
@@ -17,6 +17,7 @@ struct nft_masq {
u32 flags;
u8 sreg_proto_min;
u8 sreg_proto_max;
+ bool fullcone;
};
static const struct nla_policy nft_masq_policy[NFTA_MASQ_MAX + 1] = {
@@ -24,6 +25,7 @@ static const struct nla_policy nft_masq_
NLA_POLICY_MASK(NLA_BE32, NF_NAT_RANGE_MASK),
[NFTA_MASQ_REG_PROTO_MIN] = { .type = NLA_U32 },
[NFTA_MASQ_REG_PROTO_MAX] = { .type = NLA_U32 },
+ [NFTA_MASQ_REG_FULLCONE] = { .type = NLA_U8 },
};
static int nft_masq_validate(const struct nft_ctx *ctx,
@@ -51,6 +53,9 @@ static int nft_masq_init(const struct nf
if (tb[NFTA_MASQ_FLAGS])
priv->flags = ntohl(nla_get_be32(tb[NFTA_MASQ_FLAGS]));
+ if (tb[NFTA_MASQ_REG_FULLCONE])
+ priv->fullcone = nla_get_u8(tb[NFTA_MASQ_REG_FULLCONE]);
+
if (tb[NFTA_MASQ_REG_PROTO_MIN]) {
err = nft_parse_register_load(tb[NFTA_MASQ_REG_PROTO_MIN],
&priv->sreg_proto_min, plen);
@@ -80,6 +85,9 @@ static int nft_masq_dump(struct sk_buff
nla_put_be32(skb, NFTA_MASQ_FLAGS, htonl(priv->flags)))
goto nla_put_failure;
+ if (priv->fullcone && nla_put_u8(skb, NFTA_MASQ_REG_FULLCONE, 1))
+ goto nla_put_failure;
+
if (priv->sreg_proto_min) {
if (nft_dump_register(skb, NFTA_MASQ_REG_PROTO_MIN,
priv->sreg_proto_min) ||
@@ -112,6 +120,9 @@ static void nft_masq_eval(const struct n
switch (nft_pf(pkt)) {
case NFPROTO_IPV4:
+ if (priv->fullcone) {
+ range.min_addr.ip = 1;
+ }
regs->verdict.code = nf_nat_masquerade_ipv4(pkt->skb,
nft_hook(pkt),
&range,

View File

@ -0,0 +1,65 @@
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1477,12 +1477,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_FULLCONE: fullcone NAT (NLA_U8)
*/
enum nft_masq_attributes {
NFTA_MASQ_UNSPEC,
NFTA_MASQ_FLAGS,
NFTA_MASQ_REG_PROTO_MIN,
NFTA_MASQ_REG_PROTO_MAX,
+ NFTA_MASQ_REG_FULLCONE,
__NFTA_MASQ_MAX
};
#define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1)
--- a/net/netfilter/nft_masq.c
+++ b/net/netfilter/nft_masq.c
@@ -17,6 +17,7 @@ struct nft_masq {
u32 flags;
u8 sreg_proto_min;
u8 sreg_proto_max;
+ bool fullcone;
};
static const struct nla_policy nft_masq_policy[NFTA_MASQ_MAX + 1] = {
@@ -24,6 +25,7 @@ static const struct nla_policy nft_masq_
NLA_POLICY_MASK(NLA_BE32, NF_NAT_RANGE_MASK),
[NFTA_MASQ_REG_PROTO_MIN] = { .type = NLA_U32 },
[NFTA_MASQ_REG_PROTO_MAX] = { .type = NLA_U32 },
+ [NFTA_MASQ_REG_FULLCONE] = { .type = NLA_U8 },
};
static int nft_masq_validate(const struct nft_ctx *ctx,
@@ -51,6 +53,9 @@ static int nft_masq_init(const struct nf
if (tb[NFTA_MASQ_FLAGS])
priv->flags = ntohl(nla_get_be32(tb[NFTA_MASQ_FLAGS]));
+ if (tb[NFTA_MASQ_REG_FULLCONE])
+ priv->fullcone = nla_get_u8(tb[NFTA_MASQ_REG_FULLCONE]);
+
if (tb[NFTA_MASQ_REG_PROTO_MIN]) {
err = nft_parse_register_load(tb[NFTA_MASQ_REG_PROTO_MIN],
&priv->sreg_proto_min, plen);
@@ -80,6 +85,9 @@ static int nft_masq_dump(struct sk_buff
nla_put_be32(skb, NFTA_MASQ_FLAGS, htonl(priv->flags)))
goto nla_put_failure;
+ if (priv->fullcone && nla_put_u8(skb, NFTA_MASQ_REG_FULLCONE, 1))
+ goto nla_put_failure;
+
if (priv->sreg_proto_min) {
if (nft_dump_register(skb, NFTA_MASQ_REG_PROTO_MIN,
priv->sreg_proto_min) ||
@@ -112,6 +120,9 @@ static void nft_masq_eval(const struct n
switch (nft_pf(pkt)) {
case NFPROTO_IPV4:
+ if (priv->fullcone) {
+ range.min_addr.ip = 1;
+ }
regs->verdict.code = nf_nat_masquerade_ipv4(pkt->skb,
nft_hook(pkt),
&range,