Merge "(region_view) Removes unique_ptr<thread>" into gce-dev
diff --git a/common/commands/wifi_relay/wifi_relay.cpp b/common/commands/wifi_relay/wifi_relay.cpp
index 1af95d9..b57d710 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);
@@ -278,37 +271,36 @@
exit(1);
}
- std::unique_ptr<std::thread> nlThread(
- new std::thread([&client, &nlRoute]() {
- for (;;) {
- fd_set rs;
- FD_ZERO(&rs);
+ std::thread([&client, &nlRoute] {
+ for (;;) {
+ fd_set rs;
+ FD_ZERO(&rs);
- int fdGeneric = nl_socket_get_fd(client.Sock());
- int fdRoute = nl_socket_get_fd(nlRoute.Sock());
+ int fdGeneric = nl_socket_get_fd(client.Sock());
+ int fdRoute = nl_socket_get_fd(nlRoute.Sock());
- FD_SET(fdGeneric, &rs);
- FD_SET(fdRoute, &rs);
+ FD_SET(fdGeneric, &rs);
+ FD_SET(fdRoute, &rs);
- int maxFd = std::max(fdGeneric, fdRoute);
+ int maxFd = std::max(fdGeneric, fdRoute);
- int res = select(maxFd + 1, &rs, nullptr, nullptr, nullptr);
+ int res = select(maxFd + 1, &rs, nullptr, nullptr, nullptr);
- if (res == 0) {
- continue;
- } else if (res < 0) {
- continue;
- }
+ if (res == 0) {
+ continue;
+ } else if (res < 0) {
+ continue;
+ }
- if (FD_ISSET(fdGeneric, &rs)) {
- nl_recvmsgs_default(client.Sock());
- }
+ if (FD_ISSET(fdGeneric, &rs)) {
+ nl_recvmsgs_default(client.Sock());
+ }
- if (FD_ISSET(fdRoute, &rs)) {
- nl_recvmsgs_default(nlRoute.Sock());
- }
- }
- }));
+ if (FD_ISSET(fdRoute, &rs)) {
+ nl_recvmsgs_default(nlRoute.Sock());
+ }
+ }
+ }).detach();
const std::string phyName = FLAGS_iface_name + "_phy";
if (createRadio(&client, relay.mac80211Family(), phyName.c_str()) < 0) {
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/frontend/socket_forward_proxy/Android.bp b/common/frontend/socket_forward_proxy/Android.bp
index c70983e..caad62b 100644
--- a/common/frontend/socket_forward_proxy/Android.bp
+++ b/common/frontend/socket_forward_proxy/Android.bp
@@ -21,6 +21,7 @@
shared_libs: [
"libbase",
"libcuttlefish_fs",
+ "libcuttlefish_strings",
"cuttlefish_auto_resources",
"vsoc_lib",
"liblog",
diff --git a/common/frontend/socket_forward_proxy/main.cpp b/common/frontend/socket_forward_proxy/main.cpp
index ad1ca10..ed4196e 100644
--- a/common/frontend/socket_forward_proxy/main.cpp
+++ b/common/frontend/socket_forward_proxy/main.cpp
@@ -29,6 +29,7 @@
#include <unistd.h>
#include "common/libs/fs/shared_fd.h"
+#include "common/libs/strings/str_split.h"
#include "common/vsoc/lib/socket_forward_region_view.h"
#ifdef CUTTLEFISH_HOST
@@ -39,9 +40,12 @@
using vsoc::socket_forward::SocketForwardRegionView;
#ifdef CUTTLEFISH_HOST
-DEFINE_string(ports, "",
- "Comma-separated list of ports from which to forward TCP "
- "connections.");
+DEFINE_string(guest_ports, "",
+ "Comma-separated list of ports on which to forward TCP "
+ "connections to the guest.");
+DEFINE_string(host_ports, "",
+ "Comma-separated list of ports on which to run TCP servers on "
+ "the host.");
#endif
namespace {
@@ -154,44 +158,53 @@
}
#ifdef CUTTLEFISH_HOST
+struct PortPair {
+ int guest_port;
+ int host_port;
+};
+
+
[[noreturn]] void host_impl(SocketForwardRegionView* shm,
- std::vector<int> ports, std::size_t index) {
+ std::vector<PortPair> ports, std::size_t index) {
// launch a worker for the following port before handling the current port.
// recursion (instead of a loop) removes the need fore any join() or having
// the main thread do no work.
if (index + 1 < ports.size()) {
std::thread(host_impl, shm, ports, index + 1).detach();
}
- auto remote_port = ports[index];
- auto local_port = vsoc::GetPerInstanceDefault(remote_port);
- LOG(INFO) << "starting server on " << local_port
- << " for guest port " << remote_port;
- auto server = cvd::SharedFD::SocketLocalServer(local_port, SOCK_STREAM);
- CHECK(server->IsOpen()) << "Could not start server on port " << local_port;
+ auto guest_port = ports[index].guest_port;
+ auto host_port = ports[index].host_port;
+ LOG(INFO) << "starting server on " << host_port
+ << " for guest port " << guest_port;
+ auto server = cvd::SharedFD::SocketLocalServer(host_port, SOCK_STREAM);
+ CHECK(server->IsOpen()) << "Could not start server on port " << host_port;
while (true) {
auto client_socket = cvd::SharedFD::Accept(*server);
CHECK(client_socket->IsOpen()) << "error creating client socket";
LOG(INFO) << "client socket accepted";
- auto conn = shm->OpenConnection(remote_port);
+ auto conn = shm->OpenConnection(guest_port);
LOG(INFO) << "shm connection opened";
LaunchWorkers(std::move(conn), std::move(client_socket));
}
}
[[noreturn]] void host(SocketForwardRegionView* shm,
- std::vector<int> ports) {
+ std::vector<PortPair> ports) {
CHECK(!ports.empty());
host_impl(shm, ports, 0);
}
-std::vector<int> ParsePortsList(const std::string& ports_flag) {
- std::istringstream ports_stream{ports_flag};
- std::vector<int> ports;
- std::string port_str{};
- while (std::getline(ports_stream, port_str, ',')) {
- ports.push_back(std::stoi(port_str));
+std::vector<PortPair> ParsePortsList(const std::string& guest_ports_str,
+ const std::string& host_ports_str) {
+ std::vector<PortPair> ports{};
+ auto guest_ports = cvd::StrSplit(guest_ports_str, ',');
+ auto host_ports = cvd::StrSplit(host_ports_str, ',');
+ CHECK(guest_ports.size() == host_ports.size());
+ for (std::size_t i = 0; i < guest_ports.size(); ++i) {
+ ports.push_back({std::stoi(guest_ports[i]), std::stoi(host_ports[i])});
}
return ports;
+
}
#else
@@ -250,8 +263,9 @@
auto worker = shm->StartWorker();
#ifdef CUTTLEFISH_HOST
- CHECK(!FLAGS_ports.empty()) << "Must specify --ports flag";
- host(shm, ParsePortsList(FLAGS_ports));
+ CHECK(!FLAGS_guest_ports.empty()) << "Must specify --guest_ports flag";
+ CHECK(!FLAGS_host_ports.empty()) << "Must specify --host_ports flag";
+ host(shm, ParsePortsList(FLAGS_guest_ports, FLAGS_host_ports));
#else
guest(shm);
#endif
diff --git a/common/libs/Android.bp b/common/libs/Android.bp
index b23571f..cb4ec3e 100644
--- a/common/libs/Android.bp
+++ b/common/libs/Android.bp
@@ -17,6 +17,7 @@
"auto_resources",
"fs",
"net",
+ "strings",
"tcp_socket",
"threads",
"time",
diff --git a/common/libs/net/network_interface_manager.cpp b/common/libs/net/network_interface_manager.cpp
index 32d5583..4ee96b7 100644
--- a/common/libs/net/network_interface_manager.cpp
+++ b/common/libs/net/network_interface_manager.cpp
@@ -75,15 +75,22 @@
: nl_client_(std::move(nl_client)) {}
std::unique_ptr<NetworkInterface> NetworkInterfaceManager::Open(
- const std::string& if_name) {
+ const std::string& if_name, const std::string& if_name_alt) {
std::unique_ptr<NetworkInterface> iface;
// NOTE: do not replace this code with an IOCTL call.
// On SELinux enabled Androids, RILD is not permitted to execute an IOCTL
// and this call will fail.
- const int32_t index = if_nametoindex(if_name.c_str());
- if (index < 0) {
- LOG(ERROR) << "Failed to get interface (" << if_name << ") index.";
- return iface;
+ int32_t index = if_nametoindex(if_name.c_str());
+ if (index == 0) {
+ // Try the alternate name. This will be renamed to our preferred name
+ // by the kernel, because we specify IFLA_IFNAME, but open by index.
+ LOG(ERROR) << "Failed to get interface (" << if_name << ") index, "
+ << "trying alternate.";
+ index = if_nametoindex(if_name_alt.c_str());
+ if (index == 0) {
+ LOG(ERROR) << "Failed to get interface (" << if_name_alt << ") index.";
+ return iface;
+ }
}
iface.reset(new NetworkInterface(index));
diff --git a/common/libs/net/network_interface_manager.h b/common/libs/net/network_interface_manager.h
index 3d6ccc5..f28b0ff 100644
--- a/common/libs/net/network_interface_manager.h
+++ b/common/libs/net/network_interface_manager.h
@@ -32,14 +32,15 @@
//
// std::unique_ptr<NetlinkClient> client(NetlinkClient::GetDefault());
// NetworkInterfaceManager manager(client.get());
-// std::unique_ptr<NetworkInterface> iface(manager.Open("eth0"));
+// std::unique_ptr<NetworkInterface> iface(manager.Open("eth0", "em0"));
//
class NetworkInterfaceManager {
public:
// Open existing network interface.
//
// NOTE: this method does not fill in any NetworkInterface details yet.
- std::unique_ptr<NetworkInterface> Open(const std::string& if_name);
+ std::unique_ptr<NetworkInterface> Open(const std::string& if_name,
+ const std::string& if_name_alt);
// Apply changes made to existing network interface.
// This method cannot be used to instantiate new network interfaces.
diff --git a/common/libs/strings/Android.bp b/common/libs/strings/Android.bp
new file mode 100644
index 0000000..273c79e
--- /dev/null
+++ b/common/libs/strings/Android.bp
@@ -0,0 +1,25 @@
+//
+// Copyright (C) 2018 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.
+
+cc_library_shared {
+ name: "libcuttlefish_strings",
+ srcs: [
+ "str_split.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ ],
+ defaults: ["cuttlefish_host_and_guest"],
+}
diff --git a/common/libs/strings/str_split.cpp b/common/libs/strings/str_split.cpp
new file mode 100644
index 0000000..d76acad
--- /dev/null
+++ b/common/libs/strings/str_split.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2018 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 "common/libs/strings/str_split.h"
+
+#include <vector>
+#include <string>
+#include <sstream>
+
+std::vector<std::string> cvd::StrSplit(const std::string& src, char delimiter) {
+ std::istringstream stream{src};
+ std::vector<std::string> result;
+ for (std::string s; std::getline(stream, s, delimiter); s.clear()) {
+ result.push_back(std::move(s));
+ }
+ return result;
+}
diff --git a/common/libs/strings/str_split.h b/common/libs/strings/str_split.h
new file mode 100644
index 0000000..cd18d15
--- /dev/null
+++ b/common/libs/strings/str_split.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef CUTTLEFISH_COMMON_COMMON_LIBS_STRINGS_STR_SPLIT_H_
+#define CUTTLEFISH_COMMON_COMMON_LIBS_STRINGS_STR_SPLIT_H_
+
+#include <vector>
+#include <string>
+
+namespace cvd {
+std::vector<std::string> StrSplit(const std::string& src, char delimiter);
+} // namespace cvd
+
+#endif
diff --git a/common/libs/wifi/netlink.cc b/common/libs/wifi/netlink.cc
index 143a585..61c848b 100644
--- a/common/libs/wifi/netlink.cc
+++ b/common/libs/wifi/netlink.cc
@@ -45,7 +45,7 @@
}
// Start the thread processing asynchronous netlink responses.
- netlink_thread_.reset(new std::thread([this]() { HandleNetlinkMessages(); }));
+ std::thread([this] { HandleNetlinkMessages(); }).detach();
// Query relevant netlink families:
// MAC80211 family allows us to create virtual radios and corresponding
diff --git a/common/libs/wifi/netlink.h b/common/libs/wifi/netlink.h
index e380731..2eb374f 100644
--- a/common/libs/wifi/netlink.h
+++ b/common/libs/wifi/netlink.h
@@ -62,8 +62,6 @@
#endif
int nl80211_family_ = 0;
- std::unique_ptr<std::thread> netlink_thread_;
-
Netlink(const Netlink&) = delete;
Netlink& operator=(const Netlink&) = delete;
};
diff --git a/common/libs/wifi/packet_switch.cc b/common/libs/wifi/packet_switch.cc
index b913a69..523611e 100644
--- a/common/libs/wifi/packet_switch.cc
+++ b/common/libs/wifi/packet_switch.cc
@@ -51,7 +51,7 @@
nl_->WRCL().SetDefaultHandler(
[this](nl_msg* m) { ProcessPacket(m, false); });
- shm_xchg_.reset(new std::thread([this] {
+ shm_xchg_ = std::thread([this] {
size_t maxlen = getpagesize();
std::unique_ptr<uint8_t[]> msg(new uint8_t[maxlen]);
auto hdr = reinterpret_cast<nlmsghdr*>(msg.get());
@@ -68,7 +68,7 @@
nlm.reset(nlmsg_convert(hdr));
ProcessPacket(nlm.get(), true);
}
- }));
+ });
}
void PacketSwitch::Stop() {
@@ -77,8 +77,7 @@
started_ = false;
nl_->WRCL().SetDefaultHandler(std::function<void(nl_msg*)>());
- shm_xchg_->join();
- shm_xchg_.reset();
+ shm_xchg_.join();
}
void PacketSwitch::ProcessPacket(nl_msg* m, bool is_incoming) {
diff --git a/common/libs/wifi/packet_switch.h b/common/libs/wifi/packet_switch.h
index 257ccd2..4edf720 100644
--- a/common/libs/wifi/packet_switch.h
+++ b/common/libs/wifi/packet_switch.h
@@ -44,7 +44,7 @@
// whether to carry on working, or terminate.
bool started_ = false;
- std::unique_ptr<std::thread> shm_xchg_;
+ std::thread shm_xchg_;
std::unique_ptr<vsoc::RegionWorker> worker_;
vsoc::wifi::WifiExchangeView* shm_wifi_;
diff --git a/common/libs/wifi_relay/mac80211_hwsim.cpp b/common/libs/wifi_relay/mac80211_hwsim.cpp
index c08fcc9..ed72ce7 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";
@@ -40,7 +39,7 @@
mWifiExchange(wifiExchange) {
mWifiWorker = mWifiExchange->StartWorker();
- mThread.reset(new std::thread([this]{
+ mThread = std::thread([this]{
std::unique_ptr<uint8_t[]> buf(
new uint8_t[Mac80211HwSim::kMessageSizeMax]);
@@ -63,15 +62,14 @@
hdr = nlmsg_next(hdr, &len);
}
- }}));
+ }});
}
Mac80211HwSim::Remote::~Remote() {
mDone = true;
mWifiExchange->InterruptSelf();
- mThread->join();
- mThread.reset();
+ mThread.join();
}
intptr_t Mac80211HwSim::Remote::send(const void *data, size_t size) {
@@ -419,24 +417,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..d9e4e0f 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(
@@ -73,7 +70,7 @@
std::unique_ptr<vsoc::RegionWorker> mWifiWorker;
volatile bool mDone = false;
- std::unique_ptr<std::thread> mThread;
+ std::thread mThread;
};
int mInitCheck = -ENODEV;
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/guest/commands/vport_trigger/Android.mk b/guest/commands/vport_trigger/Android.mk
new file mode 100644
index 0000000..e994ce9
--- /dev/null
+++ b/guest/commands/vport_trigger/Android.mk
@@ -0,0 +1,26 @@
+# Copyright (C) 2018 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := vport_trigger
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := main.cpp
+LOCAL_SHARED_LIBRARIES := libcutils
+LOCAL_MULTILIB := first
+LOCAL_VENDOR_MODULE := true
+
+include $(BUILD_EXECUTABLE)
diff --git a/guest/commands/vport_trigger/main.cpp b/guest/commands/vport_trigger/main.cpp
new file mode 100644
index 0000000..7414c26
--- /dev/null
+++ b/guest/commands/vport_trigger/main.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2018 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 <cutils/properties.h>
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <dirent.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <climits>
+#include <cerrno>
+#include <string>
+
+// Taken from android::base, which wasn't available on platform versions
+// earlier than nougat.
+
+static bool ReadFdToString(int fd, std::string* content) {
+ content->clear();
+ char buf[BUFSIZ];
+ ssize_t n;
+ while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) {
+ content->append(buf, n);
+ }
+ return (n == 0) ? true : false;
+}
+
+static bool ReadFileToString(const std::string& path, std::string* content,
+ bool follow_symlinks) {
+ int flags = O_RDONLY | O_CLOEXEC | (follow_symlinks ? 0 : O_NOFOLLOW);
+ int fd = TEMP_FAILURE_RETRY(open(path.c_str(), flags));
+ if (fd == -1) {
+ return false;
+ }
+ bool result = ReadFdToString(fd, content);
+ close(fd);
+ return result;
+}
+
+int main(int argc __unused, char *argv[] __unused) {
+ const char sysfs_base[] = "/sys/class/virtio-ports/";
+ DIR *dir = opendir(sysfs_base);
+ if (dir) {
+ dirent *dp;
+ while ((dp = readdir(dir)) != nullptr) {
+ std::string dirname = dp->d_name;
+ std::string sysfs(sysfs_base + dirname + "/name");
+ struct stat st;
+ if (stat(sysfs.c_str(), &st)) {
+ continue;
+ }
+ std::string content;
+ if (!ReadFileToString(sysfs, &content, true)) {
+ continue;
+ }
+ if (content.empty()) {
+ continue;
+ }
+ content.erase(content.end() - 1);
+ // Leaves 32-11=22 characters for the port name from QEMU.
+ std::string propname("sys.cf.ser." + content);
+ std::string dev("/dev/" + dirname);
+ property_set(propname.c_str(), dev.c_str());
+ }
+ }
+ return 0;
+}
diff --git a/guest/hals/ril/vsoc_ril.cpp b/guest/hals/ril/vsoc_ril.cpp
index b60ad8d..0d33dd9 100644
--- a/guest/hals/ril/vsoc_ril.cpp
+++ b/guest/hals/ril/vsoc_ril.cpp
@@ -114,9 +114,10 @@
std::unique_ptr<cvd::NetlinkClient> nl(factory->New(NETLINK_ROUTE));
std::unique_ptr<cvd::NetworkInterfaceManager> nm(
cvd::NetworkInterfaceManager::New(factory));
- std::unique_ptr<cvd::NetworkInterface> ni(nm->Open("rmnet0"));
+ std::unique_ptr<cvd::NetworkInterface> ni(nm->Open("rmnet0", "eth0"));
if (ni) {
+ ni->SetName("rmnet0");
ni->SetAddress(ipaddr);
ni->SetBroadcastAddress(bcaddr);
ni->SetPrefixLength(prefixlen);
@@ -132,7 +133,7 @@
// This call returns true, if operation was successful.
bool TearDownNetworkInterface() {
auto nm(cvd::NetworkInterfaceManager::New(nullptr));
- auto ni(nm->Open("rmnet0"));
+ auto ni(nm->Open("rmnet0", "eth0"));
if (ni) {
ni->SetOperational(false);
diff --git a/host/commands/launch/Android.bp b/host/commands/launch/Android.bp
index 420df07..f888d79 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",
@@ -11,12 +12,15 @@
shared_libs: [
"vsoc_lib",
"libcuttlefish_fs",
+ "libcuttlefish_strings",
"cuttlefish_auto_resources",
"libicuuc",
"libbase",
+ "libnl"
],
static_libs: [
"libcuttlefish_host_config",
+ "libcuttlefish_wifi_relay",
"libivserver",
"libvadb",
"libusbip",
diff --git a/host/commands/launch/main.cc b/host/commands/launch/main.cc
index eacd5da..416ebf1 100644
--- a/host/commands/launch/main.cc
+++ b/host/commands/launch/main.cc
@@ -22,15 +22,19 @@
#include <sys/wait.h>
#include <unistd.h>
+#include <algorithm>
#include <fstream>
#include <iomanip>
#include <memory>
#include <sstream>
+#include <string>
+#include <vector>
#include <gflags/gflags.h>
#include <glog/logging.h>
#include "common/libs/fs/shared_select.h"
+#include "common/libs/strings/str_split.h"
#include "host/commands/launch/pre_launch_initializers.h"
#include "host/libs/config/file_partition.h"
#include "host/libs/config/guest_config.h"
@@ -112,17 +116,12 @@
StringFromEnv("ANDROID_HOST_OUT", StringFromEnv("HOME", ".")) +
"/bin/vnc_server",
"Location of the vnc server binary.");
-DEFINE_int32(vnc_server_port, vsoc::GetPerInstanceDefault(6444),
+DEFINE_int32(vnc_server_port, GetPerInstanceDefault(6444),
"The port on which the vnc server should listen");
DEFINE_string(socket_forward_proxy_binary,
StringFromEnv("ANDROID_HOST_OUT", StringFromEnv("HOME", ".")) +
"/bin/socket_forward_proxy",
"Location of the socket_forward_proxy binary.");
-DEFINE_string(socket_forward_proxy_ports, "5555", "Comma-separated list of "
- "ports on which to run the socket_forward_proxy server. These "
- "are the port numbers of the guest-side process. The "
- "host-side socket_forward_proxy process will bias the port "
- "numbers.");
DEFINE_bool(start_wifi_relay, true, "Whether to start the wifi_relay process.");
DEFINE_string(wifi_relay_binary,
@@ -309,6 +308,20 @@
"/bin/rm", "-f", file.c_str(), NULL};
subprocess(rm_command, NULL);
}
+
+
+// Emulators are discovered on odd numbered ports from 5555 to 5585
+constexpr int kFirstEmulatorPort = 5555;
+
+std::string GetGuestPortArg() {
+ return std::string{"--guest_ports="} + std::to_string(kFirstEmulatorPort);
+}
+
+std::string GetHostPortArg() {
+ return std::string{"--host_ports="} +
+ std::to_string(kFirstEmulatorPort + (vsoc::GetDefaultInstance() - 1) * 2);
+}
+
} // anonymous namespace
int main(int argc, char** argv) {
@@ -419,9 +432,14 @@
std::string entropy_source = "/dev/urandom";
- auto port_arg = std::string{"--ports="} + FLAGS_socket_forward_proxy_ports;
+ auto guest_port_arg = GetGuestPortArg();
+ auto host_port_arg = GetHostPortArg();
+
const char* const socket_proxy[] =
- {FLAGS_socket_forward_proxy_binary.c_str(), port_arg.c_str(), NULL};
+ {FLAGS_socket_forward_proxy_binary.c_str(),
+ guest_port_arg.c_str(),
+ host_port_arg.c_str(),
+ NULL};
subprocess(socket_proxy, nullptr, false);
config::GuestConfig cfg;
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);
+}
diff --git a/host/libs/config/host_config.cpp b/host/libs/config/host_config.cpp
index cc0218d..df39bb6 100644
--- a/host/libs/config/host_config.cpp
+++ b/host/libs/config/host_config.cpp
@@ -16,21 +16,29 @@
#include "host/libs/config/host_config.h"
-#include <stdlib.h>
-#include <string.h>
+#include <cstdlib>
+#include <cstring>
#include <string>
#include <iomanip>
#include <sstream>
#include <gflags/gflags.h>
-const char kVsocUserPrefix[] = "vsoc-";
-const char kDefaultUuidPrefix[] = "699acfc4-c8c4-11e7-882b-5065f31dc1";
+constexpr char kDefaultUuidPrefix[] = "699acfc4-c8c4-11e7-882b-5065f31dc1";
-int GetDefaultInstance() {
- char* user = getenv("USER");
- if (user && !memcmp(user, kVsocUserPrefix, sizeof(kVsocUserPrefix) - 1)) {
- int temp = atoi(user + sizeof(kVsocUserPrefix) - 1);
+DEFINE_string(domain, vsoc::GetDefaultShmClientSocketPath(),
+ "Path to the ivshmem client socket");
+DEFINE_int32(instance, vsoc::GetDefaultInstance(),
+ "Instance number. Must be unique.");
+DEFINE_string(uuid, vsoc::GetPerInstanceDefault(kDefaultUuidPrefix).c_str(),
+ "UUID to use for the device. Random if not specified");
+
+int vsoc::GetDefaultInstance() {
+ static constexpr char kVsocUserPrefix[] = "vsoc-";
+ const char* user = std::getenv("USER");
+ if (user && !std::strncmp(user, kVsocUserPrefix,
+ sizeof(kVsocUserPrefix) - 1)) {
+ int temp = std::atoi(user + sizeof(kVsocUserPrefix) - 1);
if (temp > 0) {
return temp;
}
@@ -38,13 +46,6 @@
return 1;
}
-DEFINE_string(domain, vsoc::GetDefaultShmClientSocketPath(),
- "Path to the ivshmem client socket");
-DEFINE_int32(instance, GetDefaultInstance(),
- "Instance number. Must be unique.");
-DEFINE_string(uuid, vsoc::GetPerInstanceDefault(kDefaultUuidPrefix).c_str(),
- "UUID to use for the device. Random if not specified");
-
std::string vsoc::GetPerInstanceDefault(const char* prefix) {
std::ostringstream stream;
stream << prefix << std::setfill('0') << std::setw(2)
diff --git a/host/libs/config/host_config.h b/host/libs/config/host_config.h
index 65ef523..15d2059 100644
--- a/host/libs/config/host_config.h
+++ b/host/libs/config/host_config.h
@@ -21,6 +21,7 @@
#include <string>
namespace vsoc {
+int GetDefaultInstance();
std::string GetPerInstanceDefault(const char* prefix);
int GetPerInstanceDefault(int base);
std::string GetDefaultPerInstanceDir();