diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2009-11-18 17:24:34 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2009-11-18 17:24:34 -0500 |
commit | 0f9ea5d2ab5cef732d5abbe62b9e9af3007bae81 (patch) | |
tree | f5d3f3583c991b6f162cd91f9bffdc0937b12720 /drivers/infiniband | |
parent | a7ca1f00ed2921b804d7ebda0f6fca8c9078fa42 (diff) |
RDMA/addr: Use appropriate locking with for_each_netdev()
for_each_netdev() should be used with RTNL or dev_base_lock held,
or else we risk a crash.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/addr.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index bd07803e9183..373f1118d57b 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c | |||
@@ -131,6 +131,7 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr) | |||
131 | 131 | ||
132 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 132 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
133 | case AF_INET6: | 133 | case AF_INET6: |
134 | read_lock(&dev_base_lock); | ||
134 | for_each_netdev(&init_net, dev) { | 135 | for_each_netdev(&init_net, dev) { |
135 | if (ipv6_chk_addr(&init_net, | 136 | if (ipv6_chk_addr(&init_net, |
136 | &((struct sockaddr_in6 *) addr)->sin6_addr, | 137 | &((struct sockaddr_in6 *) addr)->sin6_addr, |
@@ -139,6 +140,7 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr) | |||
139 | break; | 140 | break; |
140 | } | 141 | } |
141 | } | 142 | } |
143 | read_unlock(&dev_base_lock); | ||
142 | break; | 144 | break; |
143 | #endif | 145 | #endif |
144 | } | 146 | } |
@@ -391,14 +393,17 @@ static int addr_resolve_local(struct sockaddr *src_in, | |||
391 | { | 393 | { |
392 | struct in6_addr *a; | 394 | struct in6_addr *a; |
393 | 395 | ||
396 | read_lock(&dev_base_lock); | ||
394 | for_each_netdev(&init_net, dev) | 397 | for_each_netdev(&init_net, dev) |
395 | if (ipv6_chk_addr(&init_net, | 398 | if (ipv6_chk_addr(&init_net, |
396 | &((struct sockaddr_in6 *) dst_in)->sin6_addr, | 399 | &((struct sockaddr_in6 *) dst_in)->sin6_addr, |
397 | dev, 1)) | 400 | dev, 1)) |
398 | break; | 401 | break; |
399 | 402 | ||
400 | if (!dev) | 403 | if (!dev) { |
404 | read_unlock(&dev_base_lock); | ||
401 | return -EADDRNOTAVAIL; | 405 | return -EADDRNOTAVAIL; |
406 | } | ||
402 | 407 | ||
403 | a = &((struct sockaddr_in6 *) src_in)->sin6_addr; | 408 | a = &((struct sockaddr_in6 *) src_in)->sin6_addr; |
404 | 409 | ||
@@ -416,6 +421,7 @@ static int addr_resolve_local(struct sockaddr *src_in, | |||
416 | if (!ret) | 421 | if (!ret) |
417 | memcpy(addr->dst_dev_addr, dev->dev_addr, MAX_ADDR_LEN); | 422 | memcpy(addr->dst_dev_addr, dev->dev_addr, MAX_ADDR_LEN); |
418 | } | 423 | } |
424 | read_unlock(&dev_base_lock); | ||
419 | break; | 425 | break; |
420 | } | 426 | } |
421 | #endif | 427 | #endif |