Commit 8723e1b4ad9be4444423b4d41509ce859a629649

Authored by Eric Dumazet
Committed by David S. Miller
1 parent 9e917dca74

inet: RCU changes in inetdev_by_index()

Convert inetdev_by_index() to not increment in_dev refcount.

Callers hold RCU or RTNL, and should not decrement in_dev refcount.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 4 changed files with 16 additions and 22 deletions Side-by-side Diff

... ... @@ -403,6 +403,9 @@
403 403 return inet_insert_ifa(ifa);
404 404 }
405 405  
  406 +/* Caller must hold RCU or RTNL :
  407 + * We dont take a reference on found in_device
  408 + */
406 409 struct in_device *inetdev_by_index(struct net *net, int ifindex)
407 410 {
408 411 struct net_device *dev;
... ... @@ -411,7 +414,7 @@
411 414 rcu_read_lock();
412 415 dev = dev_get_by_index_rcu(net, ifindex);
413 416 if (dev)
414   - in_dev = in_dev_get(dev);
  417 + in_dev = rcu_dereference_rtnl(dev->ip_ptr);
415 418 rcu_read_unlock();
416 419 return in_dev;
417 420 }
... ... @@ -452,8 +455,6 @@
452 455 err = -ENODEV;
453 456 goto errout;
454 457 }
455   -
456   - __in_dev_put(in_dev);
457 458  
458 459 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
459 460 ifap = &ifa->ifa_next) {
net/ipv4/fib_semantics.c
... ... @@ -590,32 +590,29 @@
590 590 if (!dev)
591 591 goto out;
592 592 dev_hold(dev);
593   - err = -ENETDOWN;
594   - if (!(dev->flags & IFF_UP))
595   - goto out;
596   - err = 0;
597   -out:
598   - rcu_read_unlock();
599   - return err;
  593 + err = (dev->flags & IFF_UP) ? 0 : -ENETDOWN;
600 594 } else {
601 595 struct in_device *in_dev;
602 596  
603 597 if (nh->nh_flags & (RTNH_F_PERVASIVE | RTNH_F_ONLINK))
604 598 return -EINVAL;
605 599  
  600 + rcu_read_lock();
  601 + err = -ENODEV;
606 602 in_dev = inetdev_by_index(net, nh->nh_oif);
607 603 if (in_dev == NULL)
608   - return -ENODEV;
609   - if (!(in_dev->dev->flags & IFF_UP)) {
610   - in_dev_put(in_dev);
611   - return -ENETDOWN;
612   - }
  604 + goto out;
  605 + err = -ENETDOWN;
  606 + if (!(in_dev->dev->flags & IFF_UP))
  607 + goto out;
613 608 nh->nh_dev = in_dev->dev;
614 609 dev_hold(nh->nh_dev);
615 610 nh->nh_scope = RT_SCOPE_HOST;
616   - in_dev_put(in_dev);
  611 + err = 0;
617 612 }
618   - return 0;
  613 +out:
  614 + rcu_read_unlock();
  615 + return err;
619 616 }
620 617  
621 618 static inline unsigned int fib_laddr_hashfn(__be32 val)
... ... @@ -1429,8 +1429,6 @@
1429 1429  
1430 1430 if (imr->imr_ifindex) {
1431 1431 idev = inetdev_by_index(net, imr->imr_ifindex);
1432   - if (idev)
1433   - __in_dev_put(idev);
1434 1432 return idev;
1435 1433 }
1436 1434 if (imr->imr_address.s_addr) {
... ... @@ -1245,10 +1245,8 @@
1245 1245 if (ipv4_is_multicast(t->parms.iph.daddr) && t->mlink) {
1246 1246 struct in_device *in_dev;
1247 1247 in_dev = inetdev_by_index(dev_net(dev), t->mlink);
1248   - if (in_dev) {
  1248 + if (in_dev)
1249 1249 ip_mc_dec_group(in_dev, t->parms.iph.daddr);
1250   - in_dev_put(in_dev);
1251   - }
1252 1250 }
1253 1251 return 0;
1254 1252 }