aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2016-03-01 13:55:14 -0500
committerPablo Neira Ayuso <pablo@netfilter.org>2016-03-02 14:05:27 -0500
commit8a6bf5da1aefdafd60b73d9122c7af9fd2d7bb9c (patch)
tree8b27863200e3aed5a718dfb9194f6cedec8fe875 /net/netfilter
parentaf4610c39589d839551da104f7da342d86f23ea0 (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.c51
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
19const struct nla_policy nft_masq_policy[NFTA_MASQ_MAX + 1] = { 19const 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};
22EXPORT_SYMBOL_GPL(nft_masq_policy); 24EXPORT_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
73nla_put_failure: 102nla_put_failure: