| @@ -17,7 +17,9 @@ · 16 unmodified lines |
| 17 | 17 | #include <net/netfilter/nft_masq.h> |
| 18 | 18 | |
| 19 | 19 | const struct nla_policy nft_masq_policy[NFTA_MASQ_MAX + 1] = { |
| 20 | | − [NFTA_MASQ_FLAGS] = { .type = NLA_U32 }, |
| 20 | + [NFTA_MASQ_FLAGS] = { .type = NLA_U32 }, |
| 21 | + [NFTA_MASQ_REG_PROTO_MIN] = { .type = NLA_U32 }, |
| 22 | + [NFTA_MASQ_REG_PROTO_MAX] = { .type = NLA_U32 }, |
| 21 | 23 | }; |
| 22 | 24 | EXPORT_SYMBOL_GPL(nft_masq_policy); |
| 23 | 25 | |
| @@ -40,6 +42,7 @@ int nft_masq_init(const struct nft_ctx *ctx, · 16 unmodified lines |
| 40 | 42 | const struct nft_expr *expr, |
| 41 | 43 | const struct nlattr * const tb[]) |
| 42 | 44 | { |
| 45 | + u32 plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all); |
| 43 | 46 | struct nft_masq *priv = nft_expr_priv(expr); |
| 44 | 47 | int err; |
| 45 | 48 | |
| @@ -47,12 +50,32 @@ int nft_masq_init(const struct nft_ctx *ctx, · 1 unmodified line |
| 47 | 50 | if (err) |
| 48 | 51 | return err; |
| 49 | 52 | |
| 50 | | − if (tb[NFTA_MASQ_FLAGS] == NULL) |
| 51 | | − return 0; |
| 52 | | − |
| 53 | | − priv->flags = ntohl(nla_get_be32(tb[NFTA_MASQ_FLAGS])); |
| 54 | | − if (priv->flags & ~NF_NAT_RANGE_MASK) |
| 55 | | − return -EINVAL; |
| 53 | + if (tb[NFTA_MASQ_FLAGS]) { |
| 54 | + priv->flags = ntohl(nla_get_be32(tb[NFTA_MASQ_FLAGS])); |
| 55 | + if (priv->flags & ~NF_NAT_RANGE_MASK) |
| 56 | + return -EINVAL; |
| 57 | + } |
| 58 | + |
| 59 | + if (tb[NFTA_MASQ_REG_PROTO_MIN]) { |
| 60 | + priv->sreg_proto_min = |
| 61 | + nft_parse_register(tb[NFTA_MASQ_REG_PROTO_MIN]); |
| 62 | + |
| 63 | + err = nft_validate_register_load(priv->sreg_proto_min, plen); |
| 64 | + if (err < 0) |
| 65 | + return err; |
| 66 | + |
| 67 | + if (tb[NFTA_MASQ_REG_PROTO_MAX]) { |
| 68 | + priv->sreg_proto_max = |
| 69 | + nft_parse_register(tb[NFTA_MASQ_REG_PROTO_MAX]); |
| 70 | + |
| 71 | + err = nft_validate_register_load(priv->sreg_proto_max, |
| 72 | + plen); |
| 73 | + if (err < 0) |
| 74 | + return err; |
| 75 | + } else { |
| 76 | + priv->sreg_proto_max = priv->sreg_proto_min; |
| 77 | + } |
| 78 | + } |
| 56 | 79 | |
| 57 | 80 | return 0; |
| 58 | 81 | } |
| @@ -62,12 +85,18 @@ int nft_masq_dump(struct sk_buff *skb, const struct nft_expr *expr) · 3 unmodified lines |
| 62 | 85 | { |
| 63 | 86 | const struct nft_masq *priv = nft_expr_priv(expr); |
| 64 | 87 | |
| 65 | | − if (priv->flags == 0) |
| 66 | | − return 0; |
| 67 | | − |
| 68 | | − if (nla_put_be32(skb, NFTA_MASQ_FLAGS, htonl(priv->flags))) |
| 88 | + if (priv->flags != 0 && |
| 89 | + nla_put_be32(skb, NFTA_MASQ_FLAGS, htonl(priv->flags))) |
| 69 | 90 | goto nla_put_failure; |
| 70 | 91 | |
| 92 | + if (priv->sreg_proto_min) { |
| 93 | + if (nft_dump_register(skb, NFTA_MASQ_REG_PROTO_MIN, |
| 94 | + priv->sreg_proto_min) || |
| 95 | + nft_dump_register(skb, NFTA_MASQ_REG_PROTO_MAX, |
| 96 | + priv->sreg_proto_max)) |
| 97 | + goto nla_put_failure; |
| 98 | + } |
| 99 | + |
| 71 | 100 | return 0; |
| 72 | 101 | |
| 73 | 102 | nla_put_failure: |