diff options
author | David L Stevens <dlstevens@us.ibm.com> | 2005-07-08 20:47:28 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-07-08 20:47:28 -0400 |
commit | 9951f036fe8a4e6b21962559c64ff13b290ff01a (patch) | |
tree | 3d4d557102bf8d8a96d5276de7183b57c9808711 /net/ipv6/mcast.c | |
parent | 917f2f105ea4bbba8604e3ed55233eebda7afe6a (diff) |
[IPV4]: (INCLUDE,empty)/leave-group equivalence for full-state MSF APIs & errno fix
1) Adds (INCLUDE, empty)/leave-group equivalence to the full-state
multicast source filter APIs (IPv4 and IPv6)
2) Fixes an incorrect errno in the IPv6 leave-group (ENOENT should be
EADDRNOTAVAIL)
Signed-off-by: David L Stevens <dlstevens@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/mcast.c')
-rw-r--r-- | net/ipv6/mcast.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 9db4581d0d79..398c982625f8 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -281,7 +281,7 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, struct in6_addr *addr) | |||
281 | } | 281 | } |
282 | write_unlock_bh(&ipv6_sk_mc_lock); | 282 | write_unlock_bh(&ipv6_sk_mc_lock); |
283 | 283 | ||
284 | return -ENOENT; | 284 | return -EADDRNOTAVAIL; |
285 | } | 285 | } |
286 | 286 | ||
287 | static struct inet6_dev *ip6_mc_find_dev(struct in6_addr *group, int ifindex) | 287 | static struct inet6_dev *ip6_mc_find_dev(struct in6_addr *group, int ifindex) |
@@ -492,6 +492,7 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf) | |||
492 | struct inet6_dev *idev; | 492 | struct inet6_dev *idev; |
493 | struct ipv6_pinfo *inet6 = inet6_sk(sk); | 493 | struct ipv6_pinfo *inet6 = inet6_sk(sk); |
494 | struct ip6_sf_socklist *newpsl, *psl; | 494 | struct ip6_sf_socklist *newpsl, *psl; |
495 | int leavegroup = 0; | ||
495 | int i, err; | 496 | int i, err; |
496 | 497 | ||
497 | group = &((struct sockaddr_in6 *)&gsf->gf_group)->sin6_addr; | 498 | group = &((struct sockaddr_in6 *)&gsf->gf_group)->sin6_addr; |
@@ -508,6 +509,11 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf) | |||
508 | return -ENODEV; | 509 | return -ENODEV; |
509 | dev = idev->dev; | 510 | dev = idev->dev; |
510 | 511 | ||
512 | if (gsf->gf_fmode == MCAST_INCLUDE && gsf->gf_numsrc == 0) { | ||
513 | leavegroup = 1; | ||
514 | goto done; | ||
515 | } | ||
516 | |||
511 | for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) { | 517 | for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) { |
512 | if (pmc->ifindex != gsf->gf_interface) | 518 | if (pmc->ifindex != gsf->gf_interface) |
513 | continue; | 519 | continue; |
@@ -554,6 +560,8 @@ done: | |||
554 | read_unlock_bh(&idev->lock); | 560 | read_unlock_bh(&idev->lock); |
555 | in6_dev_put(idev); | 561 | in6_dev_put(idev); |
556 | dev_put(dev); | 562 | dev_put(dev); |
563 | if (leavegroup) | ||
564 | err = ipv6_sock_mc_drop(sk, gsf->gf_interface, group); | ||
557 | return err; | 565 | return err; |
558 | } | 566 | } |
559 | 567 | ||