@@ -498,28 +498,34 @@ static void rt6_probe(struct rt6_info *rt)
498
498
* Router Reachability Probe MUST be rate-limited
499
499
* to no more than one per minute.
500
500
*/
501
- neigh = rt ? rt -> n : NULL ;
502
- if (!neigh )
503
- return ;
504
- write_lock_bh (& neigh -> lock );
505
- if (neigh -> nud_state & NUD_VALID ) {
506
- write_unlock_bh (& neigh -> lock );
501
+ if (!rt || !(rt -> rt6i_flags & RTF_GATEWAY ))
507
502
return ;
503
+ rcu_read_lock_bh ();
504
+ neigh = __ipv6_neigh_lookup_noref (rt -> dst .dev , & rt -> rt6i_gateway );
505
+ if (neigh ) {
506
+ write_lock (& neigh -> lock );
507
+ if (neigh -> nud_state & NUD_VALID )
508
+ goto out ;
508
509
}
509
- if (!(neigh -> nud_state & NUD_VALID ) &&
510
+
511
+ if (!neigh ||
510
512
time_after (jiffies , neigh -> updated + rt -> rt6i_idev -> cnf .rtr_probe_interval )) {
511
513
struct in6_addr mcaddr ;
512
514
struct in6_addr * target ;
513
515
514
516
neigh -> updated = jiffies ;
515
- write_unlock_bh (& neigh -> lock );
516
517
517
- target = (struct in6_addr * )& neigh -> primary_key ;
518
+ if (neigh )
519
+ write_unlock (& neigh -> lock );
520
+
521
+ target = (struct in6_addr * )& rt -> rt6i_gateway ;
518
522
addrconf_addr_solict_mult (target , & mcaddr );
519
523
ndisc_send_ns (rt -> dst .dev , NULL , target , & mcaddr , NULL );
520
524
} else {
521
- write_unlock_bh (& neigh -> lock );
525
+ out :
526
+ write_unlock (& neigh -> lock );
522
527
}
528
+ rcu_read_unlock_bh ();
523
529
}
524
530
#else
525
531
static inline void rt6_probe (struct rt6_info * rt )
0 commit comments