diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/netfilter/Kconfig | 15 | ||||
-rw-r--r-- | net/ipv6/netfilter/Makefile | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_log_ipv6.c | 12 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_nat_redirect_ipv6.c | 75 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_reject_ipv6.c | 1 | ||||
-rw-r--r-- | net/ipv6/netfilter/nft_redir_ipv6.c | 77 | ||||
-rw-r--r-- | net/ipv6/netfilter/nft_reject_ipv6.c | 7 |
7 files changed, 184 insertions, 5 deletions
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 6af874fc187f..0dbe5c7953e5 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 |
@@ -91,6 +97,15 @@ config NFT_MASQ_IPV6 | |||
91 | This is the expression that provides IPv4 masquerading support for | 97 | This is the expression that provides IPv4 masquerading support for |
92 | nf_tables. | 98 | nf_tables. |
93 | 99 | ||
100 | config 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 | |||
94 | endif # NF_NAT_IPV6 | 109 | endif # NF_NAT_IPV6 |
95 | 110 | ||
96 | config IP6_NF_IPTABLES | 111 | config IP6_NF_IPTABLES |
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile index fbb25f01143c..d2ac9f5f212c 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 |
@@ -36,6 +37,7 @@ obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV6) += nft_chain_route_ipv6.o | |||
36 | obj-$(CONFIG_NFT_CHAIN_NAT_IPV6) += nft_chain_nat_ipv6.o | 37 | obj-$(CONFIG_NFT_CHAIN_NAT_IPV6) += nft_chain_nat_ipv6.o |
37 | obj-$(CONFIG_NFT_REJECT_IPV6) += nft_reject_ipv6.o | 38 | obj-$(CONFIG_NFT_REJECT_IPV6) += nft_reject_ipv6.o |
38 | obj-$(CONFIG_NFT_MASQ_IPV6) += nft_masq_ipv6.o | 39 | obj-$(CONFIG_NFT_MASQ_IPV6) += nft_masq_ipv6.o |
40 | obj-$(CONFIG_NFT_REDIR_IPV6) += nft_redir_ipv6.o | ||
39 | 41 | ||
40 | # matches | 42 | # matches |
41 | obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o | 43 | obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o |
diff --git a/net/ipv6/netfilter/nf_log_ipv6.c b/net/ipv6/netfilter/nf_log_ipv6.c index 7b17a0be93e7..7fc34d1681a1 100644 --- a/net/ipv6/netfilter/nf_log_ipv6.c +++ b/net/ipv6/netfilter/nf_log_ipv6.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * it under the terms of the GNU General Public License version 2 as | 5 | * it under the terms of the GNU General Public License version 2 as |
6 | * published by the Free Software Foundation. | 6 | * published by the Free Software Foundation. |
7 | */ | 7 | */ |
8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
8 | 9 | ||
9 | #include <linux/module.h> | 10 | #include <linux/module.h> |
10 | #include <linux/spinlock.h> | 11 | #include <linux/spinlock.h> |
@@ -398,8 +399,17 @@ static int __init nf_log_ipv6_init(void) | |||
398 | if (ret < 0) | 399 | if (ret < 0) |
399 | return ret; | 400 | return ret; |
400 | 401 | ||
401 | nf_log_register(NFPROTO_IPV6, &nf_ip6_logger); | 402 | ret = nf_log_register(NFPROTO_IPV6, &nf_ip6_logger); |
403 | if (ret < 0) { | ||
404 | pr_err("failed to register logger\n"); | ||
405 | goto err1; | ||
406 | } | ||
407 | |||
402 | return 0; | 408 | return 0; |
409 | |||
410 | err1: | ||
411 | unregister_pernet_subsys(&nf_log_ipv6_net_ops); | ||
412 | return ret; | ||
403 | } | 413 | } |
404 | 414 | ||
405 | static void __exit nf_log_ipv6_exit(void) | 415 | static void __exit nf_log_ipv6_exit(void) |
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/ipv6/netfilter/nf_reject_ipv6.c b/net/ipv6/netfilter/nf_reject_ipv6.c index 015eb8a80766..d05b36440e8b 100644 --- a/net/ipv6/netfilter/nf_reject_ipv6.c +++ b/net/ipv6/netfilter/nf_reject_ipv6.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <net/ip6_route.h> | 11 | #include <net/ip6_route.h> |
12 | #include <net/ip6_fib.h> | 12 | #include <net/ip6_fib.h> |
13 | #include <net/ip6_checksum.h> | 13 | #include <net/ip6_checksum.h> |
14 | #include <net/netfilter/ipv6/nf_reject.h> | ||
14 | #include <linux/netfilter_ipv6.h> | 15 | #include <linux/netfilter_ipv6.h> |
15 | #include <net/netfilter/ipv6/nf_reject.h> | 16 | #include <net/netfilter/ipv6/nf_reject.h> |
16 | 17 | ||
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 | |||
20 | static 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 | |||
43 | static struct nft_expr_type nft_redir_ipv6_type; | ||
44 | static 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 | |||
53 | static 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 | |||
62 | static int __init nft_redir_ipv6_module_init(void) | ||
63 | { | ||
64 | return nft_register_expr(&nft_redir_ipv6_type); | ||
65 | } | ||
66 | |||
67 | static void __exit nft_redir_ipv6_module_exit(void) | ||
68 | { | ||
69 | nft_unregister_expr(&nft_redir_ipv6_type); | ||
70 | } | ||
71 | |||
72 | module_init(nft_redir_ipv6_module_init); | ||
73 | module_exit(nft_redir_ipv6_module_exit); | ||
74 | |||
75 | MODULE_LICENSE("GPL"); | ||
76 | MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>"); | ||
77 | MODULE_ALIAS_NFT_AF_EXPR(AF_INET6, "redir"); | ||
diff --git a/net/ipv6/netfilter/nft_reject_ipv6.c b/net/ipv6/netfilter/nft_reject_ipv6.c index 0bc19fa87821..f73285924144 100644 --- a/net/ipv6/netfilter/nft_reject_ipv6.c +++ b/net/ipv6/netfilter/nft_reject_ipv6.c | |||
@@ -19,9 +19,9 @@ | |||
19 | #include <net/netfilter/nft_reject.h> | 19 | #include <net/netfilter/nft_reject.h> |
20 | #include <net/netfilter/ipv6/nf_reject.h> | 20 | #include <net/netfilter/ipv6/nf_reject.h> |
21 | 21 | ||
22 | void nft_reject_ipv6_eval(const struct nft_expr *expr, | 22 | static void nft_reject_ipv6_eval(const struct nft_expr *expr, |
23 | struct nft_data data[NFT_REG_MAX + 1], | 23 | struct nft_data data[NFT_REG_MAX + 1], |
24 | const struct nft_pktinfo *pkt) | 24 | const struct nft_pktinfo *pkt) |
25 | { | 25 | { |
26 | struct nft_reject *priv = nft_expr_priv(expr); | 26 | struct nft_reject *priv = nft_expr_priv(expr); |
27 | struct net *net = dev_net((pkt->in != NULL) ? pkt->in : pkt->out); | 27 | struct net *net = dev_net((pkt->in != NULL) ? pkt->in : pkt->out); |
@@ -38,7 +38,6 @@ void nft_reject_ipv6_eval(const struct nft_expr *expr, | |||
38 | 38 | ||
39 | data[NFT_REG_VERDICT].verdict = NF_DROP; | 39 | data[NFT_REG_VERDICT].verdict = NF_DROP; |
40 | } | 40 | } |
41 | EXPORT_SYMBOL_GPL(nft_reject_ipv6_eval); | ||
42 | 41 | ||
43 | static struct nft_expr_type nft_reject_ipv6_type; | 42 | static struct nft_expr_type nft_reject_ipv6_type; |
44 | static const struct nft_expr_ops nft_reject_ipv6_ops = { | 43 | static const struct nft_expr_ops nft_reject_ipv6_ops = { |