aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArturo Borrero <arturo.borrero.glez@gmail.com>2014-10-17 06:39:09 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2014-10-27 17:49:39 -0400
commite9105f1bead4ec3f64904564c7c6268185d6b363 (patch)
treec2b91e5f3183503759fd8759cdeb9bf3ccf45af2
parent9de920eddb74bf67f1d6af603acc5ed05dcd35e9 (diff)
netfilter: nf_tables: add new expression nft_redir
This new expression provides NAT in the redirect flavour, which is to redirect packets to local machine. Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/net/netfilter/nft_redir.h21
-rw-r--r--include/uapi/linux/netfilter/nf_tables.h16
-rw-r--r--net/ipv4/netfilter/Kconfig9
-rw-r--r--net/ipv4/netfilter/Makefile1
-rw-r--r--net/ipv4/netfilter/nft_redir_ipv4.c77
-rw-r--r--net/ipv6/netfilter/Kconfig9
-rw-r--r--net/ipv6/netfilter/Makefile1
-rw-r--r--net/ipv6/netfilter/nft_redir_ipv6.c77
-rw-r--r--net/netfilter/Kconfig9
-rw-r--r--net/netfilter/Makefile1
-rw-r--r--net/netfilter/nft_redir.c98
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
4struct nft_redir {
5 enum nft_registers sreg_proto_min:8;
6 enum nft_registers sreg_proto_max:8;
7 u16 flags;
8};
9
10extern const struct nla_policy nft_redir_policy[];
11
12int nft_redir_init(const struct nft_ctx *ctx,
13 const struct nft_expr *expr,
14 const struct nlattr * const tb[]);
15
16int nft_redir_dump(struct sk_buff *skb, const struct nft_expr *expr);
17
18int 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 */
847enum 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
122config 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
122config NF_NAT_SNMP_BASIC 131config 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
41obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o 41obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o
42obj-$(CONFIG_NFT_REJECT_IPV4) += nft_reject_ipv4.o 42obj-$(CONFIG_NFT_REJECT_IPV4) += nft_reject_ipv4.o
43obj-$(CONFIG_NFT_MASQ_IPV4) += nft_masq_ipv4.o 43obj-$(CONFIG_NFT_MASQ_IPV4) += nft_masq_ipv4.o
44obj-$(CONFIG_NFT_REDIR_IPV4) += nft_redir_ipv4.o
44obj-$(CONFIG_NF_TABLES_ARP) += nf_tables_arp.o 45obj-$(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
20static 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
43static struct nft_expr_type nft_redir_ipv4_type;
44static 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
53static 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
62static int __init nft_redir_ipv4_module_init(void)
63{
64 return nft_register_expr(&nft_redir_ipv4_type);
65}
66
67static void __exit nft_redir_ipv4_module_exit(void)
68{
69 nft_unregister_expr(&nft_redir_ipv4_type);
70}
71
72module_init(nft_redir_ipv4_module_init);
73module_exit(nft_redir_ipv4_module_exit);
74
75MODULE_LICENSE("GPL");
76MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>");
77MODULE_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
100config 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
100endif # NF_NAT_IPV6 109endif # NF_NAT_IPV6
101 110
102config IP6_NF_IPTABLES 111config 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
37obj-$(CONFIG_NFT_CHAIN_NAT_IPV6) += nft_chain_nat_ipv6.o 37obj-$(CONFIG_NFT_CHAIN_NAT_IPV6) += nft_chain_nat_ipv6.o
38obj-$(CONFIG_NFT_REJECT_IPV6) += nft_reject_ipv6.o 38obj-$(CONFIG_NFT_REJECT_IPV6) += nft_reject_ipv6.o
39obj-$(CONFIG_NFT_MASQ_IPV6) += nft_masq_ipv6.o 39obj-$(CONFIG_NFT_MASQ_IPV6) += nft_masq_ipv6.o
40obj-$(CONFIG_NFT_REDIR_IPV6) += nft_redir_ipv6.o
40 41
41# matches 42# matches
42obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o 43obj-$(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
20static 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
43static struct nft_expr_type nft_redir_ipv6_type;
44static 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
53static 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
62static int __init nft_redir_ipv6_module_init(void)
63{
64 return nft_register_expr(&nft_redir_ipv6_type);
65}
66
67static void __exit nft_redir_ipv6_module_exit(void)
68{
69 nft_unregister_expr(&nft_redir_ipv6_type);
70}
71
72module_init(nft_redir_ipv6_module_init);
73module_exit(nft_redir_ipv6_module_exit);
74
75MODULE_LICENSE("GPL");
76MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>");
77MODULE_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
508config 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
508config NFT_NAT 517config 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
88obj-$(CONFIG_NFT_COUNTER) += nft_counter.o 88obj-$(CONFIG_NFT_COUNTER) += nft_counter.o
89obj-$(CONFIG_NFT_LOG) += nft_log.o 89obj-$(CONFIG_NFT_LOG) += nft_log.o
90obj-$(CONFIG_NFT_MASQ) += nft_masq.o 90obj-$(CONFIG_NFT_MASQ) += nft_masq.o
91obj-$(CONFIG_NFT_REDIR) += nft_redir.o
91 92
92# generic X tables 93# generic X tables
93obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o 94obj-$(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
19const 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};
24EXPORT_SYMBOL_GPL(nft_redir_policy);
25
26int 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}
64EXPORT_SYMBOL_GPL(nft_redir_init);
65
66int 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
85nla_put_failure:
86 return -1;
87}
88EXPORT_SYMBOL_GPL(nft_redir_dump);
89
90int 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}
95EXPORT_SYMBOL_GPL(nft_redir_validate);
96
97MODULE_LICENSE("GPL");
98MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>");