Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: ipv4: provide __rcu annotation for ifa_list

ifa_list is protected by rcu, yet code doesn't reflect this.

Add the __rcu annotations and fix up all places that are now reported by
sparse.

I've done this in the same commit to not add intermediate patches that
result in new warnings.

Reported-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Florian Westphal and committed by
David S. Miller
2638eb8b cb8f1478

+135 -82
+8 -4
drivers/infiniband/hw/i40iw/i40iw_utils.c
··· 174 174 rcu_read_lock(); 175 175 in = __in_dev_get_rcu(upper_dev); 176 176 177 - if (!in->ifa_list) 178 - local_ipaddr = 0; 179 - else 180 - local_ipaddr = ntohl(in->ifa_list->ifa_address); 177 + local_ipaddr = 0; 178 + if (in) { 179 + struct in_ifaddr *ifa; 180 + 181 + ifa = rcu_dereference(in->ifa_list); 182 + if (ifa) 183 + local_ipaddr = ntohl(ifa->ifa_address); 184 + } 181 185 182 186 rcu_read_unlock(); 183 187 } else {
+7 -1
drivers/infiniband/hw/nes/nes.c
··· 183 183 184 184 rcu_read_lock(); 185 185 in = __in_dev_get_rcu(upper_dev); 186 - nesvnic->local_ipaddr = in->ifa_list->ifa_address; 186 + if (in) { 187 + struct in_ifaddr *ifa; 188 + 189 + ifa = rcu_dereference(in->ifa_list); 190 + if (ifa) 191 + nesvnic->local_ipaddr = ifa->ifa_address; 192 + } 187 193 rcu_read_unlock(); 188 194 } else { 189 195 nesvnic->local_ipaddr = ifa->ifa_address;
+10 -5
drivers/infiniband/hw/usnic/usnic_ib_main.c
··· 427 427 if (netif_carrier_ok(us_ibdev->netdev)) 428 428 usnic_fwd_carrier_up(us_ibdev->ufdev); 429 429 430 - ind = in_dev_get(netdev); 431 - if (ind->ifa_list) 432 - usnic_fwd_add_ipaddr(us_ibdev->ufdev, 433 - ind->ifa_list->ifa_address); 434 - in_dev_put(ind); 430 + rcu_read_lock(); 431 + ind = __in_dev_get_rcu(netdev); 432 + if (ind) { 433 + const struct in_ifaddr *ifa; 434 + 435 + ifa = rcu_dereference(ind->ifa_list); 436 + if (ifa) 437 + usnic_fwd_add_ipaddr(us_ibdev->ufdev, ifa->ifa_address); 438 + } 439 + rcu_read_unlock(); 435 440 436 441 usnic_mac_ip_to_gid(us_ibdev->netdev->perm_addr, 437 442 us_ibdev->ufdev->inaddr, &gid.raw[0]);
+1 -1
drivers/net/ethernet/via/via-velocity.h
··· 1509 1509 rcu_read_lock(); 1510 1510 in_dev = __in_dev_get_rcu(vptr->netdev); 1511 1511 if (in_dev != NULL) { 1512 - ifa = (struct in_ifaddr *) in_dev->ifa_list; 1512 + ifa = rcu_dereference(in_dev->ifa_list); 1513 1513 if (ifa != NULL) { 1514 1514 memcpy(vptr->ip_addr, &ifa->ifa_address, 4); 1515 1515 res = 0;
+2 -2
drivers/net/plip/plip.c
··· 1012 1012 in_dev = __in_dev_get_rcu(dev); 1013 1013 if (in_dev) { 1014 1014 /* Any address will do - we take the first */ 1015 - const struct in_ifaddr *ifa = in_dev->ifa_list; 1015 + const struct in_ifaddr *ifa = rcu_dereference(in_dev->ifa_list); 1016 1016 if (ifa) { 1017 1017 memcpy(eth->h_source, dev->dev_addr, ETH_ALEN); 1018 1018 memset(eth->h_dest, 0xfc, 2); ··· 1107 1107 /* Any address will do - we take the first. We already 1108 1108 have the first two bytes filled with 0xfc, from 1109 1109 plip_init_dev(). */ 1110 - struct in_ifaddr *ifa=in_dev->ifa_list; 1110 + const struct in_ifaddr *ifa = rcu_dereference(in_dev->ifa_list); 1111 1111 if (ifa != NULL) { 1112 1112 memcpy(dev->dev_addr+2, &ifa->ifa_local, 4); 1113 1113 }
+14 -7
drivers/net/vmxnet3/vmxnet3_drv.c
··· 3651 3651 } 3652 3652 3653 3653 if (adapter->wol & WAKE_ARP) { 3654 - in_dev = in_dev_get(netdev); 3655 - if (!in_dev) 3656 - goto skip_arp; 3654 + rcu_read_lock(); 3657 3655 3658 - ifa = (struct in_ifaddr *)in_dev->ifa_list; 3659 - if (!ifa) 3656 + in_dev = __in_dev_get_rcu(netdev); 3657 + if (!in_dev) { 3658 + rcu_read_unlock(); 3660 3659 goto skip_arp; 3660 + } 3661 + 3662 + ifa = rcu_dereference(in_dev->ifa_list); 3663 + if (!ifa) { 3664 + rcu_read_unlock(); 3665 + goto skip_arp; 3666 + } 3661 3667 3662 3668 pmConf->filters[i].patternSize = ETH_HLEN + /* Ethernet header*/ 3663 3669 sizeof(struct arphdr) + /* ARP header */ ··· 3683 3677 3684 3678 /* The Unicast IPv4 address in 'tip' field. */ 3685 3679 arpreq += 2 * ETH_ALEN + sizeof(u32); 3686 - *(u32 *)arpreq = ifa->ifa_address; 3680 + *(__be32 *)arpreq = ifa->ifa_address; 3681 + 3682 + rcu_read_unlock(); 3687 3683 3688 3684 /* The mask for the relevant bits. */ 3689 3685 pmConf->filters[i].mask[0] = 0x00; ··· 3694 3686 pmConf->filters[i].mask[3] = 0x00; 3695 3687 pmConf->filters[i].mask[4] = 0xC0; /* IPv4 TIP */ 3696 3688 pmConf->filters[i].mask[5] = 0x03; /* IPv4 TIP */ 3697 - in_dev_put(in_dev); 3698 3689 3699 3690 pmConf->wakeUpEvents |= VMXNET3_PM_WAKEUP_FILTER; 3700 3691 i++;
+2 -2
drivers/net/wireless/ath/ath6kl/cfg80211.c
··· 2194 2194 if (!in_dev) 2195 2195 return 0; 2196 2196 2197 - ifa = in_dev->ifa_list; 2197 + ifa = rtnl_dereference(in_dev->ifa_list); 2198 2198 memset(&ips, 0, sizeof(ips)); 2199 2199 2200 2200 /* Configure IP addr only if IP address count < MAX_IP_ADDRS */ 2201 2201 while (index < MAX_IP_ADDRS && ifa) { 2202 2202 ips[index] = ifa->ifa_local; 2203 - ifa = ifa->ifa_next; 2203 + ifa = rtnl_dereference(ifa->ifa_next); 2204 2204 index++; 2205 2205 } 2206 2206
+1 -1
drivers/net/wireless/marvell/mwifiex/cfg80211.c
··· 3268 3268 in_dev = __in_dev_get_rtnl(adapter->priv[i]->netdev); 3269 3269 if (!in_dev) 3270 3270 continue; 3271 - ifa = in_dev->ifa_list; 3271 + ifa = rtnl_dereference(in_dev->ifa_list); 3272 3272 if (!ifa || !ifa->ifa_local) 3273 3273 continue; 3274 3274 ips[i] = ifa->ifa_local;
+5 -1
drivers/staging/isdn/hysdn/hysdn_net.c
··· 70 70 for (i = 0; i < ETH_ALEN; i++) 71 71 dev->dev_addr[i] = 0xfc; 72 72 if ((in_dev = dev->ip_ptr) != NULL) { 73 - struct in_ifaddr *ifa = in_dev->ifa_list; 73 + const struct in_ifaddr *ifa; 74 + 75 + rcu_read_lock(); 76 + ifa = rcu_dereference(in_dev->ifa_list); 74 77 if (ifa != NULL) 75 78 memcpy(dev->dev_addr + (ETH_ALEN - sizeof(ifa->ifa_local)), &ifa->ifa_local, sizeof(ifa->ifa_local)); 79 + rcu_read_unlock(); 76 80 } 77 81 } else 78 82 memcpy(dev->dev_addr, card->mac_addr, ETH_ALEN);
+6 -15
include/linux/inetdevice.h
··· 26 26 struct net_device *dev; 27 27 refcount_t refcnt; 28 28 int dead; 29 - struct in_ifaddr *ifa_list; /* IP ifaddr chain */ 29 + struct in_ifaddr __rcu *ifa_list;/* IP ifaddr chain */ 30 30 31 31 struct ip_mc_list __rcu *mc_list; /* IP multicast filter chain */ 32 32 struct ip_mc_list __rcu * __rcu *mc_hash; ··· 136 136 137 137 struct in_ifaddr { 138 138 struct hlist_node hash; 139 - struct in_ifaddr *ifa_next; 139 + struct in_ifaddr __rcu *ifa_next; 140 140 struct in_device *ifa_dev; 141 141 struct rcu_head rcu_head; 142 142 __be32 ifa_local; ··· 206 206 return false; 207 207 } 208 208 209 - #define for_primary_ifa(in_dev) { struct in_ifaddr *ifa; \ 210 - for (ifa = (in_dev)->ifa_list; ifa && !(ifa->ifa_flags&IFA_F_SECONDARY); ifa = ifa->ifa_next) 211 - 212 - #define for_ifa(in_dev) { struct in_ifaddr *ifa; \ 213 - for (ifa = (in_dev)->ifa_list; ifa; ifa = ifa->ifa_next) 214 - 215 - 216 - #define endfor_ifa(in_dev) } 217 - 218 209 #define in_dev_for_each_ifa_rtnl(ifa, in_dev) \ 219 - for (ifa = (in_dev)->ifa_list; ifa; \ 220 - ifa = ifa->ifa_next) 210 + for (ifa = rtnl_dereference((in_dev)->ifa_list); ifa; \ 211 + ifa = rtnl_dereference(ifa->ifa_next)) 221 212 222 213 #define in_dev_for_each_ifa_rcu(ifa, in_dev) \ 223 - for (ifa = (in_dev)->ifa_list; ifa; \ 224 - ifa = ifa->ifa_next) 214 + for (ifa = rcu_dereference((in_dev)->ifa_list); ifa; \ 215 + ifa = rcu_dereference(ifa->ifa_next)) 225 216 226 217 static inline struct in_device *__in_dev_get_rcu(const struct net_device *dev) 227 218 {
+9 -3
net/core/netpoll.c
··· 696 696 697 697 if (!np->local_ip.ip) { 698 698 if (!np->ipv6) { 699 - in_dev = __in_dev_get_rtnl(ndev); 699 + const struct in_ifaddr *ifa; 700 700 701 - if (!in_dev || !in_dev->ifa_list) { 701 + in_dev = __in_dev_get_rtnl(ndev); 702 + if (!in_dev) 703 + goto put_noaddr; 704 + 705 + ifa = rtnl_dereference(in_dev->ifa_list); 706 + if (!ifa) { 707 + put_noaddr: 702 708 np_err(np, "no IP address for %s, aborting\n", 703 709 np->dev_name); 704 710 err = -EDESTADDRREQ; 705 711 goto put; 706 712 } 707 713 708 - np->local_ip.ip = in_dev->ifa_list->ifa_local; 714 + np->local_ip.ip = ifa->ifa_local; 709 715 np_info(np, "local IP %pI4\n", &np->local_ip.ip); 710 716 } else { 711 717 #if IS_ENABLED(CONFIG_IPV6)
+5 -3
net/core/pktgen.c
··· 2125 2125 rcu_read_lock(); 2126 2126 in_dev = __in_dev_get_rcu(pkt_dev->odev); 2127 2127 if (in_dev) { 2128 - if (in_dev->ifa_list) { 2129 - pkt_dev->saddr_min = 2130 - in_dev->ifa_list->ifa_address; 2128 + const struct in_ifaddr *ifa; 2129 + 2130 + ifa = rcu_dereference(in_dev->ifa_list); 2131 + if (ifa) { 2132 + pkt_dev->saddr_min = ifa->ifa_address; 2131 2133 pkt_dev->saddr_max = pkt_dev->saddr_min; 2132 2134 } 2133 2135 }
+56 -30
net/ipv4/devinet.c
··· 194 194 195 195 static BLOCKING_NOTIFIER_HEAD(inetaddr_chain); 196 196 static BLOCKING_NOTIFIER_HEAD(inetaddr_validator_chain); 197 - static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, 197 + static void inet_del_ifa(struct in_device *in_dev, 198 + struct in_ifaddr __rcu **ifap, 198 199 int destroy); 199 200 #ifdef CONFIG_SYSCTL 200 201 static int devinet_sysctl_register(struct in_device *idev); ··· 301 300 302 301 static void inetdev_destroy(struct in_device *in_dev) 303 302 { 304 - struct in_ifaddr *ifa; 305 303 struct net_device *dev; 304 + struct in_ifaddr *ifa; 306 305 307 306 ASSERT_RTNL(); 308 307 ··· 312 311 313 312 ip_mc_destroy_dev(in_dev); 314 313 315 - while ((ifa = in_dev->ifa_list) != NULL) { 314 + while ((ifa = rtnl_dereference(in_dev->ifa_list)) != NULL) { 316 315 inet_del_ifa(in_dev, &in_dev->ifa_list, 0); 317 316 inet_free_ifa(ifa); 318 317 } ··· 343 342 return 0; 344 343 } 345 344 346 - static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, 347 - int destroy, struct nlmsghdr *nlh, u32 portid) 345 + static void __inet_del_ifa(struct in_device *in_dev, 346 + struct in_ifaddr __rcu **ifap, 347 + int destroy, struct nlmsghdr *nlh, u32 portid) 348 348 { 349 349 struct in_ifaddr *promote = NULL; 350 - struct in_ifaddr *ifa, *ifa1 = *ifap; 351 - struct in_ifaddr *last_prim = in_dev->ifa_list; 350 + struct in_ifaddr *ifa, *ifa1; 351 + struct in_ifaddr *last_prim; 352 352 struct in_ifaddr *prev_prom = NULL; 353 353 int do_promote = IN_DEV_PROMOTE_SECONDARIES(in_dev); 354 354 355 355 ASSERT_RTNL(); 356 356 357 + ifa1 = rtnl_dereference(*ifap); 358 + last_prim = rtnl_dereference(in_dev->ifa_list); 357 359 if (in_dev->dead) 358 360 goto no_promotions; 359 361 ··· 365 361 **/ 366 362 367 363 if (!(ifa1->ifa_flags & IFA_F_SECONDARY)) { 368 - struct in_ifaddr **ifap1 = &ifa1->ifa_next; 364 + struct in_ifaddr __rcu **ifap1 = &ifa1->ifa_next; 369 365 370 - while ((ifa = *ifap1) != NULL) { 366 + while ((ifa = rtnl_dereference(*ifap1)) != NULL) { 371 367 if (!(ifa->ifa_flags & IFA_F_SECONDARY) && 372 368 ifa1->ifa_scope <= ifa->ifa_scope) 373 369 last_prim = ifa; ··· 400 396 * and later to add them back with new prefsrc. Do this 401 397 * while all addresses are on the device list. 402 398 */ 403 - for (ifa = promote; ifa; ifa = ifa->ifa_next) { 399 + for (ifa = promote; ifa; ifa = rtnl_dereference(ifa->ifa_next)) { 404 400 if (ifa1->ifa_mask == ifa->ifa_mask && 405 401 inet_ifa_match(ifa1->ifa_address, ifa)) 406 402 fib_del_ifaddr(ifa, ifa1); ··· 426 422 blocking_notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1); 427 423 428 424 if (promote) { 429 - struct in_ifaddr *next_sec = promote->ifa_next; 425 + struct in_ifaddr *next_sec; 430 426 427 + next_sec = rtnl_dereference(promote->ifa_next); 431 428 if (prev_prom) { 432 - prev_prom->ifa_next = promote->ifa_next; 433 - promote->ifa_next = last_prim->ifa_next; 434 - last_prim->ifa_next = promote; 429 + struct in_ifaddr *last_sec; 430 + 431 + last_sec = rtnl_dereference(last_prim->ifa_next); 432 + rcu_assign_pointer(prev_prom->ifa_next, next_sec); 433 + rcu_assign_pointer(promote->ifa_next, last_sec); 434 + rcu_assign_pointer(last_prim->ifa_next, promote); 435 435 } 436 436 437 437 promote->ifa_flags &= ~IFA_F_SECONDARY; 438 438 rtmsg_ifa(RTM_NEWADDR, promote, nlh, portid); 439 439 blocking_notifier_call_chain(&inetaddr_chain, 440 440 NETDEV_UP, promote); 441 - for (ifa = next_sec; ifa; ifa = ifa->ifa_next) { 441 + for (ifa = next_sec; ifa; 442 + ifa = rtnl_dereference(ifa->ifa_next)) { 442 443 if (ifa1->ifa_mask != ifa->ifa_mask || 443 444 !inet_ifa_match(ifa1->ifa_address, ifa)) 444 445 continue; ··· 455 446 inet_free_ifa(ifa1); 456 447 } 457 448 458 - static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, 449 + static void inet_del_ifa(struct in_device *in_dev, 450 + struct in_ifaddr __rcu **ifap, 459 451 int destroy) 460 452 { 461 453 __inet_del_ifa(in_dev, ifap, destroy, NULL, 0); ··· 469 459 static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh, 470 460 u32 portid, struct netlink_ext_ack *extack) 471 461 { 462 + struct in_ifaddr __rcu **last_primary, **ifap; 472 463 struct in_device *in_dev = ifa->ifa_dev; 473 - struct in_ifaddr *ifa1, **ifap, **last_primary; 474 464 struct in_validator_info ivi; 465 + struct in_ifaddr *ifa1; 475 466 int ret; 476 467 477 468 ASSERT_RTNL(); ··· 485 474 ifa->ifa_flags &= ~IFA_F_SECONDARY; 486 475 last_primary = &in_dev->ifa_list; 487 476 488 - for (ifap = &in_dev->ifa_list; (ifa1 = *ifap) != NULL; 489 - ifap = &ifa1->ifa_next) { 477 + ifap = &in_dev->ifa_list; 478 + ifa1 = rtnl_dereference(*ifap); 479 + 480 + while (ifa1) { 490 481 if (!(ifa1->ifa_flags & IFA_F_SECONDARY) && 491 482 ifa->ifa_scope <= ifa1->ifa_scope) 492 483 last_primary = &ifa1->ifa_next; ··· 504 491 } 505 492 ifa->ifa_flags |= IFA_F_SECONDARY; 506 493 } 494 + 495 + ifap = &ifa1->ifa_next; 496 + ifa1 = rtnl_dereference(*ifap); 507 497 } 508 498 509 499 /* Allow any devices that wish to register ifaddr validtors to weigh ··· 532 516 ifap = last_primary; 533 517 } 534 518 535 - ifa->ifa_next = *ifap; 536 - *ifap = ifa; 519 + rcu_assign_pointer(ifa->ifa_next, *ifap); 520 + rcu_assign_pointer(*ifap, ifa); 537 521 538 522 inet_hash_insert(dev_net(in_dev->dev), ifa); 539 523 ··· 633 617 struct netlink_ext_ack *extack) 634 618 { 635 619 struct net *net = sock_net(skb->sk); 620 + struct in_ifaddr __rcu **ifap; 636 621 struct nlattr *tb[IFA_MAX+1]; 637 622 struct in_device *in_dev; 638 623 struct ifaddrmsg *ifm; 639 - struct in_ifaddr *ifa, **ifap; 624 + struct in_ifaddr *ifa; 625 + 640 626 int err = -EINVAL; 641 627 642 628 ASSERT_RTNL(); ··· 655 637 goto errout; 656 638 } 657 639 658 - for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; 640 + for (ifap = &in_dev->ifa_list; (ifa = rtnl_dereference(*ifap)) != NULL; 659 641 ifap = &ifa->ifa_next) { 660 642 if (tb[IFA_LOCAL] && 661 643 ifa->ifa_local != nla_get_in_addr(tb[IFA_LOCAL])) ··· 743 725 744 726 if (ifa->ifa_valid_lft != INFINITY_LIFE_TIME && 745 727 age >= ifa->ifa_valid_lft) { 746 - struct in_ifaddr **ifap; 728 + struct in_ifaddr __rcu **ifap; 729 + struct in_ifaddr *tmp; 747 730 748 - for (ifap = &ifa->ifa_dev->ifa_list; 749 - *ifap != NULL; ifap = &(*ifap)->ifa_next) { 750 - if (*ifap == ifa) { 731 + ifap = &ifa->ifa_dev->ifa_list; 732 + tmp = rtnl_dereference(*ifap); 733 + while (tmp) { 734 + tmp = rtnl_dereference(tmp->ifa_next); 735 + if (rtnl_dereference(*ifap) == ifa) { 751 736 inet_del_ifa(ifa->ifa_dev, 752 737 ifap, 1); 753 738 break; 754 739 } 740 + ifap = &tmp->ifa_next; 741 + tmp = rtnl_dereference(*ifap); 755 742 } 756 743 } else if (ifa->ifa_preferred_lft != 757 744 INFINITY_LIFE_TIME && ··· 1000 977 { 1001 978 struct sockaddr_in sin_orig; 1002 979 struct sockaddr_in *sin = (struct sockaddr_in *)&ifr->ifr_addr; 980 + struct in_ifaddr __rcu **ifap = NULL; 1003 981 struct in_device *in_dev; 1004 - struct in_ifaddr **ifap = NULL; 1005 982 struct in_ifaddr *ifa = NULL; 1006 983 struct net_device *dev; 1007 984 char *colon; ··· 1072 1049 /* note: we only do this for a limited set of ioctls 1073 1050 and only if the original address family was AF_INET. 1074 1051 This is checked above. */ 1075 - for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; 1052 + 1053 + for (ifap = &in_dev->ifa_list; 1054 + (ifa = rtnl_dereference(*ifap)) != NULL; 1076 1055 ifap = &ifa->ifa_next) { 1077 1056 if (!strcmp(ifr->ifr_name, ifa->ifa_label) && 1078 1057 sin_orig.sin_addr.s_addr == ··· 1087 1062 4.3BSD-style and passed in junk so we fall back to 1088 1063 comparing just the label */ 1089 1064 if (!ifa) { 1090 - for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; 1065 + for (ifap = &in_dev->ifa_list; 1066 + (ifa = rtnl_dereference(*ifap)) != NULL; 1091 1067 ifap = &ifa->ifa_next) 1092 1068 if (!strcmp(ifr->ifr_name, ifa->ifa_label)) 1093 1069 break;
+2 -2
net/mac80211/main.c
··· 354 354 sdata_lock(sdata); 355 355 356 356 /* Copy the addresses to the bss_conf list */ 357 - ifa = idev->ifa_list; 357 + ifa = rtnl_dereference(idev->ifa_list); 358 358 while (ifa) { 359 359 if (c < IEEE80211_BSS_ARP_ADDR_LIST_LEN) 360 360 bss_conf->arp_addr_list[c] = ifa->ifa_address; 361 - ifa = ifa->ifa_next; 361 + ifa = rtnl_dereference(ifa->ifa_next); 362 362 c++; 363 363 } 364 364
+7 -5
net/netfilter/nf_nat_redirect.c
··· 47 47 if (hooknum == NF_INET_LOCAL_OUT) { 48 48 newdst = htonl(0x7F000001); 49 49 } else { 50 - struct in_device *indev; 51 - struct in_ifaddr *ifa; 50 + const struct in_device *indev; 52 51 53 52 newdst = 0; 54 53 55 54 indev = __in_dev_get_rcu(skb->dev); 56 - if (indev && indev->ifa_list) { 57 - ifa = indev->ifa_list; 58 - newdst = ifa->ifa_local; 55 + if (indev) { 56 + const struct in_ifaddr *ifa; 57 + 58 + ifa = rcu_dereference(indev->ifa_list); 59 + if (ifa) 60 + newdst = ifa->ifa_local; 59 61 } 60 62 61 63 if (!newdst)