diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-10-26 09:24:55 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-27 11:37:32 -0700 |
commit | 7a2b03c5175e9ddcc2a2d48ca86dea8a88b68383 (patch) | |
tree | ccc580891d9d17e2482e2f3db2b2c8cf80bdf773 /net | |
parent | b33eab08445d86c3d0dec3111ce10df561328705 (diff) | |
download | linux-7a2b03c5175e9ddcc2a2d48ca86dea8a88b68383.tar.gz linux-7a2b03c5175e9ddcc2a2d48ca86dea8a88b68383.tar.bz2 linux-7a2b03c5175e9ddcc2a2d48ca86dea8a88b68383.zip |
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) list_for_each_entry(r, &ops->rules_list, list) { if (r->pref == rule->target) { - rule->ctarget = r; + RCU_INIT_POINTER(rule->ctarget, r); break; } } - if (rule->ctarget == NULL) + if (rcu_dereference_protected(rule->ctarget, 1) == NULL) unresolved = 1; } else if (rule->action == FR_ACT_GOTO) goto errout_free; @@ -386,7 +386,7 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) list_for_each_entry(r, &ops->rules_list, list) { if (r->action == FR_ACT_GOTO && r->target == rule->pref) { - BUG_ON(r->ctarget != NULL); + BUG_ON(rtnl_dereference(r->ctarget) != NULL); rcu_assign_pointer(r->ctarget, rule); if (--ops->unresolved_rules == 0) break; @@ -487,7 +487,7 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) */ if (ops->nr_goto_rules > 0) { list_for_each_entry(tmp, &ops->rules_list, list) { - if (tmp->ctarget == rule) { + if (rtnl_dereference(tmp->ctarget) == rule) { rcu_assign_pointer(tmp->ctarget, NULL); ops->unresolved_rules++; } @@ -545,7 +545,8 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, frh->action = rule->action; frh->flags = rule->flags; - if (rule->action == FR_ACT_GOTO && rule->ctarget == NULL) + if (rule->action == FR_ACT_GOTO && + rcu_dereference_raw(rule->ctarget) == NULL) frh->flags |= FIB_RULE_UNRESOLVED; if (rule->iifname[0]) { |