Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* drivers/net/wireless/virt_wifi.c
0003  *
0004  * A fake implementation of cfg80211_ops that can be tacked on to an ethernet
0005  * net_device to make it appear as a wireless connection.
0006  *
0007  * Copyright (C) 2018 Google, Inc.
0008  *
0009  * Author: schuffelen@google.com
0010  */
0011 
0012 #include <net/cfg80211.h>
0013 #include <net/rtnetlink.h>
0014 #include <linux/etherdevice.h>
0015 #include <linux/math64.h>
0016 #include <linux/module.h>
0017 
0018 static struct wiphy *common_wiphy;
0019 
0020 struct virt_wifi_wiphy_priv {
0021     struct delayed_work scan_result;
0022     struct cfg80211_scan_request *scan_request;
0023     bool being_deleted;
0024 };
0025 
0026 static struct ieee80211_channel channel_2ghz = {
0027     .band = NL80211_BAND_2GHZ,
0028     .center_freq = 2432,
0029     .hw_value = 2432,
0030     .max_power = 20,
0031 };
0032 
0033 static struct ieee80211_rate bitrates_2ghz[] = {
0034     { .bitrate = 10 },
0035     { .bitrate = 20 },
0036     { .bitrate = 55 },
0037     { .bitrate = 110 },
0038     { .bitrate = 60 },
0039     { .bitrate = 120 },
0040     { .bitrate = 240 },
0041 };
0042 
0043 static struct ieee80211_supported_band band_2ghz = {
0044     .channels = &channel_2ghz,
0045     .bitrates = bitrates_2ghz,
0046     .band = NL80211_BAND_2GHZ,
0047     .n_channels = 1,
0048     .n_bitrates = ARRAY_SIZE(bitrates_2ghz),
0049     .ht_cap = {
0050         .ht_supported = true,
0051         .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
0052                IEEE80211_HT_CAP_GRN_FLD |
0053                IEEE80211_HT_CAP_SGI_20 |
0054                IEEE80211_HT_CAP_SGI_40 |
0055                IEEE80211_HT_CAP_DSSSCCK40,
0056         .ampdu_factor = 0x3,
0057         .ampdu_density = 0x6,
0058         .mcs = {
0059             .rx_mask = {0xff, 0xff},
0060             .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
0061         },
0062     },
0063 };
0064 
0065 static struct ieee80211_channel channel_5ghz = {
0066     .band = NL80211_BAND_5GHZ,
0067     .center_freq = 5240,
0068     .hw_value = 5240,
0069     .max_power = 20,
0070 };
0071 
0072 static struct ieee80211_rate bitrates_5ghz[] = {
0073     { .bitrate = 60 },
0074     { .bitrate = 120 },
0075     { .bitrate = 240 },
0076 };
0077 
0078 #define RX_MCS_MAP (IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | \
0079             IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | \
0080             IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 | \
0081             IEEE80211_VHT_MCS_SUPPORT_0_9 << 6 | \
0082             IEEE80211_VHT_MCS_SUPPORT_0_9 << 8 | \
0083             IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 | \
0084             IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 | \
0085             IEEE80211_VHT_MCS_SUPPORT_0_9 << 14)
0086 
0087 #define TX_MCS_MAP (IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | \
0088             IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | \
0089             IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 | \
0090             IEEE80211_VHT_MCS_SUPPORT_0_9 << 6 | \
0091             IEEE80211_VHT_MCS_SUPPORT_0_9 << 8 | \
0092             IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 | \
0093             IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 | \
0094             IEEE80211_VHT_MCS_SUPPORT_0_9 << 14)
0095 
0096 static struct ieee80211_supported_band band_5ghz = {
0097     .channels = &channel_5ghz,
0098     .bitrates = bitrates_5ghz,
0099     .band = NL80211_BAND_5GHZ,
0100     .n_channels = 1,
0101     .n_bitrates = ARRAY_SIZE(bitrates_5ghz),
0102     .ht_cap = {
0103         .ht_supported = true,
0104         .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
0105                IEEE80211_HT_CAP_GRN_FLD |
0106                IEEE80211_HT_CAP_SGI_20 |
0107                IEEE80211_HT_CAP_SGI_40 |
0108                IEEE80211_HT_CAP_DSSSCCK40,
0109         .ampdu_factor = 0x3,
0110         .ampdu_density = 0x6,
0111         .mcs = {
0112             .rx_mask = {0xff, 0xff},
0113             .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
0114         },
0115     },
0116     .vht_cap = {
0117         .vht_supported = true,
0118         .cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
0119                IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ |
0120                IEEE80211_VHT_CAP_RXLDPC |
0121                IEEE80211_VHT_CAP_SHORT_GI_80 |
0122                IEEE80211_VHT_CAP_SHORT_GI_160 |
0123                IEEE80211_VHT_CAP_TXSTBC |
0124                IEEE80211_VHT_CAP_RXSTBC_1 |
0125                IEEE80211_VHT_CAP_RXSTBC_2 |
0126                IEEE80211_VHT_CAP_RXSTBC_3 |
0127                IEEE80211_VHT_CAP_RXSTBC_4 |
0128                IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK,
0129         .vht_mcs = {
0130             .rx_mcs_map = cpu_to_le16(RX_MCS_MAP),
0131             .tx_mcs_map = cpu_to_le16(TX_MCS_MAP),
0132         }
0133     },
0134 };
0135 
0136 /* Assigned at module init. Guaranteed locally-administered and unicast. */
0137 static u8 fake_router_bssid[ETH_ALEN] __ro_after_init = {};
0138 
0139 static void virt_wifi_inform_bss(struct wiphy *wiphy)
0140 {
0141     u64 tsf = div_u64(ktime_get_boottime_ns(), 1000);
0142     struct cfg80211_bss *informed_bss;
0143     static const struct {
0144         u8 tag;
0145         u8 len;
0146         u8 ssid[8];
0147     } __packed ssid = {
0148         .tag = WLAN_EID_SSID,
0149         .len = 8,
0150         .ssid = "VirtWifi",
0151     };
0152 
0153     informed_bss = cfg80211_inform_bss(wiphy, &channel_5ghz,
0154                        CFG80211_BSS_FTYPE_PRESP,
0155                        fake_router_bssid, tsf,
0156                        WLAN_CAPABILITY_ESS, 0,
0157                        (void *)&ssid, sizeof(ssid),
0158                        DBM_TO_MBM(-50), GFP_KERNEL);
0159     cfg80211_put_bss(wiphy, informed_bss);
0160 }
0161 
0162 /* Called with the rtnl lock held. */
0163 static int virt_wifi_scan(struct wiphy *wiphy,
0164               struct cfg80211_scan_request *request)
0165 {
0166     struct virt_wifi_wiphy_priv *priv = wiphy_priv(wiphy);
0167 
0168     wiphy_debug(wiphy, "scan\n");
0169 
0170     if (priv->scan_request || priv->being_deleted)
0171         return -EBUSY;
0172 
0173     priv->scan_request = request;
0174     schedule_delayed_work(&priv->scan_result, HZ * 2);
0175 
0176     return 0;
0177 }
0178 
0179 /* Acquires and releases the rdev BSS lock. */
0180 static void virt_wifi_scan_result(struct work_struct *work)
0181 {
0182     struct virt_wifi_wiphy_priv *priv =
0183         container_of(work, struct virt_wifi_wiphy_priv,
0184                  scan_result.work);
0185     struct wiphy *wiphy = priv_to_wiphy(priv);
0186     struct cfg80211_scan_info scan_info = { .aborted = false };
0187 
0188     virt_wifi_inform_bss(wiphy);
0189 
0190     /* Schedules work which acquires and releases the rtnl lock. */
0191     cfg80211_scan_done(priv->scan_request, &scan_info);
0192     priv->scan_request = NULL;
0193 }
0194 
0195 /* May acquire and release the rdev BSS lock. */
0196 static void virt_wifi_cancel_scan(struct wiphy *wiphy)
0197 {
0198     struct virt_wifi_wiphy_priv *priv = wiphy_priv(wiphy);
0199 
0200     cancel_delayed_work_sync(&priv->scan_result);
0201     /* Clean up dangling callbacks if necessary. */
0202     if (priv->scan_request) {
0203         struct cfg80211_scan_info scan_info = { .aborted = true };
0204         /* Schedules work which acquires and releases the rtnl lock. */
0205         cfg80211_scan_done(priv->scan_request, &scan_info);
0206         priv->scan_request = NULL;
0207     }
0208 }
0209 
0210 struct virt_wifi_netdev_priv {
0211     struct delayed_work connect;
0212     struct net_device *lowerdev;
0213     struct net_device *upperdev;
0214     u32 tx_packets;
0215     u32 tx_failed;
0216     u8 connect_requested_bss[ETH_ALEN];
0217     bool is_up;
0218     bool is_connected;
0219     bool being_deleted;
0220 };
0221 
0222 /* Called with the rtnl lock held. */
0223 static int virt_wifi_connect(struct wiphy *wiphy, struct net_device *netdev,
0224                  struct cfg80211_connect_params *sme)
0225 {
0226     struct virt_wifi_netdev_priv *priv = netdev_priv(netdev);
0227     bool could_schedule;
0228 
0229     if (priv->being_deleted || !priv->is_up)
0230         return -EBUSY;
0231 
0232     could_schedule = schedule_delayed_work(&priv->connect, HZ * 2);
0233     if (!could_schedule)
0234         return -EBUSY;
0235 
0236     if (sme->bssid) {
0237         ether_addr_copy(priv->connect_requested_bss, sme->bssid);
0238     } else {
0239         virt_wifi_inform_bss(wiphy);
0240         eth_zero_addr(priv->connect_requested_bss);
0241     }
0242 
0243     wiphy_debug(wiphy, "connect\n");
0244 
0245     return 0;
0246 }
0247 
0248 /* Acquires and releases the rdev event lock. */
0249 static void virt_wifi_connect_complete(struct work_struct *work)
0250 {
0251     struct virt_wifi_netdev_priv *priv =
0252         container_of(work, struct virt_wifi_netdev_priv, connect.work);
0253     u8 *requested_bss = priv->connect_requested_bss;
0254     bool right_addr = ether_addr_equal(requested_bss, fake_router_bssid);
0255     u16 status = WLAN_STATUS_SUCCESS;
0256 
0257     if (is_zero_ether_addr(requested_bss))
0258         requested_bss = NULL;
0259 
0260     if (!priv->is_up || (requested_bss && !right_addr))
0261         status = WLAN_STATUS_UNSPECIFIED_FAILURE;
0262     else
0263         priv->is_connected = true;
0264 
0265     /* Schedules an event that acquires the rtnl lock. */
0266     cfg80211_connect_result(priv->upperdev, requested_bss, NULL, 0, NULL, 0,
0267                 status, GFP_KERNEL);
0268     netif_carrier_on(priv->upperdev);
0269 }
0270 
0271 /* May acquire and release the rdev event lock. */
0272 static void virt_wifi_cancel_connect(struct net_device *netdev)
0273 {
0274     struct virt_wifi_netdev_priv *priv = netdev_priv(netdev);
0275 
0276     /* If there is work pending, clean up dangling callbacks. */
0277     if (cancel_delayed_work_sync(&priv->connect)) {
0278         /* Schedules an event that acquires the rtnl lock. */
0279         cfg80211_connect_result(priv->upperdev,
0280                     priv->connect_requested_bss, NULL, 0,
0281                     NULL, 0,
0282                     WLAN_STATUS_UNSPECIFIED_FAILURE,
0283                     GFP_KERNEL);
0284     }
0285 }
0286 
0287 /* Called with the rtnl lock held. Acquires the rdev event lock. */
0288 static int virt_wifi_disconnect(struct wiphy *wiphy, struct net_device *netdev,
0289                 u16 reason_code)
0290 {
0291     struct virt_wifi_netdev_priv *priv = netdev_priv(netdev);
0292 
0293     if (priv->being_deleted)
0294         return -EBUSY;
0295 
0296     wiphy_debug(wiphy, "disconnect\n");
0297     virt_wifi_cancel_connect(netdev);
0298 
0299     cfg80211_disconnected(netdev, reason_code, NULL, 0, true, GFP_KERNEL);
0300     priv->is_connected = false;
0301     netif_carrier_off(netdev);
0302 
0303     return 0;
0304 }
0305 
0306 /* Called with the rtnl lock held. */
0307 static int virt_wifi_get_station(struct wiphy *wiphy, struct net_device *dev,
0308                  const u8 *mac, struct station_info *sinfo)
0309 {
0310     struct virt_wifi_netdev_priv *priv = netdev_priv(dev);
0311 
0312     wiphy_debug(wiphy, "get_station\n");
0313 
0314     if (!priv->is_connected || !ether_addr_equal(mac, fake_router_bssid))
0315         return -ENOENT;
0316 
0317     sinfo->filled = BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
0318         BIT_ULL(NL80211_STA_INFO_TX_FAILED) |
0319         BIT_ULL(NL80211_STA_INFO_SIGNAL) |
0320         BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
0321     sinfo->tx_packets = priv->tx_packets;
0322     sinfo->tx_failed = priv->tx_failed;
0323     /* For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_ */
0324     sinfo->signal = -50;
0325     sinfo->txrate = (struct rate_info) {
0326         .legacy = 10, /* units are 100kbit/s */
0327     };
0328     return 0;
0329 }
0330 
0331 /* Called with the rtnl lock held. */
0332 static int virt_wifi_dump_station(struct wiphy *wiphy, struct net_device *dev,
0333                   int idx, u8 *mac, struct station_info *sinfo)
0334 {
0335     struct virt_wifi_netdev_priv *priv = netdev_priv(dev);
0336 
0337     wiphy_debug(wiphy, "dump_station\n");
0338 
0339     if (idx != 0 || !priv->is_connected)
0340         return -ENOENT;
0341 
0342     ether_addr_copy(mac, fake_router_bssid);
0343     return virt_wifi_get_station(wiphy, dev, fake_router_bssid, sinfo);
0344 }
0345 
0346 static const struct cfg80211_ops virt_wifi_cfg80211_ops = {
0347     .scan = virt_wifi_scan,
0348 
0349     .connect = virt_wifi_connect,
0350     .disconnect = virt_wifi_disconnect,
0351 
0352     .get_station = virt_wifi_get_station,
0353     .dump_station = virt_wifi_dump_station,
0354 };
0355 
0356 /* Acquires and releases the rtnl lock. */
0357 static struct wiphy *virt_wifi_make_wiphy(void)
0358 {
0359     struct wiphy *wiphy;
0360     struct virt_wifi_wiphy_priv *priv;
0361     int err;
0362 
0363     wiphy = wiphy_new(&virt_wifi_cfg80211_ops, sizeof(*priv));
0364 
0365     if (!wiphy)
0366         return NULL;
0367 
0368     wiphy->max_scan_ssids = 4;
0369     wiphy->max_scan_ie_len = 1000;
0370     wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
0371 
0372     wiphy->bands[NL80211_BAND_2GHZ] = &band_2ghz;
0373     wiphy->bands[NL80211_BAND_5GHZ] = &band_5ghz;
0374     wiphy->bands[NL80211_BAND_60GHZ] = NULL;
0375 
0376     wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
0377 
0378     priv = wiphy_priv(wiphy);
0379     priv->being_deleted = false;
0380     priv->scan_request = NULL;
0381     INIT_DELAYED_WORK(&priv->scan_result, virt_wifi_scan_result);
0382 
0383     err = wiphy_register(wiphy);
0384     if (err < 0) {
0385         wiphy_free(wiphy);
0386         return NULL;
0387     }
0388 
0389     return wiphy;
0390 }
0391 
0392 /* Acquires and releases the rtnl lock. */
0393 static void virt_wifi_destroy_wiphy(struct wiphy *wiphy)
0394 {
0395     struct virt_wifi_wiphy_priv *priv;
0396 
0397     WARN(!wiphy, "%s called with null wiphy", __func__);
0398     if (!wiphy)
0399         return;
0400 
0401     priv = wiphy_priv(wiphy);
0402     priv->being_deleted = true;
0403     virt_wifi_cancel_scan(wiphy);
0404 
0405     if (wiphy->registered)
0406         wiphy_unregister(wiphy);
0407     wiphy_free(wiphy);
0408 }
0409 
0410 /* Enters and exits a RCU-bh critical section. */
0411 static netdev_tx_t virt_wifi_start_xmit(struct sk_buff *skb,
0412                     struct net_device *dev)
0413 {
0414     struct virt_wifi_netdev_priv *priv = netdev_priv(dev);
0415 
0416     priv->tx_packets++;
0417     if (!priv->is_connected) {
0418         priv->tx_failed++;
0419         return NET_XMIT_DROP;
0420     }
0421 
0422     skb->dev = priv->lowerdev;
0423     return dev_queue_xmit(skb);
0424 }
0425 
0426 /* Called with rtnl lock held. */
0427 static int virt_wifi_net_device_open(struct net_device *dev)
0428 {
0429     struct virt_wifi_netdev_priv *priv = netdev_priv(dev);
0430 
0431     priv->is_up = true;
0432     return 0;
0433 }
0434 
0435 /* Called with rtnl lock held. */
0436 static int virt_wifi_net_device_stop(struct net_device *dev)
0437 {
0438     struct virt_wifi_netdev_priv *n_priv = netdev_priv(dev);
0439 
0440     n_priv->is_up = false;
0441 
0442     if (!dev->ieee80211_ptr)
0443         return 0;
0444 
0445     virt_wifi_cancel_scan(dev->ieee80211_ptr->wiphy);
0446     virt_wifi_cancel_connect(dev);
0447     netif_carrier_off(dev);
0448 
0449     return 0;
0450 }
0451 
0452 static int virt_wifi_net_device_get_iflink(const struct net_device *dev)
0453 {
0454     struct virt_wifi_netdev_priv *priv = netdev_priv(dev);
0455 
0456     return priv->lowerdev->ifindex;
0457 }
0458 
0459 static const struct net_device_ops virt_wifi_ops = {
0460     .ndo_start_xmit = virt_wifi_start_xmit,
0461     .ndo_open   = virt_wifi_net_device_open,
0462     .ndo_stop   = virt_wifi_net_device_stop,
0463     .ndo_get_iflink = virt_wifi_net_device_get_iflink,
0464 };
0465 
0466 /* Invoked as part of rtnl lock release. */
0467 static void virt_wifi_net_device_destructor(struct net_device *dev)
0468 {
0469     /* Delayed past dellink to allow nl80211 to react to the device being
0470      * deleted.
0471      */
0472     kfree(dev->ieee80211_ptr);
0473     dev->ieee80211_ptr = NULL;
0474 }
0475 
0476 /* No lock interaction. */
0477 static void virt_wifi_setup(struct net_device *dev)
0478 {
0479     ether_setup(dev);
0480     dev->netdev_ops = &virt_wifi_ops;
0481     dev->needs_free_netdev  = true;
0482 }
0483 
0484 /* Called in a RCU read critical section from netif_receive_skb */
0485 static rx_handler_result_t virt_wifi_rx_handler(struct sk_buff **pskb)
0486 {
0487     struct sk_buff *skb = *pskb;
0488     struct virt_wifi_netdev_priv *priv =
0489         rcu_dereference(skb->dev->rx_handler_data);
0490 
0491     if (!priv->is_connected)
0492         return RX_HANDLER_PASS;
0493 
0494     /* GFP_ATOMIC because this is a packet interrupt handler. */
0495     skb = skb_share_check(skb, GFP_ATOMIC);
0496     if (!skb) {
0497         dev_err(&priv->upperdev->dev, "can't skb_share_check\n");
0498         return RX_HANDLER_CONSUMED;
0499     }
0500 
0501     *pskb = skb;
0502     skb->dev = priv->upperdev;
0503     skb->pkt_type = PACKET_HOST;
0504     return RX_HANDLER_ANOTHER;
0505 }
0506 
0507 /* Called with rtnl lock held. */
0508 static int virt_wifi_newlink(struct net *src_net, struct net_device *dev,
0509                  struct nlattr *tb[], struct nlattr *data[],
0510                  struct netlink_ext_ack *extack)
0511 {
0512     struct virt_wifi_netdev_priv *priv = netdev_priv(dev);
0513     int err;
0514 
0515     if (!tb[IFLA_LINK])
0516         return -EINVAL;
0517 
0518     netif_carrier_off(dev);
0519 
0520     priv->upperdev = dev;
0521     priv->lowerdev = __dev_get_by_index(src_net,
0522                         nla_get_u32(tb[IFLA_LINK]));
0523 
0524     if (!priv->lowerdev)
0525         return -ENODEV;
0526     if (!tb[IFLA_MTU])
0527         dev->mtu = priv->lowerdev->mtu;
0528     else if (dev->mtu > priv->lowerdev->mtu)
0529         return -EINVAL;
0530 
0531     err = netdev_rx_handler_register(priv->lowerdev, virt_wifi_rx_handler,
0532                      priv);
0533     if (err) {
0534         dev_err(&priv->lowerdev->dev,
0535             "can't netdev_rx_handler_register: %d\n", err);
0536         return err;
0537     }
0538 
0539     eth_hw_addr_inherit(dev, priv->lowerdev);
0540     netif_stacked_transfer_operstate(priv->lowerdev, dev);
0541 
0542     SET_NETDEV_DEV(dev, &priv->lowerdev->dev);
0543     dev->ieee80211_ptr = kzalloc(sizeof(*dev->ieee80211_ptr), GFP_KERNEL);
0544 
0545     if (!dev->ieee80211_ptr) {
0546         err = -ENOMEM;
0547         goto remove_handler;
0548     }
0549 
0550     dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION;
0551     dev->ieee80211_ptr->wiphy = common_wiphy;
0552 
0553     err = register_netdevice(dev);
0554     if (err) {
0555         dev_err(&priv->lowerdev->dev, "can't register_netdevice: %d\n",
0556             err);
0557         goto free_wireless_dev;
0558     }
0559 
0560     err = netdev_upper_dev_link(priv->lowerdev, dev, extack);
0561     if (err) {
0562         dev_err(&priv->lowerdev->dev, "can't netdev_upper_dev_link: %d\n",
0563             err);
0564         goto unregister_netdev;
0565     }
0566 
0567     dev->priv_destructor = virt_wifi_net_device_destructor;
0568     priv->being_deleted = false;
0569     priv->is_connected = false;
0570     priv->is_up = false;
0571     INIT_DELAYED_WORK(&priv->connect, virt_wifi_connect_complete);
0572     __module_get(THIS_MODULE);
0573 
0574     return 0;
0575 unregister_netdev:
0576     unregister_netdevice(dev);
0577 free_wireless_dev:
0578     kfree(dev->ieee80211_ptr);
0579     dev->ieee80211_ptr = NULL;
0580 remove_handler:
0581     netdev_rx_handler_unregister(priv->lowerdev);
0582 
0583     return err;
0584 }
0585 
0586 /* Called with rtnl lock held. */
0587 static void virt_wifi_dellink(struct net_device *dev,
0588                   struct list_head *head)
0589 {
0590     struct virt_wifi_netdev_priv *priv = netdev_priv(dev);
0591 
0592     if (dev->ieee80211_ptr)
0593         virt_wifi_cancel_scan(dev->ieee80211_ptr->wiphy);
0594 
0595     priv->being_deleted = true;
0596     virt_wifi_cancel_connect(dev);
0597     netif_carrier_off(dev);
0598 
0599     netdev_rx_handler_unregister(priv->lowerdev);
0600     netdev_upper_dev_unlink(priv->lowerdev, dev);
0601 
0602     unregister_netdevice_queue(dev, head);
0603     module_put(THIS_MODULE);
0604 
0605     /* Deleting the wiphy is handled in the module destructor. */
0606 }
0607 
0608 static struct rtnl_link_ops virt_wifi_link_ops = {
0609     .kind       = "virt_wifi",
0610     .setup      = virt_wifi_setup,
0611     .newlink    = virt_wifi_newlink,
0612     .dellink    = virt_wifi_dellink,
0613     .priv_size  = sizeof(struct virt_wifi_netdev_priv),
0614 };
0615 
0616 static bool netif_is_virt_wifi_dev(const struct net_device *dev)
0617 {
0618     return rcu_access_pointer(dev->rx_handler) == virt_wifi_rx_handler;
0619 }
0620 
0621 static int virt_wifi_event(struct notifier_block *this, unsigned long event,
0622                void *ptr)
0623 {
0624     struct net_device *lower_dev = netdev_notifier_info_to_dev(ptr);
0625     struct virt_wifi_netdev_priv *priv;
0626     struct net_device *upper_dev;
0627     LIST_HEAD(list_kill);
0628 
0629     if (!netif_is_virt_wifi_dev(lower_dev))
0630         return NOTIFY_DONE;
0631 
0632     switch (event) {
0633     case NETDEV_UNREGISTER:
0634         priv = rtnl_dereference(lower_dev->rx_handler_data);
0635         if (!priv)
0636             return NOTIFY_DONE;
0637 
0638         upper_dev = priv->upperdev;
0639 
0640         upper_dev->rtnl_link_ops->dellink(upper_dev, &list_kill);
0641         unregister_netdevice_many(&list_kill);
0642         break;
0643     }
0644 
0645     return NOTIFY_DONE;
0646 }
0647 
0648 static struct notifier_block virt_wifi_notifier = {
0649     .notifier_call = virt_wifi_event,
0650 };
0651 
0652 /* Acquires and releases the rtnl lock. */
0653 static int __init virt_wifi_init_module(void)
0654 {
0655     int err;
0656 
0657     /* Guaranteed to be locally-administered and not multicast. */
0658     eth_random_addr(fake_router_bssid);
0659 
0660     err = register_netdevice_notifier(&virt_wifi_notifier);
0661     if (err)
0662         return err;
0663 
0664     err = -ENOMEM;
0665     common_wiphy = virt_wifi_make_wiphy();
0666     if (!common_wiphy)
0667         goto notifier;
0668 
0669     err = rtnl_link_register(&virt_wifi_link_ops);
0670     if (err)
0671         goto destroy_wiphy;
0672 
0673     return 0;
0674 
0675 destroy_wiphy:
0676     virt_wifi_destroy_wiphy(common_wiphy);
0677 notifier:
0678     unregister_netdevice_notifier(&virt_wifi_notifier);
0679     return err;
0680 }
0681 
0682 /* Acquires and releases the rtnl lock. */
0683 static void __exit virt_wifi_cleanup_module(void)
0684 {
0685     /* Will delete any devices that depend on the wiphy. */
0686     rtnl_link_unregister(&virt_wifi_link_ops);
0687     virt_wifi_destroy_wiphy(common_wiphy);
0688     unregister_netdevice_notifier(&virt_wifi_notifier);
0689 }
0690 
0691 module_init(virt_wifi_init_module);
0692 module_exit(virt_wifi_cleanup_module);
0693 
0694 MODULE_LICENSE("GPL v2");
0695 MODULE_AUTHOR("Cody Schuffelen <schuffelen@google.com>");
0696 MODULE_DESCRIPTION("Driver for a wireless wrapper of ethernet devices");
0697 MODULE_ALIAS_RTNL_LINK("virt_wifi");