diff options
-rw-r--r-- | include/net/netfilter/nft_redir.h | 21 | ||||
-rw-r--r-- | include/uapi/linux/netfilter/nf_tables.h | 16 | ||||
-rw-r--r-- | net/ipv4/netfilter/Kconfig | 9 | ||||
-rw-r--r-- | net/ipv4/netfilter/Makefile | 1 | ||||
-rw-r--r-- | net/ipv4/netfilter/nft_redir_ipv4.c | 77 | ||||
-rw-r--r-- | net/ipv6/netfilter/Kconfig | 9 | ||||
-rw-r--r-- | net/ipv6/netfilter/Makefile | 1 | ||||
-rw-r--r-- | net/ipv6/netfilter/nft_redir_ipv6.c | 77 | ||||
-rw-r--r-- | net/netfilter/Kconfig | 9 | ||||
-rw-r--r-- | net/netfilter/Makefile | 1 | ||||
-rw-r--r-- | net/netfilter/nft_redir.c | 98 |
11 files changed, 319 insertions, 0 deletions
diff --git a/include/net/netfilter/nft_redir.h b/include/net/netfilter/nft_redir.h new file mode 100644 index 000000000000..a2d67546afab --- /dev/null +++ b/include/net/netfilter/nft_redir.h | |||
@@ -0,0 +1,21 @@ | |||
1 | #ifndef _NFT_REDIR_H_ | ||
2 | #define _NFT_REDIR_H_ | ||
3 | |||
4 | struct nft_redir { | ||
5 | enum nft_registers sreg_proto_min:8; | ||
6 | enum nft_registers sreg_proto_max:8; | ||
7 | u16 flags; | ||
8 | }; | ||
9 | |||
10 | extern const struct nla_policy nft_redir_policy[]; | ||
11 | |||
12 | int nft_redir_init(const struct nft_ctx *ctx, | ||
13 | const struct nft_expr *expr, | ||
14 | const struct nlattr * const tb[]); | ||
15 | |||
16 | int nft_redir_dump(struct sk_buff *skb, const struct nft_expr *expr); | ||
17 | |||
18 | int nft_redir_validate(const struct nft_ctx *ctx, const struct nft_expr *expr, | ||
19 | const struct nft_data **data); | ||
20 | |||
21 | #endif /* _NFT_REDIR_H_ */ | ||
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index f31fe7b660a5..16f62a5cf04d 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h | |||
@@ -838,6 +838,22 @@ enum nft_masq_attributes { | |||
838 | #define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1) | 838 | #define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1) |
839 | 839 | ||
840 | /** | 840 | /** |
841 | * enum nft_redir_attributes - nf_tables redirect expression netlink attributes | ||
842 | * | ||
843 | * @NFTA_REDIR_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers) | ||
844 | * @NFTA_REDIR_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers) | ||
845 | * @NFTA_REDIR_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32) | ||
846 | */ | ||
847 | enum nft_redir_attributes { | ||
848 | NFTA_REDIR_UNSPEC, | ||
849 | NFTA_REDIR_REG_PROTO_MIN, | ||
850 | NFTA_REDIR_REG_PROTO_MAX, | ||
851 | NFTA_REDIR_FLAGS, | ||
852 | __NFTA_REDIR_MAX | ||
853 | }; | ||
854 | #define NFTA_REDIR_MAX (__NFTA_REDIR_MAX - 1) | ||
855 | |||
856 | /** | ||
841 | * enum nft_gen_attributes - nf_tables ruleset generation attributes | 857 | * enum nft_gen_attributes - nf_tables ruleset generation attributes |
842 | * | 858 | * |
843 | * @NFTA_GEN_ID: Ruleset generation ID (NLA_U32) | 859 | * @NFTA_GEN_ID: Ruleset generation ID (NLA_U32) |
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index a300e2c32b26..8358b2da1549 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
@@ -119,6 +119,15 @@ config NFT_MASQ_IPV4 | |||
119 | This is the expression that provides IPv4 masquerading support for | 119 | This is the expression that provides IPv4 masquerading support for |
120 | nf_tables. | 120 | nf_tables. |
121 | 121 | ||
122 | config NFT_REDIR_IPV4 | ||
123 | tristate "IPv4 redirect support for nf_tables" | ||
124 | depends on NF_TABLES_IPV4 | ||
125 | depends on NFT_REDIR | ||
126 | select NF_NAT_REDIRECT_IPV4 | ||
127 | help | ||
128 | This is the expression that provides IPv4 redirect support for | ||
129 | nf_tables. | ||
130 | |||
122 | config NF_NAT_SNMP_BASIC | 131 | config NF_NAT_SNMP_BASIC |
123 | tristate "Basic SNMP-ALG support" | 132 | tristate "Basic SNMP-ALG support" |
124 | depends on NF_CONNTRACK_SNMP | 133 | depends on NF_CONNTRACK_SNMP |
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 34e436c92015..902bcd1597bb 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
@@ -41,6 +41,7 @@ obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV4) += nft_chain_route_ipv4.o | |||
41 | obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o | 41 | obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o |
42 | obj-$(CONFIG_NFT_REJECT_IPV4) += nft_reject_ipv4.o | 42 | obj-$(CONFIG_NFT_REJECT_IPV4) += nft_reject_ipv4.o |
43 | obj-$(CONFIG_NFT_MASQ_IPV4) += nft_masq_ipv4.o | 43 | obj-$(CONFIG_NFT_MASQ_IPV4) += nft_masq_ipv4.o |
44 | obj-$(CONFIG_NFT_REDIR_IPV4) += nft_redir_ipv4.o | ||
44 | obj-$(CONFIG_NF_TABLES_ARP) += nf_tables_arp.o | 45 | obj-$(CONFIG_NF_TABLES_ARP) += nf_tables_arp.o |
45 | 46 | ||
46 | # generic IP tables | 47 | # generic IP tables |
diff --git a/net/ipv4/netfilter/nft_redir_ipv4.c b/net/ipv4/netfilter/nft_redir_ipv4.c new file mode 100644 index 000000000000..643c5967aa27 --- /dev/null +++ b/net/ipv4/netfilter/nft_redir_ipv4.c | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/netlink.h> | ||
13 | #include <linux/netfilter.h> | ||
14 | #include <linux/netfilter/nf_tables.h> | ||
15 | #include <net/netfilter/nf_tables.h> | ||
16 | #include <net/netfilter/nf_nat.h> | ||
17 | #include <net/netfilter/ipv4/nf_nat_redirect.h> | ||
18 | #include <net/netfilter/nft_redir.h> | ||
19 | |||
20 | static void nft_redir_ipv4_eval(const struct nft_expr *expr, | ||
21 | struct nft_data data[NFT_REG_MAX + 1], | ||
22 | const struct nft_pktinfo *pkt) | ||
23 | { | ||
24 | struct nft_redir *priv = nft_expr_priv(expr); | ||
25 | struct nf_nat_ipv4_multi_range_compat mr; | ||
26 | unsigned int verdict; | ||
27 | |||
28 | memset(&mr, 0, sizeof(mr)); | ||
29 | if (priv->sreg_proto_min) { | ||
30 | mr.range[0].min.all = (__force __be16) | ||
31 | data[priv->sreg_proto_min].data[0]; | ||
32 | mr.range[0].max.all = (__force __be16) | ||
33 | data[priv->sreg_proto_max].data[0]; | ||
34 | mr.range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED; | ||
35 | } | ||
36 | |||
37 | mr.range[0].flags |= priv->flags; | ||
38 | |||
39 | verdict = nf_nat_redirect_ipv4(pkt->skb, &mr, pkt->ops->hooknum); | ||
40 | data[NFT_REG_VERDICT].verdict = verdict; | ||
41 | } | ||
42 | |||
43 | static struct nft_expr_type nft_redir_ipv4_type; | ||
44 | static const struct nft_expr_ops nft_redir_ipv4_ops = { | ||
45 | .type = &nft_redir_ipv4_type, | ||
46 | .size = NFT_EXPR_SIZE(sizeof(struct nft_redir)), | ||
47 | .eval = nft_redir_ipv4_eval, | ||
48 | .init = nft_redir_init, | ||
49 | .dump = nft_redir_dump, | ||
50 | .validate = nft_redir_validate, | ||
51 | }; | ||
52 | |||
53 | static struct nft_expr_type nft_redir_ipv4_type __read_mostly = { | ||
54 | .family = NFPROTO_IPV4, | ||
55 | .name = "redir", | ||
56 | .ops = &nft_redir_ipv4_ops, | ||
57 | .policy = nft_redir_policy, | ||
58 | .maxattr = NFTA_REDIR_MAX, | ||
59 | .owner = THIS_MODULE, | ||
60 | }; | ||
61 | |||
62 | static int __init nft_redir_ipv4_module_init(void) | ||
63 | { | ||
64 | return nft_register_expr(&nft_redir_ipv4_type); | ||
65 | } | ||
66 | |||
67 | static void __exit nft_redir_ipv4_module_exit(void) | ||
68 | { | ||
69 | nft_unregister_expr(&nft_redir_ipv4_type); | ||
70 | } | ||
71 | |||
72 | module_init(nft_redir_ipv4_module_init); | ||
73 | module_exit(nft_redir_ipv4_module_exit); | ||
74 | |||
75 | MODULE_LICENSE("GPL"); | ||
76 | MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>"); | ||
77 | MODULE_ALIAS_NFT_AF_EXPR(AF_INET, "redir"); | ||
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 462eebbf4377..0dbe5c7953e5 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig | |||
@@ -97,6 +97,15 @@ config NFT_MASQ_IPV6 | |||
97 | This is the expression that provides IPv4 masquerading support for | 97 | This is the expression that provides IPv4 masquerading support for |
98 | nf_tables. | 98 | nf_tables. |
99 | 99 | ||
100 | config NFT_REDIR_IPV6 | ||
101 | tristate "IPv6 redirect support for nf_tables" | ||
102 | depends on NF_TABLES_IPV6 | ||
103 | depends on NFT_REDIR | ||
104 | select NF_NAT_REDIRECT_IPV6 | ||
105 | help | ||
106 | This is the expression that provides IPv4 redirect support for | ||
107 | nf_tables. | ||
108 | |||
100 | endif # NF_NAT_IPV6 | 109 | endif # NF_NAT_IPV6 |
101 | 110 | ||
102 | config IP6_NF_IPTABLES | 111 | config IP6_NF_IPTABLES |
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile index 6c2baab10f21..d2ac9f5f212c 100644 --- a/net/ipv6/netfilter/Makefile +++ b/net/ipv6/netfilter/Makefile | |||
@@ -37,6 +37,7 @@ obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV6) += nft_chain_route_ipv6.o | |||
37 | obj-$(CONFIG_NFT_CHAIN_NAT_IPV6) += nft_chain_nat_ipv6.o | 37 | obj-$(CONFIG_NFT_CHAIN_NAT_IPV6) += nft_chain_nat_ipv6.o |
38 | obj-$(CONFIG_NFT_REJECT_IPV6) += nft_reject_ipv6.o | 38 | obj-$(CONFIG_NFT_REJECT_IPV6) += nft_reject_ipv6.o |
39 | obj-$(CONFIG_NFT_MASQ_IPV6) += nft_masq_ipv6.o | 39 | obj-$(CONFIG_NFT_MASQ_IPV6) += nft_masq_ipv6.o |
40 | obj-$(CONFIG_NFT_REDIR_IPV6) += nft_redir_ipv6.o | ||
40 | 41 | ||
41 | # matches | 42 | # matches |
42 | obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o | 43 | obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o |
diff --git a/net/ipv6/netfilter/nft_redir_ipv6.c b/net/ipv6/netfilter/nft_redir_ipv6.c new file mode 100644 index 000000000000..83420eeaad1c --- /dev/null +++ b/net/ipv6/netfilter/nft_redir_ipv6.c | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/netlink.h> | ||
13 | #include <linux/netfilter.h> | ||
14 | #include <linux/netfilter/nf_tables.h> | ||
15 | #include <net/netfilter/nf_tables.h> | ||
16 | #include <net/netfilter/nf_nat.h> | ||
17 | #include <net/netfilter/nft_redir.h> | ||
18 | #include <net/netfilter/ipv6/nf_nat_redirect.h> | ||
19 | |||
20 | static void nft_redir_ipv6_eval(const struct nft_expr *expr, | ||
21 | struct nft_data data[NFT_REG_MAX + 1], | ||
22 | const struct nft_pktinfo *pkt) | ||
23 | { | ||
24 | struct nft_redir *priv = nft_expr_priv(expr); | ||
25 | struct nf_nat_range range; | ||
26 | unsigned int verdict; | ||
27 | |||
28 | memset(&range, 0, sizeof(range)); | ||
29 | if (priv->sreg_proto_min) { | ||
30 | range.min_proto.all = (__force __be16) | ||
31 | data[priv->sreg_proto_min].data[0]; | ||
32 | range.max_proto.all = (__force __be16) | ||
33 | data[priv->sreg_proto_max].data[0]; | ||
34 | range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; | ||
35 | } | ||
36 | |||
37 | range.flags |= priv->flags; | ||
38 | |||
39 | verdict = nf_nat_redirect_ipv6(pkt->skb, &range, pkt->ops->hooknum); | ||
40 | data[NFT_REG_VERDICT].verdict = verdict; | ||
41 | } | ||
42 | |||
43 | static struct nft_expr_type nft_redir_ipv6_type; | ||
44 | static const struct nft_expr_ops nft_redir_ipv6_ops = { | ||
45 | .type = &nft_redir_ipv6_type, | ||
46 | .size = NFT_EXPR_SIZE(sizeof(struct nft_redir)), | ||
47 | .eval = nft_redir_ipv6_eval, | ||
48 | .init = nft_redir_init, | ||
49 | .dump = nft_redir_dump, | ||
50 | .validate = nft_redir_validate, | ||
51 | }; | ||
52 | |||
53 | static struct nft_expr_type nft_redir_ipv6_type __read_mostly = { | ||
54 | .family = NFPROTO_IPV6, | ||
55 | .name = "redir", | ||
56 | .ops = &nft_redir_ipv6_ops, | ||
57 | .policy = nft_redir_policy, | ||
58 | .maxattr = NFTA_REDIR_MAX, | ||
59 | .owner = THIS_MODULE, | ||
60 | }; | ||
61 | |||
62 | static int __init nft_redir_ipv6_module_init(void) | ||
63 | { | ||
64 | return nft_register_expr(&nft_redir_ipv6_type); | ||
65 | } | ||
66 | |||
67 | static void __exit nft_redir_ipv6_module_exit(void) | ||
68 | { | ||
69 | nft_unregister_expr(&nft_redir_ipv6_type); | ||
70 | } | ||
71 | |||
72 | module_init(nft_redir_ipv6_module_init); | ||
73 | module_exit(nft_redir_ipv6_module_exit); | ||
74 | |||
75 | MODULE_LICENSE("GPL"); | ||
76 | MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>"); | ||
77 | MODULE_ALIAS_NFT_AF_EXPR(AF_INET6, "redir"); | ||
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 49deb4edbac6..373486ae4159 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig | |||
@@ -505,6 +505,15 @@ config NFT_MASQ | |||
505 | This option adds the "masquerade" expression that you can use | 505 | This option adds the "masquerade" expression that you can use |
506 | to perform NAT in the masquerade flavour. | 506 | to perform NAT in the masquerade flavour. |
507 | 507 | ||
508 | config NFT_REDIR | ||
509 | depends on NF_TABLES | ||
510 | depends on NF_CONNTRACK | ||
511 | depends on NF_NAT | ||
512 | tristate "Netfilter nf_tables redirect support" | ||
513 | help | ||
514 | This options adds the "redirect" expression that you can use | ||
515 | to perform NAT in the redirect flavour. | ||
516 | |||
508 | config NFT_NAT | 517 | config NFT_NAT |
509 | depends on NF_TABLES | 518 | depends on NF_TABLES |
510 | depends on NF_CONNTRACK | 519 | depends on NF_CONNTRACK |
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index a9571be3f791..f3eb4680f2ec 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile | |||
@@ -88,6 +88,7 @@ obj-$(CONFIG_NFT_HASH) += nft_hash.o | |||
88 | obj-$(CONFIG_NFT_COUNTER) += nft_counter.o | 88 | obj-$(CONFIG_NFT_COUNTER) += nft_counter.o |
89 | obj-$(CONFIG_NFT_LOG) += nft_log.o | 89 | obj-$(CONFIG_NFT_LOG) += nft_log.o |
90 | obj-$(CONFIG_NFT_MASQ) += nft_masq.o | 90 | obj-$(CONFIG_NFT_MASQ) += nft_masq.o |
91 | obj-$(CONFIG_NFT_REDIR) += nft_redir.o | ||
91 | 92 | ||
92 | # generic X tables | 93 | # generic X tables |
93 | obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o | 94 | obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o |
diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c new file mode 100644 index 000000000000..e27b4e35718a --- /dev/null +++ b/net/netfilter/nft_redir.c | |||
@@ -0,0 +1,98 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/netlink.h> | ||
13 | #include <linux/netfilter.h> | ||
14 | #include <linux/netfilter/nf_tables.h> | ||
15 | #include <net/netfilter/nf_nat.h> | ||
16 | #include <net/netfilter/nf_tables.h> | ||
17 | #include <net/netfilter/nft_redir.h> | ||
18 | |||
19 | const struct nla_policy nft_redir_policy[NFTA_REDIR_MAX + 1] = { | ||
20 | [NFTA_REDIR_REG_PROTO_MIN] = { .type = NLA_U32 }, | ||
21 | [NFTA_REDIR_REG_PROTO_MAX] = { .type = NLA_U32 }, | ||
22 | [NFTA_REDIR_FLAGS] = { .type = NLA_U32 }, | ||
23 | }; | ||
24 | EXPORT_SYMBOL_GPL(nft_redir_policy); | ||
25 | |||
26 | int nft_redir_init(const struct nft_ctx *ctx, | ||
27 | const struct nft_expr *expr, | ||
28 | const struct nlattr * const tb[]) | ||
29 | { | ||
30 | struct nft_redir *priv = nft_expr_priv(expr); | ||
31 | u32 nla_be32; | ||
32 | int err; | ||
33 | |||
34 | err = nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT); | ||
35 | if (err < 0) | ||
36 | return err; | ||
37 | |||
38 | if (tb[NFTA_REDIR_REG_PROTO_MIN]) { | ||
39 | nla_be32 = nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MIN]); | ||
40 | priv->sreg_proto_min = ntohl(nla_be32); | ||
41 | err = nft_validate_input_register(priv->sreg_proto_min); | ||
42 | if (err < 0) | ||
43 | return err; | ||
44 | |||
45 | if (tb[NFTA_REDIR_REG_PROTO_MAX]) { | ||
46 | nla_be32 = nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MAX]); | ||
47 | priv->sreg_proto_max = ntohl(nla_be32); | ||
48 | err = nft_validate_input_register(priv->sreg_proto_max); | ||
49 | if (err < 0) | ||
50 | return err; | ||
51 | } else { | ||
52 | priv->sreg_proto_max = priv->sreg_proto_min; | ||
53 | } | ||
54 | } | ||
55 | |||
56 | if (tb[NFTA_REDIR_FLAGS]) { | ||
57 | priv->flags = ntohl(nla_get_be32(tb[NFTA_REDIR_FLAGS])); | ||
58 | if (priv->flags & ~NF_NAT_RANGE_MASK) | ||
59 | return -EINVAL; | ||
60 | } | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | EXPORT_SYMBOL_GPL(nft_redir_init); | ||
65 | |||
66 | int nft_redir_dump(struct sk_buff *skb, const struct nft_expr *expr) | ||
67 | { | ||
68 | const struct nft_redir *priv = nft_expr_priv(expr); | ||
69 | |||
70 | if (priv->sreg_proto_min) { | ||
71 | if (nla_put_be32(skb, NFTA_REDIR_REG_PROTO_MIN, | ||
72 | htonl(priv->sreg_proto_min))) | ||
73 | goto nla_put_failure; | ||
74 | if (nla_put_be32(skb, NFTA_REDIR_REG_PROTO_MAX, | ||
75 | htonl(priv->sreg_proto_max))) | ||
76 | goto nla_put_failure; | ||
77 | } | ||
78 | |||
79 | if (priv->flags != 0 && | ||
80 | nla_put_be32(skb, NFTA_REDIR_FLAGS, htonl(priv->flags))) | ||
81 | goto nla_put_failure; | ||
82 | |||
83 | return 0; | ||
84 | |||
85 | nla_put_failure: | ||
86 | return -1; | ||
87 | } | ||
88 | EXPORT_SYMBOL_GPL(nft_redir_dump); | ||
89 | |||
90 | int nft_redir_validate(const struct nft_ctx *ctx, const struct nft_expr *expr, | ||
91 | const struct nft_data **data) | ||
92 | { | ||
93 | return nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT); | ||
94 | } | ||
95 | EXPORT_SYMBOL_GPL(nft_redir_validate); | ||
96 | |||
97 | MODULE_LICENSE("GPL"); | ||
98 | MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>"); | ||