aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Engelhardt <jengelh@inai.de>2012-09-21 05:41:34 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2012-09-21 06:12:05 -0400
commit2cbc78a29e76a2e92c172651204f3117491877d2 (patch)
treef61c52236d72a68a746fa09def3052d712e7b0d0
parentb3d54b3e406b5d6ac391590bf7524e887e8e13c3 (diff)
netfilter: combine ipt_REDIRECT and ip6t_REDIRECT
Combine more modules since the actual code is so small anyway that the kmod metadata and the module in its loaded state totally outweighs the combined actual code size. IP_NF_TARGET_REDIRECT becomes a compat option; IP6_NF_TARGET_REDIRECT is completely eliminated since it has not see a release yet. Signed-off-by: Jan Engelhardt <jengelh@inai.de> Acked-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--net/ipv4/netfilter/Kconfig12
-rw-r--r--net/ipv4/netfilter/Makefile1
-rw-r--r--net/ipv4/netfilter/ipt_REDIRECT.c113
-rw-r--r--net/ipv6/netfilter/Kconfig10
-rw-r--r--net/ipv6/netfilter/Makefile1
-rw-r--r--net/ipv6/netfilter/ip6t_REDIRECT.c98
-rw-r--r--net/netfilter/Kconfig11
-rw-r--r--net/netfilter/Makefile1
-rw-r--r--net/netfilter/xt_REDIRECT.c190
9 files changed, 207 insertions, 230 deletions
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 6f140084004f..d8d6f2a5bf12 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -181,13 +181,11 @@ config IP_NF_TARGET_NETMAP
181config IP_NF_TARGET_REDIRECT 181config IP_NF_TARGET_REDIRECT
182 tristate "REDIRECT target support" 182 tristate "REDIRECT target support"
183 depends on NETFILTER_ADVANCED 183 depends on NETFILTER_ADVANCED
184 help 184 select NETFILTER_XT_TARGET_REDIRECT
185 REDIRECT is a special case of NAT: all incoming connections are 185 ---help---
186 mapped onto the incoming interface's address, causing the packets to 186 This is a backwards-compat option for the user's convenience
187 come to the local machine instead of passing through. This is 187 (e.g. when running oldconfig). It selects
188 useful for transparent proxies. 188 CONFIG_NETFILTER_XT_TARGET_REDIRECT.
189
190 To compile it as a module, choose M here. If unsure, say N.
191 189
192endif 190endif
193 191
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index f4446c5d6595..007b128eecc9 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -45,7 +45,6 @@ obj-$(CONFIG_IP_NF_MATCH_RPFILTER) += ipt_rpfilter.o
45obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o 45obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
46obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o 46obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
47obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o 47obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
48obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
49obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o 48obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
50obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o 49obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
51 50
diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c
deleted file mode 100644
index 11407d7d2472..000000000000
--- a/net/ipv4/netfilter/ipt_REDIRECT.c
+++ /dev/null
@@ -1,113 +0,0 @@
1/* Redirect. Simple mapping which alters dst to a local IP address. */
2/* (C) 1999-2001 Paul `Rusty' Russell
3 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10#include <linux/types.h>
11#include <linux/ip.h>
12#include <linux/timer.h>
13#include <linux/module.h>
14#include <linux/netfilter.h>
15#include <linux/netdevice.h>
16#include <linux/if.h>
17#include <linux/inetdevice.h>
18#include <net/protocol.h>
19#include <net/checksum.h>
20#include <linux/netfilter_ipv4.h>
21#include <linux/netfilter/x_tables.h>
22#include <net/netfilter/nf_nat.h>
23
24MODULE_LICENSE("GPL");
25MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
26MODULE_DESCRIPTION("Xtables: Connection redirection to localhost");
27
28/* FIXME: Take multiple ranges --RR */
29static int redirect_tg_check(const struct xt_tgchk_param *par)
30{
31 const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
32
33 if (mr->range[0].flags & NF_NAT_RANGE_MAP_IPS) {
34 pr_debug("bad MAP_IPS.\n");
35 return -EINVAL;
36 }
37 if (mr->rangesize != 1) {
38 pr_debug("bad rangesize %u.\n", mr->rangesize);
39 return -EINVAL;
40 }
41 return 0;
42}
43
44static unsigned int
45redirect_tg(struct sk_buff *skb, const struct xt_action_param *par)
46{
47 struct nf_conn *ct;
48 enum ip_conntrack_info ctinfo;
49 __be32 newdst;
50 const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
51 struct nf_nat_range newrange;
52
53 NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING ||
54 par->hooknum == NF_INET_LOCAL_OUT);
55
56 ct = nf_ct_get(skb, &ctinfo);
57 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
58
59 /* Local packets: make them go to loopback */
60 if (par->hooknum == NF_INET_LOCAL_OUT)
61 newdst = htonl(0x7F000001);
62 else {
63 struct in_device *indev;
64 struct in_ifaddr *ifa;
65
66 newdst = 0;
67
68 rcu_read_lock();
69 indev = __in_dev_get_rcu(skb->dev);
70 if (indev && (ifa = indev->ifa_list))
71 newdst = ifa->ifa_local;
72 rcu_read_unlock();
73
74 if (!newdst)
75 return NF_DROP;
76 }
77
78 /* Transfer from original range. */
79 memset(&newrange.min_addr, 0, sizeof(newrange.min_addr));
80 memset(&newrange.max_addr, 0, sizeof(newrange.max_addr));
81 newrange.flags = mr->range[0].flags | NF_NAT_RANGE_MAP_IPS;
82 newrange.min_addr.ip = newdst;
83 newrange.max_addr.ip = newdst;
84 newrange.min_proto = mr->range[0].min;
85 newrange.max_proto = mr->range[0].max;
86
87 /* Hand modified range to generic setup. */
88 return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST);
89}
90
91static struct xt_target redirect_tg_reg __read_mostly = {
92 .name = "REDIRECT",
93 .family = NFPROTO_IPV4,
94 .target = redirect_tg,
95 .targetsize = sizeof(struct nf_nat_ipv4_multi_range_compat),
96 .table = "nat",
97 .hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT),
98 .checkentry = redirect_tg_check,
99 .me = THIS_MODULE,
100};
101
102static int __init redirect_tg_init(void)
103{
104 return xt_register_target(&redirect_tg_reg);
105}
106
107static void __exit redirect_tg_exit(void)
108{
109 xt_unregister_target(&redirect_tg_reg);
110}
111
112module_init(redirect_tg_init);
113module_exit(redirect_tg_exit);
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 007bb450f04f..c72532a60d88 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -209,16 +209,6 @@ config IP6_NF_TARGET_MASQUERADE
209 209
210 To compile it as a module, choose M here. If unsure, say N. 210 To compile it as a module, choose M here. If unsure, say N.
211 211
212config IP6_NF_TARGET_REDIRECT
213 tristate "REDIRECT target support"
214 help
215 REDIRECT is a special case of NAT: all incoming connections are
216 mapped onto the incoming interface's address, causing the packets to
217 come to the local machine instead of passing through. This is
218 useful for transparent proxies.
219
220 To compile it as a module, choose M here. If unsure, say N.
221
222config IP6_NF_TARGET_NPT 212config IP6_NF_TARGET_NPT
223 tristate "NPT (Network Prefix translation) target support" 213 tristate "NPT (Network Prefix translation) target support"
224 help 214 help
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index de8e0d11338d..2d11fcc2cf3c 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -36,5 +36,4 @@ obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
36# targets 36# targets
37obj-$(CONFIG_IP6_NF_TARGET_MASQUERADE) += ip6t_MASQUERADE.o 37obj-$(CONFIG_IP6_NF_TARGET_MASQUERADE) += ip6t_MASQUERADE.o
38obj-$(CONFIG_IP6_NF_TARGET_NPT) += ip6t_NPT.o 38obj-$(CONFIG_IP6_NF_TARGET_NPT) += ip6t_NPT.o
39obj-$(CONFIG_IP6_NF_TARGET_REDIRECT) += ip6t_REDIRECT.o
40obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o 39obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
diff --git a/net/ipv6/netfilter/ip6t_REDIRECT.c b/net/ipv6/netfilter/ip6t_REDIRECT.c
deleted file mode 100644
index 60497a3c6004..000000000000
--- a/net/ipv6/netfilter/ip6t_REDIRECT.c
+++ /dev/null
@@ -1,98 +0,0 @@
1/*
2 * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
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 * Based on Rusty Russell's IPv4 REDIRECT target. Development of IPv6
9 * NAT funded by Astaro.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/netfilter.h>
15#include <linux/netfilter_ipv6.h>
16#include <linux/netfilter/x_tables.h>
17#include <net/addrconf.h>
18#include <net/netfilter/nf_nat.h>
19
20static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT;
21
22static unsigned int
23redirect_tg6(struct sk_buff *skb, const struct xt_action_param *par)
24{
25 const struct nf_nat_range *range = par->targinfo;
26 struct nf_nat_range newrange;
27 struct in6_addr newdst;
28 enum ip_conntrack_info ctinfo;
29 struct nf_conn *ct;
30
31 ct = nf_ct_get(skb, &ctinfo);
32 if (par->hooknum == NF_INET_LOCAL_OUT)
33 newdst = loopback_addr;
34 else {
35 struct inet6_dev *idev;
36 struct inet6_ifaddr *ifa;
37 bool addr = false;
38
39 rcu_read_lock();
40 idev = __in6_dev_get(skb->dev);
41 if (idev != NULL) {
42 list_for_each_entry(ifa, &idev->addr_list, if_list) {
43 newdst = ifa->addr;
44 addr = true;
45 break;
46 }
47 }
48 rcu_read_unlock();
49
50 if (!addr)
51 return NF_DROP;
52 }
53
54 newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS;
55 newrange.min_addr.in6 = newdst;
56 newrange.max_addr.in6 = newdst;
57 newrange.min_proto = range->min_proto;
58 newrange.max_proto = range->max_proto;
59
60 return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST);
61}
62
63static int redirect_tg6_checkentry(const struct xt_tgchk_param *par)
64{
65 const struct nf_nat_range *range = par->targinfo;
66
67 if (range->flags & NF_NAT_RANGE_MAP_IPS)
68 return -EINVAL;
69 return 0;
70}
71
72static struct xt_target redirect_tg6_reg __read_mostly = {
73 .name = "REDIRECT",
74 .family = NFPROTO_IPV6,
75 .checkentry = redirect_tg6_checkentry,
76 .target = redirect_tg6,
77 .targetsize = sizeof(struct nf_nat_range),
78 .table = "nat",
79 .hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT),
80 .me = THIS_MODULE,
81};
82
83static int __init redirect_tg6_init(void)
84{
85 return xt_register_target(&redirect_tg6_reg);
86}
87
88static void __exit redirect_tg6_exit(void)
89{
90 xt_unregister_target(&redirect_tg6_reg);
91}
92
93module_init(redirect_tg6_init);
94module_exit(redirect_tg6_exit);
95
96MODULE_LICENSE("GPL");
97MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
98MODULE_DESCRIPTION("Xtables: Connection redirection to localhost");
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index ad0e0da62ede..fefa514b9917 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -690,6 +690,17 @@ config NETFILTER_XT_TARGET_RATEEST
690 690
691 To compile it as a module, choose M here. If unsure, say N. 691 To compile it as a module, choose M here. If unsure, say N.
692 692
693config NETFILTER_XT_TARGET_REDIRECT
694 tristate "REDIRECT target support"
695 depends on NF_NAT
696 ---help---
697 REDIRECT is a special case of NAT: all incoming connections are
698 mapped onto the incoming interface's address, causing the packets to
699 come to the local machine instead of passing through. This is
700 useful for transparent proxies.
701
702 To compile it as a module, choose M here. If unsure, say N.
703
693config NETFILTER_XT_TARGET_TEE 704config NETFILTER_XT_TARGET_TEE
694 tristate '"TEE" - packet cloning to alternate destination' 705 tristate '"TEE" - packet cloning to alternate destination'
695 depends on NETFILTER_ADVANCED 706 depends on NETFILTER_ADVANCED
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 600d28ba514c..32596978df1d 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -87,6 +87,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NETMAP) += xt_NETMAP.o
87obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o 87obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
88obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o 88obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
89obj-$(CONFIG_NETFILTER_XT_TARGET_RATEEST) += xt_RATEEST.o 89obj-$(CONFIG_NETFILTER_XT_TARGET_RATEEST) += xt_RATEEST.o
90obj-$(CONFIG_NETFILTER_XT_TARGET_REDIRECT) += xt_REDIRECT.o
90obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o 91obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
91obj-$(CONFIG_NETFILTER_XT_TARGET_TPROXY) += xt_TPROXY.o 92obj-$(CONFIG_NETFILTER_XT_TARGET_TPROXY) += xt_TPROXY.o
92obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o 93obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
diff --git a/net/netfilter/xt_REDIRECT.c b/net/netfilter/xt_REDIRECT.c
new file mode 100644
index 000000000000..22a10309297c
--- /dev/null
+++ b/net/netfilter/xt_REDIRECT.c
@@ -0,0 +1,190 @@
1/*
2 * (C) 1999-2001 Paul `Rusty' Russell
3 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
4 * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Based on Rusty Russell's IPv4 REDIRECT target. Development of IPv6
11 * NAT funded by Astaro.
12 */
13
14#include <linux/if.h>
15#include <linux/inetdevice.h>
16#include <linux/ip.h>
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/netdevice.h>
20#include <linux/netfilter.h>
21#include <linux/types.h>
22#include <linux/netfilter_ipv4.h>
23#include <linux/netfilter_ipv6.h>
24#include <linux/netfilter/x_tables.h>
25#include <net/addrconf.h>
26#include <net/checksum.h>
27#include <net/protocol.h>
28#include <net/netfilter/nf_nat.h>
29
30static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT;
31
32static unsigned int
33redirect_tg6(struct sk_buff *skb, const struct xt_action_param *par)
34{
35 const struct nf_nat_range *range = par->targinfo;
36 struct nf_nat_range newrange;
37 struct in6_addr newdst;
38 enum ip_conntrack_info ctinfo;
39 struct nf_conn *ct;
40
41 ct = nf_ct_get(skb, &ctinfo);
42 if (par->hooknum == NF_INET_LOCAL_OUT)
43 newdst = loopback_addr;
44 else {
45 struct inet6_dev *idev;
46 struct inet6_ifaddr *ifa;
47 bool addr = false;
48
49 rcu_read_lock();
50 idev = __in6_dev_get(skb->dev);
51 if (idev != NULL) {
52 list_for_each_entry(ifa, &idev->addr_list, if_list) {
53 newdst = ifa->addr;
54 addr = true;
55 break;
56 }
57 }
58 rcu_read_unlock();
59
60 if (!addr)
61 return NF_DROP;
62 }
63
64 newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS;
65 newrange.min_addr.in6 = newdst;
66 newrange.max_addr.in6 = newdst;
67 newrange.min_proto = range->min_proto;
68 newrange.max_proto = range->max_proto;
69
70 return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST);
71}
72
73static int redirect_tg6_checkentry(const struct xt_tgchk_param *par)
74{
75 const struct nf_nat_range *range = par->targinfo;
76
77 if (range->flags & NF_NAT_RANGE_MAP_IPS)
78 return -EINVAL;
79 return 0;
80}
81
82/* FIXME: Take multiple ranges --RR */
83static int redirect_tg4_check(const struct xt_tgchk_param *par)
84{
85 const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
86
87 if (mr->range[0].flags & NF_NAT_RANGE_MAP_IPS) {
88 pr_debug("bad MAP_IPS.\n");
89 return -EINVAL;
90 }
91 if (mr->rangesize != 1) {
92 pr_debug("bad rangesize %u.\n", mr->rangesize);
93 return -EINVAL;
94 }
95 return 0;
96}
97
98static unsigned int
99redirect_tg4(struct sk_buff *skb, const struct xt_action_param *par)
100{
101 struct nf_conn *ct;
102 enum ip_conntrack_info ctinfo;
103 __be32 newdst;
104 const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
105 struct nf_nat_range newrange;
106
107 NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING ||
108 par->hooknum == NF_INET_LOCAL_OUT);
109
110 ct = nf_ct_get(skb, &ctinfo);
111 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
112
113 /* Local packets: make them go to loopback */
114 if (par->hooknum == NF_INET_LOCAL_OUT)
115 newdst = htonl(0x7F000001);
116 else {
117 struct in_device *indev;
118 struct in_ifaddr *ifa;
119
120 newdst = 0;
121
122 rcu_read_lock();
123 indev = __in_dev_get_rcu(skb->dev);
124 if (indev && (ifa = indev->ifa_list))
125 newdst = ifa->ifa_local;
126 rcu_read_unlock();
127
128 if (!newdst)
129 return NF_DROP;
130 }
131
132 /* Transfer from original range. */
133 memset(&newrange.min_addr, 0, sizeof(newrange.min_addr));
134 memset(&newrange.max_addr, 0, sizeof(newrange.max_addr));
135 newrange.flags = mr->range[0].flags | NF_NAT_RANGE_MAP_IPS;
136 newrange.min_addr.ip = newdst;
137 newrange.max_addr.ip = newdst;
138 newrange.min_proto = mr->range[0].min;
139 newrange.max_proto = mr->range[0].max;
140
141 /* Hand modified range to generic setup. */
142 return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST);
143}
144
145static struct xt_target redirect_tg_reg[] __read_mostly = {
146 {
147 .name = "REDIRECT",
148 .family = NFPROTO_IPV6,
149 .revision = 0,
150 .table = "nat",
151 .checkentry = redirect_tg6_checkentry,
152 .target = redirect_tg6,
153 .targetsize = sizeof(struct nf_nat_range),
154 .hooks = (1 << NF_INET_PRE_ROUTING) |
155 (1 << NF_INET_LOCAL_OUT),
156 .me = THIS_MODULE,
157 },
158 {
159 .name = "REDIRECT",
160 .family = NFPROTO_IPV4,
161 .revision = 0,
162 .table = "nat",
163 .target = redirect_tg4,
164 .checkentry = redirect_tg4_check,
165 .targetsize = sizeof(struct nf_nat_ipv4_multi_range_compat),
166 .hooks = (1 << NF_INET_PRE_ROUTING) |
167 (1 << NF_INET_LOCAL_OUT),
168 .me = THIS_MODULE,
169 },
170};
171
172static int __init redirect_tg_init(void)
173{
174 return xt_register_targets(redirect_tg_reg,
175 ARRAY_SIZE(redirect_tg_reg));
176}
177
178static void __exit redirect_tg_exit(void)
179{
180 xt_unregister_targets(redirect_tg_reg, ARRAY_SIZE(redirect_tg_reg));
181}
182
183module_init(redirect_tg_init);
184module_exit(redirect_tg_exit);
185
186MODULE_LICENSE("GPL");
187MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
188MODULE_DESCRIPTION("Xtables: Connection redirection to localhost");
189MODULE_ALIAS("ip6t_REDIRECT");
190MODULE_ALIAS("ipt_REDIRECT");