diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-10-26 05:24:55 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-27 14:37:32 -0400 |
commit | 7a2b03c5175e9ddcc2a2d48ca86dea8a88b68383 (patch) | |
tree | ccc580891d9d17e2482e2f3db2b2c8cf80bdf773 /net | |
parent | b33eab08445d86c3d0dec3111ce10df561328705 (diff) |
fib_rules: __rcu annotates ctarget
Adds __rcu annotation to (struct fib_rule)->ctarget
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/fib_rules.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 12b43cc2f889..82a4369ae150 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
@@ -351,12 +351,12 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
351 | 351 | ||
352 | list_for_each_entry(r, &ops->rules_list, list) { | 352 | list_for_each_entry(r, &ops->rules_list, list) { |
353 | if (r->pref == rule->target) { | 353 | if (r->pref == rule->target) { |
354 | rule->ctarget = r; | 354 | RCU_INIT_POINTER(rule->ctarget, r); |
355 | break; | 355 | break; |
356 | } | 356 | } |
357 | } | 357 | } |
358 | 358 | ||
359 | if (rule->ctarget == NULL) | 359 | if (rcu_dereference_protected(rule->ctarget, 1) == NULL) |
360 | unresolved = 1; | 360 | unresolved = 1; |
361 | } else if (rule->action == FR_ACT_GOTO) | 361 | } else if (rule->action == FR_ACT_GOTO) |
362 | goto errout_free; | 362 | goto errout_free; |
@@ -386,7 +386,7 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
386 | list_for_each_entry(r, &ops->rules_list, list) { | 386 | list_for_each_entry(r, &ops->rules_list, list) { |
387 | if (r->action == FR_ACT_GOTO && | 387 | if (r->action == FR_ACT_GOTO && |
388 | r->target == rule->pref) { | 388 | r->target == rule->pref) { |
389 | BUG_ON(r->ctarget != NULL); | 389 | BUG_ON(rtnl_dereference(r->ctarget) != NULL); |
390 | rcu_assign_pointer(r->ctarget, rule); | 390 | rcu_assign_pointer(r->ctarget, rule); |
391 | if (--ops->unresolved_rules == 0) | 391 | if (--ops->unresolved_rules == 0) |
392 | break; | 392 | break; |
@@ -487,7 +487,7 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
487 | */ | 487 | */ |
488 | if (ops->nr_goto_rules > 0) { | 488 | if (ops->nr_goto_rules > 0) { |
489 | list_for_each_entry(tmp, &ops->rules_list, list) { | 489 | list_for_each_entry(tmp, &ops->rules_list, list) { |
490 | if (tmp->ctarget == rule) { | 490 | if (rtnl_dereference(tmp->ctarget) == rule) { |
491 | rcu_assign_pointer(tmp->ctarget, NULL); | 491 | rcu_assign_pointer(tmp->ctarget, NULL); |
492 | ops->unresolved_rules++; | 492 | ops->unresolved_rules++; |
493 | } | 493 | } |
@@ -545,7 +545,8 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, | |||
545 | frh->action = rule->action; | 545 | frh->action = rule->action; |
546 | frh->flags = rule->flags; | 546 | frh->flags = rule->flags; |
547 | 547 | ||
548 | if (rule->action == FR_ACT_GOTO && rule->ctarget == NULL) | 548 | if (rule->action == FR_ACT_GOTO && |
549 | rcu_dereference_raw(rule->ctarget) == NULL) | ||
549 | frh->flags |= FIB_RULE_UNRESOLVED; | 550 | frh->flags |= FIB_RULE_UNRESOLVED; |
550 | 551 | ||
551 | if (rule->iifname[0]) { | 552 | if (rule->iifname[0]) { |