| .. | .. |
|---|
| 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; |
|---|