diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2009-11-05 23:56:46 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-06 01:34:21 -0500 |
commit | 40c9c31e388bfd513269df737f874d0cd53c1616 (patch) | |
tree | 0662514dcdd011f6f173723d01b53d1190e530df /net | |
parent | 122ec6ffca3967ffaa96a4c7a5dc9cd71866e0bc (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')
-rw-r--r-- | net/sctp/ipv6.c | 19 |
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 | } |