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;
}
Example #2
0
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);
}
Example #3
0
File: ip_gre.c Project: 3null/linux
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;
}
Example #4
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));
	}
}
Example #5
0
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);
}
Example #7
0
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();
}
Example #9
0
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;
}