Makes wifi configurable over shared memory
Passes the mac addresses of host and guest devices through the wifi
exchange region.
Changes MacAddress type to std::array to make its size known at
compile time and moves it to the region view.
Test: run on gce
Bug: 76433498
Change-Id: Ie964a22424f0ff5004d32efcdf487894b8083c62
diff --git a/common/commands/wifi_relay/wifi_relay.cpp b/common/commands/wifi_relay/wifi_relay.cpp
index 1af95d9..27fede1 100644
--- a/common/commands/wifi_relay/wifi_relay.cpp
+++ b/common/commands/wifi_relay/wifi_relay.cpp
@@ -33,16 +33,6 @@
#include <fstream>
-DEFINE_string(
- guest_mac_address,
- "00:43:56:44:80:02",
- "MAC address of the wifi interface to be created on the guest.");
-
-DEFINE_string(
- host_mac_address,
- "42:00:00:00:00:00",
- "MAC address of the wifi interface running on the host.");
-
#if !defined(CUTTLEFISH_HOST)
DEFINE_string(
iface_name, "wlan0", "Name of the wifi interface to be created.");
@@ -241,11 +231,14 @@
int main(int argc, char **argv) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
- Mac80211HwSim::MacAddress guestMAC, hostMAC;
- if (!Mac80211HwSim::ParseMACAddress(FLAGS_guest_mac_address, &guestMAC)
- || !Mac80211HwSim::ParseMACAddress(FLAGS_host_mac_address, &hostMAC)) {
- exit(1);
- }
+ auto wifi_view = vsoc::wifi::WifiExchangeView::GetInstance(
+#if defined(CUTTLEFISH_HOST)
+ vsoc::GetDomain().c_str()
+#endif
+ );
+
+ Mac80211HwSim::MacAddress guestMAC = wifi_view->GetGuestMACAddress();
+ Mac80211HwSim::MacAddress hostMAC = wifi_view->GetHostMACAddress();
#ifdef CUTTLEFISH_HOST
WifiRelay relay(hostMAC, guestMAC);
diff --git a/common/commands/wifi_relay/wifi_relay.h b/common/commands/wifi_relay/wifi_relay.h
index 98dce3a..db94648 100644
--- a/common/commands/wifi_relay/wifi_relay.h
+++ b/common/commands/wifi_relay/wifi_relay.h
@@ -44,4 +44,3 @@
std::unique_ptr<Mac80211HwSim> mMac80211HwSim;
};
-
diff --git a/common/libs/wifi_relay/mac80211_hwsim.cpp b/common/libs/wifi_relay/mac80211_hwsim.cpp
index c08fcc9..2fc9c70 100644
--- a/common/libs/wifi_relay/mac80211_hwsim.cpp
+++ b/common/libs/wifi_relay/mac80211_hwsim.cpp
@@ -22,7 +22,6 @@
#include <netlink/genl/ctrl.h>
#include <netlink/genl/genl.h>
#include <signal.h>
-#include <string>
static constexpr char kWifiSimFamilyName[] = "MAC80211_HWSIM";
static constexpr char kNl80211FamilyName[] = "nl80211";
@@ -419,24 +418,3 @@
mRemotes.erase(it);
}
}
-
-// static
-bool Mac80211HwSim::ParseMACAddress(const std::string &s, MacAddress *mac) {
- mac->resize(ETH_ALEN);
-
- char dummy;
- if (sscanf(s.c_str(),
- "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx%c",
- &(*mac)[0],
- &(*mac)[1],
- &(*mac)[2],
- &(*mac)[3],
- &(*mac)[4],
- &(*mac)[5],
- &dummy) != 6) {
- LOG(ERROR) << "Failed to parse MAC address: " << s;
- return false;
- }
-
- return true;
-}
diff --git a/common/libs/wifi_relay/mac80211_hwsim.h b/common/libs/wifi_relay/mac80211_hwsim.h
index 43f94fe..d0801d2 100644
--- a/common/libs/wifi_relay/mac80211_hwsim.h
+++ b/common/libs/wifi_relay/mac80211_hwsim.h
@@ -24,10 +24,9 @@
#include <memory>
#include <mutex>
#include <netlink/netlink.h>
-#include <vector>
struct Mac80211HwSim {
- using MacAddress = std::vector<uint8_t>;
+ using MacAddress = vsoc::wifi::WifiExchangeView::MacAddress;
static constexpr size_t kMessageSizeMax = 128 * 1024;
@@ -52,8 +51,6 @@
void removeRemote(const MacAddress &mac);
- static bool ParseMACAddress(const std::string &s, MacAddress *mac);
-
private:
struct Remote {
explicit Remote(
diff --git a/common/vsoc/lib/wifi_exchange_view.cpp b/common/vsoc/lib/wifi_exchange_view.cpp
index 1cb3bf9..23dcd09 100644
--- a/common/vsoc/lib/wifi_exchange_view.cpp
+++ b/common/vsoc/lib/wifi_exchange_view.cpp
@@ -15,6 +15,9 @@
*/
#include "common/vsoc/lib/wifi_exchange_view.h"
+#include <algorithm>
+#include <string>
+
#include <linux/if_ether.h>
#include "common/vsoc/lib/circqueue_impl.h"
@@ -41,12 +44,74 @@
#endif
}
-void WifiExchangeView::SetGuestMACAddress(const uint8_t* mac_address) {
- memcpy(data()->mac_address, mac_address, ETH_ALEN);
+void WifiExchangeView::SetGuestMACAddress(
+ const WifiExchangeView::MacAddress& mac_address) {
+ std::copy(std::begin(mac_address),
+ std::end(mac_address),
+ std::begin(data()->guest_mac_address));
}
-void WifiExchangeView::GetGuestMACAddress(uint8_t* mac_address) {
- memcpy(mac_address, data()->mac_address, ETH_ALEN);
+WifiExchangeView::MacAddress WifiExchangeView::GetGuestMACAddress() {
+ WifiExchangeView::MacAddress ret;
+ std::copy(std::begin(data()->guest_mac_address),
+ std::end(data()->guest_mac_address),
+ std::begin(ret));
+ return ret;
+}
+
+void WifiExchangeView::SetHostMACAddress(
+ const WifiExchangeView::MacAddress& mac_address) {
+ std::copy(std::begin(mac_address),
+ std::end(mac_address),
+ std::begin(data()->host_mac_address));
+}
+
+WifiExchangeView::MacAddress WifiExchangeView::GetHostMACAddress() {
+ WifiExchangeView::MacAddress ret;
+ std::copy(std::begin(data()->host_mac_address),
+ std::end(data()->host_mac_address),
+ std::begin(ret));
+ return ret;
+}
+
+// static
+bool WifiExchangeView::ParseMACAddress(const std::string& s,
+ WifiExchangeView::MacAddress* mac) {
+ char dummy;
+ // This is likely to always be true, but better safe than sorry
+ static_assert(std::tuple_size<WifiExchangeView::MacAddress>::value == 6,
+ "Mac address size has changed");
+ if (sscanf(s.c_str(),
+ "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx%c",
+ &(*mac)[0],
+ &(*mac)[1],
+ &(*mac)[2],
+ &(*mac)[3],
+ &(*mac)[4],
+ &(*mac)[5],
+ &dummy) != 6) {
+ return false;
+ }
+ return true;
+}
+
+// static
+std::string WifiExchangeView::MacAddressToString(
+ const WifiExchangeView::MacAddress& mac) {
+ char buffer[3 * mac.size()];
+ // This is likely to always be true, but better safe than sorry
+ static_assert(std::tuple_size<WifiExchangeView::MacAddress>::value == 6,
+ "Mac address size has changed");
+ snprintf(buffer,
+ sizeof(buffer),
+ "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0],
+ mac[1],
+ mac[2],
+ mac[3],
+ mac[4],
+ mac[5]);
+ return std::string(buffer);
}
} // namespace wifi
diff --git a/common/vsoc/lib/wifi_exchange_view.h b/common/vsoc/lib/wifi_exchange_view.h
index ad0d968..5230a8e 100644
--- a/common/vsoc/lib/wifi_exchange_view.h
+++ b/common/vsoc/lib/wifi_exchange_view.h
@@ -15,6 +15,7 @@
*/
#pragma once
+#include <array>
#include <memory>
#include "common/vsoc/lib/typed_region_view.h"
@@ -29,6 +30,10 @@
WifiExchangeView,
vsoc::layout::wifi::WifiExchangeLayout> {
public:
+ using MacAddress = std::array<
+ uint8_t,
+ sizeof(vsoc::layout::wifi::WifiExchangeLayout::guest_mac_address)>;
+
// Send netlink packet to peer.
// returns true, if operation was successful.
intptr_t Send(const void* buffer, intptr_t length);
@@ -38,11 +43,18 @@
intptr_t Recv(void* buffer, intptr_t max_length);
// Set guest MAC address.
- void SetGuestMACAddress(const uint8_t* mac_address);
- void GetGuestMACAddress(uint8_t* mac_address);
+ void SetGuestMACAddress(const MacAddress& mac_address);
+ MacAddress GetGuestMACAddress();
+
+ // Set host MAC address.
+ void SetHostMACAddress(const MacAddress& mac_address);
+ MacAddress GetHostMACAddress();
void SetConfigReady();
void WaitConfigReady();
+
+ static bool ParseMACAddress(const std::string &s, MacAddress *mac);
+ static std::string MacAddressToString(const MacAddress& mac);
};
} // namespace wifi
diff --git a/common/vsoc/shm/version.h b/common/vsoc/shm/version.h
index 4948de4..0efae81 100644
--- a/common/vsoc/shm/version.h
+++ b/common/vsoc/shm/version.h
@@ -126,14 +126,13 @@
// Versioning information for wifi_layout.h
namespace wifi {
namespace {
-constexpr uint32_t version = 0;
+constexpr uint32_t version = 1;
} // namespace
constexpr size_t WifiExchangeLayout_size =
65548 + // sizeof(CircularPacketQueue<16, 8192>) - forward
65548 + // sizeof(CircularPacketQueue<16, 8192>) - reverse
- 4 + // Lock config_lock_
- 2 + // bool config_ready_ (and even address alignment)
- 6; // uint8_t[6] MAC address.
+ 6 + // uint8_t[6] MAC address.
+ 6; // uint8_t[6] MAC address.
} // namespace wifi
// Versioning information for ril_layout.h
diff --git a/common/vsoc/shm/wifi_exchange_layout.h b/common/vsoc/shm/wifi_exchange_layout.h
index 2ca957c..93f1a9e 100644
--- a/common/vsoc/shm/wifi_exchange_layout.h
+++ b/common/vsoc/shm/wifi_exchange_layout.h
@@ -31,12 +31,10 @@
// Traffic originating from guest that proceeds towards host.
CircularPacketQueue<16, 8192> guest_egress;
- // config_lock_ manages access to configuration section
- SpinLock config_lock_;
- // config_ready_ indicates whether config section is ready to be accessed.
- bool config_ready_;
// Desired MAC address for guest device.
- uint8_t mac_address[6];
+ uint8_t guest_mac_address[6];
+ // MAC address of host device.
+ uint8_t host_mac_address[6];
static const char* region_name;
};
diff --git a/host/commands/launch/Android.bp b/host/commands/launch/Android.bp
index 420df07..c6b2163 100644
--- a/host/commands/launch/Android.bp
+++ b/host/commands/launch/Android.bp
@@ -4,6 +4,7 @@
"main.cc",
"screen_region_handler.cc",
"ril_region_handler.cc",
+ "wifi_region_handler.cc",
],
header_libs: [
"cuttlefish_glog",
@@ -14,9 +15,11 @@
"cuttlefish_auto_resources",
"libicuuc",
"libbase",
+ "libnl"
],
static_libs: [
"libcuttlefish_host_config",
+ "libcuttlefish_wifi_relay",
"libivserver",
"libvadb",
"libusbip",
diff --git a/host/commands/launch/pre_launch_initializers.h b/host/commands/launch/pre_launch_initializers.h
index 0d3746d..d5f44ed 100644
--- a/host/commands/launch/pre_launch_initializers.h
+++ b/host/commands/launch/pre_launch_initializers.h
@@ -22,11 +22,13 @@
// source file and call from PreLaunchInitializers::Initialize().
void InitializeScreenRegion();
void InitializeRilRegion();
+void InitializeWifiRegion();
class PreLaunchInitializers {
public:
static void Initialize() {
InitializeScreenRegion();
InitializeRilRegion();
+ InitializeWifiRegion();
}
};
diff --git a/host/commands/launch/screen_region_handler.cc b/host/commands/launch/screen_region_handler.cc
index 9ad0f50..5844537 100644
--- a/host/commands/launch/screen_region_handler.cc
+++ b/host/commands/launch/screen_region_handler.cc
@@ -30,7 +30,7 @@
auto region =
vsoc::screen::ScreenRegionView::GetInstance(vsoc::GetDomain().c_str());
if (!region) {
- LOG(INFO) << "Framebuffer region was not found";
+ LOG(ERROR) << "Framebuffer region was not found";
return;
}
auto dest = region->data();
diff --git a/host/commands/launch/wifi_region_handler.cc b/host/commands/launch/wifi_region_handler.cc
new file mode 100644
index 0000000..7f82c6a
--- /dev/null
+++ b/host/commands/launch/wifi_region_handler.cc
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cassert>
+#include <string>
+
+#include <gflags/gflags.h>
+#include <glog/logging.h>
+
+#include "common/vsoc/lib/wifi_exchange_view.h"
+#include "host/commands/launch/pre_launch_initializers.h"
+#include "host/libs/config/host_config.h"
+
+using vsoc::wifi::WifiExchangeView;
+
+namespace {
+
+std::string GetPerInstanceDefaultMacAddress(const char* base_mac) {
+ WifiExchangeView::MacAddress addr;
+ if (!WifiExchangeView::ParseMACAddress(base_mac, &addr)) {
+ LOG(FATAL) << "Unable to parse MAC address: " << base_mac;
+ return "";
+ }
+ // Modify the last byte of the mac address to make it different for every cvd
+ addr.back() = static_cast<uint8_t>(vsoc::GetPerInstanceDefault(addr.back()));
+ return WifiExchangeView::MacAddressToString(addr);
+}
+
+} // namespace
+
+DEFINE_string(guest_mac_address,
+ GetPerInstanceDefaultMacAddress("00:43:56:44:80:01"),
+ "MAC address of the wifi interface to be created on the guest.");
+
+DEFINE_string(host_mac_address,
+ "42:00:00:00:00:00",
+ "MAC address of the wifi interface running on the host.");
+
+void InitializeWifiRegion() {
+ auto region = WifiExchangeView::GetInstance(vsoc::GetDomain().c_str());
+ if (!region) {
+ LOG(FATAL) << "Wifi region not found";
+ return;
+ }
+ WifiExchangeView::MacAddress guest_mac, host_mac;
+ if (!WifiExchangeView::ParseMACAddress(FLAGS_guest_mac_address, &guest_mac)) {
+ LOG(FATAL) << "Unable to parse guest mac address: "
+ << FLAGS_guest_mac_address;
+ return;
+ }
+ LOG(INFO) << "Setting guest mac to " << FLAGS_guest_mac_address;
+ region->SetGuestMACAddress(guest_mac);
+ if (!WifiExchangeView::ParseMACAddress(FLAGS_host_mac_address, &host_mac)) {
+ LOG(FATAL) << "Unable to parse guest mac address: "
+ << FLAGS_guest_mac_address;
+ return;
+ }
+ LOG(INFO) << "Setting host mac to " << FLAGS_host_mac_address;
+ region->SetHostMACAddress(host_mac);
+}