Re: [PATCH][MCAST]Two fix for implementation of MLDv2 .
From: Yan Zheng <hidden>
Date: 2005-11-02 14:22:26
Also in:
lkml
Hi. Here is my another patch. It makes a node send state change report properly when a multicast address's soure filter mode change is cause by forwarding state change and etc. Regards. Signed-off-by: Yan Zheng <redacted> Index:net/ipv6/mcast.c ===========================================================
--- linux-2.6.14/net/ipv6/mcast.c 2005-10-30 23:09:33.000000000 +0800
+++ /tmp/ipv6/mcast.c 2005-11-02 22:04:32.000000000 +0800@@ -128,7 +128,8 @@ static DEFINE_RWLOCK(ipv6_sk_mc_lock); static struct socket *igmp6_socket; -int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr); +static int ipv6_dev_mc_dec_intern(struct inet6_dev *idev, + struct in6_addr *addr, int delta); static void igmp6_join_group(struct ifmcaddr6 *ma); static void igmp6_leave_group(struct ifmcaddr6 *ma);
@@ -270,7 +271,7 @@ int ipv6_sock_mc_drop(struct sock *sk, i if (idev) { (void) ip6_mc_leave_src(sk,mc_lst,idev); - __ipv6_dev_mc_dec(idev, &mc_lst->addr); + ipv6_dev_mc_dec_intern(idev,&mc_lst->addr,1); in6_dev_put(idev); } dev_put(dev);
@@ -336,7 +337,7 @@ void ipv6_sock_mc_close(struct sock *sk) if (idev) { (void) ip6_mc_leave_src(sk, mc_lst, idev); - __ipv6_dev_mc_dec(idev, &mc_lst->addr); + ipv6_dev_mc_dec_intern(idev, &mc_lst->addr, 1); in6_dev_put(idev); } dev_put(dev);
@@ -907,10 +908,9 @@ int ipv6_dev_mc_inc(struct net_device *d return 0; } -/* - * device multicast group del - */ -int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr) + +static int ipv6_dev_mc_dec_intern(struct inet6_dev *idev, + struct in6_addr *addr, int delta) { struct ifmcaddr6 *ma, **map;
@@ -920,20 +920,27 @@ int __ipv6_dev_mc_dec(struct inet6_dev * if (--ma->mca_users == 0) { *map = ma->next; write_unlock_bh(&idev->lock); - igmp6_group_dropped(ma); - ma_put(ma); return 0; } write_unlock_bh(&idev->lock); + if (!delta && ip6_mc_del_src(idev, addr, + MCAST_EXCLUDE, 0, NULL, 0)) + return -EINVAL; // bug return 0; } } write_unlock_bh(&idev->lock); - return -ENOENT; } +/* + * device multicast group del + */ +int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr) +{ + return ipv6_dev_mc_dec_intern(idev, addr, 0); +} int ipv6_dev_mc_dec(struct net_device *dev, struct in6_addr *addr) {