int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) { struct ip_mc_socklist *iml, **imlp; rtnl_lock(); for (imlp=&sk->protinfo.af_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; if (--iml->count) { rtnl_unlock(); return 0; } *imlp = iml->next; in_dev = inetdev_by_index(iml->multi.imr_ifindex); if (in_dev) { ip_mc_dec_group(in_dev, imr->imr_multiaddr.s_addr); in_dev_put(in_dev); } rtnl_unlock(); sock_kfree_s(sk, iml, sizeof(*iml)); return 0; } } rtnl_unlock(); return -EADDRNOTAVAIL; }
void ip_mc_down(struct in_device *in_dev) { struct ip_mc_list *i; for (i=in_dev->mc_list; i; i=i->next) igmp_group_dropped(i); ip_mc_dec_group(in_dev, IGMP_ALL_HOSTS); }
static int ipgre_close(struct net_device *dev) { struct ip_tunnel *t = netdev_priv(dev); if (ipv4_is_multicast(t->parms.iph.daddr) && t->mlink) { struct in_device *in_dev; in_dev = inetdev_by_index(t->net, t->mlink); if (in_dev) ip_mc_dec_group(in_dev, t->parms.iph.daddr); } return 0; }
void ip_mc_drop_socket(struct sock *sk) { struct ip_mc_socklist *iml; while ((iml=sk->ip_mc_list) != NULL) { struct in_device *in_dev; sk->ip_mc_list = iml->next; if ((in_dev = inetdev_by_index(iml->multi.imr_ifindex)) != NULL) ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr); sock_kfree_s(sk, iml, sizeof(*iml)); } }
void ip_mc_drop_socket(struct sock *sk) { int i; if(sk->ip_mc_list==NULL) return; for(i=0;i<IP_MAX_MEMBERSHIPS;i++) { if(sk->ip_mc_list->multidev[i]) { ip_mc_dec_group(sk->ip_mc_list->multidev[i], sk->ip_mc_list->multiaddr[i]); sk->ip_mc_list->multidev[i]=NULL; } } kfree_s(sk->ip_mc_list,sizeof(*sk->ip_mc_list)); sk->ip_mc_list=NULL; }
void ip_mc_down(struct in_device *in_dev) { struct ip_mc_list *i; #ifdef CONFIG_RG_IGMP_PROXY igmprx_if_down(in_dev); #endif #ifdef CONFIG_RG_IGMP_PROXY_MODULE if (igmp_proxy_if_down) igmp_proxy_if_down(in_dev); #endif ASSERT_RTNL(); for (i=in_dev->mc_list; i; i=i->next) igmp_group_dropped(i); ip_mc_dec_group(in_dev, IGMP_ALL_HOSTS); }
int ip_mc_leave_group(struct sock *sk, struct device *dev, unsigned long addr) { int i; if(!MULTICAST(addr)) return -EINVAL; if(!(dev->flags&IFF_MULTICAST)) return -EADDRNOTAVAIL; if(sk->ip_mc_list==NULL) return -EADDRNOTAVAIL; for(i=0;i<IP_MAX_MEMBERSHIPS;i++) { if(sk->ip_mc_list->multiaddr[i]==addr && sk->ip_mc_list->multidev[i]==dev) { sk->ip_mc_list->multidev[i]=NULL; ip_mc_dec_group(dev,addr); return 0; } } return -EADDRNOTAVAIL; }
void ip_mc_drop_socket(struct sock *sk) { struct ip_mc_socklist *iml; if (sk->protinfo.af_inet.mc_list == NULL) return; rtnl_lock(); while ((iml=sk->protinfo.af_inet.mc_list) != NULL) { struct in_device *in_dev; sk->protinfo.af_inet.mc_list = iml->next; if ((in_dev = inetdev_by_index(iml->multi.imr_ifindex)) != NULL) { ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr); in_dev_put(in_dev); } sock_kfree_s(sk, iml, sizeof(*iml)); } rtnl_unlock(); }
int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) { struct ip_mc_socklist *iml, **imlp; for (imlp=&sk->ip_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; if (--iml->count) return 0; *imlp = iml->next; synchronize_bh(); in_dev = inetdev_by_index(iml->multi.imr_ifindex); if (in_dev) ip_mc_dec_group(in_dev, imr->imr_multiaddr.s_addr); sock_kfree_s(sk, iml, sizeof(*iml)); return 0; } } return -EADDRNOTAVAIL; }