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(struct net *net, int vifi, int notify) { 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(dev); dev_put(dev); return 0; }
int vlan_dev_stop(struct net_device *dev) { struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; dev_mc_unsync(real_dev, dev); if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(real_dev, -1); if (dev->flags & IFF_PROMISC) dev_set_promiscuity(real_dev, -1); if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) dev_unicast_delete(real_dev, dev->dev_addr, dev->addr_len); return 0; }
static int mif6_delete(struct net *net, int vifi, struct list_head *head) { struct mif_device *v; struct net_device *dev; struct inet6_dev *in6_dev; if (vifi < 0 || vifi >= net->ipv6.maxvif) return -EADDRNOTAVAIL; v = &net->ipv6.vif6_table[vifi]; write_lock_bh(&mrt_lock); dev = v->dev; v->dev = NULL; if (!dev) { write_unlock_bh(&mrt_lock); return -EADDRNOTAVAIL; } #ifdef CONFIG_IPV6_PIMSM_V2 if (vifi == net->ipv6.mroute_reg_vif_num) net->ipv6.mroute_reg_vif_num = -1; #endif if (vifi + 1 == net->ipv6.maxvif) { int tmp; for (tmp = vifi - 1; tmp >= 0; tmp--) { if (MIF_EXISTS(net, tmp)) break; } net->ipv6.maxvif = tmp + 1; } write_unlock_bh(&mrt_lock); dev_set_allmulti(dev, -1); in6_dev = __in6_dev_get(dev); if (in6_dev) in6_dev->cnf.mc_forwarding--; if (v->flags & MIFF_REGISTER) unregister_netdevice_queue(dev, head); dev_put(dev); return 0; }
static int dsa_slave_close(struct net_device *dev) { struct dsa_slave_priv *p = netdev_priv(dev); struct net_device *master = p->parent->dst->master_netdev; dev_mc_unsync(master, dev); dev_uc_unsync(master, dev); if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(master, -1); if (dev->flags & IFF_PROMISC) dev_set_promiscuity(master, -1); if (compare_ether_addr(dev->dev_addr, master->dev_addr)) dev_uc_del(master, dev->dev_addr); return 0; }
static int vlan_dev_stop(struct net_device *dev) { struct vlan_dev_info *vlan = vlan_dev_info(dev); struct net_device *real_dev = vlan->real_dev; dev_mc_unsync(real_dev, dev); dev_uc_unsync(real_dev, dev); if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(real_dev, -1); if (dev->flags & IFF_PROMISC) dev_set_promiscuity(real_dev, -1); if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) dev_uc_del(real_dev, dev->dev_addr); netif_carrier_off(dev); return 0; }
static void packet_dev_mc(struct net_device *dev, struct packet_mclist *i, int what) { switch (i->type) { case PACKET_MR_MULTICAST: if (what > 0) dev_mc_add(dev, i->addr, i->alen, 0); else dev_mc_delete(dev, i->addr, i->alen, 0); break; case PACKET_MR_PROMISC: dev_set_promiscuity(dev, what); break; case PACKET_MR_ALLMULTI: dev_set_allmulti(dev, what); break; default:; } }
static int vlan_dev_stop(struct net_device *dev) { struct vlan_dev_priv *vlan = vlan_dev_priv(dev); struct net_device *real_dev = vlan->real_dev; dev_mc_unsync(real_dev, dev); dev_uc_unsync(real_dev, dev); if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(real_dev, -1); if (dev->flags & IFF_PROMISC) dev_set_promiscuity(real_dev, -1); if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) dev_uc_del(real_dev, dev->dev_addr); if (!(vlan->flags & VLAN_FLAG_BRIDGE_BINDING)) netif_carrier_off(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; }
static int mif6_delete(int vifi) { struct mif_device *v; struct net_device *dev; if (vifi < 0 || vifi >= maxvif) return -EADDRNOTAVAIL; v = &vif6_table[vifi]; write_lock_bh(&mrt_lock); dev = v->dev; v->dev = NULL; if (!dev) { write_unlock_bh(&mrt_lock); return -EADDRNOTAVAIL; } #ifdef CONFIG_IPV6_PIMSM_V2 if (vifi == reg_vif_num) reg_vif_num = -1; #endif if (vifi + 1 == maxvif) { int tmp; for (tmp = vifi - 1; tmp >= 0; tmp--) { if (MIF_EXISTS(tmp)) break; } maxvif = tmp + 1; } write_unlock_bh(&mrt_lock); dev_set_allmulti(dev, -1); if (v->flags & MIFF_REGISTER) unregister_netdevice(dev); dev_put(dev); return 0; }
static int vlan_dev_stop(struct net_device *dev) { struct vlan_dev_info *vlan = vlan_dev_info(dev); struct net_device *real_dev = vlan->real_dev; if (vlan->flags & VLAN_FLAG_GVRP) vlan_gvrp_request_leave(dev); dev_mc_unsync(real_dev, dev); dev_unicast_unsync(real_dev, dev); if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(real_dev, -1); if (dev->flags & IFF_PROMISC) dev_set_promiscuity(real_dev, -1); if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) dev_unicast_delete(real_dev, dev->dev_addr, dev->addr_len); return 0; }
int vlan_dev_open(struct net_device *dev) { struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev); struct net_device *real_dev = vlan->real_dev; int err; if (!(real_dev->flags & IFF_UP)) return -ENETDOWN; if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) { err = dev_unicast_add(real_dev, dev->dev_addr, ETH_ALEN); if (err < 0) return err; } memcpy(vlan->real_dev_addr, real_dev->dev_addr, ETH_ALEN); if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(real_dev, 1); if (dev->flags & IFF_PROMISC) dev_set_promiscuity(real_dev, 1); return 0; }
static int dsa_slave_close(struct net_device *dev) { struct dsa_slave_priv *p = netdev_priv(dev); struct net_device *master = p->parent->dst->master_netdev; struct dsa_switch *ds = p->parent; if (p->phy) phy_stop(p->phy); dev_mc_unsync(master, dev); dev_uc_unsync(master, dev); if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(master, -1); if (dev->flags & IFF_PROMISC) dev_set_promiscuity(master, -1); if (!ether_addr_equal(dev->dev_addr, master->dev_addr)) dev_uc_del(master, dev->dev_addr); if (ds->drv->port_disable) ds->drv->port_disable(ds, p->port, p->phy); 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; /* 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 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; }
static int mif6_add(struct mif6ctl *vifc, int mrtsock) { int vifi = vifc->mif6c_mifi; struct mif_device *v = &vif6_table[vifi]; struct net_device *dev; /* Is vif busy ? */ if (MIF_EXISTS(vifi)) return -EADDRINUSE; switch (vifc->mif6c_flags) { #ifdef CONFIG_IPV6_PIMSM_V2 case MIFF_REGISTER: /* * Special Purpose VIF in PIM * All the packets will be sent to the daemon */ if (reg_vif_num >= 0) return -EADDRINUSE; dev = ip6mr_reg_vif(); if (!dev) return -ENOBUFS; break; #endif case 0: dev = dev_get_by_index(vifc->mif6c_pifi); if (!dev) return -EADDRNOTAVAIL; dev_put(dev); break; default: return -EINVAL; } dev_set_allmulti(dev, 1); /* * Fill in the VIF structures */ v->rate_limit = vifc->vifc_rate_limit; v->flags = vifc->mif6c_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 & MIFF_REGISTER) v->link = dev->iflink; /* And finish update writing critical data */ write_lock_bh(&mrt_lock); dev_hold(dev); v->dev = dev; #ifdef CONFIG_IPV6_PIMSM_V2 if (v->flags & MIFF_REGISTER) reg_vif_num = vifi; #endif if (vifi + 1 > maxvif) maxvif = vifi + 1; write_unlock_bh(&mrt_lock); return 0; }
/** Taken from Gleb + Lennert's VLAN code, and modified... */ void vlan_dev_set_multicast_list(struct net_device *vlan_dev) { struct dev_mc_list *dmi; struct net_device *real_dev; int inc; if (vlan_dev && (vlan_dev->priv_flags & IFF_802_1Q_VLAN)) { /* Then it's a real vlan device, as far as we can tell.. */ real_dev = VLAN_DEV_INFO(vlan_dev)->real_dev; /* compare the current promiscuity to the last promisc we had.. */ inc = vlan_dev->promiscuity - VLAN_DEV_INFO(vlan_dev)->old_promiscuity; if (inc) { printk(KERN_INFO "%s: dev_set_promiscuity(master, %d)\n", vlan_dev->name, inc); dev_set_promiscuity(real_dev, inc); /* found in dev.c */ VLAN_DEV_INFO(vlan_dev)->old_promiscuity = vlan_dev->promiscuity; } inc = vlan_dev->allmulti - VLAN_DEV_INFO(vlan_dev)->old_allmulti; if (inc) { printk(KERN_INFO "%s: dev_set_allmulti(master, %d)\n", vlan_dev->name, inc); dev_set_allmulti(real_dev, inc); /* dev.c */ VLAN_DEV_INFO(vlan_dev)->old_allmulti = vlan_dev->allmulti; } /* looking for addresses to add to master's list */ for (dmi = vlan_dev->mc_list; dmi != NULL; dmi = dmi->next) { if (vlan_should_add_mc(dmi, VLAN_DEV_INFO(vlan_dev)->old_mc_list)) { dev_mc_add(real_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); printk(KERN_DEBUG "%s: add %.2x:%.2x:%.2x:%.2x:%.2x:%.2x mcast address to master interface\n", vlan_dev->name, dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2], dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]); } } /* looking for addresses to delete from master's list */ for (dmi = VLAN_DEV_INFO(vlan_dev)->old_mc_list; dmi != NULL; dmi = dmi->next) { if (vlan_should_add_mc(dmi, vlan_dev->mc_list)) { /* if we think we should add it to the new list, then we should really * delete it from the real list on the underlying device. */ dev_mc_delete(real_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); printk(KERN_DEBUG "%s: del %.2x:%.2x:%.2x:%.2x:%.2x:%.2x mcast address from master interface\n", vlan_dev->name, dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2], dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]); } } /* save multicast list */ vlan_copy_mc_list(vlan_dev->mc_list, VLAN_DEV_INFO(vlan_dev)); } }
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; }