This patch fixes the multicast group matching for IP_DROP_MEMBERSHIP, similar to the IP_ADD_MEMBERSHIP fix in a prior patch. Groups are identified by <group address,interface> and including the interface address in the match will fail if a leave-group is done by address when the join was done by index, or if different addresses on the same interface are used in the join and leave.
+-DLS
[in-line for viewing, attached for applying]
Signed-off-by: David L Stevens <[EMAIL PROTECTED]>
diff -ruNp linux-2.6.12.1v1mc-4/net/ipv4/igmp.c
linux-2.6.12.1v1mc-5/net/ipv4/igmp.c
--- linux-2.6.12.1v1mc-4/net/ipv4/igmp.c 2005-07-05
15:32:21.000000000 -0700
+++ linux-2.6.12.1v1mc-5/net/ipv4/igmp.c 2005-07-08
13:45:51.000000000 -0700
@@ -1687,24 +1687,25 @@ int ip_mc_leave_group(struct sock *sk, s
{
struct inet_sock *inet = inet_sk(sk);
struct ip_mc_socklist *iml, **imlp;
+ struct in_device *in_dev;
+ u32 group = imr->imr_multiaddr.s_addr;
+ u32 ifindex;
rtnl_lock();
+ in_dev = ip_mc_find_dev(imr);
+ if (!in_dev) {
+ rtnl_unlock();
+ return -ENODEV;
+ }
+ ifindex = imr->imr_ifindex;
for (imlp = &inet->mc_list; (iml = *imlp) != NULL; imlp =
&iml->next) {
- if
(iml->multi.imr_multiaddr.s_addr==imr->imr_multiaddr.s_addr &&
- iml->multi.imr_address.s_addr==imr->imr_address.s_addr
&&
- (!imr->imr_ifindex ||
iml->multi.imr_ifindex==imr->imr_ifindex)) {
- struct in_device *in_dev;
-
- in_dev = inetdev_by_index(iml->multi.imr_ifindex);
- if (in_dev)
- (void) ip_mc_leave_src(sk, iml, in_dev);
+ if (iml->multi.imr_multiaddr.s_addr == group &&
+ iml->multi.imr_ifindex == ifindex) {
+ (void) ip_mc_leave_src(sk, iml, in_dev);
*imlp = iml->next;
- if (in_dev) {
- ip_mc_dec_group(in_dev,
imr->imr_multiaddr.s_addr);
- in_dev_put(in_dev);
- }
+ ip_mc_dec_group(in_dev, group);
rtnl_unlock();
sock_kfree_s(sk, iml, sizeof(*iml));
return 0;
v1mc-5.patch
Description: Binary data
