summaryrefslogtreecommitdiff
path: root/net/netfilter
diff options
context:
space:
mode:
authorArturo Borrero <arturo.borrero.glez@gmail.com>2014-10-16 12:23:29 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2014-10-27 22:47:06 +0100
commit8b13eddfdf04cbfa561725cfc42d6868fe896f56 (patch)
treea54fcd289d9acb1566a841f66045127227c84d25 /net/netfilter
parentb8901ac319768cdd3afa060787503e0c405f9607 (diff)
netfilter: refactor NAT redirect IPv4 to use it from nf_tables
This patch refactors the IPv4 code so it can be usable both from xt and nf_tables. A similar patch follows-up to handle IPv6. Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/Kconfig1
-rw-r--r--net/netfilter/xt_REDIRECT.c44
2 files changed, 3 insertions, 42 deletions
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
config NETFILTER_XT_TARGET_REDIRECT
tristate "REDIRECT target support"
depends on NF_NAT
+ select NF_NAT_REDIRECT_IPV4
---help---
REDIRECT is a special case of NAT: all incoming connections are
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 @@
#include <net/checksum.h>
#include <net/protocol.h>
#include <net/netfilter/nf_nat.h>
+#include <net/netfilter/ipv4/nf_nat_redirect.h>
static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT;
@@ -98,48 +99,7 @@ static int redirect_tg4_check(const struct xt_tgchk_param *par)
static unsigned int
redirect_tg4(struct sk_buff *skb, const struct xt_action_param *par)
{
- struct nf_conn *ct;
- enum ip_conntrack_info ctinfo;
- __be32 newdst;
- const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
- struct nf_nat_range newrange;
-
- NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING ||
- par->hooknum == NF_INET_LOCAL_OUT);
-
- ct = nf_ct_get(skb, &ctinfo);
- NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
-
- /* Local packets: make them go to loopback */
- if (par->hooknum == NF_INET_LOCAL_OUT)
- newdst = htonl(0x7F000001);
- else {
- struct in_device *indev;
- struct in_ifaddr *ifa;
-
- newdst = 0;
-
- rcu_read_lock();
- indev = __in_dev_get_rcu(skb->dev);
- if (indev && (ifa = indev->ifa_list))
- newdst = ifa->ifa_local;
- rcu_read_unlock();
-
- if (!newdst)
- return NF_DROP;
- }
-
- /* Transfer from original range. */
- memset(&newrange.min_addr, 0, sizeof(newrange.min_addr));
- memset(&newrange.max_addr, 0, sizeof(newrange.max_addr));
- newrange.flags = mr->range[0].flags | NF_NAT_RANGE_MAP_IPS;
- newrange.min_addr.ip = newdst;
- newrange.max_addr.ip = newdst;
- newrange.min_proto = mr->range[0].min;
- newrange.max_proto = mr->range[0].max;
-
- /* Hand modified range to generic setup. */
- return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST);
+ return nf_nat_redirect_ipv4(skb, par->targinfo, par->hooknum);
}
static struct xt_target redirect_tg_reg[] __read_mostly = {