Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Jan Engelhardt and committed by
Pablo Neira Ayuso
2cbc78a2 b3d54b3e

+207 -230
+5 -7
net/ipv4/netfilter/Kconfig
··· 181 181 config IP_NF_TARGET_REDIRECT 182 182 tristate "REDIRECT target support" 183 183 depends on NETFILTER_ADVANCED 184 - help 185 - REDIRECT is a special case of NAT: all incoming connections are 186 - mapped onto the incoming interface's address, causing the packets to 187 - come to the local machine instead of passing through. This is 188 - useful for transparent proxies. 189 - 190 - To compile it as a module, choose M here. If unsure, say N. 184 + select NETFILTER_XT_TARGET_REDIRECT 185 + ---help--- 186 + This is a backwards-compat option for the user's convenience 187 + (e.g. when running oldconfig). It selects 188 + CONFIG_NETFILTER_XT_TARGET_REDIRECT. 191 189 192 190 endif 193 191
-1
net/ipv4/netfilter/Makefile
··· 45 45 obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o 46 46 obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o 47 47 obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o 48 - obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o 49 48 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o 50 49 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o 51 50
-113
net/ipv4/netfilter/ipt_REDIRECT.c
··· 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 - 24 - MODULE_LICENSE("GPL"); 25 - MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 26 - MODULE_DESCRIPTION("Xtables: Connection redirection to localhost"); 27 - 28 - /* FIXME: Take multiple ranges --RR */ 29 - static 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 - 44 - static unsigned int 45 - redirect_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 - 91 - static 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 - 102 - static int __init redirect_tg_init(void) 103 - { 104 - return xt_register_target(&redirect_tg_reg); 105 - } 106 - 107 - static void __exit redirect_tg_exit(void) 108 - { 109 - xt_unregister_target(&redirect_tg_reg); 110 - } 111 - 112 - module_init(redirect_tg_init); 113 - module_exit(redirect_tg_exit);
-10
net/ipv6/netfilter/Kconfig
··· 209 209 210 210 To compile it as a module, choose M here. If unsure, say N. 211 211 212 - config 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 - 222 212 config IP6_NF_TARGET_NPT 223 213 tristate "NPT (Network Prefix translation) target support" 224 214 help
-1
net/ipv6/netfilter/Makefile
··· 36 36 # targets 37 37 obj-$(CONFIG_IP6_NF_TARGET_MASQUERADE) += ip6t_MASQUERADE.o 38 38 obj-$(CONFIG_IP6_NF_TARGET_NPT) += ip6t_NPT.o 39 - obj-$(CONFIG_IP6_NF_TARGET_REDIRECT) += ip6t_REDIRECT.o 40 39 obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
-98
net/ipv6/netfilter/ip6t_REDIRECT.c
··· 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 - 20 - static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT; 21 - 22 - static unsigned int 23 - redirect_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 - 63 - static 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 - 72 - static 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 - 83 - static int __init redirect_tg6_init(void) 84 - { 85 - return xt_register_target(&redirect_tg6_reg); 86 - } 87 - 88 - static void __exit redirect_tg6_exit(void) 89 - { 90 - xt_unregister_target(&redirect_tg6_reg); 91 - } 92 - 93 - module_init(redirect_tg6_init); 94 - module_exit(redirect_tg6_exit); 95 - 96 - MODULE_LICENSE("GPL"); 97 - MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 98 - MODULE_DESCRIPTION("Xtables: Connection redirection to localhost");
+11
net/netfilter/Kconfig
··· 690 690 691 691 To compile it as a module, choose M here. If unsure, say N. 692 692 693 + config 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 + 693 704 config NETFILTER_XT_TARGET_TEE 694 705 tristate '"TEE" - packet cloning to alternate destination' 695 706 depends on NETFILTER_ADVANCED
+1
net/netfilter/Makefile
··· 87 87 obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o 88 88 obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o 89 89 obj-$(CONFIG_NETFILTER_XT_TARGET_RATEEST) += xt_RATEEST.o 90 + obj-$(CONFIG_NETFILTER_XT_TARGET_REDIRECT) += xt_REDIRECT.o 90 91 obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o 91 92 obj-$(CONFIG_NETFILTER_XT_TARGET_TPROXY) += xt_TPROXY.o 92 93 obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
+190
net/netfilter/xt_REDIRECT.c
··· 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 + 30 + static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT; 31 + 32 + static unsigned int 33 + redirect_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 + 73 + static 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 */ 83 + static 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 + 98 + static unsigned int 99 + redirect_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 + 145 + static 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 + 172 + static int __init redirect_tg_init(void) 173 + { 174 + return xt_register_targets(redirect_tg_reg, 175 + ARRAY_SIZE(redirect_tg_reg)); 176 + } 177 + 178 + static void __exit redirect_tg_exit(void) 179 + { 180 + xt_unregister_targets(redirect_tg_reg, ARRAY_SIZE(redirect_tg_reg)); 181 + } 182 + 183 + module_init(redirect_tg_init); 184 + module_exit(redirect_tg_exit); 185 + 186 + MODULE_LICENSE("GPL"); 187 + MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 188 + MODULE_DESCRIPTION("Xtables: Connection redirection to localhost"); 189 + MODULE_ALIAS("ip6t_REDIRECT"); 190 + MODULE_ALIAS("ipt_REDIRECT");