1 // SPDX-License-Identifier: GPL-2.0 2 /* drivers/net/wireless/virt_wifi.c 3 * 4 * A fake implementation of cfg80211_ops that can be tacked on to an ethernet 5 * net_device to make it appear as a wireless connection. 6 * 7 * Copyright (C) 2018 Google, Inc. 8 * 9 * Author: schuffelen@google.com 10 */ 11 12 #include <net/cfg80211.h> 13 #include <net/rtnetlink.h> 14 #include <linux/etherdevice.h> 15 #include <linux/math64.h> 16 #include <linux/module.h> 17 18 static struct wiphy *common_wiphy; 19 20 struct virt_wifi_wiphy_priv { 21 struct delayed_work scan_result; 22 struct cfg80211_scan_request *scan_request; 23 bool being_deleted; 24 }; 25 26 static struct ieee80211_channel channel_2ghz = { 27 .band = NL80211_BAND_2GHZ, 28 .center_freq = 2432, 29 .hw_value = 2432, 30 .max_power = 20, 31 }; 32 33 static struct ieee80211_rate bitrates_2ghz[] = { 34 { .bitrate = 10 }, 35 { .bitrate = 20 }, 36 { .bitrate = 55 }, 37 { .bitrate = 110 }, 38 { .bitrate = 60 }, 39 { .bitrate = 120 }, 40 { .bitrate = 240 }, 41 }; 42 43 static struct ieee80211_supported_band band_2ghz = { 44 .channels = &channel_2ghz, 45 .bitrates = bitrates_2ghz, 46 .band = NL80211_BAND_2GHZ, 47 .n_channels = 1, 48 .n_bitrates = ARRAY_SIZE(bitrates_2ghz), 49 .ht_cap = { 50 .ht_supported = true, 51 .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 52 IEEE80211_HT_CAP_GRN_FLD | 53 IEEE80211_HT_CAP_SGI_20 | 54 IEEE80211_HT_CAP_SGI_40 | 55 IEEE80211_HT_CAP_DSSSCCK40, 56 .ampdu_factor = 0x3, 57 .ampdu_density = 0x6, 58 .mcs = { 59 .rx_mask = {0xff, 0xff}, 60 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, 61 }, 62 }, 63 }; 64 65 static struct ieee80211_channel channel_5ghz = { 66 .band = NL80211_BAND_5GHZ, 67 .center_freq = 5240, 68 .hw_value = 5240, 69 .max_power = 20, 70 }; 71 72 static struct ieee80211_rate bitrates_5ghz[] = { 73 { .bitrate = 60 }, 74 { .bitrate = 120 }, 75 { .bitrate = 240 }, 76 }; 77 78 #define RX_MCS_MAP (IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | \ 79 IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | \ 80 IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 | \ 81 IEEE80211_VHT_MCS_SUPPORT_0_9 << 6 | \ 82 IEEE80211_VHT_MCS_SUPPORT_0_9 << 8 | \ 83 IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 | \ 84 IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 | \ 85 IEEE80211_VHT_MCS_SUPPORT_0_9 << 14) 86 87 #define TX_MCS_MAP (IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | \ 88 IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | \ 89 IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 | \ 90 IEEE80211_VHT_MCS_SUPPORT_0_9 << 6 | \ 91 IEEE80211_VHT_MCS_SUPPORT_0_9 << 8 | \ 92 IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 | \ 93 IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 | \ 94 IEEE80211_VHT_MCS_SUPPORT_0_9 << 14) 95 96 static struct ieee80211_supported_band band_5ghz = { 97 .channels = &channel_5ghz, 98 .bitrates = bitrates_5ghz, 99 .band = NL80211_BAND_5GHZ, 100 .n_channels = 1, 101 .n_bitrates = ARRAY_SIZE(bitrates_5ghz), 102 .ht_cap = { 103 .ht_supported = true, 104 .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 105 IEEE80211_HT_CAP_GRN_FLD | 106 IEEE80211_HT_CAP_SGI_20 | 107 IEEE80211_HT_CAP_SGI_40 | 108 IEEE80211_HT_CAP_DSSSCCK40, 109 .ampdu_factor = 0x3, 110 .ampdu_density = 0x6, 111 .mcs = { 112 .rx_mask = {0xff, 0xff}, 113 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, 114 }, 115 }, 116 .vht_cap = { 117 .vht_supported = true, 118 .cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | 119 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ | 120 IEEE80211_VHT_CAP_RXLDPC | 121 IEEE80211_VHT_CAP_SHORT_GI_80 | 122 IEEE80211_VHT_CAP_SHORT_GI_160 | 123 IEEE80211_VHT_CAP_TXSTBC | 124 IEEE80211_VHT_CAP_RXSTBC_1 | 125 IEEE80211_VHT_CAP_RXSTBC_2 | 126 IEEE80211_VHT_CAP_RXSTBC_3 | 127 IEEE80211_VHT_CAP_RXSTBC_4 | 128 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK, 129 .vht_mcs = { 130 .rx_mcs_map = cpu_to_le16(RX_MCS_MAP), 131 .tx_mcs_map = cpu_to_le16(TX_MCS_MAP), 132 } 133 }, 134 }; 135 136 /* Assigned at module init. Guaranteed locally-administered and unicast. */ 137 static u8 fake_router_bssid[ETH_ALEN] __ro_after_init = {}; 138 139 #define VIRT_WIFI_SSID "VirtWifi" 140 #define VIRT_WIFI_SSID_LEN 8 141 142 static void virt_wifi_inform_bss(struct wiphy *wiphy) 143 { 144 u64 tsf = div_u64(ktime_get_boottime_ns(), 1000); 145 struct cfg80211_bss *informed_bss; 146 static const struct { 147 u8 tag; 148 u8 len; 149 u8 ssid[8] __nonstring; 150 } __packed ssid = { 151 .tag = WLAN_EID_SSID, 152 .len = VIRT_WIFI_SSID_LEN, 153 .ssid = VIRT_WIFI_SSID, 154 }; 155 156 informed_bss = cfg80211_inform_bss(wiphy, &channel_5ghz, 157 CFG80211_BSS_FTYPE_PRESP, 158 fake_router_bssid, tsf, 159 WLAN_CAPABILITY_ESS, 0, 160 (void *)&ssid, sizeof(ssid), 161 DBM_TO_MBM(-50), GFP_KERNEL); 162 cfg80211_put_bss(wiphy, informed_bss); 163 } 164 165 /* Called with the rtnl lock held. */ 166 static int virt_wifi_scan(struct wiphy *wiphy, 167 struct cfg80211_scan_request *request) 168 { 169 struct virt_wifi_wiphy_priv *priv = wiphy_priv(wiphy); 170 171 wiphy_debug(wiphy, "scan\n"); 172 173 if (priv->scan_request || priv->being_deleted) 174 return -EBUSY; 175 176 priv->scan_request = request; 177 schedule_delayed_work(&priv->scan_result, HZ * 2); 178 179 return 0; 180 } 181 182 /* Acquires and releases the rdev BSS lock. */ 183 static void virt_wifi_scan_result(struct work_struct *work) 184 { 185 struct virt_wifi_wiphy_priv *priv = 186 container_of(work, struct virt_wifi_wiphy_priv, 187 scan_result.work); 188 struct wiphy *wiphy = priv_to_wiphy(priv); 189 struct cfg80211_scan_info scan_info = { .aborted = false }; 190 191 virt_wifi_inform_bss(wiphy); 192 193 /* Schedules work which acquires and releases the rtnl lock. */ 194 cfg80211_scan_done(priv->scan_request, &scan_info); 195 priv->scan_request = NULL; 196 } 197 198 /* May acquire and release the rdev BSS lock. */ 199 static void virt_wifi_cancel_scan(struct wiphy *wiphy) 200 { 201 struct virt_wifi_wiphy_priv *priv = wiphy_priv(wiphy); 202 203 cancel_delayed_work_sync(&priv->scan_result); 204 /* Clean up dangling callbacks if necessary. */ 205 if (priv->scan_request) { 206 struct cfg80211_scan_info scan_info = { .aborted = true }; 207 /* Schedules work which acquires and releases the rtnl lock. */ 208 cfg80211_scan_done(priv->scan_request, &scan_info); 209 priv->scan_request = NULL; 210 } 211 } 212 213 struct virt_wifi_netdev_priv { 214 struct delayed_work connect; 215 struct net_device *lowerdev; 216 struct net_device *upperdev; 217 u32 tx_packets; 218 u32 tx_failed; 219 u32 connect_requested_ssid_len; 220 u8 connect_requested_ssid[IEEE80211_MAX_SSID_LEN]; 221 u8 connect_requested_bss[ETH_ALEN]; 222 bool is_up; 223 bool is_connected; 224 bool being_deleted; 225 }; 226 227 /* Called with the rtnl lock held. */ 228 static int virt_wifi_connect(struct wiphy *wiphy, struct net_device *netdev, 229 struct cfg80211_connect_params *sme) 230 { 231 struct virt_wifi_netdev_priv *priv = netdev_priv(netdev); 232 bool could_schedule; 233 234 if (priv->being_deleted || !priv->is_up) 235 return -EBUSY; 236 237 if (!sme->ssid) 238 return -EINVAL; 239 240 priv->connect_requested_ssid_len = sme->ssid_len; 241 memcpy(priv->connect_requested_ssid, sme->ssid, sme->ssid_len); 242 243 could_schedule = schedule_delayed_work(&priv->connect, HZ * 2); 244 if (!could_schedule) 245 return -EBUSY; 246 247 if (sme->bssid) { 248 ether_addr_copy(priv->connect_requested_bss, sme->bssid); 249 } else { 250 virt_wifi_inform_bss(wiphy); 251 eth_zero_addr(priv->connect_requested_bss); 252 } 253 254 wiphy_debug(wiphy, "connect\n"); 255 256 return 0; 257 } 258 259 /* Acquires and releases the rdev event lock. */ 260 static void virt_wifi_connect_complete(struct work_struct *work) 261 { 262 struct virt_wifi_netdev_priv *priv = 263 container_of(work, struct virt_wifi_netdev_priv, connect.work); 264 u8 *requested_bss = priv->connect_requested_bss; 265 bool right_addr = ether_addr_equal(requested_bss, fake_router_bssid); 266 bool right_ssid = priv->connect_requested_ssid_len == VIRT_WIFI_SSID_LEN && 267 !memcmp(priv->connect_requested_ssid, VIRT_WIFI_SSID, 268 priv->connect_requested_ssid_len); 269 u16 status = WLAN_STATUS_SUCCESS; 270 271 if (is_zero_ether_addr(requested_bss)) 272 requested_bss = NULL; 273 274 if (!priv->is_up || (requested_bss && !right_addr) || !right_ssid) 275 status = WLAN_STATUS_UNSPECIFIED_FAILURE; 276 else 277 priv->is_connected = true; 278 279 /* Schedules an event that acquires the rtnl lock. */ 280 cfg80211_connect_result(priv->upperdev, 281 priv->is_connected ? fake_router_bssid : NULL, 282 NULL, 0, NULL, 0, 283 status, GFP_KERNEL); 284 netif_carrier_on(priv->upperdev); 285 } 286 287 /* May acquire and release the rdev event lock. */ 288 static void virt_wifi_cancel_connect(struct net_device *netdev) 289 { 290 struct virt_wifi_netdev_priv *priv = netdev_priv(netdev); 291 292 /* If there is work pending, clean up dangling callbacks. */ 293 if (cancel_delayed_work_sync(&priv->connect)) { 294 /* Schedules an event that acquires the rtnl lock. */ 295 cfg80211_connect_result(priv->upperdev, 296 priv->connect_requested_bss, NULL, 0, 297 NULL, 0, 298 WLAN_STATUS_UNSPECIFIED_FAILURE, 299 GFP_KERNEL); 300 } 301 } 302 303 /* Called with the rtnl lock held. Acquires the rdev event lock. */ 304 static int virt_wifi_disconnect(struct wiphy *wiphy, struct net_device *netdev, 305 u16 reason_code) 306 { 307 struct virt_wifi_netdev_priv *priv = netdev_priv(netdev); 308 309 if (priv->being_deleted) 310 return -EBUSY; 311 312 wiphy_debug(wiphy, "disconnect\n"); 313 virt_wifi_cancel_connect(netdev); 314 315 cfg80211_disconnected(netdev, reason_code, NULL, 0, true, GFP_KERNEL); 316 priv->is_connected = false; 317 netif_carrier_off(netdev); 318 319 return 0; 320 } 321 322 /* Called with the rtnl lock held. */ 323 static int virt_wifi_get_station(struct wiphy *wiphy, struct net_device *dev, 324 const u8 *mac, struct station_info *sinfo) 325 { 326 struct virt_wifi_netdev_priv *priv = netdev_priv(dev); 327 328 wiphy_debug(wiphy, "get_station\n"); 329 330 if (!priv->is_connected || !ether_addr_equal(mac, fake_router_bssid)) 331 return -ENOENT; 332 333 sinfo->filled = BIT_ULL(NL80211_STA_INFO_TX_PACKETS) | 334 BIT_ULL(NL80211_STA_INFO_TX_FAILED) | 335 BIT_ULL(NL80211_STA_INFO_SIGNAL) | 336 BIT_ULL(NL80211_STA_INFO_TX_BITRATE); 337 sinfo->tx_packets = priv->tx_packets; 338 sinfo->tx_failed = priv->tx_failed; 339 /* For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_ */ 340 sinfo->signal = -50; 341 sinfo->txrate = (struct rate_info) { 342 .legacy = 10, /* units are 100kbit/s */ 343 }; 344 return 0; 345 } 346 347 /* Called with the rtnl lock held. */ 348 static int virt_wifi_dump_station(struct wiphy *wiphy, struct net_device *dev, 349 int idx, u8 *mac, struct station_info *sinfo) 350 { 351 struct virt_wifi_netdev_priv *priv = netdev_priv(dev); 352 353 wiphy_debug(wiphy, "dump_station\n"); 354 355 if (idx != 0 || !priv->is_connected) 356 return -ENOENT; 357 358 ether_addr_copy(mac, fake_router_bssid); 359 return virt_wifi_get_station(wiphy, dev, fake_router_bssid, sinfo); 360 } 361 362 static const struct cfg80211_ops virt_wifi_cfg80211_ops = { 363 .scan = virt_wifi_scan, 364 365 .connect = virt_wifi_connect, 366 .disconnect = virt_wifi_disconnect, 367 368 .get_station = virt_wifi_get_station, 369 .dump_station = virt_wifi_dump_station, 370 }; 371 372 /* Acquires and releases the rtnl lock. */ 373 static struct wiphy *virt_wifi_make_wiphy(void) 374 { 375 struct wiphy *wiphy; 376 struct virt_wifi_wiphy_priv *priv; 377 int err; 378 379 wiphy = wiphy_new(&virt_wifi_cfg80211_ops, sizeof(*priv)); 380 381 if (!wiphy) 382 return NULL; 383 384 wiphy->max_scan_ssids = 4; 385 wiphy->max_scan_ie_len = 1000; 386 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 387 388 wiphy->bands[NL80211_BAND_2GHZ] = &band_2ghz; 389 wiphy->bands[NL80211_BAND_5GHZ] = &band_5ghz; 390 wiphy->bands[NL80211_BAND_60GHZ] = NULL; 391 392 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); 393 394 priv = wiphy_priv(wiphy); 395 priv->being_deleted = false; 396 priv->scan_request = NULL; 397 INIT_DELAYED_WORK(&priv->scan_result, virt_wifi_scan_result); 398 399 err = wiphy_register(wiphy); 400 if (err < 0) { 401 wiphy_free(wiphy); 402 return NULL; 403 } 404 405 return wiphy; 406 } 407 408 /* Acquires and releases the rtnl lock. */ 409 static void virt_wifi_destroy_wiphy(struct wiphy *wiphy) 410 { 411 struct virt_wifi_wiphy_priv *priv; 412 413 WARN(!wiphy, "%s called with null wiphy", __func__); 414 if (!wiphy) 415 return; 416 417 priv = wiphy_priv(wiphy); 418 priv->being_deleted = true; 419 virt_wifi_cancel_scan(wiphy); 420 421 if (wiphy->registered) 422 wiphy_unregister(wiphy); 423 wiphy_free(wiphy); 424 } 425 426 /* Enters and exits a RCU-bh critical section. */ 427 static netdev_tx_t virt_wifi_start_xmit(struct sk_buff *skb, 428 struct net_device *dev) 429 { 430 struct virt_wifi_netdev_priv *priv = netdev_priv(dev); 431 432 priv->tx_packets++; 433 if (!priv->is_connected) { 434 priv->tx_failed++; 435 return NET_XMIT_DROP; 436 } 437 438 skb->dev = priv->lowerdev; 439 return dev_queue_xmit(skb); 440 } 441 442 /* Called with rtnl lock held. */ 443 static int virt_wifi_net_device_open(struct net_device *dev) 444 { 445 struct virt_wifi_netdev_priv *priv = netdev_priv(dev); 446 447 priv->is_up = true; 448 return 0; 449 } 450 451 /* Called with rtnl lock held. */ 452 static int virt_wifi_net_device_stop(struct net_device *dev) 453 { 454 struct virt_wifi_netdev_priv *n_priv = netdev_priv(dev); 455 456 n_priv->is_up = false; 457 458 if (!dev->ieee80211_ptr) 459 return 0; 460 461 virt_wifi_cancel_scan(dev->ieee80211_ptr->wiphy); 462 virt_wifi_cancel_connect(dev); 463 netif_carrier_off(dev); 464 465 return 0; 466 } 467 468 static int virt_wifi_net_device_get_iflink(const struct net_device *dev) 469 { 470 struct virt_wifi_netdev_priv *priv = netdev_priv(dev); 471 472 return READ_ONCE(priv->lowerdev->ifindex); 473 } 474 475 static const struct net_device_ops virt_wifi_ops = { 476 .ndo_start_xmit = virt_wifi_start_xmit, 477 .ndo_open = virt_wifi_net_device_open, 478 .ndo_stop = virt_wifi_net_device_stop, 479 .ndo_get_iflink = virt_wifi_net_device_get_iflink, 480 }; 481 482 /* Invoked as part of rtnl lock release. */ 483 static void virt_wifi_net_device_destructor(struct net_device *dev) 484 { 485 /* Delayed past dellink to allow nl80211 to react to the device being 486 * deleted. 487 */ 488 kfree(dev->ieee80211_ptr); 489 dev->ieee80211_ptr = NULL; 490 } 491 492 /* No lock interaction. */ 493 static void virt_wifi_setup(struct net_device *dev) 494 { 495 ether_setup(dev); 496 dev->netdev_ops = &virt_wifi_ops; 497 dev->needs_free_netdev = true; 498 } 499 500 /* Called in a RCU read critical section from netif_receive_skb */ 501 static rx_handler_result_t virt_wifi_rx_handler(struct sk_buff **pskb) 502 { 503 struct sk_buff *skb = *pskb; 504 struct virt_wifi_netdev_priv *priv = 505 rcu_dereference(skb->dev->rx_handler_data); 506 507 if (!priv->is_connected) 508 return RX_HANDLER_PASS; 509 510 /* GFP_ATOMIC because this is a packet interrupt handler. */ 511 skb = skb_share_check(skb, GFP_ATOMIC); 512 if (!skb) { 513 dev_err(&priv->upperdev->dev, "can't skb_share_check\n"); 514 return RX_HANDLER_CONSUMED; 515 } 516 517 *pskb = skb; 518 skb->dev = priv->upperdev; 519 skb->pkt_type = PACKET_HOST; 520 return RX_HANDLER_ANOTHER; 521 } 522 523 /* Called with rtnl lock held. */ 524 static int virt_wifi_newlink(struct net_device *dev, 525 struct rtnl_newlink_params *params, 526 struct netlink_ext_ack *extack) 527 { 528 struct virt_wifi_netdev_priv *priv = netdev_priv(dev); 529 struct net *link_net = rtnl_newlink_link_net(params); 530 struct nlattr **tb = params->tb; 531 int err; 532 533 if (!tb[IFLA_LINK]) 534 return -EINVAL; 535 536 netif_carrier_off(dev); 537 538 priv->upperdev = dev; 539 priv->lowerdev = __dev_get_by_index(link_net, 540 nla_get_u32(tb[IFLA_LINK])); 541 542 if (!priv->lowerdev) 543 return -ENODEV; 544 if (!tb[IFLA_MTU]) 545 dev->mtu = priv->lowerdev->mtu; 546 else if (dev->mtu > priv->lowerdev->mtu) 547 return -EINVAL; 548 549 err = netdev_rx_handler_register(priv->lowerdev, virt_wifi_rx_handler, 550 priv); 551 if (err) { 552 dev_err(&priv->lowerdev->dev, 553 "can't netdev_rx_handler_register: %d\n", err); 554 return err; 555 } 556 557 eth_hw_addr_inherit(dev, priv->lowerdev); 558 netif_stacked_transfer_operstate(priv->lowerdev, dev); 559 560 SET_NETDEV_DEV(dev, &priv->lowerdev->dev); 561 dev->ieee80211_ptr = kzalloc(sizeof(*dev->ieee80211_ptr), GFP_KERNEL); 562 563 if (!dev->ieee80211_ptr) { 564 err = -ENOMEM; 565 goto remove_handler; 566 } 567 568 dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; 569 dev->ieee80211_ptr->wiphy = common_wiphy; 570 571 err = register_netdevice(dev); 572 if (err) { 573 dev_err(&priv->lowerdev->dev, "can't register_netdevice: %d\n", 574 err); 575 goto free_wireless_dev; 576 } 577 578 err = netdev_upper_dev_link(priv->lowerdev, dev, extack); 579 if (err) { 580 dev_err(&priv->lowerdev->dev, "can't netdev_upper_dev_link: %d\n", 581 err); 582 goto unregister_netdev; 583 } 584 585 dev->priv_destructor = virt_wifi_net_device_destructor; 586 priv->being_deleted = false; 587 priv->is_connected = false; 588 priv->is_up = false; 589 INIT_DELAYED_WORK(&priv->connect, virt_wifi_connect_complete); 590 __module_get(THIS_MODULE); 591 592 return 0; 593 unregister_netdev: 594 unregister_netdevice(dev); 595 free_wireless_dev: 596 kfree(dev->ieee80211_ptr); 597 dev->ieee80211_ptr = NULL; 598 remove_handler: 599 netdev_rx_handler_unregister(priv->lowerdev); 600 601 return err; 602 } 603 604 /* Called with rtnl lock held. */ 605 static void virt_wifi_dellink(struct net_device *dev, 606 struct list_head *head) 607 { 608 struct virt_wifi_netdev_priv *priv = netdev_priv(dev); 609 610 if (dev->ieee80211_ptr) 611 virt_wifi_cancel_scan(dev->ieee80211_ptr->wiphy); 612 613 priv->being_deleted = true; 614 virt_wifi_cancel_connect(dev); 615 netif_carrier_off(dev); 616 617 netdev_rx_handler_unregister(priv->lowerdev); 618 netdev_upper_dev_unlink(priv->lowerdev, dev); 619 620 unregister_netdevice_queue(dev, head); 621 module_put(THIS_MODULE); 622 623 /* Deleting the wiphy is handled in the module destructor. */ 624 } 625 626 static struct rtnl_link_ops virt_wifi_link_ops = { 627 .kind = "virt_wifi", 628 .setup = virt_wifi_setup, 629 .newlink = virt_wifi_newlink, 630 .dellink = virt_wifi_dellink, 631 .priv_size = sizeof(struct virt_wifi_netdev_priv), 632 }; 633 634 static bool netif_is_virt_wifi_dev(const struct net_device *dev) 635 { 636 return rcu_access_pointer(dev->rx_handler) == virt_wifi_rx_handler; 637 } 638 639 static int virt_wifi_event(struct notifier_block *this, unsigned long event, 640 void *ptr) 641 { 642 struct net_device *lower_dev = netdev_notifier_info_to_dev(ptr); 643 struct virt_wifi_netdev_priv *priv; 644 struct net_device *upper_dev; 645 LIST_HEAD(list_kill); 646 647 if (!netif_is_virt_wifi_dev(lower_dev)) 648 return NOTIFY_DONE; 649 650 switch (event) { 651 case NETDEV_UNREGISTER: 652 priv = rtnl_dereference(lower_dev->rx_handler_data); 653 if (!priv) 654 return NOTIFY_DONE; 655 656 upper_dev = priv->upperdev; 657 658 upper_dev->rtnl_link_ops->dellink(upper_dev, &list_kill); 659 unregister_netdevice_many(&list_kill); 660 break; 661 } 662 663 return NOTIFY_DONE; 664 } 665 666 static struct notifier_block virt_wifi_notifier = { 667 .notifier_call = virt_wifi_event, 668 }; 669 670 /* Acquires and releases the rtnl lock. */ 671 static int __init virt_wifi_init_module(void) 672 { 673 int err; 674 675 /* Guaranteed to be locally-administered and not multicast. */ 676 eth_random_addr(fake_router_bssid); 677 678 err = register_netdevice_notifier(&virt_wifi_notifier); 679 if (err) 680 return err; 681 682 err = -ENOMEM; 683 common_wiphy = virt_wifi_make_wiphy(); 684 if (!common_wiphy) 685 goto notifier; 686 687 err = rtnl_link_register(&virt_wifi_link_ops); 688 if (err) 689 goto destroy_wiphy; 690 691 return 0; 692 693 destroy_wiphy: 694 virt_wifi_destroy_wiphy(common_wiphy); 695 notifier: 696 unregister_netdevice_notifier(&virt_wifi_notifier); 697 return err; 698 } 699 700 /* Acquires and releases the rtnl lock. */ 701 static void __exit virt_wifi_cleanup_module(void) 702 { 703 /* Will delete any devices that depend on the wiphy. */ 704 rtnl_link_unregister(&virt_wifi_link_ops); 705 virt_wifi_destroy_wiphy(common_wiphy); 706 unregister_netdevice_notifier(&virt_wifi_notifier); 707 } 708 709 module_init(virt_wifi_init_module); 710 module_exit(virt_wifi_cleanup_module); 711 712 MODULE_LICENSE("GPL v2"); 713 MODULE_AUTHOR("Cody Schuffelen <schuffelen@google.com>"); 714 MODULE_DESCRIPTION("Driver for a wireless wrapper of ethernet devices"); 715 MODULE_ALIAS_RTNL_LINK("virt_wifi"); 716