diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2016-03-01 13:55:14 -0500 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2016-03-02 14:05:27 -0500 |
commit | 8a6bf5da1aefdafd60b73d9122c7af9fd2d7bb9c (patch) | |
tree | 8b27863200e3aed5a718dfb9194f6cedec8fe875 /net/netfilter | |
parent | af4610c39589d839551da104f7da342d86f23ea0 (diff) |
netfilter: nft_masq: support port range
Complete masquerading support by allowing port range selection.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter')
-rw-r--r-- | net/netfilter/nft_masq.c | 51 |
1 files changed, 40 insertions, 11 deletions
diff --git a/net/netfilter/nft_masq.c b/net/netfilter/nft_masq.c index 9aea747b43ea..81b5ad6165ac 100644 --- a/net/netfilter/nft_masq.c +++ b/net/netfilter/nft_masq.c | |||
@@ -17,7 +17,9 @@ | |||
17 | #include <net/netfilter/nft_masq.h> | 17 | #include <net/netfilter/nft_masq.h> |
18 | 18 | ||
19 | const struct nla_policy nft_masq_policy[NFTA_MASQ_MAX + 1] = { | 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 | EXPORT_SYMBOL_GPL(nft_masq_policy); | 24 | EXPORT_SYMBOL_GPL(nft_masq_policy); |
23 | 25 | ||
@@ -40,6 +42,7 @@ int nft_masq_init(const struct nft_ctx *ctx, | |||
40 | const struct nft_expr *expr, | 42 | const struct nft_expr *expr, |
41 | const struct nlattr * const tb[]) | 43 | const struct nlattr * const tb[]) |
42 | { | 44 | { |
45 | u32 plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all); | ||
43 | struct nft_masq *priv = nft_expr_priv(expr); | 46 | struct nft_masq *priv = nft_expr_priv(expr); |
44 | int err; | 47 | int err; |
45 | 48 | ||
@@ -47,12 +50,32 @@ int nft_masq_init(const struct nft_ctx *ctx, | |||
47 | if (err) | 50 | if (err) |
48 | return err; | 51 | return err; |
49 | 52 | ||
50 | if (tb[NFTA_MASQ_FLAGS] == NULL) | 53 | if (tb[NFTA_MASQ_FLAGS]) { |
51 | return 0; | 54 | priv->flags = ntohl(nla_get_be32(tb[NFTA_MASQ_FLAGS])); |
52 | 55 | if (priv->flags & ~NF_NAT_RANGE_MASK) | |
53 | priv->flags = ntohl(nla_get_be32(tb[NFTA_MASQ_FLAGS])); | 56 | return -EINVAL; |
54 | if (priv->flags & ~NF_NAT_RANGE_MASK) | 57 | } |
55 | return -EINVAL; | 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 | return 0; | 80 | return 0; |
58 | } | 81 | } |
@@ -62,12 +85,18 @@ int nft_masq_dump(struct sk_buff *skb, const struct nft_expr *expr) | |||
62 | { | 85 | { |
63 | const struct nft_masq *priv = nft_expr_priv(expr); | 86 | const struct nft_masq *priv = nft_expr_priv(expr); |
64 | 87 | ||
65 | if (priv->flags == 0) | 88 | if (priv->flags != 0 && |
66 | return 0; | 89 | nla_put_be32(skb, NFTA_MASQ_FLAGS, htonl(priv->flags))) |
67 | |||
68 | if (nla_put_be32(skb, NFTA_MASQ_FLAGS, htonl(priv->flags))) | ||
69 | goto nla_put_failure; | 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 | return 0; | 100 | return 0; |
72 | 101 | ||
73 | nla_put_failure: | 102 | nla_put_failure: |