/* * device multicast group del */ int ipv6_dev_mc_dec(struct net_device *dev, struct in6_addr *addr) { struct inet6_dev *idev; struct ifmcaddr6 *ma, **map; idev = in6_dev_get(dev); if (idev == NULL) return -ENODEV; write_lock_bh(&idev->lock); for (map = &idev->mc_list; (ma=*map) != NULL; map = &ma->next) { if (ipv6_addr_cmp(&ma->mca_addr, addr) == 0) { if (--ma->mca_users == 0) { *map = ma->next; write_unlock_bh(&idev->lock); igmp6_group_dropped(ma); ma_put(ma); in6_dev_put(idev); return 0; } write_unlock_bh(&idev->lock); in6_dev_put(idev); return 0; } } write_unlock_bh(&idev->lock); in6_dev_put(idev); return -ENOENT; }
void ipv6_mc_destroy_dev(struct inet6_dev *idev) { struct ifmcaddr6 *i; while ((i = idev->mc_list) != NULL) { idev->mc_list = i->if_next; igmp6_group_dropped(i); kfree(i); } }
void ipv6_mc_down(struct inet6_dev *idev) { struct ifmcaddr6 *i; MDBG3((KERN_DEBUG "ipv6_mc_down(idev=%p)\n", idev)); /* Withdraw multicast list */ read_lock_bh(&idev->lock); for (i = idev->mc_list; i; i=i->next) igmp6_group_dropped(i); read_unlock_bh(&idev->lock); }
void ipv6_mc_down(struct inet6_dev *idev) { struct ifmcaddr6 *i; struct in6_addr maddr; /* Withdraw multicast list */ for (i = idev->mc_list; i; i=i->if_next) igmp6_group_dropped(i); /* Delete all-nodes address. */ ipv6_addr_all_nodes(&maddr); ipv6_dev_mc_dec(idev->dev, &maddr); }
void ipv6_mc_destroy_dev(struct inet6_dev *idev) { struct ifmcaddr6 *i; write_lock_bh(&idev->lock); while ((i = idev->mc_list) != NULL) { idev->mc_list = i->next; write_unlock_bh(&idev->lock); igmp6_group_dropped(i); ma_put(i); write_lock_bh(&idev->lock); } write_unlock_bh(&idev->lock); }
/* * device multicast group del */ int ipv6_dev_mc_dec(struct net_device *dev, struct in6_addr *addr) { struct inet6_dev *idev; struct ifmcaddr6 *ma, **map; #ifdef CONFIG_IPV6_MLD6_DEBUG char abuf[128]; in6_ntop(addr, abuf); MDBG3((KERN_DEBUG "ipv6_dev_mc_dec(dev=%p(%s), addr=%s)\n", dev, dev->name ? dev->name : "<null>", abuf)); #endif idev = in6_dev_get(dev); if (idev == NULL) return -ENODEV; write_lock_bh(&idev->lock); for (map = &idev->mc_list; (ma=*map) != NULL; map = &ma->next) { if (ipv6_addr_cmp(&ma->mca_addr, addr) == 0) { if (--ma->mca_users == 0) { *map = ma->next; write_unlock_bh(&idev->lock); igmp6_group_dropped(ma); ma_put(ma); in6_dev_put(idev); return 0; } write_unlock_bh(&idev->lock); in6_dev_put(idev); return 0; } } write_unlock_bh(&idev->lock); in6_dev_put(idev); return -ENOENT; }
/* * device multicast group del */ int ipv6_dev_mc_dec(struct device *dev, struct in6_addr *addr) { struct ifmcaddr6 *ma, **lnk; int hash; hash = ipv6_addr_hash(addr); for (lnk = &inet6_mcast_lst[hash]; (ma=*lnk) != NULL; lnk = &ma->next) { if (ipv6_addr_cmp(&ma->mca_addr, addr) == 0 && ma->dev == dev) { if (atomic_dec_and_test(&ma->mca_users)) { igmp6_group_dropped(ma); *lnk = ma->next; ipv6_mca_remove(dev, ma); kfree(ma); } return 0; } } return -ENOENT; }
void ipv6_mc_destroy_dev(struct inet6_dev *idev) { struct ifmcaddr6 *i; struct in6_addr maddr; MDBG3((KERN_DEBUG "ipv6_mc_destroy_dev(idev=%p)\n", idev)); /* Delete all-nodes address. */ ipv6_addr_all_nodes(&maddr); ipv6_dev_mc_dec(idev->dev, &maddr); write_lock_bh(&idev->lock); while ((i = idev->mc_list) != NULL) { idev->mc_list = i->next; write_unlock_bh(&idev->lock); igmp6_group_dropped(i); ma_put(i); write_lock_bh(&idev->lock); } write_unlock_bh(&idev->lock); }