/** * mipv6_mn_send_home_na - send NA when returning home * @haddr: home address to advertise * * After returning home, MN must advertise all its valid addresses in * home link to all nodes. **/ void mipv6_mn_send_home_na(struct in6_addr *haddr) { struct net_device *dev = NULL; struct in6_addr mc_allnodes; struct mn_info *hinfo = NULL; read_lock_bh(&mn_info_lock); hinfo = mipv6_mn_get_info(haddr); hinfo->is_at_home = 1; if (!hinfo) { read_unlock_bh(&mn_info_lock); return; } dev = dev_get_by_index(hinfo->ifindex); read_unlock_bh(&mn_info_lock); if (dev == NULL) { DEBUG((DBG_ERROR, "Send home_na: device not found.")); return; } ipv6_addr_all_nodes(&mc_allnodes); if (ipv6_get_lladdr(dev, haddr) == 0) ndisc_send_na(dev, NULL, &mc_allnodes, haddr, 0, 0, 1, 1); ndisc_send_na(dev, NULL, &mc_allnodes, haddr, 0, 0, 1, 1); dev_put(dev); }
void ipv6_mc_init_dev(struct inet6_dev *idev) { struct in6_addr maddr; /* Add all-nodes address. */ ipv6_addr_all_nodes(&maddr); ipv6_dev_mc_inc(idev->dev, &maddr); }
void ipv6_mc_up(struct inet6_dev *idev) { struct ifmcaddr6 *i; struct in6_addr maddr; /* Add all-nodes address. */ ipv6_addr_all_nodes(&maddr); ipv6_dev_mc_inc(idev->dev, &maddr); /* Install multicast list, except for all-nodes (already installed) */ for (i = idev->mc_list; i; i=i->if_next) igmp6_group_added(i); }
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; 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); }