static struct inet6_dev * ipv6_add_dev(struct device *dev) { struct inet6_dev *ndev, **bptr, *iter; int hash; if (dev->mtu < IPV6_MIN_MTU) return NULL; ndev = kmalloc(sizeof(struct inet6_dev), GFP_KERNEL); if (ndev) { char name[64]; memset(ndev, 0, sizeof(struct inet6_dev)); ndev->dev = dev; memcpy(&ndev->cnf, &ipv6_devconf_dflt, sizeof(ndev->cnf)); ndev->cnf.mtu6 = dev->mtu; ndev->cnf.sysctl = NULL; ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl); if (ndev->nd_parms == NULL) { kfree(ndev); return NULL; } ipv6_statistics.Ip6LastChange = timeticks(jiffies); ndev->stats.ipv6.Ip6LastChange = timeticks(jiffies); #ifdef CONFIG_PROC_FS sprintf(name, "%d", dev->ifindex); ndev->stats.proc_dir_entry = create_proc_entry(name, 0, proc_net_devsnmp6); if (!ndev->stats.proc_dir_entry) printk(KERN_WARNING "addrconf_notify(): cannot create /proc/net/dev_snmp6/%s\n",name); ndev->stats.proc_dir_entry->read_proc = afinet6_read_devsnmp; ndev->stats.proc_dir_entry->data = ndev; #endif #ifdef CONFIG_SYSCTL neigh_sysctl_register(dev, ndev->nd_parms, NET_IPV6, NET_IPV6_NEIGH, "ipv6"); addrconf_sysctl_register(ndev, &ndev->cnf); #endif hash = ipv6_devindex_hash(dev->ifindex); bptr = &inet6_dev_lst[hash]; iter = *bptr; for (; iter; iter = iter->next) bptr = &iter->next; *bptr = ndev; } return ndev; }
static struct inet6_dev * ipv6_add_dev(struct net_device *dev) { struct inet6_dev *ndev; ASSERT_RTNL(); if (dev->mtu < IPV6_MIN_MTU) return NULL; ndev = kmalloc(sizeof(struct inet6_dev), GFP_KERNEL); if (ndev) { memset(ndev, 0, sizeof(struct inet6_dev)); ndev->lock = RW_LOCK_UNLOCKED; ndev->dev = dev; memcpy(&ndev->cnf, &ipv6_devconf_dflt, sizeof(ndev->cnf)); ndev->cnf.mtu6 = dev->mtu; ndev->cnf.sysctl = NULL; ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl); if (ndev->nd_parms == NULL) { kfree(ndev); return NULL; } inet6_dev_count++; /* We refer to the device */ dev_hold(dev); write_lock_bh(&addrconf_lock); dev->ip6_ptr = ndev; /* One reference from device */ in6_dev_hold(ndev); write_unlock_bh(&addrconf_lock); ipv6_mc_init_dev(ndev); #ifdef CONFIG_SYSCTL neigh_sysctl_register(dev, ndev->nd_parms, NET_IPV6, NET_IPV6_NEIGH, "ipv6"); addrconf_sysctl_register(ndev, &ndev->cnf); #endif } return ndev; }
struct in_device *inetdev_init(struct net_device *dev) { struct in_device *in_dev; ASSERT_RTNL(); in_dev = kmalloc(sizeof(*in_dev), GFP_KERNEL); if (!in_dev) goto out; memset(in_dev, 0, sizeof(*in_dev)); INIT_RCU_HEAD(&in_dev->rcu_head); memcpy(&in_dev->cnf, &ipv4_devconf_dflt, sizeof(in_dev->cnf)); in_dev->cnf.sysctl = NULL; in_dev->dev = dev; if ((in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl)) == NULL) goto out_kfree; /* Reference in_dev->dev */ dev_hold(dev); #ifdef CONFIG_SYSCTL neigh_sysctl_register(dev, in_dev->arp_parms, NET_IPV4, NET_IPV4_NEIGH, "ipv4", NULL); #endif /* Account for reference dev->ip_ptr (below) */ in_dev_hold(in_dev); #ifdef CONFIG_SYSCTL devinet_sysctl_register(in_dev, &in_dev->cnf); #endif ip_mc_init_dev(in_dev); if (dev->flags & IFF_UP) ip_mc_up(in_dev); out: /* we can receive as soon as ip_ptr is set -- do this last */ smp_wmb(); dev->ip_ptr = in_dev; return in_dev; out_kfree: kfree(in_dev); in_dev = NULL; goto out; }
struct in_device *inetdev_init(struct net_device *dev) { struct in_device *in_dev; ASSERT_RTNL(); in_dev = kmalloc(sizeof(*in_dev), GFP_KERNEL); if (!in_dev) goto out; memset(in_dev, 0, sizeof(*in_dev)); in_dev->lock = RW_LOCK_UNLOCKED; memcpy(&in_dev->cnf, &ipv4_devconf_dflt, sizeof(in_dev->cnf)); in_dev->cnf.sysctl = NULL; in_dev->dev = dev; if ((in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl)) == NULL) goto out_kfree; inet_dev_count++; /* Reference in_dev->dev */ dev_hold(dev); #ifdef CONFIG_SYSCTL neigh_sysctl_register(dev, in_dev->arp_parms, NET_IPV4, NET_IPV4_NEIGH, "ipv4", NULL); #endif write_lock_bh(&inetdev_lock); dev->ip_ptr = in_dev; /* Account for reference dev->ip_ptr */ in_dev_hold(in_dev); write_unlock_bh(&inetdev_lock); #ifdef CONFIG_SYSCTL devinet_sysctl_register(in_dev, &in_dev->cnf); #endif ip_mc_init_dev(in_dev); if (dev->flags & IFF_UP) ip_mc_up(in_dev); out: return in_dev; out_kfree: kfree(in_dev); in_dev = NULL; goto out; }
static struct inet6_dev * ipv6_add_dev(struct device *dev) { struct inet6_dev *ndev, **bptr, *iter; int hash; if (dev->mtu < IPV6_MIN_MTU) return NULL; ndev = kmalloc(sizeof(struct inet6_dev), gfp_any()); if (ndev) { memset(ndev, 0, sizeof(struct inet6_dev)); ndev->dev = dev; memcpy(&ndev->cnf, &ipv6_devconf_dflt, sizeof(ndev->cnf)); ndev->cnf.mtu6 = dev->mtu; ndev->cnf.sysctl = NULL; ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl); if (ndev->nd_parms == NULL) { kfree(ndev); return NULL; } #ifdef CONFIG_SYSCTL neigh_sysctl_register(dev, ndev->nd_parms, NET_IPV6, NET_IPV6_NEIGH, "ipv6"); addrconf_sysctl_register(ndev, &ndev->cnf); #endif hash = ipv6_devindex_hash(dev->ifindex); bptr = &inet6_dev_lst[hash]; iter = *bptr; for (; iter; iter = iter->next) bptr = &iter->next; *bptr = ndev; } return ndev; }