aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netfilter/ipv4/nf_nat_redirect.h9
-rw-r--r--net/ipv4/netfilter/Kconfig6
-rw-r--r--net/ipv4/netfilter/Makefile1
-rw-r--r--net/ipv4/netfilter/nf_nat_redirect_ipv4.c82
-rw-r--r--net/netfilter/Kconfig1
-rw-r--r--net/netfilter/xt_REDIRECT.c44
6 files changed, 101 insertions, 42 deletions
diff --git a/include/net/netfilter/ipv4/nf_nat_redirect.h b/include/net/netfilter/ipv4/nf_nat_redirect.h
new file mode 100644
index 000000000000..19e1df3a0a4d
--- /dev/null
+++ b/include/net/netfilter/ipv4/nf_nat_redirect.h
@@ -0,0 +1,9 @@
1#ifndef _NF_NAT_REDIRECT_IPV4_H_
2#define _NF_NAT_REDIRECT_IPV4_H_
3
4unsigned int
5nf_nat_redirect_ipv4(struct sk_buff *skb,
6 const struct nf_nat_ipv4_multi_range_compat *mr,
7 unsigned int hooknum);
8
9#endif /* _NF_NAT_REDIRECT_IPV4_H_ */
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 4c019d5c3f57..a300e2c32b26 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -104,6 +104,12 @@ config NF_NAT_MASQUERADE_IPV4
104 This is the kernel functionality to provide NAT in the masquerade 104 This is the kernel functionality to provide NAT in the masquerade
105 flavour (automatic source address selection). 105 flavour (automatic source address selection).
106 106
107config NF_NAT_REDIRECT_IPV4
108 tristate "IPv4 redirect support"
109 help
110 This is the kernel functionality to provide NAT in the redirect
111 flavour (redirect packets to local machine).
112
107config NFT_MASQ_IPV4 113config NFT_MASQ_IPV4
108 tristate "IPv4 masquerading support for nf_tables" 114 tristate "IPv4 masquerading support for nf_tables"
109 depends on NF_TABLES_IPV4 115 depends on NF_TABLES_IPV4
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index f4cef5af0969..34e436c92015 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o
31obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o 31obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o
32obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o 32obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o
33obj-$(CONFIG_NF_NAT_MASQUERADE_IPV4) += nf_nat_masquerade_ipv4.o 33obj-$(CONFIG_NF_NAT_MASQUERADE_IPV4) += nf_nat_masquerade_ipv4.o
34obj-$(CONFIG_NF_NAT_REDIRECT_IPV4) += nf_nat_redirect_ipv4.o
34 35
35# NAT protocols (nf_nat) 36# NAT protocols (nf_nat)
36obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o 37obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o
diff --git a/net/ipv4/netfilter/nf_nat_redirect_ipv4.c b/net/ipv4/netfilter/nf_nat_redirect_ipv4.c
new file mode 100644
index 000000000000..a220552fc532
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_redirect_ipv4.c
@@ -0,0 +1,82 @@
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/x_tables.h>
24#include <net/addrconf.h>
25#include <net/checksum.h>
26#include <net/protocol.h>
27#include <net/netfilter/nf_nat.h>
28#include <net/netfilter/ipv4/nf_nat_redirect.h>
29
30unsigned int
31nf_nat_redirect_ipv4(struct sk_buff *skb,
32 const struct nf_nat_ipv4_multi_range_compat *mr,
33 unsigned int hooknum)
34{
35 struct nf_conn *ct;
36 enum ip_conntrack_info ctinfo;
37 __be32 newdst;
38 struct nf_nat_range newrange;
39
40 NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING ||
41 hooknum == NF_INET_LOCAL_OUT);
42
43 ct = nf_ct_get(skb, &ctinfo);
44 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
45
46 /* Local packets: make them go to loopback */
47 if (hooknum == NF_INET_LOCAL_OUT) {
48 newdst = htonl(0x7F000001);
49 } else {
50 struct in_device *indev;
51 struct in_ifaddr *ifa;
52
53 newdst = 0;
54
55 rcu_read_lock();
56 indev = __in_dev_get_rcu(skb->dev);
57 if (indev != NULL) {
58 ifa = indev->ifa_list;
59 newdst = ifa->ifa_local;
60 }
61 rcu_read_unlock();
62
63 if (!newdst)
64 return NF_DROP;
65 }
66
67 /* Transfer from original range. */
68 memset(&newrange.min_addr, 0, sizeof(newrange.min_addr));
69 memset(&newrange.max_addr, 0, sizeof(newrange.max_addr));
70 newrange.flags = mr->range[0].flags | NF_NAT_RANGE_MAP_IPS;
71 newrange.min_addr.ip = newdst;
72 newrange.max_addr.ip = newdst;
73 newrange.min_proto = mr->range[0].min;
74 newrange.max_proto = mr->range[0].max;
75
76 /* Hand modified range to generic setup. */
77 return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST);
78}
79EXPORT_SYMBOL_GPL(nf_nat_redirect_ipv4);
80
81MODULE_LICENSE("GPL");
82MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index ae5096ab65eb..a0716a3f08b0 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -835,6 +835,7 @@ config NETFILTER_XT_TARGET_RATEEST
835config NETFILTER_XT_TARGET_REDIRECT 835config NETFILTER_XT_TARGET_REDIRECT
836 tristate "REDIRECT target support" 836 tristate "REDIRECT target support"
837 depends on NF_NAT 837 depends on NF_NAT
838 select NF_NAT_REDIRECT_IPV4
838 ---help--- 839 ---help---
839 REDIRECT is a special case of NAT: all incoming connections are 840 REDIRECT is a special case of NAT: all incoming connections are
840 mapped onto the incoming interface's address, causing the packets to 841 mapped onto the incoming interface's address, causing the packets to
diff --git a/net/netfilter/xt_REDIRECT.c b/net/netfilter/xt_REDIRECT.c
index 22a10309297c..b4ffac5fe8e9 100644
--- a/net/netfilter/xt_REDIRECT.c
+++ b/net/netfilter/xt_REDIRECT.c
@@ -26,6 +26,7 @@
26#include <net/checksum.h> 26#include <net/checksum.h>
27#include <net/protocol.h> 27#include <net/protocol.h>
28#include <net/netfilter/nf_nat.h> 28#include <net/netfilter/nf_nat.h>
29#include <net/netfilter/ipv4/nf_nat_redirect.h>
29 30
30static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT; 31static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT;
31 32
@@ -98,48 +99,7 @@ static int redirect_tg4_check(const struct xt_tgchk_param *par)
98static unsigned int 99static unsigned int
99redirect_tg4(struct sk_buff *skb, const struct xt_action_param *par) 100redirect_tg4(struct sk_buff *skb, const struct xt_action_param *par)
100{ 101{
101 struct nf_conn *ct; 102 return nf_nat_redirect_ipv4(skb, par->targinfo, par->hooknum);
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} 103}
144 104
145static struct xt_target redirect_tg_reg[] __read_mostly = { 105static struct xt_target redirect_tg_reg[] __read_mostly = {