diff options
author | YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org> | 2013-01-17 07:53:02 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-01-17 18:38:18 -0500 |
commit | 7ff74a596b6aa47ccc71f6b9a26006af69d0e33f (patch) | |
tree | 7b6ff3fd661d413d185ed05d0443a69c8ee838c3 /net/ipv6/route.c | |
parent | cbf1de72324a8105ddcc3d9ce9acbc613faea17e (diff) |
ndisc: Update neigh->updated with write lock.
neigh->nud_state and neigh->updated are under protection of
neigh->lock.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r-- | net/ipv6/route.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 7c34c01b515b..1341f68e8009 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -499,22 +499,26 @@ static void rt6_probe(struct rt6_info *rt) | |||
499 | * to no more than one per minute. | 499 | * to no more than one per minute. |
500 | */ | 500 | */ |
501 | neigh = rt ? rt->n : NULL; | 501 | neigh = rt ? rt->n : NULL; |
502 | if (!neigh || (neigh->nud_state & NUD_VALID)) | 502 | if (!neigh) |
503 | return; | ||
504 | write_lock_bh(&neigh->lock); | ||
505 | if (neigh->nud_state & NUD_VALID) { | ||
506 | write_unlock_bh(&neigh->lock); | ||
503 | return; | 507 | return; |
504 | read_lock_bh(&neigh->lock); | 508 | } |
505 | if (!(neigh->nud_state & NUD_VALID) && | 509 | if (!(neigh->nud_state & NUD_VALID) && |
506 | time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) { | 510 | time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) { |
507 | struct in6_addr mcaddr; | 511 | struct in6_addr mcaddr; |
508 | struct in6_addr *target; | 512 | struct in6_addr *target; |
509 | 513 | ||
510 | neigh->updated = jiffies; | 514 | neigh->updated = jiffies; |
511 | read_unlock_bh(&neigh->lock); | 515 | write_unlock_bh(&neigh->lock); |
512 | 516 | ||
513 | target = (struct in6_addr *)&neigh->primary_key; | 517 | target = (struct in6_addr *)&neigh->primary_key; |
514 | addrconf_addr_solict_mult(target, &mcaddr); | 518 | addrconf_addr_solict_mult(target, &mcaddr); |
515 | ndisc_send_ns(rt->dst.dev, NULL, target, &mcaddr, NULL); | 519 | ndisc_send_ns(rt->dst.dev, NULL, target, &mcaddr, NULL); |
516 | } else { | 520 | } else { |
517 | read_unlock_bh(&neigh->lock); | 521 | write_unlock_bh(&neigh->lock); |
518 | } | 522 | } |
519 | } | 523 | } |
520 | #else | 524 | #else |