diff options
author | Patrick McHardy <kaber@trash.net> | 2006-12-03 01:05:25 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-12-03 01:05:25 -0500 |
commit | 9457d851fc5df54522d733f72cbb1f02ab59272e (patch) | |
tree | 42a460d65cbb45b100c43f97ba8a7490df844bb8 | |
parent | bff9a89bcac5b68ac0a1ea856b1726a35ae1eabb (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>
-rw-r--r-- | include/net/netfilter/nf_conntrack_expect.h | 3 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_core.c | 19 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_ftp.c | 1 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_helper.c | 3 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 1 |
5 files changed, 21 insertions, 6 deletions
diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index 2d335f024c85..5d853e826d1d 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h | |||
@@ -22,6 +22,9 @@ struct nf_conntrack_expect | |||
22 | void (*expectfn)(struct nf_conn *new, | 22 | void (*expectfn)(struct nf_conn *new, |
23 | struct nf_conntrack_expect *this); | 23 | struct nf_conntrack_expect *this); |
24 | 24 | ||
25 | /* Helper to assign to new connection */ | ||
26 | struct nf_conntrack_helper *helper; | ||
27 | |||
25 | /* The conntrack of the master connection */ | 28 | /* The conntrack of the master connection */ |
26 | struct nf_conn *master; | 29 | struct nf_conn *master; |
27 | 30 | ||
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) | |||
545 | static struct nf_conn * | 545 | static 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 | ||
630 | void nf_conntrack_free(struct nf_conn *conntrack) | 630 | void 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 | ||