aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2006-12-03 01:07:13 -0500
committerDavid S. Miller <davem@davemloft.net>2006-12-03 01:07:13 -0500
commit5b1158e909ecbe1a052203e0d8df15633f829930 (patch)
tree1d29320fd6184b982b1a8a83e7e1e9f25537d3ff /net/netfilter
parentd2483ddefd38b06053cdce7206382ca61f6282b1 (diff)
[NETFILTER]: Add NAT support for nf_conntrack
Add NAT support for nf_conntrack. Joint work of Jozsef Kadlecsik, Yasuyuki Kozakai, Martin Josefsson and myself. Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/nf_conntrack_core.c23
-rw-r--r--net/netfilter/nf_conntrack_netlink.c46
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c2
-rw-r--r--net/netfilter/nf_conntrack_standalone.c5
4 files changed, 52 insertions, 24 deletions
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index f952a7fb6ae3..aa8beabfeebb 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -579,7 +579,8 @@ __nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
579 /* FIXME: protect helper list per RCU */ 579 /* FIXME: protect helper list per RCU */
580 read_lock_bh(&nf_conntrack_lock); 580 read_lock_bh(&nf_conntrack_lock);
581 helper = __nf_ct_helper_find(repl); 581 helper = __nf_ct_helper_find(repl);
582 if (helper) 582 /* NAT might want to assign a helper later */
583 if (helper || features & NF_CT_F_NAT)
583 features |= NF_CT_F_HELP; 584 features |= NF_CT_F_HELP;
584 read_unlock_bh(&nf_conntrack_lock); 585 read_unlock_bh(&nf_conntrack_lock);
585 586
@@ -850,6 +851,26 @@ int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse,
850 orig->dst.protonum)); 851 orig->dst.protonum));
851} 852}
852 853
854/* Alter reply tuple (maybe alter helper). This is for NAT, and is
855 implicitly racy: see __nf_conntrack_confirm */
856void nf_conntrack_alter_reply(struct nf_conn *ct,
857 const struct nf_conntrack_tuple *newreply)
858{
859 struct nf_conn_help *help = nfct_help(ct);
860
861 write_lock_bh(&nf_conntrack_lock);
862 /* Should be unconfirmed, so not in hash table yet */
863 NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
864
865 DEBUGP("Altering reply tuple of %p to ", ct);
866 NF_CT_DUMP_TUPLE(newreply);
867
868 ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
869 if (!ct->master && help && help->expecting == 0)
870 help->helper = __nf_ct_helper_find(newreply);
871 write_unlock_bh(&nf_conntrack_lock);
872}
873
853/* Refresh conntrack for this many jiffies and do accounting if do_acct is 1 */ 874/* Refresh conntrack for this many jiffies and do accounting if do_acct is 1 */
854void __nf_ct_refresh_acct(struct nf_conn *ct, 875void __nf_ct_refresh_acct(struct nf_conn *ct,
855 enum ip_conntrack_info ctinfo, 876 enum ip_conntrack_info ctinfo,
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index f9c8ddd5973c..bd1d2de75e45 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -39,7 +39,11 @@
39#include <net/netfilter/nf_conntrack_helper.h> 39#include <net/netfilter/nf_conntrack_helper.h>
40#include <net/netfilter/nf_conntrack_l3proto.h> 40#include <net/netfilter/nf_conntrack_l3proto.h>
41#include <net/netfilter/nf_conntrack_l4proto.h> 41#include <net/netfilter/nf_conntrack_l4proto.h>
42#include <linux/netfilter_ipv4/ip_nat_protocol.h> 42#include <net/netfilter/nf_conntrack_tuple.h>
43#ifdef CONFIG_NF_NAT_NEEDED
44#include <net/netfilter/nf_nat_core.h>
45#include <net/netfilter/nf_nat_protocol.h>
46#endif
43 47
44#include <linux/netfilter/nfnetlink.h> 48#include <linux/netfilter/nfnetlink.h>
45#include <linux/netfilter/nfnetlink_conntrack.h> 49#include <linux/netfilter/nfnetlink_conntrack.h>
@@ -430,7 +434,7 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
430restart: 434restart:
431 list_for_each_prev(i, &nf_conntrack_hash[cb->args[0]]) { 435 list_for_each_prev(i, &nf_conntrack_hash[cb->args[0]]) {
432 h = (struct nf_conntrack_tuple_hash *) i; 436 h = (struct nf_conntrack_tuple_hash *) i;
433 if (DIRECTION(h) != IP_CT_DIR_ORIGINAL) 437 if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
434 continue; 438 continue;
435 ct = nf_ct_tuplehash_to_ctrack(h); 439 ct = nf_ct_tuplehash_to_ctrack(h);
436 /* Dump entries of a given L3 protocol number. 440 /* Dump entries of a given L3 protocol number.
@@ -556,28 +560,28 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct nf_conntrack_tuple *tuple,
556 return 0; 560 return 0;
557} 561}
558 562
559#ifdef CONFIG_IP_NF_NAT_NEEDED 563#ifdef CONFIG_NF_NAT_NEEDED
560static const size_t cta_min_protonat[CTA_PROTONAT_MAX] = { 564static const size_t cta_min_protonat[CTA_PROTONAT_MAX] = {
561 [CTA_PROTONAT_PORT_MIN-1] = sizeof(u_int16_t), 565 [CTA_PROTONAT_PORT_MIN-1] = sizeof(u_int16_t),
562 [CTA_PROTONAT_PORT_MAX-1] = sizeof(u_int16_t), 566 [CTA_PROTONAT_PORT_MAX-1] = sizeof(u_int16_t),
563}; 567};
564 568
565static int ctnetlink_parse_nat_proto(struct nfattr *attr, 569static int nfnetlink_parse_nat_proto(struct nfattr *attr,
566 const struct nf_conn *ct, 570 const struct nf_conn *ct,
567 struct ip_nat_range *range) 571 struct nf_nat_range *range)
568{ 572{
569 struct nfattr *tb[CTA_PROTONAT_MAX]; 573 struct nfattr *tb[CTA_PROTONAT_MAX];
570 struct ip_nat_protocol *npt; 574 struct nf_nat_protocol *npt;
571 575
572 nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr); 576 nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr);
573 577
574 if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat)) 578 if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat))
575 return -EINVAL; 579 return -EINVAL;
576 580
577 npt = ip_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum); 581 npt = nf_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum);
578 582
579 if (!npt->nfattr_to_range) { 583 if (!npt->nfattr_to_range) {
580 ip_nat_proto_put(npt); 584 nf_nat_proto_put(npt);
581 return 0; 585 return 0;
582 } 586 }
583 587
@@ -585,7 +589,7 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
585 if (npt->nfattr_to_range(tb, range) > 0) 589 if (npt->nfattr_to_range(tb, range) > 0)
586 range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED; 590 range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
587 591
588 ip_nat_proto_put(npt); 592 nf_nat_proto_put(npt);
589 593
590 return 0; 594 return 0;
591} 595}
@@ -596,8 +600,8 @@ static const size_t cta_min_nat[CTA_NAT_MAX] = {
596}; 600};
597 601
598static inline int 602static inline int
599ctnetlink_parse_nat(struct nfattr *nat, 603nfnetlink_parse_nat(struct nfattr *nat,
600 const struct nf_conn *ct, struct ip_nat_range *range) 604 const struct nf_conn *ct, struct nf_nat_range *range)
601{ 605{
602 struct nfattr *tb[CTA_NAT_MAX]; 606 struct nfattr *tb[CTA_NAT_MAX];
603 int err; 607 int err;
@@ -623,7 +627,7 @@ ctnetlink_parse_nat(struct nfattr *nat,
623 if (!tb[CTA_NAT_PROTO-1]) 627 if (!tb[CTA_NAT_PROTO-1])
624 return 0; 628 return 0;
625 629
626 err = ctnetlink_parse_nat_proto(tb[CTA_NAT_PROTO-1], ct, range); 630 err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO-1], ct, range);
627 if (err < 0) 631 if (err < 0)
628 return err; 632 return err;
629 633
@@ -798,35 +802,35 @@ ctnetlink_change_status(struct nf_conn *ct, struct nfattr *cda[])
798 return -EINVAL; 802 return -EINVAL;
799 803
800 if (cda[CTA_NAT_SRC-1] || cda[CTA_NAT_DST-1]) { 804 if (cda[CTA_NAT_SRC-1] || cda[CTA_NAT_DST-1]) {
801#ifndef CONFIG_IP_NF_NAT_NEEDED 805#ifndef CONFIG_NF_NAT_NEEDED
802 return -EINVAL; 806 return -EINVAL;
803#else 807#else
804 struct ip_nat_range range; 808 struct nf_nat_range range;
805 809
806 if (cda[CTA_NAT_DST-1]) { 810 if (cda[CTA_NAT_DST-1]) {
807 if (ctnetlink_parse_nat(cda[CTA_NAT_DST-1], ct, 811 if (nfnetlink_parse_nat(cda[CTA_NAT_DST-1], ct,
808 &range) < 0) 812 &range) < 0)
809 return -EINVAL; 813 return -EINVAL;
810 if (ip_nat_initialized(ct, 814 if (nf_nat_initialized(ct,
811 HOOK2MANIP(NF_IP_PRE_ROUTING))) 815 HOOK2MANIP(NF_IP_PRE_ROUTING)))
812 return -EEXIST; 816 return -EEXIST;
813 ip_nat_setup_info(ct, &range, hooknum); 817 nf_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
814 } 818 }
815 if (cda[CTA_NAT_SRC-1]) { 819 if (cda[CTA_NAT_SRC-1]) {
816 if (ctnetlink_parse_nat(cda[CTA_NAT_SRC-1], ct, 820 if (nfnetlink_parse_nat(cda[CTA_NAT_SRC-1], ct,
817 &range) < 0) 821 &range) < 0)
818 return -EINVAL; 822 return -EINVAL;
819 if (ip_nat_initialized(ct, 823 if (nf_nat_initialized(ct,
820 HOOK2MANIP(NF_IP_POST_ROUTING))) 824 HOOK2MANIP(NF_IP_POST_ROUTING)))
821 return -EEXIST; 825 return -EEXIST;
822 ip_nat_setup_info(ct, &range, hooknum); 826 nf_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
823 } 827 }
824#endif 828#endif
825 } 829 }
826 830
827 /* Be careful here, modifying NAT bits can screw up things, 831 /* Be careful here, modifying NAT bits can screw up things,
828 * so don't let users modify them directly if they don't pass 832 * so don't let users modify them directly if they don't pass
829 * ip_nat_range. */ 833 * nf_nat_range. */
830 ct->status |= status & ~(IPS_NAT_DONE_MASK | IPS_NAT_MASK); 834 ct->status |= status & ~(IPS_NAT_DONE_MASK | IPS_NAT_MASK);
831 return 0; 835 return 0;
832} 836}
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 71f492fc6413..8156e429b885 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -730,7 +730,7 @@ static int tcp_in_window(struct ip_ct_tcp *state,
730 return res; 730 return res;
731} 731}
732 732
733#ifdef CONFIG_IP_NF_NAT_NEEDED 733#ifdef CONFIG_NF_NAT_NEEDED
734/* Update sender->td_end after NAT successfully mangled the packet */ 734/* Update sender->td_end after NAT successfully mangled the packet */
735/* Caller must linearize skb at tcp header. */ 735/* Caller must linearize skb at tcp header. */
736void nf_conntrack_tcp_update(struct sk_buff *skb, 736void nf_conntrack_tcp_update(struct sk_buff *skb,
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index be94b6359725..3f56a3a6c399 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -530,8 +530,11 @@ EXPORT_SYMBOL(nf_conntrack_lock);
530EXPORT_SYMBOL(nf_conntrack_hash); 530EXPORT_SYMBOL(nf_conntrack_hash);
531EXPORT_SYMBOL(nf_conntrack_untracked); 531EXPORT_SYMBOL(nf_conntrack_untracked);
532EXPORT_SYMBOL_GPL(nf_conntrack_find_get); 532EXPORT_SYMBOL_GPL(nf_conntrack_find_get);
533#ifdef CONFIG_IP_NF_NAT_NEEDED 533#ifdef CONFIG_NF_NAT_NEEDED
534EXPORT_SYMBOL(nf_conntrack_tcp_update); 534EXPORT_SYMBOL(nf_conntrack_tcp_update);
535EXPORT_SYMBOL(nf_conntrack_register_cache);
536EXPORT_SYMBOL(nf_conntrack_unregister_cache);
537EXPORT_SYMBOL(nf_conntrack_alter_reply);
535#endif 538#endif
536EXPORT_SYMBOL(__nf_conntrack_confirm); 539EXPORT_SYMBOL(__nf_conntrack_confirm);
537EXPORT_SYMBOL(nf_ct_get_tuple); 540EXPORT_SYMBOL(nf_ct_get_tuple);