diff options
author | Arturo Borrero <arturo.borrero.glez@gmail.com> | 2014-10-17 06:37:52 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-10-27 17:48:10 -0400 |
commit | 9de920eddb74bf67f1d6af603acc5ed05dcd35e9 (patch) | |
tree | 096dea317cc6ee9d5de3b29b081e8a4968c51de0 | |
parent | 8b13eddfdf04cbfa561725cfc42d6868fe896f56 (diff) |
netfilter: refactor NAT redirect IPv6 code to use it from nf_tables
This patch refactors the IPv6 code so it can be usable both from xt and
nf_tables.
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/ipv6/nf_nat_redirect.h | 8 | ||||
-rw-r--r-- | net/ipv6/netfilter/Kconfig | 6 | ||||
-rw-r--r-- | net/ipv6/netfilter/Makefile | 1 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_nat_redirect_ipv6.c | 75 | ||||
-rw-r--r-- | net/netfilter/Kconfig | 1 | ||||
-rw-r--r-- | net/netfilter/xt_REDIRECT.c | 40 |
6 files changed, 93 insertions, 38 deletions
diff --git a/include/net/netfilter/ipv6/nf_nat_redirect.h b/include/net/netfilter/ipv6/nf_nat_redirect.h new file mode 100644 index 000000000000..1ebdffc461cc --- /dev/null +++ b/include/net/netfilter/ipv6/nf_nat_redirect.h | |||
@@ -0,0 +1,8 @@ | |||
1 | #ifndef _NF_NAT_REDIRECT_IPV6_H_ | ||
2 | #define _NF_NAT_REDIRECT_IPV6_H_ | ||
3 | |||
4 | unsigned int | ||
5 | nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range *range, | ||
6 | unsigned int hooknum); | ||
7 | |||
8 | #endif /* _NF_NAT_REDIRECT_IPV6_H_ */ | ||
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 6af874fc187f..462eebbf4377 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig | |||
@@ -82,6 +82,12 @@ config NF_NAT_MASQUERADE_IPV6 | |||
82 | This is the kernel functionality to provide NAT in the masquerade | 82 | This is the kernel functionality to provide NAT in the masquerade |
83 | flavour (automatic source address selection) for IPv6. | 83 | flavour (automatic source address selection) for IPv6. |
84 | 84 | ||
85 | config NF_NAT_REDIRECT_IPV6 | ||
86 | tristate "IPv6 redirect support" | ||
87 | help | ||
88 | This is the kernel functionality to provide NAT in the redirect | ||
89 | flavour (redirect packet to local machine) for IPv6. | ||
90 | |||
85 | config NFT_MASQ_IPV6 | 91 | config NFT_MASQ_IPV6 |
86 | tristate "IPv6 masquerade support for nf_tables" | 92 | tristate "IPv6 masquerade support for nf_tables" |
87 | depends on NF_TABLES_IPV6 | 93 | depends on NF_TABLES_IPV6 |
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile index fbb25f01143c..6c2baab10f21 100644 --- a/net/ipv6/netfilter/Makefile +++ b/net/ipv6/netfilter/Makefile | |||
@@ -19,6 +19,7 @@ obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o | |||
19 | nf_nat_ipv6-y := nf_nat_l3proto_ipv6.o nf_nat_proto_icmpv6.o | 19 | nf_nat_ipv6-y := nf_nat_l3proto_ipv6.o nf_nat_proto_icmpv6.o |
20 | obj-$(CONFIG_NF_NAT_IPV6) += nf_nat_ipv6.o | 20 | obj-$(CONFIG_NF_NAT_IPV6) += nf_nat_ipv6.o |
21 | obj-$(CONFIG_NF_NAT_MASQUERADE_IPV6) += nf_nat_masquerade_ipv6.o | 21 | obj-$(CONFIG_NF_NAT_MASQUERADE_IPV6) += nf_nat_masquerade_ipv6.o |
22 | obj-$(CONFIG_NF_NAT_REDIRECT_IPV6) += nf_nat_redirect_ipv6.o | ||
22 | 23 | ||
23 | # defrag | 24 | # defrag |
24 | nf_defrag_ipv6-y := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o | 25 | nf_defrag_ipv6-y := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o |
diff --git a/net/ipv6/netfilter/nf_nat_redirect_ipv6.c b/net/ipv6/netfilter/nf_nat_redirect_ipv6.c new file mode 100644 index 000000000000..ea1308aeb048 --- /dev/null +++ b/net/ipv6/netfilter/nf_nat_redirect_ipv6.c | |||
@@ -0,0 +1,75 @@ | |||
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_ipv6.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/ipv6/nf_nat_redirect.h> | ||
29 | |||
30 | static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT; | ||
31 | |||
32 | unsigned int | ||
33 | nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range *range, | ||
34 | unsigned int hooknum) | ||
35 | { | ||
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 (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 | EXPORT_SYMBOL_GPL(nf_nat_redirect_ipv6); | ||
73 | |||
74 | MODULE_LICENSE("GPL"); | ||
75 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | ||
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index a0716a3f08b0..49deb4edbac6 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig | |||
@@ -836,6 +836,7 @@ config 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 | select NF_NAT_REDIRECT_IPV4 |
839 | select NF_NAT_REDIRECT_IPV6 if IP6_NF_IPTABLES | ||
839 | ---help--- | 840 | ---help--- |
840 | REDIRECT is a special case of NAT: all incoming connections are | 841 | REDIRECT is a special case of NAT: all incoming connections are |
841 | mapped onto the incoming interface's address, causing the packets to | 842 | 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 b4ffac5fe8e9..b6ec67efd900 100644 --- a/net/netfilter/xt_REDIRECT.c +++ b/net/netfilter/xt_REDIRECT.c | |||
@@ -27,48 +27,12 @@ | |||
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 | #include <net/netfilter/ipv4/nf_nat_redirect.h> |
30 | 30 | #include <net/netfilter/ipv6/nf_nat_redirect.h> | |
31 | static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT; | ||
32 | 31 | ||
33 | static unsigned int | 32 | static unsigned int |
34 | redirect_tg6(struct sk_buff *skb, const struct xt_action_param *par) | 33 | redirect_tg6(struct sk_buff *skb, const struct xt_action_param *par) |
35 | { | 34 | { |
36 | const struct nf_nat_range *range = par->targinfo; | 35 | return nf_nat_redirect_ipv6(skb, par->targinfo, par->hooknum); |
37 | struct nf_nat_range newrange; | ||
38 | struct in6_addr newdst; | ||
39 | enum ip_conntrack_info ctinfo; | ||
40 | struct nf_conn *ct; | ||
41 | |||
42 | ct = nf_ct_get(skb, &ctinfo); | ||
43 | if (par->hooknum == NF_INET_LOCAL_OUT) | ||
44 | newdst = loopback_addr; | ||
45 | else { | ||
46 | struct inet6_dev *idev; | ||
47 | struct inet6_ifaddr *ifa; | ||
48 | bool addr = false; | ||
49 | |||
50 | rcu_read_lock(); | ||
51 | idev = __in6_dev_get(skb->dev); | ||
52 | if (idev != NULL) { | ||
53 | list_for_each_entry(ifa, &idev->addr_list, if_list) { | ||
54 | newdst = ifa->addr; | ||
55 | addr = true; | ||
56 | break; | ||
57 | } | ||
58 | } | ||
59 | rcu_read_unlock(); | ||
60 | |||
61 | if (!addr) | ||
62 | return NF_DROP; | ||
63 | } | ||
64 | |||
65 | newrange.flags = range->flags | NF_NAT_RANGE_MAP_IPS; | ||
66 | newrange.min_addr.in6 = newdst; | ||
67 | newrange.max_addr.in6 = newdst; | ||
68 | newrange.min_proto = range->min_proto; | ||
69 | newrange.max_proto = range->max_proto; | ||
70 | |||
71 | return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_DST); | ||
72 | } | 36 | } |
73 | 37 | ||
74 | static int redirect_tg6_checkentry(const struct xt_tgchk_param *par) | 38 | static int redirect_tg6_checkentry(const struct xt_tgchk_param *par) |