Loading include/net/netfilter/nft_masq.h +3 −1 Original line number Diff line number Diff line Loading @@ -3,6 +3,8 @@ struct nft_masq { u32 flags; enum nft_registers sreg_proto_min:8; enum nft_registers sreg_proto_max:8; }; extern const struct nla_policy nft_masq_policy[]; Loading include/uapi/linux/netfilter/nf_tables.h +4 −0 Original line number Diff line number Diff line Loading @@ -951,10 +951,14 @@ enum nft_nat_attributes { * enum nft_masq_attributes - nf_tables masquerade expression 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) */ enum nft_masq_attributes { NFTA_MASQ_UNSPEC, NFTA_MASQ_FLAGS, NFTA_MASQ_REG_PROTO_MIN, NFTA_MASQ_REG_PROTO_MAX, __NFTA_MASQ_MAX }; #define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1) Loading net/ipv4/netfilter/nft_masq_ipv4.c +6 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,12 @@ static void nft_masq_ipv4_eval(const struct nft_expr *expr, memset(&range, 0, sizeof(range)); range.flags = priv->flags; if (priv->sreg_proto_min) { range.min_proto.all = *(__be16 *)®s->data[priv->sreg_proto_min]; range.max_proto.all = *(__be16 *)®s->data[priv->sreg_proto_max]; } regs->verdict.code = nf_nat_masquerade_ipv4(pkt->skb, pkt->hook, &range, pkt->out); } Loading net/ipv6/netfilter/nft_masq_ipv6.c +6 −1 Original line number Diff line number Diff line Loading @@ -26,7 +26,12 @@ static void nft_masq_ipv6_eval(const struct nft_expr *expr, memset(&range, 0, sizeof(range)); range.flags = priv->flags; if (priv->sreg_proto_min) { range.min_proto.all = *(__be16 *)®s->data[priv->sreg_proto_min]; range.max_proto.all = *(__be16 *)®s->data[priv->sreg_proto_max]; } regs->verdict.code = nf_nat_masquerade_ipv6(pkt->skb, &range, pkt->out); } Loading net/netfilter/nft_masq.c +40 −11 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ 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 }, }; EXPORT_SYMBOL_GPL(nft_masq_policy); Loading @@ -40,6 +42,7 @@ int nft_masq_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) { u32 plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all); struct nft_masq *priv = nft_expr_priv(expr); int err; Loading @@ -47,12 +50,32 @@ int nft_masq_init(const struct nft_ctx *ctx, if (err) return err; if (tb[NFTA_MASQ_FLAGS] == NULL) return 0; if (tb[NFTA_MASQ_FLAGS]) { priv->flags = ntohl(nla_get_be32(tb[NFTA_MASQ_FLAGS])); if (priv->flags & ~NF_NAT_RANGE_MASK) return -EINVAL; } if (tb[NFTA_MASQ_REG_PROTO_MIN]) { priv->sreg_proto_min = nft_parse_register(tb[NFTA_MASQ_REG_PROTO_MIN]); err = nft_validate_register_load(priv->sreg_proto_min, plen); if (err < 0) return err; if (tb[NFTA_MASQ_REG_PROTO_MAX]) { priv->sreg_proto_max = nft_parse_register(tb[NFTA_MASQ_REG_PROTO_MAX]); err = nft_validate_register_load(priv->sreg_proto_max, plen); if (err < 0) return err; } else { priv->sreg_proto_max = priv->sreg_proto_min; } } return 0; } Loading @@ -62,11 +85,17 @@ int nft_masq_dump(struct sk_buff *skb, const struct nft_expr *expr) { const struct nft_masq *priv = nft_expr_priv(expr); if (priv->flags == 0) return 0; if (priv->flags != 0 && nla_put_be32(skb, NFTA_MASQ_FLAGS, htonl(priv->flags))) goto nla_put_failure; if (nla_put_be32(skb, NFTA_MASQ_FLAGS, htonl(priv->flags))) if (priv->sreg_proto_min) { if (nft_dump_register(skb, NFTA_MASQ_REG_PROTO_MIN, priv->sreg_proto_min) || nft_dump_register(skb, NFTA_MASQ_REG_PROTO_MAX, priv->sreg_proto_max)) goto nla_put_failure; } return 0; Loading Loading
include/net/netfilter/nft_masq.h +3 −1 Original line number Diff line number Diff line Loading @@ -3,6 +3,8 @@ struct nft_masq { u32 flags; enum nft_registers sreg_proto_min:8; enum nft_registers sreg_proto_max:8; }; extern const struct nla_policy nft_masq_policy[]; Loading
include/uapi/linux/netfilter/nf_tables.h +4 −0 Original line number Diff line number Diff line Loading @@ -951,10 +951,14 @@ enum nft_nat_attributes { * enum nft_masq_attributes - nf_tables masquerade expression 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) */ enum nft_masq_attributes { NFTA_MASQ_UNSPEC, NFTA_MASQ_FLAGS, NFTA_MASQ_REG_PROTO_MIN, NFTA_MASQ_REG_PROTO_MAX, __NFTA_MASQ_MAX }; #define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1) Loading
net/ipv4/netfilter/nft_masq_ipv4.c +6 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,12 @@ static void nft_masq_ipv4_eval(const struct nft_expr *expr, memset(&range, 0, sizeof(range)); range.flags = priv->flags; if (priv->sreg_proto_min) { range.min_proto.all = *(__be16 *)®s->data[priv->sreg_proto_min]; range.max_proto.all = *(__be16 *)®s->data[priv->sreg_proto_max]; } regs->verdict.code = nf_nat_masquerade_ipv4(pkt->skb, pkt->hook, &range, pkt->out); } Loading
net/ipv6/netfilter/nft_masq_ipv6.c +6 −1 Original line number Diff line number Diff line Loading @@ -26,7 +26,12 @@ static void nft_masq_ipv6_eval(const struct nft_expr *expr, memset(&range, 0, sizeof(range)); range.flags = priv->flags; if (priv->sreg_proto_min) { range.min_proto.all = *(__be16 *)®s->data[priv->sreg_proto_min]; range.max_proto.all = *(__be16 *)®s->data[priv->sreg_proto_max]; } regs->verdict.code = nf_nat_masquerade_ipv6(pkt->skb, &range, pkt->out); } Loading
net/netfilter/nft_masq.c +40 −11 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ 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 }, }; EXPORT_SYMBOL_GPL(nft_masq_policy); Loading @@ -40,6 +42,7 @@ int nft_masq_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) { u32 plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all); struct nft_masq *priv = nft_expr_priv(expr); int err; Loading @@ -47,12 +50,32 @@ int nft_masq_init(const struct nft_ctx *ctx, if (err) return err; if (tb[NFTA_MASQ_FLAGS] == NULL) return 0; if (tb[NFTA_MASQ_FLAGS]) { priv->flags = ntohl(nla_get_be32(tb[NFTA_MASQ_FLAGS])); if (priv->flags & ~NF_NAT_RANGE_MASK) return -EINVAL; } if (tb[NFTA_MASQ_REG_PROTO_MIN]) { priv->sreg_proto_min = nft_parse_register(tb[NFTA_MASQ_REG_PROTO_MIN]); err = nft_validate_register_load(priv->sreg_proto_min, plen); if (err < 0) return err; if (tb[NFTA_MASQ_REG_PROTO_MAX]) { priv->sreg_proto_max = nft_parse_register(tb[NFTA_MASQ_REG_PROTO_MAX]); err = nft_validate_register_load(priv->sreg_proto_max, plen); if (err < 0) return err; } else { priv->sreg_proto_max = priv->sreg_proto_min; } } return 0; } Loading @@ -62,11 +85,17 @@ int nft_masq_dump(struct sk_buff *skb, const struct nft_expr *expr) { const struct nft_masq *priv = nft_expr_priv(expr); if (priv->flags == 0) return 0; if (priv->flags != 0 && nla_put_be32(skb, NFTA_MASQ_FLAGS, htonl(priv->flags))) goto nla_put_failure; if (nla_put_be32(skb, NFTA_MASQ_FLAGS, htonl(priv->flags))) if (priv->sreg_proto_min) { if (nft_dump_register(skb, NFTA_MASQ_REG_PROTO_MIN, priv->sreg_proto_min) || nft_dump_register(skb, NFTA_MASQ_REG_PROTO_MAX, priv->sreg_proto_max)) goto nla_put_failure; } return 0; Loading