aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesper Dangaard Brouer <brouer@redhat.com>2014-03-03 08:46:01 -0500
committerPablo Neira Ayuso <pablo@netfilter.org>2014-03-07 05:41:01 -0500
commitca7433df3a672efc88e08222cfa4b3aa965ca324 (patch)
treefa88e7bec5578690bb19effe9ee4f88fe82011ac
parente1b207dac13ddb2f8ddebc7dc9729a97421909bd (diff)
netfilter: conntrack: seperate expect locking from nf_conntrack_lock
Netfilter expectations are protected with the same lock as conntrack entries (nf_conntrack_lock). This patch split out expectations locking to use it's own lock (nf_conntrack_expect_lock). Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net> Reviewed-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/net/netfilter/nf_conntrack_core.h2
-rw-r--r--net/netfilter/nf_conntrack_core.c60
-rw-r--r--net/netfilter/nf_conntrack_expect.c20
-rw-r--r--net/netfilter/nf_conntrack_h323_main.c4
-rw-r--r--net/netfilter/nf_conntrack_helper.c22
-rw-r--r--net/netfilter/nf_conntrack_netlink.c32
-rw-r--r--net/netfilter/nf_conntrack_sip.c8
7 files changed, 79 insertions, 69 deletions
diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
index 15308b8eb5b5..d12a631d0415 100644
--- a/include/net/netfilter/nf_conntrack_core.h
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -79,4 +79,6 @@ print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
79 79
80extern spinlock_t nf_conntrack_lock ; 80extern spinlock_t nf_conntrack_lock ;
81 81
82extern spinlock_t nf_conntrack_expect_lock;
83
82#endif /* _NF_CONNTRACK_CORE_H */ 84#endif /* _NF_CONNTRACK_CORE_H */
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 92d597788d6a..4cdf1ade1530 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -63,6 +63,9 @@ EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook);
63DEFINE_SPINLOCK(nf_conntrack_lock); 63DEFINE_SPINLOCK(nf_conntrack_lock);
64EXPORT_SYMBOL_GPL(nf_conntrack_lock); 64EXPORT_SYMBOL_GPL(nf_conntrack_lock);
65 65
66__cacheline_aligned_in_smp DEFINE_SPINLOCK(nf_conntrack_expect_lock);
67EXPORT_SYMBOL_GPL(nf_conntrack_expect_lock);
68
66unsigned int nf_conntrack_htable_size __read_mostly; 69unsigned int nf_conntrack_htable_size __read_mostly;
67EXPORT_SYMBOL_GPL(nf_conntrack_htable_size); 70EXPORT_SYMBOL_GPL(nf_conntrack_htable_size);
68 71
@@ -247,9 +250,6 @@ destroy_conntrack(struct nf_conntrack *nfct)
247 NF_CT_ASSERT(atomic_read(&nfct->use) == 0); 250 NF_CT_ASSERT(atomic_read(&nfct->use) == 0);
248 NF_CT_ASSERT(!timer_pending(&ct->timeout)); 251 NF_CT_ASSERT(!timer_pending(&ct->timeout));
249 252
250 /* To make sure we don't get any weird locking issues here:
251 * destroy_conntrack() MUST NOT be called with a write lock
252 * to nf_conntrack_lock!!! -HW */
253 rcu_read_lock(); 253 rcu_read_lock();
254 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct)); 254 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
255 if (l4proto && l4proto->destroy) 255 if (l4proto && l4proto->destroy)
@@ -257,17 +257,18 @@ destroy_conntrack(struct nf_conntrack *nfct)
257 257
258 rcu_read_unlock(); 258 rcu_read_unlock();
259 259
260 spin_lock_bh(&nf_conntrack_lock); 260 local_bh_disable();
261 /* Expectations will have been removed in clean_from_lists, 261 /* Expectations will have been removed in clean_from_lists,
262 * except TFTP can create an expectation on the first packet, 262 * except TFTP can create an expectation on the first packet,
263 * before connection is in the list, so we need to clean here, 263 * before connection is in the list, so we need to clean here,
264 * too. */ 264 * too.
265 */
265 nf_ct_remove_expectations(ct); 266 nf_ct_remove_expectations(ct);
266 267
267 nf_ct_del_from_dying_or_unconfirmed_list(ct); 268 nf_ct_del_from_dying_or_unconfirmed_list(ct);
268 269
269 NF_CT_STAT_INC(net, delete); 270 NF_CT_STAT_INC(net, delete);
270 spin_unlock_bh(&nf_conntrack_lock); 271 local_bh_enable();
271 272
272 if (ct->master) 273 if (ct->master)
273 nf_ct_put(ct->master); 274 nf_ct_put(ct->master);
@@ -851,7 +852,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
851 struct nf_conn_help *help; 852 struct nf_conn_help *help;
852 struct nf_conntrack_tuple repl_tuple; 853 struct nf_conntrack_tuple repl_tuple;
853 struct nf_conntrack_ecache *ecache; 854 struct nf_conntrack_ecache *ecache;
854 struct nf_conntrack_expect *exp; 855 struct nf_conntrack_expect *exp = NULL;
855 u16 zone = tmpl ? nf_ct_zone(tmpl) : NF_CT_DEFAULT_ZONE; 856 u16 zone = tmpl ? nf_ct_zone(tmpl) : NF_CT_DEFAULT_ZONE;
856 struct nf_conn_timeout *timeout_ext; 857 struct nf_conn_timeout *timeout_ext;
857 unsigned int *timeouts; 858 unsigned int *timeouts;
@@ -895,30 +896,35 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
895 ecache ? ecache->expmask : 0, 896 ecache ? ecache->expmask : 0,
896 GFP_ATOMIC); 897 GFP_ATOMIC);
897 898
898 spin_lock_bh(&nf_conntrack_lock); 899 local_bh_disable();
899 exp = nf_ct_find_expectation(net, zone, tuple); 900 if (net->ct.expect_count) {
900 if (exp) { 901 spin_lock(&nf_conntrack_expect_lock);
901 pr_debug("conntrack: expectation arrives ct=%p exp=%p\n", 902 exp = nf_ct_find_expectation(net, zone, tuple);
902 ct, exp); 903 if (exp) {
903 /* Welcome, Mr. Bond. We've been expecting you... */ 904 pr_debug("conntrack: expectation arrives ct=%p exp=%p\n",
904 __set_bit(IPS_EXPECTED_BIT, &ct->status); 905 ct, exp);
905 /* exp->master safe, refcnt bumped in nf_ct_find_expectation */ 906 /* Welcome, Mr. Bond. We've been expecting you... */
906 ct->master = exp->master; 907 __set_bit(IPS_EXPECTED_BIT, &ct->status);
907 if (exp->helper) { 908 /* exp->master safe, refcnt bumped in nf_ct_find_expectation */
908 help = nf_ct_helper_ext_add(ct, exp->helper, 909 ct->master = exp->master;
909 GFP_ATOMIC); 910 if (exp->helper) {
910 if (help) 911 help = nf_ct_helper_ext_add(ct, exp->helper,
911 rcu_assign_pointer(help->helper, exp->helper); 912 GFP_ATOMIC);
912 } 913 if (help)
914 rcu_assign_pointer(help->helper, exp->helper);
915 }
913 916
914#ifdef CONFIG_NF_CONNTRACK_MARK 917#ifdef CONFIG_NF_CONNTRACK_MARK
915 ct->mark = exp->master->mark; 918 ct->mark = exp->master->mark;
916#endif 919#endif
917#ifdef CONFIG_NF_CONNTRACK_SECMARK 920#ifdef CONFIG_NF_CONNTRACK_SECMARK
918 ct->secmark = exp->master->secmark; 921 ct->secmark = exp->master->secmark;
919#endif 922#endif
920 NF_CT_STAT_INC(net, expect_new); 923 NF_CT_STAT_INC(net, expect_new);
921 } else { 924 }
925 spin_unlock(&nf_conntrack_expect_lock);
926 }
927 if (!exp) {
922 __nf_ct_try_assign_helper(ct, tmpl, GFP_ATOMIC); 928 __nf_ct_try_assign_helper(ct, tmpl, GFP_ATOMIC);
923 NF_CT_STAT_INC(net, new); 929 NF_CT_STAT_INC(net, new);
924 } 930 }
@@ -927,7 +933,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
927 nf_conntrack_get(&ct->ct_general); 933 nf_conntrack_get(&ct->ct_general);
928 nf_ct_add_to_unconfirmed_list(ct); 934 nf_ct_add_to_unconfirmed_list(ct);
929 935
930 spin_unlock_bh(&nf_conntrack_lock); 936 local_bh_enable();
931 937
932 if (exp) { 938 if (exp) {
933 if (exp->expectfn) 939 if (exp->expectfn)
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index f02805e0c7c5..f87e8f68ad45 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -66,9 +66,9 @@ static void nf_ct_expectation_timed_out(unsigned long ul_expect)
66{ 66{
67 struct nf_conntrack_expect *exp = (void *)ul_expect; 67 struct nf_conntrack_expect *exp = (void *)ul_expect;
68 68
69 spin_lock_bh(&nf_conntrack_lock); 69 spin_lock_bh(&nf_conntrack_expect_lock);
70 nf_ct_unlink_expect(exp); 70 nf_ct_unlink_expect(exp);
71 spin_unlock_bh(&nf_conntrack_lock); 71 spin_unlock_bh(&nf_conntrack_expect_lock);
72 nf_ct_expect_put(exp); 72 nf_ct_expect_put(exp);
73} 73}
74 74
@@ -191,12 +191,14 @@ void nf_ct_remove_expectations(struct nf_conn *ct)
191 if (!help) 191 if (!help)
192 return; 192 return;
193 193
194 spin_lock_bh(&nf_conntrack_expect_lock);
194 hlist_for_each_entry_safe(exp, next, &help->expectations, lnode) { 195 hlist_for_each_entry_safe(exp, next, &help->expectations, lnode) {
195 if (del_timer(&exp->timeout)) { 196 if (del_timer(&exp->timeout)) {
196 nf_ct_unlink_expect(exp); 197 nf_ct_unlink_expect(exp);
197 nf_ct_expect_put(exp); 198 nf_ct_expect_put(exp);
198 } 199 }
199 } 200 }
201 spin_unlock_bh(&nf_conntrack_expect_lock);
200} 202}
201EXPORT_SYMBOL_GPL(nf_ct_remove_expectations); 203EXPORT_SYMBOL_GPL(nf_ct_remove_expectations);
202 204
@@ -231,12 +233,12 @@ static inline int expect_matches(const struct nf_conntrack_expect *a,
231/* Generally a bad idea to call this: could have matched already. */ 233/* Generally a bad idea to call this: could have matched already. */
232void nf_ct_unexpect_related(struct nf_conntrack_expect *exp) 234void nf_ct_unexpect_related(struct nf_conntrack_expect *exp)
233{ 235{
234 spin_lock_bh(&nf_conntrack_lock); 236 spin_lock_bh(&nf_conntrack_expect_lock);
235 if (del_timer(&exp->timeout)) { 237 if (del_timer(&exp->timeout)) {
236 nf_ct_unlink_expect(exp); 238 nf_ct_unlink_expect(exp);
237 nf_ct_expect_put(exp); 239 nf_ct_expect_put(exp);
238 } 240 }
239 spin_unlock_bh(&nf_conntrack_lock); 241 spin_unlock_bh(&nf_conntrack_expect_lock);
240} 242}
241EXPORT_SYMBOL_GPL(nf_ct_unexpect_related); 243EXPORT_SYMBOL_GPL(nf_ct_unexpect_related);
242 244
@@ -349,7 +351,7 @@ static int nf_ct_expect_insert(struct nf_conntrack_expect *exp)
349 setup_timer(&exp->timeout, nf_ct_expectation_timed_out, 351 setup_timer(&exp->timeout, nf_ct_expectation_timed_out,
350 (unsigned long)exp); 352 (unsigned long)exp);
351 helper = rcu_dereference_protected(master_help->helper, 353 helper = rcu_dereference_protected(master_help->helper,
352 lockdep_is_held(&nf_conntrack_lock)); 354 lockdep_is_held(&nf_conntrack_expect_lock));
353 if (helper) { 355 if (helper) {
354 exp->timeout.expires = jiffies + 356 exp->timeout.expires = jiffies +
355 helper->expect_policy[exp->class].timeout * HZ; 357 helper->expect_policy[exp->class].timeout * HZ;
@@ -409,7 +411,7 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
409 } 411 }
410 /* Will be over limit? */ 412 /* Will be over limit? */
411 helper = rcu_dereference_protected(master_help->helper, 413 helper = rcu_dereference_protected(master_help->helper,
412 lockdep_is_held(&nf_conntrack_lock)); 414 lockdep_is_held(&nf_conntrack_expect_lock));
413 if (helper) { 415 if (helper) {
414 p = &helper->expect_policy[expect->class]; 416 p = &helper->expect_policy[expect->class];
415 if (p->max_expected && 417 if (p->max_expected &&
@@ -436,7 +438,7 @@ int nf_ct_expect_related_report(struct nf_conntrack_expect *expect,
436{ 438{
437 int ret; 439 int ret;
438 440
439 spin_lock_bh(&nf_conntrack_lock); 441 spin_lock_bh(&nf_conntrack_expect_lock);
440 ret = __nf_ct_expect_check(expect); 442 ret = __nf_ct_expect_check(expect);
441 if (ret <= 0) 443 if (ret <= 0)
442 goto out; 444 goto out;
@@ -444,11 +446,11 @@ int nf_ct_expect_related_report(struct nf_conntrack_expect *expect,
444 ret = nf_ct_expect_insert(expect); 446 ret = nf_ct_expect_insert(expect);
445 if (ret < 0) 447 if (ret < 0)
446 goto out; 448 goto out;
447 spin_unlock_bh(&nf_conntrack_lock); 449 spin_unlock_bh(&nf_conntrack_expect_lock);
448 nf_ct_expect_event_report(IPEXP_NEW, expect, portid, report); 450 nf_ct_expect_event_report(IPEXP_NEW, expect, portid, report);
449 return ret; 451 return ret;
450out: 452out:
451 spin_unlock_bh(&nf_conntrack_lock); 453 spin_unlock_bh(&nf_conntrack_expect_lock);
452 return ret; 454 return ret;
453} 455}
454EXPORT_SYMBOL_GPL(nf_ct_expect_related_report); 456EXPORT_SYMBOL_GPL(nf_ct_expect_related_report);
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index 70866d192efc..3a3a60b126e0 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -1476,7 +1476,7 @@ static int process_rcf(struct sk_buff *skb, struct nf_conn *ct,
1476 nf_ct_refresh(ct, skb, info->timeout * HZ); 1476 nf_ct_refresh(ct, skb, info->timeout * HZ);
1477 1477
1478 /* Set expect timeout */ 1478 /* Set expect timeout */
1479 spin_lock_bh(&nf_conntrack_lock); 1479 spin_lock_bh(&nf_conntrack_expect_lock);
1480 exp = find_expect(ct, &ct->tuplehash[dir].tuple.dst.u3, 1480 exp = find_expect(ct, &ct->tuplehash[dir].tuple.dst.u3,
1481 info->sig_port[!dir]); 1481 info->sig_port[!dir]);
1482 if (exp) { 1482 if (exp) {
@@ -1486,7 +1486,7 @@ static int process_rcf(struct sk_buff *skb, struct nf_conn *ct,
1486 nf_ct_dump_tuple(&exp->tuple); 1486 nf_ct_dump_tuple(&exp->tuple);
1487 set_expect_timeout(exp, info->timeout); 1487 set_expect_timeout(exp, info->timeout);
1488 } 1488 }
1489 spin_unlock_bh(&nf_conntrack_lock); 1489 spin_unlock_bh(&nf_conntrack_expect_lock);
1490 } 1490 }
1491 1491
1492 return 0; 1492 return 0;
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 27d9302c2191..29bd704edb85 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -250,16 +250,14 @@ out:
250} 250}
251EXPORT_SYMBOL_GPL(__nf_ct_try_assign_helper); 251EXPORT_SYMBOL_GPL(__nf_ct_try_assign_helper);
252 252
253/* appropiate ct lock protecting must be taken by caller */
253static inline int unhelp(struct nf_conntrack_tuple_hash *i, 254static inline int unhelp(struct nf_conntrack_tuple_hash *i,
254 const struct nf_conntrack_helper *me) 255 const struct nf_conntrack_helper *me)
255{ 256{
256 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(i); 257 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(i);
257 struct nf_conn_help *help = nfct_help(ct); 258 struct nf_conn_help *help = nfct_help(ct);
258 259
259 if (help && rcu_dereference_protected( 260 if (help && rcu_dereference_raw(help->helper) == me) {
260 help->helper,
261 lockdep_is_held(&nf_conntrack_lock)
262 ) == me) {
263 nf_conntrack_event(IPCT_HELPER, ct); 261 nf_conntrack_event(IPCT_HELPER, ct);
264 RCU_INIT_POINTER(help->helper, NULL); 262 RCU_INIT_POINTER(help->helper, NULL);
265 } 263 }
@@ -284,17 +282,17 @@ static LIST_HEAD(nf_ct_helper_expectfn_list);
284 282
285void nf_ct_helper_expectfn_register(struct nf_ct_helper_expectfn *n) 283void nf_ct_helper_expectfn_register(struct nf_ct_helper_expectfn *n)
286{ 284{
287 spin_lock_bh(&nf_conntrack_lock); 285 spin_lock_bh(&nf_conntrack_expect_lock);
288 list_add_rcu(&n->head, &nf_ct_helper_expectfn_list); 286 list_add_rcu(&n->head, &nf_ct_helper_expectfn_list);
289 spin_unlock_bh(&nf_conntrack_lock); 287 spin_unlock_bh(&nf_conntrack_expect_lock);
290} 288}
291EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_register); 289EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_register);
292 290
293void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n) 291void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n)
294{ 292{
295 spin_lock_bh(&nf_conntrack_lock); 293 spin_lock_bh(&nf_conntrack_expect_lock);
296 list_del_rcu(&n->head); 294 list_del_rcu(&n->head);
297 spin_unlock_bh(&nf_conntrack_lock); 295 spin_unlock_bh(&nf_conntrack_expect_lock);
298} 296}
299EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_unregister); 297EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_unregister);
300 298
@@ -399,13 +397,14 @@ static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me,
399 int cpu; 397 int cpu;
400 398
401 /* Get rid of expectations */ 399 /* Get rid of expectations */
400 spin_lock_bh(&nf_conntrack_expect_lock);
402 for (i = 0; i < nf_ct_expect_hsize; i++) { 401 for (i = 0; i < nf_ct_expect_hsize; i++) {
403 hlist_for_each_entry_safe(exp, next, 402 hlist_for_each_entry_safe(exp, next,
404 &net->ct.expect_hash[i], hnode) { 403 &net->ct.expect_hash[i], hnode) {
405 struct nf_conn_help *help = nfct_help(exp->master); 404 struct nf_conn_help *help = nfct_help(exp->master);
406 if ((rcu_dereference_protected( 405 if ((rcu_dereference_protected(
407 help->helper, 406 help->helper,
408 lockdep_is_held(&nf_conntrack_lock) 407 lockdep_is_held(&nf_conntrack_expect_lock)
409 ) == me || exp->helper == me) && 408 ) == me || exp->helper == me) &&
410 del_timer(&exp->timeout)) { 409 del_timer(&exp->timeout)) {
411 nf_ct_unlink_expect(exp); 410 nf_ct_unlink_expect(exp);
@@ -413,6 +412,7 @@ static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me,
413 } 412 }
414 } 413 }
415 } 414 }
415 spin_unlock_bh(&nf_conntrack_expect_lock);
416 416
417 /* Get rid of expecteds, set helpers to NULL. */ 417 /* Get rid of expecteds, set helpers to NULL. */
418 for_each_possible_cpu(cpu) { 418 for_each_possible_cpu(cpu) {
@@ -423,10 +423,12 @@ static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me,
423 unhelp(h, me); 423 unhelp(h, me);
424 spin_unlock_bh(&pcpu->lock); 424 spin_unlock_bh(&pcpu->lock);
425 } 425 }
426 spin_lock_bh(&nf_conntrack_lock);
426 for (i = 0; i < net->ct.htable_size; i++) { 427 for (i = 0; i < net->ct.htable_size; i++) {
427 hlist_nulls_for_each_entry(h, nn, &net->ct.hash[i], hnnode) 428 hlist_nulls_for_each_entry(h, nn, &net->ct.hash[i], hnnode)
428 unhelp(h, me); 429 unhelp(h, me);
429 } 430 }
431 spin_unlock_bh(&nf_conntrack_lock);
430} 432}
431 433
432void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me) 434void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
@@ -444,10 +446,8 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
444 synchronize_rcu(); 446 synchronize_rcu();
445 447
446 rtnl_lock(); 448 rtnl_lock();
447 spin_lock_bh(&nf_conntrack_lock);
448 for_each_net(net) 449 for_each_net(net)
449 __nf_conntrack_helper_unregister(me, net); 450 __nf_conntrack_helper_unregister(me, net);
450 spin_unlock_bh(&nf_conntrack_lock);
451 rtnl_unlock(); 451 rtnl_unlock();
452} 452}
453EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister); 453EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 4ac8ce68bc16..be4d1b0bbb6a 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1376,14 +1376,14 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[])
1376 nf_ct_protonum(ct)); 1376 nf_ct_protonum(ct));
1377 if (helper == NULL) { 1377 if (helper == NULL) {
1378#ifdef CONFIG_MODULES 1378#ifdef CONFIG_MODULES
1379 spin_unlock_bh(&nf_conntrack_lock); 1379 spin_unlock_bh(&nf_conntrack_expect_lock);
1380 1380
1381 if (request_module("nfct-helper-%s", helpname) < 0) { 1381 if (request_module("nfct-helper-%s", helpname) < 0) {
1382 spin_lock_bh(&nf_conntrack_lock); 1382 spin_lock_bh(&nf_conntrack_expect_lock);
1383 return -EOPNOTSUPP; 1383 return -EOPNOTSUPP;
1384 } 1384 }
1385 1385
1386 spin_lock_bh(&nf_conntrack_lock); 1386 spin_lock_bh(&nf_conntrack_expect_lock);
1387 helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct), 1387 helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct),
1388 nf_ct_protonum(ct)); 1388 nf_ct_protonum(ct));
1389 if (helper) 1389 if (helper)
@@ -1821,9 +1821,9 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1821 err = -EEXIST; 1821 err = -EEXIST;
1822 ct = nf_ct_tuplehash_to_ctrack(h); 1822 ct = nf_ct_tuplehash_to_ctrack(h);
1823 if (!(nlh->nlmsg_flags & NLM_F_EXCL)) { 1823 if (!(nlh->nlmsg_flags & NLM_F_EXCL)) {
1824 spin_lock_bh(&nf_conntrack_lock); 1824 spin_lock_bh(&nf_conntrack_expect_lock);
1825 err = ctnetlink_change_conntrack(ct, cda); 1825 err = ctnetlink_change_conntrack(ct, cda);
1826 spin_unlock_bh(&nf_conntrack_lock); 1826 spin_unlock_bh(&nf_conntrack_expect_lock);
1827 if (err == 0) { 1827 if (err == 0) {
1828 nf_conntrack_eventmask_report((1 << IPCT_REPLY) | 1828 nf_conntrack_eventmask_report((1 << IPCT_REPLY) |
1829 (1 << IPCT_ASSURED) | 1829 (1 << IPCT_ASSURED) |
@@ -2152,9 +2152,9 @@ ctnetlink_nfqueue_parse(const struct nlattr *attr, struct nf_conn *ct)
2152 if (ret < 0) 2152 if (ret < 0)
2153 return ret; 2153 return ret;
2154 2154
2155 spin_lock_bh(&nf_conntrack_lock); 2155 spin_lock_bh(&nf_conntrack_expect_lock);
2156 ret = ctnetlink_nfqueue_parse_ct((const struct nlattr **)cda, ct); 2156 ret = ctnetlink_nfqueue_parse_ct((const struct nlattr **)cda, ct);
2157 spin_unlock_bh(&nf_conntrack_lock); 2157 spin_unlock_bh(&nf_conntrack_expect_lock);
2158 2158
2159 return ret; 2159 return ret;
2160} 2160}
@@ -2709,13 +2709,13 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
2709 } 2709 }
2710 2710
2711 /* after list removal, usage count == 1 */ 2711 /* after list removal, usage count == 1 */
2712 spin_lock_bh(&nf_conntrack_lock); 2712 spin_lock_bh(&nf_conntrack_expect_lock);
2713 if (del_timer(&exp->timeout)) { 2713 if (del_timer(&exp->timeout)) {
2714 nf_ct_unlink_expect_report(exp, NETLINK_CB(skb).portid, 2714 nf_ct_unlink_expect_report(exp, NETLINK_CB(skb).portid,
2715 nlmsg_report(nlh)); 2715 nlmsg_report(nlh));
2716 nf_ct_expect_put(exp); 2716 nf_ct_expect_put(exp);
2717 } 2717 }
2718 spin_unlock_bh(&nf_conntrack_lock); 2718 spin_unlock_bh(&nf_conntrack_expect_lock);
2719 /* have to put what we 'get' above. 2719 /* have to put what we 'get' above.
2720 * after this line usage count == 0 */ 2720 * after this line usage count == 0 */
2721 nf_ct_expect_put(exp); 2721 nf_ct_expect_put(exp);
@@ -2724,7 +2724,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
2724 struct nf_conn_help *m_help; 2724 struct nf_conn_help *m_help;
2725 2725
2726 /* delete all expectations for this helper */ 2726 /* delete all expectations for this helper */
2727 spin_lock_bh(&nf_conntrack_lock); 2727 spin_lock_bh(&nf_conntrack_expect_lock);
2728 for (i = 0; i < nf_ct_expect_hsize; i++) { 2728 for (i = 0; i < nf_ct_expect_hsize; i++) {
2729 hlist_for_each_entry_safe(exp, next, 2729 hlist_for_each_entry_safe(exp, next,
2730 &net->ct.expect_hash[i], 2730 &net->ct.expect_hash[i],
@@ -2739,10 +2739,10 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
2739 } 2739 }
2740 } 2740 }
2741 } 2741 }
2742 spin_unlock_bh(&nf_conntrack_lock); 2742 spin_unlock_bh(&nf_conntrack_expect_lock);
2743 } else { 2743 } else {
2744 /* This basically means we have to flush everything*/ 2744 /* This basically means we have to flush everything*/
2745 spin_lock_bh(&nf_conntrack_lock); 2745 spin_lock_bh(&nf_conntrack_expect_lock);
2746 for (i = 0; i < nf_ct_expect_hsize; i++) { 2746 for (i = 0; i < nf_ct_expect_hsize; i++) {
2747 hlist_for_each_entry_safe(exp, next, 2747 hlist_for_each_entry_safe(exp, next,
2748 &net->ct.expect_hash[i], 2748 &net->ct.expect_hash[i],
@@ -2755,7 +2755,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
2755 } 2755 }
2756 } 2756 }
2757 } 2757 }
2758 spin_unlock_bh(&nf_conntrack_lock); 2758 spin_unlock_bh(&nf_conntrack_expect_lock);
2759 } 2759 }
2760 2760
2761 return 0; 2761 return 0;
@@ -2981,11 +2981,11 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
2981 if (err < 0) 2981 if (err < 0)
2982 return err; 2982 return err;
2983 2983
2984 spin_lock_bh(&nf_conntrack_lock); 2984 spin_lock_bh(&nf_conntrack_expect_lock);
2985 exp = __nf_ct_expect_find(net, zone, &tuple); 2985 exp = __nf_ct_expect_find(net, zone, &tuple);
2986 2986
2987 if (!exp) { 2987 if (!exp) {
2988 spin_unlock_bh(&nf_conntrack_lock); 2988 spin_unlock_bh(&nf_conntrack_expect_lock);
2989 err = -ENOENT; 2989 err = -ENOENT;
2990 if (nlh->nlmsg_flags & NLM_F_CREATE) { 2990 if (nlh->nlmsg_flags & NLM_F_CREATE) {
2991 err = ctnetlink_create_expect(net, zone, cda, 2991 err = ctnetlink_create_expect(net, zone, cda,
@@ -2999,7 +2999,7 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
2999 err = -EEXIST; 2999 err = -EEXIST;
3000 if (!(nlh->nlmsg_flags & NLM_F_EXCL)) 3000 if (!(nlh->nlmsg_flags & NLM_F_EXCL))
3001 err = ctnetlink_change_expect(exp, cda); 3001 err = ctnetlink_change_expect(exp, cda);
3002 spin_unlock_bh(&nf_conntrack_lock); 3002 spin_unlock_bh(&nf_conntrack_expect_lock);
3003 3003
3004 return err; 3004 return err;
3005} 3005}
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 466410eaa482..4c3ba1c8d682 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -800,7 +800,7 @@ static int refresh_signalling_expectation(struct nf_conn *ct,
800 struct hlist_node *next; 800 struct hlist_node *next;
801 int found = 0; 801 int found = 0;
802 802
803 spin_lock_bh(&nf_conntrack_lock); 803 spin_lock_bh(&nf_conntrack_expect_lock);
804 hlist_for_each_entry_safe(exp, next, &help->expectations, lnode) { 804 hlist_for_each_entry_safe(exp, next, &help->expectations, lnode) {
805 if (exp->class != SIP_EXPECT_SIGNALLING || 805 if (exp->class != SIP_EXPECT_SIGNALLING ||
806 !nf_inet_addr_cmp(&exp->tuple.dst.u3, addr) || 806 !nf_inet_addr_cmp(&exp->tuple.dst.u3, addr) ||
@@ -815,7 +815,7 @@ static int refresh_signalling_expectation(struct nf_conn *ct,
815 found = 1; 815 found = 1;
816 break; 816 break;
817 } 817 }
818 spin_unlock_bh(&nf_conntrack_lock); 818 spin_unlock_bh(&nf_conntrack_expect_lock);
819 return found; 819 return found;
820} 820}
821 821
@@ -825,7 +825,7 @@ static void flush_expectations(struct nf_conn *ct, bool media)
825 struct nf_conntrack_expect *exp; 825 struct nf_conntrack_expect *exp;
826 struct hlist_node *next; 826 struct hlist_node *next;
827 827
828 spin_lock_bh(&nf_conntrack_lock); 828 spin_lock_bh(&nf_conntrack_expect_lock);
829 hlist_for_each_entry_safe(exp, next, &help->expectations, lnode) { 829 hlist_for_each_entry_safe(exp, next, &help->expectations, lnode) {
830 if ((exp->class != SIP_EXPECT_SIGNALLING) ^ media) 830 if ((exp->class != SIP_EXPECT_SIGNALLING) ^ media)
831 continue; 831 continue;
@@ -836,7 +836,7 @@ static void flush_expectations(struct nf_conn *ct, bool media)
836 if (!media) 836 if (!media)
837 break; 837 break;
838 } 838 }
839 spin_unlock_bh(&nf_conntrack_lock); 839 spin_unlock_bh(&nf_conntrack_expect_lock);
840} 840}
841 841
842static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff, 842static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff,