aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2006-12-03 01:05:25 -0500
committerDavid S. Miller <davem@davemloft.net>2006-12-03 01:05:25 -0500
commit9457d851fc5df54522d733f72cbb1f02ab59272e (patch)
tree42a460d65cbb45b100c43f97ba8a7490df844bb8 /net
parentbff9a89bcac5b68ac0a1ea856b1726a35ae1eabb (diff)
[NETFILTER]: nf_conntrack: automatic helper assignment for expectations
Some helpers (namely H.323) manually assign further helpers to expected connections. This is not possible with nf_conntrack anymore since we need to know whether a helper is used at allocation time. Handle the helper assignment centrally, which allows to perform the correct allocation and as a nice side effect eliminates the need for the H.323 helper to fiddle with nf_conntrack_lock. Mid term the allocation scheme really needs to be redesigned since we do both the helper and expectation lookup _twice_ for every new connection. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/nf_conntrack_core.c19
-rw-r--r--net/netfilter/nf_conntrack_ftp.c1
-rw-r--r--net/netfilter/nf_conntrack_helper.c3
-rw-r--r--net/netfilter/nf_conntrack_netlink.c1
4 files changed, 18 insertions, 6 deletions
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index a401b1e31028..f952a7fb6ae3 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -545,10 +545,10 @@ static int early_drop(struct list_head *chain)
545static struct nf_conn * 545static struct nf_conn *
546__nf_conntrack_alloc(const struct nf_conntrack_tuple *orig, 546__nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
547 const struct nf_conntrack_tuple *repl, 547 const struct nf_conntrack_tuple *repl,
548 const struct nf_conntrack_l3proto *l3proto) 548 const struct nf_conntrack_l3proto *l3proto,
549 u_int32_t features)
549{ 550{
550 struct nf_conn *conntrack = NULL; 551 struct nf_conn *conntrack = NULL;
551 u_int32_t features = 0;
552 struct nf_conntrack_helper *helper; 552 struct nf_conntrack_helper *helper;
553 553
554 if (unlikely(!nf_conntrack_hash_rnd_initted)) { 554 if (unlikely(!nf_conntrack_hash_rnd_initted)) {
@@ -574,7 +574,7 @@ __nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
574 } 574 }
575 575
576 /* find features needed by this conntrack. */ 576 /* find features needed by this conntrack. */
577 features = l3proto->get_features(orig); 577 features |= l3proto->get_features(orig);
578 578
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);
@@ -624,7 +624,7 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
624 struct nf_conntrack_l3proto *l3proto; 624 struct nf_conntrack_l3proto *l3proto;
625 625
626 l3proto = __nf_ct_l3proto_find(orig->src.l3num); 626 l3proto = __nf_ct_l3proto_find(orig->src.l3num);
627 return __nf_conntrack_alloc(orig, repl, l3proto); 627 return __nf_conntrack_alloc(orig, repl, l3proto, 0);
628} 628}
629 629
630void nf_conntrack_free(struct nf_conn *conntrack) 630void nf_conntrack_free(struct nf_conn *conntrack)
@@ -649,13 +649,20 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
649 struct nf_conn *conntrack; 649 struct nf_conn *conntrack;
650 struct nf_conntrack_tuple repl_tuple; 650 struct nf_conntrack_tuple repl_tuple;
651 struct nf_conntrack_expect *exp; 651 struct nf_conntrack_expect *exp;
652 u_int32_t features = 0;
652 653
653 if (!nf_ct_invert_tuple(&repl_tuple, tuple, l3proto, l4proto)) { 654 if (!nf_ct_invert_tuple(&repl_tuple, tuple, l3proto, l4proto)) {
654 DEBUGP("Can't invert tuple.\n"); 655 DEBUGP("Can't invert tuple.\n");
655 return NULL; 656 return NULL;
656 } 657 }
657 658
658 conntrack = __nf_conntrack_alloc(tuple, &repl_tuple, l3proto); 659 read_lock_bh(&nf_conntrack_lock);
660 exp = __nf_conntrack_expect_find(tuple);
661 if (exp && exp->helper)
662 features = NF_CT_F_HELP;
663 read_unlock_bh(&nf_conntrack_lock);
664
665 conntrack = __nf_conntrack_alloc(tuple, &repl_tuple, l3proto, features);
659 if (conntrack == NULL || IS_ERR(conntrack)) { 666 if (conntrack == NULL || IS_ERR(conntrack)) {
660 DEBUGP("Can't allocate conntrack.\n"); 667 DEBUGP("Can't allocate conntrack.\n");
661 return (struct nf_conntrack_tuple_hash *)conntrack; 668 return (struct nf_conntrack_tuple_hash *)conntrack;
@@ -676,6 +683,8 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
676 /* Welcome, Mr. Bond. We've been expecting you... */ 683 /* Welcome, Mr. Bond. We've been expecting you... */
677 __set_bit(IPS_EXPECTED_BIT, &conntrack->status); 684 __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
678 conntrack->master = exp->master; 685 conntrack->master = exp->master;
686 if (exp->helper)
687 nfct_help(conntrack)->helper = exp->helper;
679#ifdef CONFIG_NF_CONNTRACK_MARK 688#ifdef CONFIG_NF_CONNTRACK_MARK
680 conntrack->mark = exp->master->mark; 689 conntrack->mark = exp->master->mark;
681#endif 690#endif
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index fdac52beeb8c..e96c41d17ee3 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -516,6 +516,7 @@ static int help(struct sk_buff **pskb,
516 } 516 }
517 517
518 exp->expectfn = NULL; 518 exp->expectfn = NULL;
519 exp->helper = NULL;
519 exp->flags = 0; 520 exp->flags = 0;
520 521
521 /* Now, NAT might want to mangle the packet, and register the 522 /* Now, NAT might want to mangle the packet, and register the
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 2628f4ba35ee..81542dc75069 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -129,7 +129,8 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
129 /* Get rid of expectations */ 129 /* Get rid of expectations */
130 list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, list) { 130 list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, list) {
131 struct nf_conn_help *help = nfct_help(exp->master); 131 struct nf_conn_help *help = nfct_help(exp->master);
132 if (help->helper == me && del_timer(&exp->timeout)) { 132 if ((help->helper == me || exp->helper == me) &&
133 del_timer(&exp->timeout)) {
133 nf_ct_unlink_expect(exp); 134 nf_ct_unlink_expect(exp);
134 nf_conntrack_expect_put(exp); 135 nf_conntrack_expect_put(exp);
135 } 136 }
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index a693d3bd4c11..acaef4025951 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1447,6 +1447,7 @@ ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3)
1447 exp->expectfn = NULL; 1447 exp->expectfn = NULL;
1448 exp->flags = 0; 1448 exp->flags = 0;
1449 exp->master = ct; 1449 exp->master = ct;
1450 exp->helper = NULL;
1450 memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple)); 1451 memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple));
1451 memcpy(&exp->mask, &mask, sizeof(struct nf_conntrack_tuple)); 1452 memcpy(&exp->mask, &mask, sizeof(struct nf_conntrack_tuple));
1452 1453