diff options
author | Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> | 2015-03-18 13:50:43 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-18 22:05:09 -0400 |
commit | 54ff9ef36bdf84d469a098cbf8e2a103fbc77054 (patch) | |
tree | 74fb6219d97f44685a80b090888ffd5ea667e01e /net/ipv6 | |
parent | baf606d9c9b12517e47e0d1370e8aa9f7323f210 (diff) |
ipv4, ipv6: kill ip_mc_{join, leave}_group and ipv6_sock_mc_{join, drop}
in favor of their inner __ ones, which doesn't grab rtnl.
As these functions need to operate on a locked socket, we can't be
grabbing rtnl by then. It's too late and doing so causes reversed
locking.
So this patch:
- move rtnl handling to callers instead while already fixing some
reversed locking situations, like on vxlan and ipvs code.
- renames __ ones to not have the __ mark:
__ip_mc_{join,leave}_group -> ip_mc_{join,leave}_group
__ipv6_sock_mc_{join,drop} -> ipv6_sock_mc_{join,drop}
Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 4 | ||||
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 21 | ||||
-rw-r--r-- | net/ipv6/mcast.c | 30 |
3 files changed, 18 insertions, 37 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 88d2cf0cae52..158378e73f0a 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -2473,9 +2473,9 @@ static int ipv6_mc_config(struct sock *sk, bool join, | |||
2473 | 2473 | ||
2474 | lock_sock(sk); | 2474 | lock_sock(sk); |
2475 | if (join) | 2475 | if (join) |
2476 | ret = __ipv6_sock_mc_join(sk, ifindex, addr); | 2476 | ret = ipv6_sock_mc_join(sk, ifindex, addr); |
2477 | else | 2477 | else |
2478 | ret = __ipv6_sock_mc_drop(sk, ifindex, addr); | 2478 | ret = ipv6_sock_mc_drop(sk, ifindex, addr); |
2479 | release_sock(sk); | 2479 | release_sock(sk); |
2480 | 2480 | ||
2481 | return ret; | 2481 | return ret; |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index f2b731df8d77..cc5883791bac 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -124,6 +124,11 @@ static bool setsockopt_needs_rtnl(int optname) | |||
124 | case IPV6_DROP_MEMBERSHIP: | 124 | case IPV6_DROP_MEMBERSHIP: |
125 | case MCAST_JOIN_GROUP: | 125 | case MCAST_JOIN_GROUP: |
126 | case MCAST_LEAVE_GROUP: | 126 | case MCAST_LEAVE_GROUP: |
127 | case MCAST_JOIN_SOURCE_GROUP: | ||
128 | case MCAST_LEAVE_SOURCE_GROUP: | ||
129 | case MCAST_BLOCK_SOURCE: | ||
130 | case MCAST_UNBLOCK_SOURCE: | ||
131 | case MCAST_MSFILTER: | ||
127 | return true; | 132 | return true; |
128 | } | 133 | } |
129 | return false; | 134 | return false; |
@@ -597,9 +602,9 @@ done: | |||
597 | break; | 602 | break; |
598 | 603 | ||
599 | if (optname == IPV6_ADD_MEMBERSHIP) | 604 | if (optname == IPV6_ADD_MEMBERSHIP) |
600 | retv = __ipv6_sock_mc_join(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr); | 605 | retv = ipv6_sock_mc_join(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr); |
601 | else | 606 | else |
602 | retv = __ipv6_sock_mc_drop(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr); | 607 | retv = ipv6_sock_mc_drop(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr); |
603 | break; | 608 | break; |
604 | } | 609 | } |
605 | case IPV6_JOIN_ANYCAST: | 610 | case IPV6_JOIN_ANYCAST: |
@@ -638,11 +643,11 @@ done: | |||
638 | } | 643 | } |
639 | psin6 = (struct sockaddr_in6 *)&greq.gr_group; | 644 | psin6 = (struct sockaddr_in6 *)&greq.gr_group; |
640 | if (optname == MCAST_JOIN_GROUP) | 645 | if (optname == MCAST_JOIN_GROUP) |
641 | retv = __ipv6_sock_mc_join(sk, greq.gr_interface, | 646 | retv = ipv6_sock_mc_join(sk, greq.gr_interface, |
642 | &psin6->sin6_addr); | 647 | &psin6->sin6_addr); |
643 | else | 648 | else |
644 | retv = __ipv6_sock_mc_drop(sk, greq.gr_interface, | 649 | retv = ipv6_sock_mc_drop(sk, greq.gr_interface, |
645 | &psin6->sin6_addr); | 650 | &psin6->sin6_addr); |
646 | break; | 651 | break; |
647 | } | 652 | } |
648 | case MCAST_JOIN_SOURCE_GROUP: | 653 | case MCAST_JOIN_SOURCE_GROUP: |
@@ -674,8 +679,8 @@ done: | |||
674 | struct sockaddr_in6 *psin6; | 679 | struct sockaddr_in6 *psin6; |
675 | 680 | ||
676 | psin6 = (struct sockaddr_in6 *)&greqs.gsr_group; | 681 | psin6 = (struct sockaddr_in6 *)&greqs.gsr_group; |
677 | retv = __ipv6_sock_mc_join(sk, greqs.gsr_interface, | 682 | retv = ipv6_sock_mc_join(sk, greqs.gsr_interface, |
678 | &psin6->sin6_addr); | 683 | &psin6->sin6_addr); |
679 | /* prior join w/ different source is ok */ | 684 | /* prior join w/ different source is ok */ |
680 | if (retv && retv != -EADDRINUSE) | 685 | if (retv && retv != -EADDRINUSE) |
681 | break; | 686 | break; |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 1dd1fedff9f4..cbb66fd3da6d 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -132,7 +132,7 @@ static int unsolicited_report_interval(struct inet6_dev *idev) | |||
132 | return iv > 0 ? iv : 1; | 132 | return iv > 0 ? iv : 1; |
133 | } | 133 | } |
134 | 134 | ||
135 | int __ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr) | 135 | int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr) |
136 | { | 136 | { |
137 | struct net_device *dev = NULL; | 137 | struct net_device *dev = NULL; |
138 | struct ipv6_mc_socklist *mc_lst; | 138 | struct ipv6_mc_socklist *mc_lst; |
@@ -199,24 +199,12 @@ int __ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *add | |||
199 | 199 | ||
200 | return 0; | 200 | return 0; |
201 | } | 201 | } |
202 | EXPORT_SYMBOL(__ipv6_sock_mc_join); | ||
203 | |||
204 | int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr) | ||
205 | { | ||
206 | int ret; | ||
207 | |||
208 | rtnl_lock(); | ||
209 | ret = __ipv6_sock_mc_join(sk, ifindex, addr); | ||
210 | rtnl_unlock(); | ||
211 | |||
212 | return ret; | ||
213 | } | ||
214 | EXPORT_SYMBOL(ipv6_sock_mc_join); | 202 | EXPORT_SYMBOL(ipv6_sock_mc_join); |
215 | 203 | ||
216 | /* | 204 | /* |
217 | * socket leave on multicast group | 205 | * socket leave on multicast group |
218 | */ | 206 | */ |
219 | int __ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr) | 207 | int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr) |
220 | { | 208 | { |
221 | struct ipv6_pinfo *np = inet6_sk(sk); | 209 | struct ipv6_pinfo *np = inet6_sk(sk); |
222 | struct ipv6_mc_socklist *mc_lst; | 210 | struct ipv6_mc_socklist *mc_lst; |
@@ -255,18 +243,6 @@ int __ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *add | |||
255 | 243 | ||
256 | return -EADDRNOTAVAIL; | 244 | return -EADDRNOTAVAIL; |
257 | } | 245 | } |
258 | EXPORT_SYMBOL(__ipv6_sock_mc_drop); | ||
259 | |||
260 | int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr) | ||
261 | { | ||
262 | int ret; | ||
263 | |||
264 | rtnl_lock(); | ||
265 | ret = __ipv6_sock_mc_drop(sk, ifindex, addr); | ||
266 | rtnl_unlock(); | ||
267 | |||
268 | return ret; | ||
269 | } | ||
270 | EXPORT_SYMBOL(ipv6_sock_mc_drop); | 246 | EXPORT_SYMBOL(ipv6_sock_mc_drop); |
271 | 247 | ||
272 | /* called with rcu_read_lock() */ | 248 | /* called with rcu_read_lock() */ |
@@ -460,7 +436,7 @@ done: | |||
460 | read_unlock_bh(&idev->lock); | 436 | read_unlock_bh(&idev->lock); |
461 | rcu_read_unlock(); | 437 | rcu_read_unlock(); |
462 | if (leavegroup) | 438 | if (leavegroup) |
463 | return ipv6_sock_mc_drop(sk, pgsr->gsr_interface, group); | 439 | err = ipv6_sock_mc_drop(sk, pgsr->gsr_interface, group); |
464 | return err; | 440 | return err; |
465 | } | 441 | } |
466 | 442 | ||