.. | .. |
---|
351 | 351 | { |
---|
352 | 352 | struct in_ifaddr *promote = NULL; |
---|
353 | 353 | struct in_ifaddr *ifa, *ifa1; |
---|
354 | | - struct in_ifaddr *last_prim; |
---|
| 354 | + struct in_ifaddr __rcu **last_prim; |
---|
355 | 355 | struct in_ifaddr *prev_prom = NULL; |
---|
356 | 356 | int do_promote = IN_DEV_PROMOTE_SECONDARIES(in_dev); |
---|
357 | 357 | |
---|
358 | 358 | ASSERT_RTNL(); |
---|
359 | 359 | |
---|
360 | 360 | ifa1 = rtnl_dereference(*ifap); |
---|
361 | | - last_prim = rtnl_dereference(in_dev->ifa_list); |
---|
| 361 | + last_prim = ifap; |
---|
362 | 362 | if (in_dev->dead) |
---|
363 | 363 | goto no_promotions; |
---|
364 | 364 | |
---|
.. | .. |
---|
372 | 372 | while ((ifa = rtnl_dereference(*ifap1)) != NULL) { |
---|
373 | 373 | if (!(ifa->ifa_flags & IFA_F_SECONDARY) && |
---|
374 | 374 | ifa1->ifa_scope <= ifa->ifa_scope) |
---|
375 | | - last_prim = ifa; |
---|
| 375 | + last_prim = &ifa->ifa_next; |
---|
376 | 376 | |
---|
377 | 377 | if (!(ifa->ifa_flags & IFA_F_SECONDARY) || |
---|
378 | 378 | ifa1->ifa_mask != ifa->ifa_mask || |
---|
.. | .. |
---|
436 | 436 | |
---|
437 | 437 | rcu_assign_pointer(prev_prom->ifa_next, next_sec); |
---|
438 | 438 | |
---|
439 | | - last_sec = rtnl_dereference(last_prim->ifa_next); |
---|
| 439 | + last_sec = rtnl_dereference(*last_prim); |
---|
440 | 440 | rcu_assign_pointer(promote->ifa_next, last_sec); |
---|
441 | | - rcu_assign_pointer(last_prim->ifa_next, promote); |
---|
| 441 | + rcu_assign_pointer(*last_prim, promote); |
---|
442 | 442 | } |
---|
443 | 443 | |
---|
444 | 444 | promote->ifa_flags &= ~IFA_F_SECONDARY; |
---|