diff options
-rw-r--r-- | include/net/netfilter/nf_tables.h | 3 | ||||
-rw-r--r-- | include/net/netfilter/nft_masq.h | 3 | ||||
-rw-r--r-- | net/ipv4/netfilter/nft_masq_ipv4.c | 1 | ||||
-rw-r--r-- | net/ipv6/netfilter/nft_masq_ipv6.c | 1 | ||||
-rw-r--r-- | net/netfilter/nf_tables_api.c | 14 | ||||
-rw-r--r-- | net/netfilter/nft_masq.c | 12 | ||||
-rw-r--r-- | net/netfilter/nft_nat.c | 12 |
7 files changed, 46 insertions, 0 deletions
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 3d7292392fac..845c596bf594 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h | |||
@@ -530,6 +530,9 @@ enum nft_chain_type { | |||
530 | NFT_CHAIN_T_MAX | 530 | NFT_CHAIN_T_MAX |
531 | }; | 531 | }; |
532 | 532 | ||
533 | int nft_chain_validate_dependency(const struct nft_chain *chain, | ||
534 | enum nft_chain_type type); | ||
535 | |||
533 | struct nft_stats { | 536 | struct nft_stats { |
534 | u64 bytes; | 537 | u64 bytes; |
535 | u64 pkts; | 538 | u64 pkts; |
diff --git a/include/net/netfilter/nft_masq.h b/include/net/netfilter/nft_masq.h index c72729f954f4..e2a518b60e19 100644 --- a/include/net/netfilter/nft_masq.h +++ b/include/net/netfilter/nft_masq.h | |||
@@ -13,4 +13,7 @@ int nft_masq_init(const struct nft_ctx *ctx, | |||
13 | 13 | ||
14 | int nft_masq_dump(struct sk_buff *skb, const struct nft_expr *expr); | 14 | int nft_masq_dump(struct sk_buff *skb, const struct nft_expr *expr); |
15 | 15 | ||
16 | int nft_masq_validate(const struct nft_ctx *ctx, const struct nft_expr *expr, | ||
17 | const struct nft_data **data); | ||
18 | |||
16 | #endif /* _NFT_MASQ_H_ */ | 19 | #endif /* _NFT_MASQ_H_ */ |
diff --git a/net/ipv4/netfilter/nft_masq_ipv4.c b/net/ipv4/netfilter/nft_masq_ipv4.c index 1c636d6b5b50..c1023c445920 100644 --- a/net/ipv4/netfilter/nft_masq_ipv4.c +++ b/net/ipv4/netfilter/nft_masq_ipv4.c | |||
@@ -39,6 +39,7 @@ static const struct nft_expr_ops nft_masq_ipv4_ops = { | |||
39 | .eval = nft_masq_ipv4_eval, | 39 | .eval = nft_masq_ipv4_eval, |
40 | .init = nft_masq_init, | 40 | .init = nft_masq_init, |
41 | .dump = nft_masq_dump, | 41 | .dump = nft_masq_dump, |
42 | .validate = nft_masq_validate, | ||
42 | }; | 43 | }; |
43 | 44 | ||
44 | static struct nft_expr_type nft_masq_ipv4_type __read_mostly = { | 45 | static struct nft_expr_type nft_masq_ipv4_type __read_mostly = { |
diff --git a/net/ipv6/netfilter/nft_masq_ipv6.c b/net/ipv6/netfilter/nft_masq_ipv6.c index 556262f40761..8a7ac685076d 100644 --- a/net/ipv6/netfilter/nft_masq_ipv6.c +++ b/net/ipv6/netfilter/nft_masq_ipv6.c | |||
@@ -39,6 +39,7 @@ static const struct nft_expr_ops nft_masq_ipv6_ops = { | |||
39 | .eval = nft_masq_ipv6_eval, | 39 | .eval = nft_masq_ipv6_eval, |
40 | .init = nft_masq_init, | 40 | .init = nft_masq_init, |
41 | .dump = nft_masq_dump, | 41 | .dump = nft_masq_dump, |
42 | .validate = nft_masq_validate, | ||
42 | }; | 43 | }; |
43 | 44 | ||
44 | static struct nft_expr_type nft_masq_ipv6_type __read_mostly = { | 45 | static struct nft_expr_type nft_masq_ipv6_type __read_mostly = { |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 556a0dfa4abc..65eb2a1160d5 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
@@ -3744,6 +3744,20 @@ static const struct nfnetlink_subsystem nf_tables_subsys = { | |||
3744 | .abort = nf_tables_abort, | 3744 | .abort = nf_tables_abort, |
3745 | }; | 3745 | }; |
3746 | 3746 | ||
3747 | int nft_chain_validate_dependency(const struct nft_chain *chain, | ||
3748 | enum nft_chain_type type) | ||
3749 | { | ||
3750 | const struct nft_base_chain *basechain; | ||
3751 | |||
3752 | if (chain->flags & NFT_BASE_CHAIN) { | ||
3753 | basechain = nft_base_chain(chain); | ||
3754 | if (basechain->type->type != type) | ||
3755 | return -EOPNOTSUPP; | ||
3756 | } | ||
3757 | return 0; | ||
3758 | } | ||
3759 | EXPORT_SYMBOL_GPL(nft_chain_validate_dependency); | ||
3760 | |||
3747 | /* | 3761 | /* |
3748 | * Loop detection - walk through the ruleset beginning at the destination chain | 3762 | * Loop detection - walk through the ruleset beginning at the destination chain |
3749 | * of a new jump until either the source chain is reached (loop) or all | 3763 | * of a new jump until either the source chain is reached (loop) or all |
diff --git a/net/netfilter/nft_masq.c b/net/netfilter/nft_masq.c index 6637bab00567..d1ffd5eb3a9b 100644 --- a/net/netfilter/nft_masq.c +++ b/net/netfilter/nft_masq.c | |||
@@ -26,6 +26,11 @@ int nft_masq_init(const struct nft_ctx *ctx, | |||
26 | const struct nlattr * const tb[]) | 26 | const struct nlattr * const tb[]) |
27 | { | 27 | { |
28 | struct nft_masq *priv = nft_expr_priv(expr); | 28 | struct nft_masq *priv = nft_expr_priv(expr); |
29 | int err; | ||
30 | |||
31 | err = nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT); | ||
32 | if (err < 0) | ||
33 | return err; | ||
29 | 34 | ||
30 | if (tb[NFTA_MASQ_FLAGS] == NULL) | 35 | if (tb[NFTA_MASQ_FLAGS] == NULL) |
31 | return 0; | 36 | return 0; |
@@ -55,5 +60,12 @@ nla_put_failure: | |||
55 | } | 60 | } |
56 | EXPORT_SYMBOL_GPL(nft_masq_dump); | 61 | EXPORT_SYMBOL_GPL(nft_masq_dump); |
57 | 62 | ||
63 | int nft_masq_validate(const struct nft_ctx *ctx, const struct nft_expr *expr, | ||
64 | const struct nft_data **data) | ||
65 | { | ||
66 | return nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT); | ||
67 | } | ||
68 | EXPORT_SYMBOL_GPL(nft_masq_validate); | ||
69 | |||
58 | MODULE_LICENSE("GPL"); | 70 | MODULE_LICENSE("GPL"); |
59 | MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>"); | 71 | MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>"); |
diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c index 799550b476fb..0f0af6e86fb8 100644 --- a/net/netfilter/nft_nat.c +++ b/net/netfilter/nft_nat.c | |||
@@ -95,6 +95,10 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, | |||
95 | u32 family; | 95 | u32 family; |
96 | int err; | 96 | int err; |
97 | 97 | ||
98 | err = nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT); | ||
99 | if (err < 0) | ||
100 | return err; | ||
101 | |||
98 | if (tb[NFTA_NAT_TYPE] == NULL) | 102 | if (tb[NFTA_NAT_TYPE] == NULL) |
99 | return -EINVAL; | 103 | return -EINVAL; |
100 | 104 | ||
@@ -205,6 +209,13 @@ nla_put_failure: | |||
205 | return -1; | 209 | return -1; |
206 | } | 210 | } |
207 | 211 | ||
212 | static int nft_nat_validate(const struct nft_ctx *ctx, | ||
213 | const struct nft_expr *expr, | ||
214 | const struct nft_data **data) | ||
215 | { | ||
216 | return nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT); | ||
217 | } | ||
218 | |||
208 | static struct nft_expr_type nft_nat_type; | 219 | static struct nft_expr_type nft_nat_type; |
209 | static const struct nft_expr_ops nft_nat_ops = { | 220 | static const struct nft_expr_ops nft_nat_ops = { |
210 | .type = &nft_nat_type, | 221 | .type = &nft_nat_type, |
@@ -212,6 +223,7 @@ static const struct nft_expr_ops nft_nat_ops = { | |||
212 | .eval = nft_nat_eval, | 223 | .eval = nft_nat_eval, |
213 | .init = nft_nat_init, | 224 | .init = nft_nat_init, |
214 | .dump = nft_nat_dump, | 225 | .dump = nft_nat_dump, |
226 | .validate = nft_nat_validate, | ||
215 | }; | 227 | }; |
216 | 228 | ||
217 | static struct nft_expr_type nft_nat_type __read_mostly = { | 229 | static struct nft_expr_type nft_nat_type __read_mostly = { |