aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorHarald Welte <laforge@netfilter.org>2005-09-26 18:25:11 -0400
committerDavid S. Miller <davem@davemloft.net>2005-09-26 18:25:11 -0400
commit188bab3ae0ed164bc18f98be932512d777dd038b (patch)
tree58a4a77478e8abf0af5afa53dee6a6b1e5828387 /net/ipv4
parentb85daee0e497c8fe7c4dc3531674ede645b37cdf (diff)
[NETFILTER]: Fix invalid module autoloading by splitting iptable_nat
When you've enabled conntrack and NAT as a module (standard case in all distributions), and you've also enabled the new conntrack netlink interface, loading ip_conntrack_netlink.ko will auto-load iptable_nat.ko. This causes a huge performance penalty, since for every packet you iterate the nat code, even if you don't want it. This patch splits iptable_nat.ko into the NAT core (ip_nat.ko) and the iptables frontend (iptable_nat.ko). Threfore, ip_conntrack_netlink.ko will only pull ip_nat.ko, but not the frontend. ip_nat.ko will "only" allocate some resources, but not affect runtime performance. This separation is also a nice step in anticipation of new packet filters (nf-hipac, ipset, pkttables) being able to use the NAT core. Signed-off-by: Harald Welte <laforge@netfilter.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/netfilter/Makefile5
-rw-r--r--net/ipv4/netfilter/ip_nat_core.c35
-rw-r--r--net/ipv4/netfilter/ip_nat_helper.c4
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c25
4 files changed, 35 insertions, 34 deletions
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 89002533f2a2..dab4b58dd31e 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -4,7 +4,8 @@
4 4
5# objects for the standalone - connection tracking / NAT 5# objects for the standalone - connection tracking / NAT
6ip_conntrack-objs := ip_conntrack_standalone.o ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o 6ip_conntrack-objs := ip_conntrack_standalone.o ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o
7iptable_nat-objs := ip_nat_standalone.o ip_nat_rule.o ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o 7ip_nat-objs := ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o
8iptable_nat-objs := ip_nat_rule.o ip_nat_standalone.o
8 9
9ip_conntrack_pptp-objs := ip_conntrack_helper_pptp.o ip_conntrack_proto_gre.o 10ip_conntrack_pptp-objs := ip_conntrack_helper_pptp.o ip_conntrack_proto_gre.o
10ip_nat_pptp-objs := ip_nat_helper_pptp.o ip_nat_proto_gre.o 11ip_nat_pptp-objs := ip_nat_helper_pptp.o ip_nat_proto_gre.o
@@ -40,7 +41,7 @@ obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
40# the three instances of ip_tables 41# the three instances of ip_tables
41obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o 42obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
42obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o 43obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
43obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o 44obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o ip_nat.o
44obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o 45obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
45 46
46# matches 47# matches
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index c3ea891d38e7..c5e3abd24672 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -74,12 +74,14 @@ ip_nat_proto_find_get(u_int8_t protonum)
74 74
75 return p; 75 return p;
76} 76}
77EXPORT_SYMBOL_GPL(ip_nat_proto_find_get);
77 78
78void 79void
79ip_nat_proto_put(struct ip_nat_protocol *p) 80ip_nat_proto_put(struct ip_nat_protocol *p)
80{ 81{
81 module_put(p->me); 82 module_put(p->me);
82} 83}
84EXPORT_SYMBOL_GPL(ip_nat_proto_put);
83 85
84/* We keep an extra hash for each conntrack, for fast searching. */ 86/* We keep an extra hash for each conntrack, for fast searching. */
85static inline unsigned int 87static inline unsigned int
@@ -111,6 +113,7 @@ ip_nat_cheat_check(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
111 return csum_fold(csum_partial((char *)diffs, sizeof(diffs), 113 return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
112 oldcheck^0xFFFF)); 114 oldcheck^0xFFFF));
113} 115}
116EXPORT_SYMBOL(ip_nat_cheat_check);
114 117
115/* Is this tuple already taken? (not by us) */ 118/* Is this tuple already taken? (not by us) */
116int 119int
@@ -127,6 +130,7 @@ ip_nat_used_tuple(const struct ip_conntrack_tuple *tuple,
127 invert_tuplepr(&reply, tuple); 130 invert_tuplepr(&reply, tuple);
128 return ip_conntrack_tuple_taken(&reply, ignored_conntrack); 131 return ip_conntrack_tuple_taken(&reply, ignored_conntrack);
129} 132}
133EXPORT_SYMBOL(ip_nat_used_tuple);
130 134
131/* If we source map this tuple so reply looks like reply_tuple, will 135/* If we source map this tuple so reply looks like reply_tuple, will
132 * that meet the constraints of range. */ 136 * that meet the constraints of range. */
@@ -347,6 +351,7 @@ ip_nat_setup_info(struct ip_conntrack *conntrack,
347 351
348 return NF_ACCEPT; 352 return NF_ACCEPT;
349} 353}
354EXPORT_SYMBOL(ip_nat_setup_info);
350 355
351/* Returns true if succeeded. */ 356/* Returns true if succeeded. */
352static int 357static int
@@ -387,10 +392,10 @@ manip_pkt(u_int16_t proto,
387} 392}
388 393
389/* Do packet manipulations according to ip_nat_setup_info. */ 394/* Do packet manipulations according to ip_nat_setup_info. */
390unsigned int nat_packet(struct ip_conntrack *ct, 395unsigned int ip_nat_packet(struct ip_conntrack *ct,
391 enum ip_conntrack_info ctinfo, 396 enum ip_conntrack_info ctinfo,
392 unsigned int hooknum, 397 unsigned int hooknum,
393 struct sk_buff **pskb) 398 struct sk_buff **pskb)
394{ 399{
395 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 400 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
396 unsigned long statusbit; 401 unsigned long statusbit;
@@ -417,12 +422,13 @@ unsigned int nat_packet(struct ip_conntrack *ct,
417 } 422 }
418 return NF_ACCEPT; 423 return NF_ACCEPT;
419} 424}
425EXPORT_SYMBOL_GPL(ip_nat_packet);
420 426
421/* Dir is direction ICMP is coming from (opposite to packet it contains) */ 427/* Dir is direction ICMP is coming from (opposite to packet it contains) */
422int icmp_reply_translation(struct sk_buff **pskb, 428int ip_nat_icmp_reply_translation(struct sk_buff **pskb,
423 struct ip_conntrack *ct, 429 struct ip_conntrack *ct,
424 enum ip_nat_manip_type manip, 430 enum ip_nat_manip_type manip,
425 enum ip_conntrack_dir dir) 431 enum ip_conntrack_dir dir)
426{ 432{
427 struct { 433 struct {
428 struct icmphdr icmp; 434 struct icmphdr icmp;
@@ -509,6 +515,7 @@ int icmp_reply_translation(struct sk_buff **pskb,
509 515
510 return 1; 516 return 1;
511} 517}
518EXPORT_SYMBOL_GPL(ip_nat_icmp_reply_translation);
512 519
513/* Protocol registration. */ 520/* Protocol registration. */
514int ip_nat_protocol_register(struct ip_nat_protocol *proto) 521int ip_nat_protocol_register(struct ip_nat_protocol *proto)
@@ -525,6 +532,7 @@ int ip_nat_protocol_register(struct ip_nat_protocol *proto)
525 write_unlock_bh(&ip_nat_lock); 532 write_unlock_bh(&ip_nat_lock);
526 return ret; 533 return ret;
527} 534}
535EXPORT_SYMBOL(ip_nat_protocol_register);
528 536
529/* Noone stores the protocol anywhere; simply delete it. */ 537/* Noone stores the protocol anywhere; simply delete it. */
530void ip_nat_protocol_unregister(struct ip_nat_protocol *proto) 538void ip_nat_protocol_unregister(struct ip_nat_protocol *proto)
@@ -536,6 +544,7 @@ void ip_nat_protocol_unregister(struct ip_nat_protocol *proto)
536 /* Someone could be still looking at the proto in a bh. */ 544 /* Someone could be still looking at the proto in a bh. */
537 synchronize_net(); 545 synchronize_net();
538} 546}
547EXPORT_SYMBOL(ip_nat_protocol_unregister);
539 548
540#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \ 549#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
541 defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE) 550 defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
@@ -582,7 +591,7 @@ EXPORT_SYMBOL_GPL(ip_nat_port_nfattr_to_range);
582EXPORT_SYMBOL_GPL(ip_nat_port_range_to_nfattr); 591EXPORT_SYMBOL_GPL(ip_nat_port_range_to_nfattr);
583#endif 592#endif
584 593
585int __init ip_nat_init(void) 594static int __init ip_nat_init(void)
586{ 595{
587 size_t i; 596 size_t i;
588 597
@@ -624,10 +633,14 @@ static int clean_nat(struct ip_conntrack *i, void *data)
624 return 0; 633 return 0;
625} 634}
626 635
627/* Not __exit: called from ip_nat_standalone.c:init_or_cleanup() --RR */ 636static void __exit ip_nat_cleanup(void)
628void ip_nat_cleanup(void)
629{ 637{
630 ip_ct_iterate_cleanup(&clean_nat, NULL); 638 ip_ct_iterate_cleanup(&clean_nat, NULL);
631 ip_conntrack_destroyed = NULL; 639 ip_conntrack_destroyed = NULL;
632 vfree(bysource); 640 vfree(bysource);
633} 641}
642
643MODULE_LICENSE("GPL");
644
645module_init(ip_nat_init);
646module_exit(ip_nat_cleanup);
diff --git a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c
index d2dd5d313556..5d506e0564d5 100644
--- a/net/ipv4/netfilter/ip_nat_helper.c
+++ b/net/ipv4/netfilter/ip_nat_helper.c
@@ -199,6 +199,7 @@ ip_nat_mangle_tcp_packet(struct sk_buff **pskb,
199 } 199 }
200 return 1; 200 return 1;
201} 201}
202EXPORT_SYMBOL(ip_nat_mangle_tcp_packet);
202 203
203/* Generic function for mangling variable-length address changes inside 204/* Generic function for mangling variable-length address changes inside
204 * NATed UDP connections (like the CONNECT DATA XXXXX MESG XXXXX INDEX XXXXX 205 * NATed UDP connections (like the CONNECT DATA XXXXX MESG XXXXX INDEX XXXXX
@@ -256,6 +257,7 @@ ip_nat_mangle_udp_packet(struct sk_buff **pskb,
256 257
257 return 1; 258 return 1;
258} 259}
260EXPORT_SYMBOL(ip_nat_mangle_udp_packet);
259 261
260/* Adjust one found SACK option including checksum correction */ 262/* Adjust one found SACK option including checksum correction */
261static void 263static void
@@ -399,6 +401,7 @@ ip_nat_seq_adjust(struct sk_buff **pskb,
399 401
400 return 1; 402 return 1;
401} 403}
404EXPORT_SYMBOL(ip_nat_seq_adjust);
402 405
403/* Setup NAT on this expected conntrack so it follows master. */ 406/* Setup NAT on this expected conntrack so it follows master. */
404/* If we fail to get a free NAT slot, we'll get dropped on confirm */ 407/* If we fail to get a free NAT slot, we'll get dropped on confirm */
@@ -425,3 +428,4 @@ void ip_nat_follow_master(struct ip_conntrack *ct,
425 /* hook doesn't matter, but it has to do destination manip */ 428 /* hook doesn't matter, but it has to do destination manip */
426 ip_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING); 429 ip_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
427} 430}
431EXPORT_SYMBOL(ip_nat_follow_master);
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index 0ff368b131f6..30cd4e18c129 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -108,8 +108,8 @@ ip_nat_fn(unsigned int hooknum,
108 case IP_CT_RELATED: 108 case IP_CT_RELATED:
109 case IP_CT_RELATED+IP_CT_IS_REPLY: 109 case IP_CT_RELATED+IP_CT_IS_REPLY:
110 if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP) { 110 if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP) {
111 if (!icmp_reply_translation(pskb, ct, maniptype, 111 if (!ip_nat_icmp_reply_translation(pskb, ct, maniptype,
112 CTINFO2DIR(ctinfo))) 112 CTINFO2DIR(ctinfo)))
113 return NF_DROP; 113 return NF_DROP;
114 else 114 else
115 return NF_ACCEPT; 115 return NF_ACCEPT;
@@ -152,7 +152,7 @@ ip_nat_fn(unsigned int hooknum,
152 } 152 }
153 153
154 IP_NF_ASSERT(info); 154 IP_NF_ASSERT(info);
155 return nat_packet(ct, ctinfo, hooknum, pskb); 155 return ip_nat_packet(ct, ctinfo, hooknum, pskb);
156} 156}
157 157
158static unsigned int 158static unsigned int
@@ -325,15 +325,10 @@ static int init_or_cleanup(int init)
325 printk("ip_nat_init: can't setup rules.\n"); 325 printk("ip_nat_init: can't setup rules.\n");
326 goto cleanup_nothing; 326 goto cleanup_nothing;
327 } 327 }
328 ret = ip_nat_init();
329 if (ret < 0) {
330 printk("ip_nat_init: can't setup rules.\n");
331 goto cleanup_rule_init;
332 }
333 ret = nf_register_hook(&ip_nat_in_ops); 328 ret = nf_register_hook(&ip_nat_in_ops);
334 if (ret < 0) { 329 if (ret < 0) {
335 printk("ip_nat_init: can't register in hook.\n"); 330 printk("ip_nat_init: can't register in hook.\n");
336 goto cleanup_nat; 331 goto cleanup_rule_init;
337 } 332 }
338 ret = nf_register_hook(&ip_nat_out_ops); 333 ret = nf_register_hook(&ip_nat_out_ops);
339 if (ret < 0) { 334 if (ret < 0) {
@@ -374,8 +369,6 @@ static int init_or_cleanup(int init)
374 nf_unregister_hook(&ip_nat_out_ops); 369 nf_unregister_hook(&ip_nat_out_ops);
375 cleanup_inops: 370 cleanup_inops:
376 nf_unregister_hook(&ip_nat_in_ops); 371 nf_unregister_hook(&ip_nat_in_ops);
377 cleanup_nat:
378 ip_nat_cleanup();
379 cleanup_rule_init: 372 cleanup_rule_init:
380 ip_nat_rule_cleanup(); 373 ip_nat_rule_cleanup();
381 cleanup_nothing: 374 cleanup_nothing:
@@ -395,14 +388,4 @@ static void __exit fini(void)
395module_init(init); 388module_init(init);
396module_exit(fini); 389module_exit(fini);
397 390
398EXPORT_SYMBOL(ip_nat_setup_info);
399EXPORT_SYMBOL(ip_nat_protocol_register);
400EXPORT_SYMBOL(ip_nat_protocol_unregister);
401EXPORT_SYMBOL_GPL(ip_nat_proto_find_get);
402EXPORT_SYMBOL_GPL(ip_nat_proto_put);
403EXPORT_SYMBOL(ip_nat_cheat_check);
404EXPORT_SYMBOL(ip_nat_mangle_tcp_packet);
405EXPORT_SYMBOL(ip_nat_mangle_udp_packet);
406EXPORT_SYMBOL(ip_nat_used_tuple);
407EXPORT_SYMBOL(ip_nat_follow_master);
408MODULE_LICENSE("GPL"); 391MODULE_LICENSE("GPL");