aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/ipv6.c
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2009-11-05 23:56:46 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-06 01:34:21 -0500
commit40c9c31e388bfd513269df737f874d0cd53c1616 (patch)
tree0662514dcdd011f6f173723d01b53d1190e530df /net/sctp/ipv6.c
parent122ec6ffca3967ffaa96a4c7a5dc9cd71866e0bc (diff)
sctp: ipv6: avoid touching device refcount
Avoid touching device refcount in sctp/ipv6, thanks to RCU Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/ipv6.c')
-rw-r--r--net/sctp/ipv6.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index bacd6a7318be..cc50fbe99291 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -837,15 +837,16 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
837 if (type & IPV6_ADDR_LINKLOCAL) { 837 if (type & IPV6_ADDR_LINKLOCAL) {
838 if (!addr->v6.sin6_scope_id) 838 if (!addr->v6.sin6_scope_id)
839 return 0; 839 return 0;
840 dev = dev_get_by_index(&init_net, addr->v6.sin6_scope_id); 840 rcu_read_lock();
841 if (!dev) 841 dev = dev_get_by_index_rcu(&init_net,
842 return 0; 842 addr->v6.sin6_scope_id);
843 if (!ipv6_chk_addr(&init_net, &addr->v6.sin6_addr, 843 if (!dev ||
844 !ipv6_chk_addr(&init_net, &addr->v6.sin6_addr,
844 dev, 0)) { 845 dev, 0)) {
845 dev_put(dev); 846 rcu_read_unlock();
846 return 0; 847 return 0;
847 } 848 }
848 dev_put(dev); 849 rcu_read_unlock();
849 } else if (type == IPV6_ADDR_MAPPED) { 850 } else if (type == IPV6_ADDR_MAPPED) {
850 if (!opt->v4mapped) 851 if (!opt->v4mapped)
851 return 0; 852 return 0;
@@ -873,10 +874,12 @@ static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
873 if (type & IPV6_ADDR_LINKLOCAL) { 874 if (type & IPV6_ADDR_LINKLOCAL) {
874 if (!addr->v6.sin6_scope_id) 875 if (!addr->v6.sin6_scope_id)
875 return 0; 876 return 0;
876 dev = dev_get_by_index(&init_net, addr->v6.sin6_scope_id); 877 rcu_read_lock();
878 dev = dev_get_by_index_rcu(&init_net,
879 addr->v6.sin6_scope_id);
880 rcu_read_unlock();
877 if (!dev) 881 if (!dev)
878 return 0; 882 return 0;
879 dev_put(dev);
880 } 883 }
881 af = opt->pf->af; 884 af = opt->pf->af;
882 } 885 }