diff --git a/target/linux/generic/hack-5.10/983-add-bcm-fullconenat-to-nft.patch b/target/linux/generic/hack-5.10/983-add-bcm-fullconenat-to-nft.patch new file mode 100644 index 000000000..bb1cd62a3 --- /dev/null +++ b/target/linux/generic/hack-5.10/983-add-bcm-fullconenat-to-nft.patch @@ -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); diff --git a/target/linux/generic/hack-5.15/983-add-bcm-fullconenat-to-nft.patch b/target/linux/generic/hack-5.15/983-add-bcm-fullconenat-to-nft.patch new file mode 100644 index 000000000..bb1cd62a3 --- /dev/null +++ b/target/linux/generic/hack-5.15/983-add-bcm-fullconenat-to-nft.patch @@ -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); diff --git a/target/linux/generic/hack-5.4/983-add-bcm-fullconenat-to-nft.patch b/target/linux/generic/hack-5.4/983-add-bcm-fullconenat-to-nft.patch new file mode 100644 index 000000000..bb1cd62a3 --- /dev/null +++ b/target/linux/generic/hack-5.4/983-add-bcm-fullconenat-to-nft.patch @@ -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); diff --git a/target/linux/generic/hack-6.1/983-add-bcm-fullconenat-to-nft.patch b/target/linux/generic/hack-6.1/983-add-bcm-fullconenat-to-nft.patch new file mode 100644 index 000000000..bb1cd62a3 --- /dev/null +++ b/target/linux/generic/hack-6.1/983-add-bcm-fullconenat-to-nft.patch @@ -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); diff --git a/target/linux/generic/hack-6.12/983-add-bcm-fullconenat-to-nft.patch b/target/linux/generic/hack-6.12/983-add-bcm-fullconenat-to-nft.patch new file mode 100644 index 000000000..ec868e19f --- /dev/null +++ b/target/linux/generic/hack-6.12/983-add-bcm-fullconenat-to-nft.patch @@ -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, diff --git a/target/linux/generic/hack-6.6/983-add-bcm-fullconenat-to-nft.patch b/target/linux/generic/hack-6.6/983-add-bcm-fullconenat-to-nft.patch new file mode 100644 index 000000000..ec868e19f --- /dev/null +++ b/target/linux/generic/hack-6.6/983-add-bcm-fullconenat-to-nft.patch @@ -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,