void ip_mc_inc_group(struct in_device *in_dev, u32 addr) { struct ip_mc_list *i, *im; im = (struct ip_mc_list *)kmalloc(sizeof(*im), GFP_KERNEL); for (i=in_dev->mc_list; i; i=i->next) { if (i->multiaddr == addr) { i->users++; if (im) kfree(im); return; } } if (!im) return; im->users=1; im->interface=in_dev; im->multiaddr=addr; #ifdef CONFIG_IP_MULTICAST im->tm_running=0; init_timer(&im->timer); im->timer.data=(unsigned long)im; im->timer.function=&igmp_timer_expire; im->unsolicit_count = IGMP_Unsolicited_Report_Count; im->reporter = 0; im->loaded = 0; #endif im->next=in_dev->mc_list; in_dev->mc_list=im; igmp_group_added(im); if (in_dev->dev->flags & IFF_UP) ip_rt_multicast_event(in_dev); return; }
static int vif_delete(struct net *net, int vifi, int notify, struct list_head *head) { struct vif_device *v; struct net_device *dev; struct in_device *in_dev; if (vifi < 0 || vifi >= net->ipv4.maxvif) return -EADDRNOTAVAIL; v = &net->ipv4.vif_table[vifi]; write_lock_bh(&mrt_lock); dev = v->dev; v->dev = NULL; if (!dev) { write_unlock_bh(&mrt_lock); return -EADDRNOTAVAIL; } #ifdef CONFIG_IP_PIMSM if (vifi == net->ipv4.mroute_reg_vif_num) net->ipv4.mroute_reg_vif_num = -1; #endif if (vifi+1 == net->ipv4.maxvif) { int tmp; for (tmp=vifi-1; tmp>=0; tmp--) { if (VIF_EXISTS(net, tmp)) break; } net->ipv4.maxvif = tmp+1; } write_unlock_bh(&mrt_lock); dev_set_allmulti(dev, -1); if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) { IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)--; ip_rt_multicast_event(in_dev); } if (v->flags&(VIFF_TUNNEL|VIFF_REGISTER) && !notify) unregister_netdevice_queue(dev, head); dev_put(dev); return 0; }
static int vif_delete(int vifi) { struct vif_device *v; struct net_device *dev; struct in_device *in_dev; if (vifi < 0 || vifi >= maxvif) return -EADDRNOTAVAIL; v = &vif_table[vifi]; write_lock_bh(&mrt_lock); dev = v->dev; v->dev = NULL; if (!dev) { write_unlock_bh(&mrt_lock); return -EADDRNOTAVAIL; } #ifdef CONFIG_IP_PIMSM if (vifi == reg_vif_num) reg_vif_num = -1; #endif if (vifi+1 == maxvif) { int tmp; for (tmp=vifi-1; tmp>=0; tmp--) { if (VIF_EXISTS(tmp)) break; } maxvif = tmp+1; } write_unlock_bh(&mrt_lock); dev_set_allmulti(dev, -1); if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) { in_dev->cnf.mc_forwarding--; ip_rt_multicast_event(in_dev); } if (v->flags&(VIFF_TUNNEL|VIFF_REGISTER)) unregister_netdevice(dev); dev_put(dev); return 0; }
static int vif_delete(int vifi) { struct vif_device *v; struct device *dev; struct in_device *in_dev; if (vifi < 0 || vifi >= maxvif || !(vifc_map&(1<<vifi))) return -EADDRNOTAVAIL; v = &vif_table[vifi]; dev = v->dev; v->dev = NULL; vifc_map &= ~(1<<vifi); if ((in_dev = dev->ip_ptr) != NULL) in_dev->cnf.mc_forwarding = 0; dev_set_allmulti(dev, -1); ip_rt_multicast_event(in_dev); if (v->flags&(VIFF_TUNNEL|VIFF_REGISTER)) { #ifdef CONFIG_IP_PIMSM if (vifi == reg_vif_num) { reg_vif_num = -1; reg_dev = NULL; } #endif unregister_netdevice(dev); if (v->flags&VIFF_REGISTER) kfree(dev); } if (vifi+1 == maxvif) { int tmp; for (tmp=vifi-1; tmp>=0; tmp--) { if (vifc_map&(1<<tmp)) break; } maxvif = tmp+1; } return 0; }
void ip_mc_inc_group(struct in_device *in_dev, u32 addr) { struct ip_mc_list *im; ASSERT_RTNL(); for (im=in_dev->mc_list; im; im=im->next) { if (im->multiaddr == addr) { im->users++; goto out; } } im = (struct ip_mc_list *)kmalloc(sizeof(*im), GFP_KERNEL); if (!im) goto out; im->users=1; im->interface=in_dev; in_dev_hold(in_dev); im->multiaddr=addr; atomic_set(&im->refcnt, 1); spin_lock_init(&im->lock); #ifdef CONFIG_IP_MULTICAST im->tm_running=0; init_timer(&im->timer); im->timer.data=(unsigned long)im; im->timer.function=&igmp_timer_expire; im->unsolicit_count = IGMP_Unsolicited_Report_Count; im->reporter = 0; #endif im->loaded = 0; write_lock_bh(&in_dev->lock); im->next=in_dev->mc_list; in_dev->mc_list=im; write_unlock_bh(&in_dev->lock); igmp_group_added(im); if (in_dev->dev->flags & IFF_UP) ip_rt_multicast_event(in_dev); out: return; }
int ip_mc_dec_group(struct in_device *in_dev, u32 addr) { struct ip_mc_list *i, **ip; for (ip=&in_dev->mc_list; (i=*ip)!=NULL; ip=&i->next) { if (i->multiaddr==addr) { if (--i->users == 0) { *ip = i->next; synchronize_bh(); igmp_group_dropped(i); if (in_dev->dev->flags & IFF_UP) ip_rt_multicast_event(in_dev); kfree_s(i, sizeof(*i)); } return 0; } } return -ESRCH; }
void ip_mc_dec_group(struct in_device *in_dev, u32 addr) { struct ip_mc_list *i, **ip; ASSERT_RTNL(); for (ip=&in_dev->mc_list; (i=*ip)!=NULL; ip=&i->next) { if (i->multiaddr==addr) { if (--i->users == 0) { write_lock_bh(&in_dev->lock); *ip = i->next; write_unlock_bh(&in_dev->lock); igmp_group_dropped(i); if (in_dev->dev->flags & IFF_UP) ip_rt_multicast_event(in_dev); ip_ma_put(i); return; } break; } } }
static int vif_add(struct vifctl *vifc, int mrtsock) { int vifi = vifc->vifc_vifi; struct vif_device *v = &vif_table[vifi]; struct net_device *dev; struct in_device *in_dev; /* Is vif busy ? */ if (VIF_EXISTS(vifi)) return -EADDRINUSE; switch (vifc->vifc_flags) { #ifdef CONFIG_IP_PIMSM case VIFF_REGISTER: /* * Special Purpose VIF in PIM * All the packets will be sent to the daemon */ if (reg_vif_num >= 0) return -EADDRINUSE; dev = ipmr_reg_vif(); if (!dev) return -ENOBUFS; break; #endif case VIFF_TUNNEL: dev = ipmr_new_tunnel(vifc); if (!dev) return -ENOBUFS; break; case 0: dev=ip_dev_find(vifc->vifc_lcl_addr.s_addr); if (!dev) return -EADDRNOTAVAIL; __dev_put(dev); break; default: return -EINVAL; } if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) return -EADDRNOTAVAIL; in_dev->cnf.mc_forwarding++; dev_set_allmulti(dev, +1); ip_rt_multicast_event(in_dev); /* * Fill in the VIF structures */ v->rate_limit=vifc->vifc_rate_limit; v->local=vifc->vifc_lcl_addr.s_addr; v->remote=vifc->vifc_rmt_addr.s_addr; v->flags=vifc->vifc_flags; if (!mrtsock) v->flags |= VIFF_STATIC; v->threshold=vifc->vifc_threshold; v->bytes_in = 0; v->bytes_out = 0; v->pkt_in = 0; v->pkt_out = 0; v->link = dev->ifindex; if (v->flags&(VIFF_TUNNEL|VIFF_REGISTER)) v->link = dev->iflink; /* And finish update writing critical data */ write_lock_bh(&mrt_lock); dev_hold(dev); v->dev=dev; #ifdef CONFIG_IP_PIMSM if (v->flags&VIFF_REGISTER) reg_vif_num = vifi; #endif if (vifi+1 > maxvif) maxvif = vifi+1; write_unlock_bh(&mrt_lock); return 0; }
static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock) { int vifi = vifc->vifc_vifi; struct vif_device *v = &net->ipv4.vif_table[vifi]; struct net_device *dev; struct in_device *in_dev; int err; /* Is vif busy ? */ if (VIF_EXISTS(net, vifi)) return -EADDRINUSE; switch (vifc->vifc_flags) { #ifdef CONFIG_IP_PIMSM case VIFF_REGISTER: /* * Special Purpose VIF in PIM * All the packets will be sent to the daemon */ if (net->ipv4.mroute_reg_vif_num >= 0) return -EADDRINUSE; dev = ipmr_reg_vif(net); if (!dev) return -ENOBUFS; err = dev_set_allmulti(dev, 1); if (err) { unregister_netdevice(dev); dev_put(dev); return err; } break; #endif case VIFF_TUNNEL: dev = ipmr_new_tunnel(net, vifc); if (!dev) return -ENOBUFS; err = dev_set_allmulti(dev, 1); if (err) { ipmr_del_tunnel(dev, vifc); dev_put(dev); return err; } break; case VIFF_USE_IFINDEX: case 0: if (vifc->vifc_flags == VIFF_USE_IFINDEX) { dev = dev_get_by_index(net, vifc->vifc_lcl_ifindex); if (dev && dev->ip_ptr == NULL) { dev_put(dev); return -EADDRNOTAVAIL; } } else dev = ip_dev_find(net, vifc->vifc_lcl_addr.s_addr); if (!dev) return -EADDRNOTAVAIL; err = dev_set_allmulti(dev, 1); if (err) { dev_put(dev); return err; } break; default: return -EINVAL; } if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) { dev_put(dev); return -EADDRNOTAVAIL; } IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++; ip_rt_multicast_event(in_dev); /* * Fill in the VIF structures */ v->rate_limit = vifc->vifc_rate_limit; v->local = vifc->vifc_lcl_addr.s_addr; v->remote = vifc->vifc_rmt_addr.s_addr; v->flags = vifc->vifc_flags; if (!mrtsock) v->flags |= VIFF_STATIC; v->threshold = vifc->vifc_threshold; v->bytes_in = 0; v->bytes_out = 0; v->pkt_in = 0; v->pkt_out = 0; v->link = dev->ifindex; if (v->flags&(VIFF_TUNNEL|VIFF_REGISTER)) v->link = dev->iflink; /* And finish update writing critical data */ write_lock_bh(&mrt_lock); v->dev = dev; #ifdef CONFIG_IP_PIMSM if (v->flags&VIFF_REGISTER) net->ipv4.mroute_reg_vif_num = vifi; #endif if (vifi+1 > net->ipv4.maxvif) net->ipv4.maxvif = vifi+1; write_unlock_bh(&mrt_lock); return 0; }
static int vif_add(struct vifctl *vifc, int mrtsock) { int vifi = vifc->vifc_vifi; struct vif_device *v = &vif_table[vifi]; struct net_device *dev; struct in_device *in_dev; /*[Santosh: to add "ppp" interface into VIF table]*/ #if defined (CONFIG_IFX_IGMP_PROXY) || defined (CONFIG_IFX_IGMP_PROXY_MODULE) struct in_device *ip; struct in_ifaddr *in; __u32 addr; dev=ip_dev_find(vifc->vifc_lcl_addr.s_addr); if (dev) __dev_put(dev); if (!dev){ addr = vifc->vifc_lcl_addr.s_addr; for(dev = dev_base; dev; dev = dev->next){ if (dev == NULL) continue; if (strncmp (dev->name,"ppp",3) != 0) continue; ip = dev->ip_ptr; if( (ip == NULL) || ((in = ip->ifa_list) == NULL )) { DBPRINT ("vif_add: Device: %s not assigned IP address\n",dev->name); } if (( in->ifa_address == addr ) && (strncmp (dev->name,"ppp",3) == 0)) { break; } } } // if (!dev) #endif /* Is vif busy ? */ if (VIF_EXISTS(vifi)) return -EADDRINUSE; switch (vifc->vifc_flags) { #ifdef CONFIG_IP_PIMSM case VIFF_REGISTER: /* * Special Purpose VIF in PIM * All the packets will be sent to the daemon */ if (reg_vif_num >= 0) return -EADDRINUSE; dev = ipmr_reg_vif(vifc); if (!dev) return -ENOBUFS; break; #endif case VIFF_TUNNEL: dev = ipmr_new_tunnel(vifc); if (!dev) return -ENOBUFS; break; case 0: /*[Santosh: to add "ppp" interface into VIF table]*/ #if defined (CONFIG_IFX_IGMP_PROXY) || defined (CONFIG_IFX_IGMP_PROXY_MODULE) if (strncmp (dev->name, "ppp",3) == 0) { break; } #endif dev=ip_dev_find(vifc->vifc_lcl_addr.s_addr); if (!dev) return -EADDRNOTAVAIL; __dev_put(dev); break; default: return -EINVAL; } if ((in_dev = __in_dev_get(dev)) == NULL) return -EADDRNOTAVAIL; in_dev->cnf.mc_forwarding++; dev_set_allmulti(dev, +1); ip_rt_multicast_event(in_dev); /* * Fill in the VIF structures */ v->rate_limit=vifc->vifc_rate_limit; v->local=vifc->vifc_lcl_addr.s_addr; v->remote=vifc->vifc_rmt_addr.s_addr; v->flags=vifc->vifc_flags; if (!mrtsock) v->flags |= VIFF_STATIC; v->threshold=vifc->vifc_threshold; v->bytes_in = 0; v->bytes_out = 0; v->pkt_in = 0; v->pkt_out = 0; v->link = dev->ifindex; if (v->flags&(VIFF_TUNNEL|VIFF_REGISTER)) v->link = dev->iflink; /* And finish update writing critical data */ write_lock_bh(&mrt_lock); dev_hold(dev); v->dev=dev; #ifdef CONFIG_IP_PIMSM if (v->flags&VIFF_REGISTER) reg_vif_num = vifi; #endif if (vifi+1 > maxvif) maxvif = vifi+1; write_unlock_bh(&mrt_lock); return 0; }