static int ip6_tnl_init_net(struct net *net) { struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); int err; ip6n->tnls[0] = ip6n->tnls_wc; ip6n->tnls[1] = ip6n->tnls_r_l; err = -ENOMEM; ip6n->fb_tnl_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6tnl0", ip6_tnl_dev_setup); if (!ip6n->fb_tnl_dev) goto err_alloc_dev; dev_net_set(ip6n->fb_tnl_dev, net); ip6_fb_tnl_dev_init(ip6n->fb_tnl_dev); err = register_netdev(ip6n->fb_tnl_dev); if (err < 0) goto err_register; return 0; err_register: free_netdev(ip6n->fb_tnl_dev); err_alloc_dev: return err; }
/* Setup and register the loopback device. */ static __net_init int loopback_net_init(struct net *net) { struct net_device *dev; int err; err = -ENOMEM; dev = alloc_netdev(0, "lo", loopback_setup); if (!dev) goto out; dev_net_set(dev, net); err = register_netdev(dev); if (err) goto out_free_netdev; net->loopback_dev = dev; return 0; out_free_netdev: free_netdev(dev); out: if (net == &init_net) panic("loopback: Failed to register netdevice: %d\n", err); return err; }
static struct ip_tunnel * ipip6_tunnel_locate(struct net *net, struct ip_tunnel_parm *parms, int create) { __be32 remote = parms->iph.daddr; __be32 local = parms->iph.saddr; struct ip_tunnel *t, **tp, *nt; struct net_device *dev; char name[IFNAMSIZ]; struct sit_net *sitn = net_generic(net, sit_net_id); for (tp = __ipip6_bucket(sitn, parms); (t = *tp) != NULL; tp = &t->next) { if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr && parms->link == t->parms.link) { if (create) return NULL; else return t; } } if (!create) goto failed; if (parms->name[0]) strlcpy(name, parms->name, IFNAMSIZ); else sprintf(name, "sit%%d"); dev = alloc_netdev(sizeof(*t), name, ipip6_tunnel_setup); if (dev == NULL) return NULL; dev_net_set(dev, net); if (strchr(name, '%')) { if (dev_alloc_name(dev, name) < 0) goto failed_free; } nt = netdev_priv(dev); nt->parms = *parms; ipip6_tunnel_init(dev); if (parms->i_flags & SIT_ISATAP) dev->priv_flags |= IFF_ISATAP; if (register_netdevice(dev) < 0) goto failed_free; dev_hold(dev); ipip6_tunnel_link(sitn, nt); return nt; failed_free: free_netdev(dev); failed: return NULL; }
static struct net_device *ip6mr_reg_vif(struct net *net) { struct net_device *dev; dev = alloc_netdev(0, "pim6reg", reg_vif_setup); if (dev == NULL) return NULL; dev_net_set(dev, net); if (register_netdevice(dev)) { free_netdev(dev); return NULL; } dev->iflink = 0; if (dev_open(dev)) goto failure; dev_hold(dev); return dev; failure: /* allow the register to be completed before unregistering. */ rtnl_unlock(); rtnl_lock(); unregister_netdevice(dev); return NULL; }
static int register_vlan_device(struct net_device *real_dev, u16 vlan_id) { struct net_device *new_dev; struct net *net = dev_net(real_dev); struct vlan_net *vn = net_generic(net, vlan_net_id); char name[IFNAMSIZ]; int err; if (vlan_id >= VLAN_VID_MASK) return -ERANGE; err = vlan_check_real_dev(real_dev, vlan_id); if (err < 0) return err; switch (vn->name_type) { case VLAN_NAME_TYPE_RAW_PLUS_VID: snprintf(name, IFNAMSIZ, "%s.%.4i", real_dev->name, vlan_id); break; case VLAN_NAME_TYPE_PLUS_VID_NO_PAD: snprintf(name, IFNAMSIZ, "vlan%i", vlan_id); break; case VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD: snprintf(name, IFNAMSIZ, "%s.%i", real_dev->name, vlan_id); break; case VLAN_NAME_TYPE_PLUS_VID: default: snprintf(name, IFNAMSIZ, "vlan%.4i", vlan_id); } new_dev = alloc_netdev(sizeof(struct vlan_dev_priv), name, vlan_setup); if (new_dev == NULL) return -ENOBUFS; dev_net_set(new_dev, net); new_dev->mtu = real_dev->mtu; vlan_dev_priv(new_dev)->vlan_id = vlan_id; vlan_dev_priv(new_dev)->real_dev = real_dev; vlan_dev_priv(new_dev)->dent = NULL; vlan_dev_priv(new_dev)->flags = VLAN_FLAG_REORDER_HDR; new_dev->rtnl_link_ops = &vlan_link_ops; err = register_vlan_dev(new_dev); if (err < 0) goto out_free_newdev; return 0; out_free_newdev: free_netdev(new_dev); return err; }
static struct vport *internal_dev_create(const struct vport_parms *parms) { struct vport *vport; struct internal_dev *internal_dev; int err; vport = ovs_vport_alloc(0, &ovs_internal_vport_ops, parms); if (IS_ERR(vport)) { err = PTR_ERR(vport); goto error; } vport->dev = alloc_netdev(sizeof(struct internal_dev), parms->name, NET_NAME_USER, do_setup); if (!vport->dev) { err = -ENOMEM; goto error_free_vport; } vport->dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); if (!vport->dev->tstats) { err = -ENOMEM; goto error_free_netdev; } #ifdef HAVE_IFF_PHONY_HEADROOM vport->dev->needed_headroom = vport->dp->max_headroom; #endif dev_net_set(vport->dev, ovs_dp_get_net(vport->dp)); internal_dev = internal_dev_priv(vport->dev); internal_dev->vport = vport; /* Restrict bridge port to current netns. */ if (vport->port_no == OVSP_LOCAL) vport->dev->features |= NETIF_F_NETNS_LOCAL; rtnl_lock(); err = register_netdevice(vport->dev); if (err) goto error_unlock; dev_set_promiscuity(vport->dev, 1); rtnl_unlock(); netif_start_queue(vport->dev); return vport; error_unlock: rtnl_unlock(); free_percpu(vport->dev->tstats); error_free_netdev: free_netdev(vport->dev); error_free_vport: ovs_vport_free(vport); error: return ERR_PTR(err); }
static struct vport *internal_dev_create(const struct vport_parms *parms) { struct vport *vport; struct netdev_vport *netdev_vport; struct internal_dev *internal_dev; int err; vport = ovs_vport_alloc(sizeof(struct netdev_vport), &ovs_internal_vport_ops, parms); if (IS_ERR(vport)) { err = PTR_ERR(vport); goto error; } netdev_vport = netdev_vport_priv(vport); netdev_vport->dev = alloc_netdev(sizeof(struct internal_dev), parms->name, NET_NAME_UNKNOWN, do_setup); if (!netdev_vport->dev) { err = -ENOMEM; goto error_free_vport; } dev_net_set(netdev_vport->dev, ovs_dp_get_net(vport->dp)); internal_dev = internal_dev_priv(netdev_vport->dev); internal_dev->vport = vport; /* Restrict bridge port to current netns. */ if (vport->port_no == OVSP_LOCAL) netdev_vport->dev->features |= NETIF_F_NETNS_LOCAL; rtnl_lock(); err = register_netdevice(netdev_vport->dev); if (err) goto error_free_netdev; dev_set_promiscuity(netdev_vport->dev, 1); rtnl_unlock(); netif_start_queue(netdev_vport->dev); return vport; error_free_netdev: rtnl_unlock(); free_netdev(netdev_vport->dev); error_free_vport: ovs_vport_free(vport); error: return ERR_PTR(err); }
static int sit_init_net(struct net *net) { int err; struct sit_net *sitn; if (!(get_exec_env()->features & VE_FEATURE_SIT)) return 0; err = -ENOMEM; sitn = kzalloc(sizeof(struct sit_net), GFP_KERNEL); if (sitn == NULL) goto err_alloc; err = net_assign_generic(net, sit_net_id, sitn); if (err < 0) goto err_assign; sitn->tunnels[0] = sitn->tunnels_wc; sitn->tunnels[1] = sitn->tunnels_l; sitn->tunnels[2] = sitn->tunnels_r; sitn->tunnels[3] = sitn->tunnels_r_l; sitn->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "sit0", ipip6_tunnel_setup); if (!sitn->fb_tunnel_dev) { err = -ENOMEM; goto err_alloc_dev; } dev_net_set(sitn->fb_tunnel_dev, net); ipip6_fb_tunnel_init(sitn->fb_tunnel_dev); if ((err = register_netdev(sitn->fb_tunnel_dev))) goto err_reg_dev; return 0; err_reg_dev: dev_put(sitn->fb_tunnel_dev); free_netdev(sitn->fb_tunnel_dev); err_alloc_dev: /* nothing */ err_assign: kfree(sitn); err_alloc: return err; }
static struct ip_tunnel * ipgre_tunnel_locate(struct net *net, struct ip_tunnel_parm *parms, int create) { struct ip_tunnel *t, *nt; struct net_device *dev; char name[IFNAMSIZ]; struct ipgre_net *ign = net_generic(net, ipgre_net_id); t = ipgre_tunnel_find(net, parms, ARPHRD_IPGRE); if (t || !create) return t; if (parms->name[0]) strlcpy(name, parms->name, IFNAMSIZ); else sprintf(name, "gre%%d"); dev = alloc_netdev(sizeof(*t), name, ipgre_tunnel_setup); if (!dev) return NULL; dev_net_set(dev, net); if (strchr(name, '%')) { if (dev_alloc_name(dev, name) < 0) goto failed_free; } nt = netdev_priv(dev); nt->parms = *parms; dev->rtnl_link_ops = &ipgre_link_ops; dev->mtu = ipgre_tunnel_bind_dev(dev); if (register_netdevice(dev) < 0) goto failed_free; dev_hold(dev); ipgre_tunnel_link(ign, nt); return nt; failed_free: free_netdev(dev); return NULL; }
static struct net_device *__ip_tunnel_create(struct net *net, const struct rtnl_link_ops *ops, struct ip_tunnel_parm *parms) { int err; struct ip_tunnel *tunnel; struct net_device *dev; char name[IFNAMSIZ]; if (parms->name[0]) strlcpy(name, parms->name, IFNAMSIZ); else { if (strlen(ops->kind) > (IFNAMSIZ - 3)) { err = -E2BIG; goto failed; } strlcpy(name, ops->kind, IFNAMSIZ); strncat(name, "%d", 2); } ASSERT_RTNL(); dev = alloc_netdev(ops->priv_size, name, ops->setup); if (!dev) { err = -ENOMEM; goto failed; } dev_net_set(dev, net); dev->rtnl_link_ops = ops; tunnel = netdev_priv(dev); tunnel->parms = *parms; tunnel->net = net; err = register_netdevice(dev); if (err) goto failed_free; return dev; failed_free: free_netdev(dev); failed: return ERR_PTR(err); }
int qtnf_core_net_attach(struct qtnf_wmac *mac, struct qtnf_vif *vif, const char *name, unsigned char name_assign_type, enum nl80211_iftype iftype) { struct wiphy *wiphy = priv_to_wiphy(mac); struct net_device *dev; void *qdev_vif; int ret; dev = alloc_netdev_mqs(sizeof(struct qtnf_vif *), name, name_assign_type, ether_setup, 1, 1); if (!dev) { memset(&vif->wdev, 0, sizeof(vif->wdev)); vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED; return -ENOMEM; } vif->netdev = dev; dev->netdev_ops = &qtnf_netdev_ops; dev->needs_free_netdev = true; dev_net_set(dev, wiphy_net(wiphy)); dev->ieee80211_ptr = &vif->wdev; dev->ieee80211_ptr->iftype = iftype; ether_addr_copy(dev->dev_addr, vif->mac_addr); SET_NETDEV_DEV(dev, wiphy_dev(wiphy)); dev->flags |= IFF_BROADCAST | IFF_MULTICAST; dev->watchdog_timeo = QTNF_DEF_WDOG_TIMEOUT; dev->tx_queue_len = 100; qdev_vif = netdev_priv(dev); *((void **)qdev_vif) = vif; SET_NETDEV_DEV(dev, mac->bus->dev); ret = register_netdevice(dev); if (ret) { free_netdev(dev); vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED; } return ret; }
static struct net_device *ipmr_reg_vif(struct net *net) { struct net_device *dev; struct in_device *in_dev; dev = alloc_netdev(0, "pimreg", reg_vif_setup); if (dev == NULL) return NULL; dev_net_set(dev, net); if (register_netdevice(dev)) { free_netdev(dev); return NULL; } dev->iflink = 0; rcu_read_lock(); if ((in_dev = __in_dev_get_rcu(dev)) == NULL) { rcu_read_unlock(); goto failure; } ipv4_devconf_setall(in_dev); IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0; rcu_read_unlock(); if (dev_open(dev)) goto failure; dev_hold(dev); return dev; failure: /* allow the register to be completed before unregistering. */ rtnl_unlock(); rtnl_lock(); unregister_netdevice(dev); return NULL; }
static int ip6_tnl_init_net(struct net *net) { int err; struct ip6_tnl_net *ip6n; err = -ENOMEM; ip6n = kzalloc(sizeof(struct ip6_tnl_net), GFP_KERNEL); if (ip6n == NULL) goto err_alloc; err = net_assign_generic(net, ip6_tnl_net_id, ip6n); if (err < 0) goto err_assign; ip6n->tnls[0] = ip6n->tnls_wc; ip6n->tnls[1] = ip6n->tnls_r_l; err = -ENOMEM; ip6n->fb_tnl_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6tnl0", ip6_tnl_dev_setup); if (!ip6n->fb_tnl_dev) goto err_alloc_dev; dev_net_set(ip6n->fb_tnl_dev, net); ip6_fb_tnl_dev_init(ip6n->fb_tnl_dev); err = register_netdev(ip6n->fb_tnl_dev); if (err < 0) goto err_register; return 0; err_register: free_netdev(ip6n->fb_tnl_dev); err_alloc_dev: /* nothing */ err_assign: kfree(ip6n); err_alloc: return err; }
static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p) { struct net_device *dev; struct ip6_tnl *t; char name[IFNAMSIZ]; int err; struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); if (p->name[0]) strlcpy(name, p->name, IFNAMSIZ); else sprintf(name, "ip6tnl%%d"); dev = alloc_netdev(sizeof (*t), name, ip6_tnl_dev_setup); if (dev == NULL) goto failed; dev_net_set(dev, net); if (strchr(name, '%')) { if (dev_alloc_name(dev, name) < 0) goto failed_free; } t = netdev_priv(dev); t->parms = *p; ip6_tnl_dev_init(dev); if ((err = register_netdevice(dev)) < 0) goto failed_free; dev_hold(dev); ip6_tnl_link(ip6n, t); return t; failed_free: free_netdev(dev); failed: return NULL; }
/* * Create a new btn interface unit. Fails if it can't allocate memory * or if there is already a unit with the requested number. * unit == -1 means allocate a new number. */ static struct btn * btn_create_interface(struct net *net, enum btn_dev_type dev_type, int *retp) { struct btn *btn; struct btn_net *btn_net; struct net_device *dev = NULL; int ret = -ENOMEM; int unit; dev = alloc_netdev(sizeof(struct btn), "", btn_setup); if (!dev) goto out1; if (dev_type == BTN_IP_DEV) { dev->header_ops = NULL; dev->flags = IFF_NOARP & (~IFF_BROADCAST & ~IFF_MULTICAST); } btn_net = btn_pernet(net); btn = netdev_priv(dev); btn->dev = dev; spin_lock_init(&btn->rlock); spin_lock_init(&btn->wlock); btn_init_file(&btn->file); /* * drum roll: don't forget to set * the net device is belong to */ dev_net_set(dev, net); ret = -EEXIST; mutex_lock(&btn_net->all_btn_mutex); unit = btn_get_unit(&btn_net->units_idr, btn); btn->file.index = unit; sprintf(dev->name, "btn%d", unit); ret = register_netdev(dev); if (ret != 0) { printk(KERN_ERR "BTN: couldn't register device %s (%d)\n", dev->name, ret); goto out2; } printk(KERN_INFO "BT register net dev name: %s \n", dev->name); netif_carrier_on(dev); btn->btn_net = net; btn->dev_type = dev_type; atomic_inc(&btn_unit_count); mutex_unlock(&btn_net->all_btn_mutex); return btn; out2: mutex_unlock(&btn_net->all_btn_mutex); free_netdev(dev); out1: *retp = ret; return NULL; }
/* Attach a VLAN device to a mac address (ie Ethernet Card). * Returns 0 if the device was created or a negative error code otherwise. */ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id) { struct net_device *new_dev; struct net *net = dev_net(real_dev); struct vlan_net *vn = net_generic(net, vlan_net_id); char name[IFNAMSIZ]; int err; if (vlan_id >= VLAN_VID_MASK) return -ERANGE; err = vlan_check_real_dev(real_dev, vlan_id); if (err < 0) return err; /* Gotta set up the fields for the device. */ switch (vn->name_type) { case VLAN_NAME_TYPE_RAW_PLUS_VID: /* name will look like: eth1.0005 */ snprintf(name, IFNAMSIZ, "%s.%.4i", real_dev->name, vlan_id); break; case VLAN_NAME_TYPE_PLUS_VID_NO_PAD: /* Put our vlan.VID in the name. * Name will look like: vlan5 */ snprintf(name, IFNAMSIZ, "vlan%i", vlan_id); break; case VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD: /* Put our vlan.VID in the name. * Name will look like: eth0.5 */ snprintf(name, IFNAMSIZ, "%s.%i", real_dev->name, vlan_id); break; case VLAN_NAME_TYPE_PLUS_VID: /* Put our vlan.VID in the name. * Name will look like: vlan0005 */ default: snprintf(name, IFNAMSIZ, "vlan%.4i", vlan_id); } new_dev = alloc_netdev(sizeof(struct vlan_dev_priv), name, vlan_setup); if (new_dev == NULL) return -ENOBUFS; dev_net_set(new_dev, net); /* need 4 bytes for extra VLAN header info, * hope the underlying device can handle it. */ new_dev->mtu = real_dev->mtu; new_dev->priv_flags |= (real_dev->priv_flags & IFF_UNICAST_FLT); vlan_dev_priv(new_dev)->vlan_id = vlan_id; vlan_dev_priv(new_dev)->real_dev = real_dev; vlan_dev_priv(new_dev)->dent = NULL; vlan_dev_priv(new_dev)->flags = VLAN_FLAG_REORDER_HDR; new_dev->rtnl_link_ops = &vlan_link_ops; err = register_vlan_dev(new_dev); if (err < 0) goto out_free_newdev; return 0; out_free_newdev: free_netdev(new_dev); return err; }
static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg) { struct net_device *dev; char name[IFNAMSIZ]; struct l2tp_tunnel *tunnel; struct l2tp_session *session; struct l2tp_eth *priv; struct l2tp_eth_sess *spriv; int rc; struct l2tp_eth_net *pn; tunnel = l2tp_tunnel_find(net, tunnel_id); if (!tunnel) { rc = -ENODEV; goto out; } session = l2tp_session_find(net, tunnel, session_id); if (session) { rc = -EEXIST; goto out; } if (cfg->ifname) { dev = dev_get_by_name(net, cfg->ifname); if (dev) { dev_put(dev); rc = -EEXIST; goto out; } strlcpy(name, cfg->ifname, IFNAMSIZ); } else strcpy(name, L2TP_ETH_DEV_NAME); session = l2tp_session_create(sizeof(*spriv), tunnel, session_id, peer_session_id, cfg); if (!session) { rc = -ENOMEM; goto out; } dev = alloc_netdev(sizeof(*priv), name, l2tp_eth_dev_setup); if (!dev) { rc = -ENOMEM; goto out_del_session; } dev_net_set(dev, net); if (session->mtu == 0) session->mtu = dev->mtu - session->hdr_len; dev->mtu = session->mtu; dev->needed_headroom += session->hdr_len; priv = netdev_priv(dev); priv->dev = dev; priv->session = session; INIT_LIST_HEAD(&priv->list); priv->tunnel_sock = tunnel->sock; session->recv_skb = l2tp_eth_dev_recv; session->session_close = l2tp_eth_delete; #if defined(CONFIG_L2TP_DEBUGFS) || defined(CONFIG_L2TP_DEBUGFS_MODULE) session->show = l2tp_eth_show; #endif spriv = l2tp_session_priv(session); spriv->dev = dev; rc = register_netdev(dev); if (rc < 0) goto out_del_dev; __module_get(THIS_MODULE); /* Must be done after register_netdev() */ strlcpy(session->ifname, dev->name, IFNAMSIZ); dev_hold(dev); pn = l2tp_eth_pernet(dev_net(dev)); spin_lock(&pn->l2tp_eth_lock); list_add(&priv->list, &pn->l2tp_eth_dev_list); spin_unlock(&pn->l2tp_eth_lock); return 0; out_del_dev: free_netdev(dev); spriv->dev = NULL; out_del_session: l2tp_session_delete(session); out: return rc; }
/* * create a new virtual interface with the given name */ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, char *name, enum nl80211_iftype type, u32 *flags, struct vif_params *params) { struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); struct mwifiex_private *priv; struct net_device *dev; void *mdev_priv; struct wireless_dev *wdev; if (!adapter) return ERR_PTR(-EFAULT); switch (type) { case NL80211_IFTYPE_UNSPECIFIED: case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: priv = adapter->priv[MWIFIEX_BSS_TYPE_STA]; if (priv->bss_mode) { wiphy_err(wiphy, "cannot create multiple sta/adhoc ifaces\n"); return ERR_PTR(-EINVAL); } wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); if (!wdev) return ERR_PTR(-ENOMEM); wdev->wiphy = wiphy; priv->wdev = wdev; wdev->iftype = NL80211_IFTYPE_STATION; if (type == NL80211_IFTYPE_UNSPECIFIED) priv->bss_mode = NL80211_IFTYPE_STATION; else priv->bss_mode = type; priv->bss_type = MWIFIEX_BSS_TYPE_STA; priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; priv->bss_priority = MWIFIEX_BSS_ROLE_STA; priv->bss_role = MWIFIEX_BSS_ROLE_STA; priv->bss_num = 0; break; case NL80211_IFTYPE_AP: priv = adapter->priv[MWIFIEX_BSS_TYPE_UAP]; if (priv->bss_mode) { wiphy_err(wiphy, "Can't create multiple AP interfaces"); return ERR_PTR(-EINVAL); } wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); if (!wdev) return ERR_PTR(-ENOMEM); priv->wdev = wdev; wdev->wiphy = wiphy; wdev->iftype = NL80211_IFTYPE_AP; priv->bss_type = MWIFIEX_BSS_TYPE_UAP; priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; priv->bss_priority = MWIFIEX_BSS_ROLE_UAP; priv->bss_role = MWIFIEX_BSS_ROLE_UAP; priv->bss_started = 0; priv->bss_num = 0; priv->bss_mode = type; break; default: wiphy_err(wiphy, "type not supported\n"); return ERR_PTR(-EINVAL); } dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), name, ether_setup, 1); if (!dev) { wiphy_err(wiphy, "no memory available for netdevice\n"); priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; return ERR_PTR(-ENOMEM); } mwifiex_init_priv_params(priv, dev); priv->netdev = dev; mwifiex_setup_ht_caps(&wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv); if (adapter->config_bands & BAND_A) mwifiex_setup_ht_caps( &wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv); dev_net_set(dev, wiphy_net(wiphy)); dev->ieee80211_ptr = priv->wdev; dev->ieee80211_ptr->iftype = priv->bss_mode; memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN); memcpy(dev->perm_addr, wiphy->perm_addr, ETH_ALEN); SET_NETDEV_DEV(dev, wiphy_dev(wiphy)); dev->flags |= IFF_BROADCAST | IFF_MULTICAST; dev->watchdog_timeo = MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT; dev->hard_header_len += MWIFIEX_MIN_DATA_HEADER_LEN; mdev_priv = netdev_priv(dev); *((unsigned long *) mdev_priv) = (unsigned long) priv; SET_NETDEV_DEV(dev, adapter->dev); /* Register network device */ if (register_netdevice(dev)) { wiphy_err(wiphy, "cannot register virtual network device\n"); free_netdev(dev); priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; return ERR_PTR(-EFAULT); } sema_init(&priv->async_sem, 1); priv->scan_pending_on_block = false; dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name); #ifdef CONFIG_DEBUG_FS mwifiex_dev_debugfs_init(priv); #endif return dev; }
/** * @brief Register the device with cfg80211 * * @param dev A pointer to net_device structure * @param bss_type BSS type * * @return MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE */ mlan_status woal_register_uap_cfg80211(struct net_device * dev, t_u8 bss_type) { mlan_status ret = MLAN_STATUS_SUCCESS; moal_private *priv = (moal_private *) netdev_priv(dev); void *wdev_priv = NULL; struct wireless_dev *wdev = NULL; mlan_fw_info fw_info; ENTER(); /* Allocate wireless device */ wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); if (!wdev) { PRINTM(MERROR, "Could not allocate wireless device\n"); ret = MLAN_STATUS_FAILURE; goto err_wdev; } /* Allocate wiphy */ wdev->wiphy = wiphy_new(&woal_cfg80211_uap_ops, sizeof(moal_private *)); if (!wdev->wiphy) { PRINTM(MERROR, "Could not allocate wiphy device\n"); ret = MLAN_STATUS_FAILURE; goto err_wdev; } if (bss_type == MLAN_BSS_TYPE_UAP) { dev_set_name(&wdev->wiphy->dev, dev->name); wdev->iftype = NL80211_IFTYPE_AP; wdev->wiphy->interface_modes = MBIT(NL80211_IFTYPE_AP) | MBIT(NL80211_IFTYPE_STATION) | 0; wdev->wiphy->max_scan_ssids = 10; } /* Make this wiphy known to this driver only */ wdev->wiphy->privid = mrvl_wiphy_privid; /* Supported bands */ wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &cfg80211_band_2ghz; if (MLAN_STATUS_SUCCESS == woal_request_get_fw_info(priv, MOAL_CMD_WAIT, &fw_info)) { if (fw_info.fw_bands & BAND_A) wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &cfg80211_band_5ghz; } /* Initialize cipher suits */ wdev->wiphy->cipher_suites = cfg80211_cipher_suites; wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cfg80211_cipher_suites); wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; /* We are using custom domains */ wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; wdev->wiphy->reg_notifier = NULL; // TODO: woal_cfg80211_reg_notifier; /* Set moal_private pointer in wiphy_priv */ wdev_priv = wiphy_priv(wdev->wiphy); *(unsigned long *) wdev_priv = (unsigned long) priv; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39) || defined(COMPAT_WIRELESS) set_wiphy_dev(wdev->wiphy, (struct device *) priv->phandle->hotplug_device); #endif if (wiphy_register(wdev->wiphy) < 0) { PRINTM(MERROR, "Wiphy device registration failed!\n"); ret = MLAN_STATUS_FAILURE; goto err_wdev; } dev_net_set(dev, wiphy_net(wdev->wiphy)); dev->ieee80211_ptr = wdev; SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy)); priv->wdev = wdev; if (ret != MLAN_STATUS_SUCCESS) { PRINTM(MERROR, "Wiphy device registration failed!\n"); } else { PRINTM(MINFO, "Successfully registered wiphy device\n"); LEAVE(); return ret; } wiphy_unregister(wdev->wiphy); err_wdev: dev->ieee80211_ptr = NULL; if (wdev && wdev->wiphy) wiphy_free(wdev->wiphy); kfree(wdev); LEAVE(); return ret; }
/* * create a new virtual interface with the given name */ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, char *name, enum nl80211_iftype type, u32 *flags, struct vif_params *params) { struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); struct mwifiex_adapter *adapter; struct net_device *dev; void *mdev_priv; if (!priv) return NULL; adapter = priv->adapter; if (!adapter) return NULL; switch (type) { case NL80211_IFTYPE_UNSPECIFIED: case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: if (priv->bss_mode) { wiphy_err(wiphy, "cannot create multiple" " station/adhoc interfaces\n"); return NULL; } if (type == NL80211_IFTYPE_UNSPECIFIED) priv->bss_mode = NL80211_IFTYPE_STATION; else priv->bss_mode = type; priv->bss_type = MWIFIEX_BSS_TYPE_STA; priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; priv->bss_priority = 0; priv->bss_role = MWIFIEX_BSS_ROLE_STA; priv->bss_index = 0; priv->bss_num = 0; break; default: wiphy_err(wiphy, "type not supported\n"); return NULL; } dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), name, ether_setup, 1); if (!dev) { wiphy_err(wiphy, "no memory available for netdevice\n"); goto error; } dev_net_set(dev, wiphy_net(wiphy)); dev->ieee80211_ptr = priv->wdev; dev->ieee80211_ptr->iftype = priv->bss_mode; memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN); memcpy(dev->perm_addr, wiphy->perm_addr, ETH_ALEN); SET_NETDEV_DEV(dev, wiphy_dev(wiphy)); dev->flags |= IFF_BROADCAST | IFF_MULTICAST; dev->watchdog_timeo = MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT; dev->hard_header_len += MWIFIEX_MIN_DATA_HEADER_LEN; mdev_priv = netdev_priv(dev); *((unsigned long *) mdev_priv) = (unsigned long) priv; priv->netdev = dev; mwifiex_init_priv_params(priv, dev); SET_NETDEV_DEV(dev, adapter->dev); /* Register network device */ if (register_netdevice(dev)) { wiphy_err(wiphy, "cannot register virtual network device\n"); goto error; } sema_init(&priv->async_sem, 1); priv->scan_pending_on_block = false; dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name); #ifdef CONFIG_DEBUG_FS mwifiex_dev_debugfs_init(priv); #endif return dev; error: if (dev && (dev->reg_state == NETREG_UNREGISTERED)) free_netdev(dev); priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; return NULL; }
/* * This function registers the device with CFG802.11 subsystem. * * The function creates the wireless device/wiphy, populates it with * default parameters and handler function pointers, and finally * registers the device. */ int mwifiex_register_cfg80211(struct net_device *dev, u8 *mac, struct mwifiex_private *priv) { int ret; void *wdev_priv; struct wireless_dev *wdev; wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); if (!wdev) { dev_err(priv->adapter->dev, "%s: allocating wireless device\n", __func__); return -ENOMEM; } wdev->wiphy = wiphy_new(&mwifiex_cfg80211_ops, sizeof(struct mwifiex_private *)); if (!wdev->wiphy) { kfree(wdev); return -ENOMEM; } wdev->iftype = NL80211_IFTYPE_STATION; wdev->wiphy->max_scan_ssids = 10; wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; mwifiex_setup_ht_caps( &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv); if (priv->adapter->config_bands & BAND_A) { wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; mwifiex_setup_ht_caps( &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv); } else { wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; } /* Initialize cipher suits */ wdev->wiphy->cipher_suites = mwifiex_cipher_suites; wdev->wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites); memcpy(wdev->wiphy->perm_addr, mac, 6); wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; /* We are using custom domains */ wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; wdev->wiphy->reg_notifier = mwifiex_reg_notifier; /* Set struct mwifiex_private pointer in wiphy_priv */ wdev_priv = wiphy_priv(wdev->wiphy); *(unsigned long *) wdev_priv = (unsigned long) priv; set_wiphy_dev(wdev->wiphy, (struct device *) priv->adapter->dev); ret = wiphy_register(wdev->wiphy); if (ret < 0) { dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n", __func__); wiphy_free(wdev->wiphy); kfree(wdev); return ret; } else { dev_dbg(priv->adapter->dev, "info: successfully registered wiphy device\n"); } dev_net_set(dev, wiphy_net(wdev->wiphy)); dev->ieee80211_ptr = wdev; memcpy(dev->dev_addr, wdev->wiphy->perm_addr, 6); memcpy(dev->perm_addr, wdev->wiphy->perm_addr, 6); SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy)); priv->wdev = wdev; dev->flags |= IFF_BROADCAST | IFF_MULTICAST; dev->watchdog_timeo = MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT; dev->hard_header_len += MWIFIEX_MIN_DATA_HEADER_LEN; return ret; }
static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg) { unsigned char name_assign_type; struct net_device *dev; char name[IFNAMSIZ]; struct l2tp_session *session; struct l2tp_eth *priv; struct l2tp_eth_sess *spriv; int rc; if (cfg->ifname) { strlcpy(name, cfg->ifname, IFNAMSIZ); name_assign_type = NET_NAME_USER; } else { strcpy(name, L2TP_ETH_DEV_NAME); name_assign_type = NET_NAME_ENUM; } session = l2tp_session_create(sizeof(*spriv), tunnel, session_id, peer_session_id, cfg); if (IS_ERR(session)) { rc = PTR_ERR(session); goto out; } dev = alloc_netdev(sizeof(*priv), name, name_assign_type, l2tp_eth_dev_setup); if (!dev) { rc = -ENOMEM; goto out_del_session; } dev_net_set(dev, net); dev->min_mtu = 0; dev->max_mtu = ETH_MAX_MTU; l2tp_eth_adjust_mtu(tunnel, session, dev); priv = netdev_priv(dev); priv->dev = dev; priv->session = session; priv->tunnel_sock = tunnel->sock; session->recv_skb = l2tp_eth_dev_recv; session->session_close = l2tp_eth_delete; #if IS_ENABLED(CONFIG_L2TP_DEBUGFS) session->show = l2tp_eth_show; #endif spriv = l2tp_session_priv(session); spriv->dev = dev; rc = register_netdev(dev); if (rc < 0) goto out_del_dev; __module_get(THIS_MODULE); /* Must be done after register_netdev() */ strlcpy(session->ifname, dev->name, IFNAMSIZ); dev_hold(dev); return 0; out_del_dev: free_netdev(dev); spriv->dev = NULL; out_del_session: l2tp_session_delete(session); out: return rc; }
int sn_register_netdev(void *bar, struct sn_device *dev) { struct sn_conf_space *conf = bar; int ret; struct net *net = NULL; /* network namespace */ rtnl_lock(); if (conf->netns_fd >= 0) { #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0)) log_err("'netns' option requires Linux kernel 4.0 or higher\n"); ret = -EINVAL; goto fail_free; #else net = get_net_ns_by_fd(conf->netns_fd); if (IS_ERR(net)) { log_err("invalid or not a net namespace fd %d\n", conf->netns_fd); ret = PTR_ERR(net); goto fail_free; } #endif } else if (conf->container_pid) { net = get_net_ns_by_pid(conf->container_pid); if (IS_ERR(net)) { log_err("cannot find namespace of pid %d\n", conf->container_pid); ret = PTR_ERR(net); goto fail_free; } } if (!IS_ERR_OR_NULL(net)) { dev_net_set(dev->netdev, net); put_net(net); } ret = register_netdevice(dev->netdev); if (ret) { log_err("%s: register_netdev() failed (ret = %d)\n", dev->netdev->name, ret); goto fail_free; } /* interface "UP" by default */ dev_open(dev->netdev); strcpy(conf->ifname, dev->netdev->name); log_info("%s: registered - %pM txq %d rxq %d\n", dev->netdev->name, dev->netdev->dev_addr, dev->netdev->real_num_tx_queues, dev->netdev->real_num_rx_queues); rtnl_unlock(); return ret; fail_free: rtnl_unlock(); free_netdev(dev->netdev); return ret; }