Rename and bridge the wifi virtio interface
Test: WiFi still works the old way, bridge created for virtio
Change-Id: Ib3ffdd2611f866a2c46da257619a0ad2c27ada4d
diff --git a/guest/commands/wifi_setup/Android.bp b/guest/commands/wifi_setup/Android.bp
index 9df9660..b8fb83d 100644
--- a/guest/commands/wifi_setup/Android.bp
+++ b/guest/commands/wifi_setup/Android.bp
@@ -17,13 +17,15 @@
name: "wifi_setup",
srcs: [
"cmd.cpp",
- "mac80211_hwsim.cpp",
+ "guest_bridge.cpp",
+ "mac80211_hwsim.cpp",
"nl_client.cpp",
"wifi_relay.cpp",
],
shared_libs: [
"libbase",
"vsoc_lib",
+ "cuttlefish_net",
"libcuttlefish_fs",
"cuttlefish_auto_resources",
"liblog",
@@ -37,4 +39,3 @@
],
defaults: ["cuttlefish_guest_only", "cuttlefish_native_isa"]
}
-
diff --git a/guest/commands/wifi_setup/guest_bridge.cpp b/guest/commands/wifi_setup/guest_bridge.cpp
new file mode 100644
index 0000000..99a2b05
--- /dev/null
+++ b/guest/commands/wifi_setup/guest_bridge.cpp
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "wifi_setup"
+
+#include "guest_bridge.h"
+
+#include <net/if.h>
+#include <cstdio>
+#include <log/log.h>
+#include "common/libs/net/netlink_client.h"
+#include "common/libs/net/network_interface.h"
+#include "common/libs/net/network_interface_manager.h"
+#include "common/libs/fs/shared_fd.h"
+
+int bridge_interface(const cvd::SharedFD& bfd, const char* bridge_name,
+ uint32_t slave_index, const char* name) {
+ struct ifreq ifr;
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, bridge_name, sizeof(ifr.ifr_name));
+ ifr.ifr_ifindex = slave_index;
+ if (bfd->Ioctl(SIOCBRADDIF, &ifr) == -1) {
+ ALOGE("unable to add %d (%s) to bridge (%s)", (int)slave_index, name,
+ bfd->StrError());
+ return -1;
+ }
+ return 0;
+}
+
+int make_bridge(const char* eth_name, const char* wifi_name) {
+ int32_t data_index = if_nametoindex(eth_name);
+ if (data_index == 0) {
+ ALOGE("invalid data interface name '%s'", eth_name);
+ return 2;
+ }
+ std::string ap_name(wifi_name);
+ ap_name+="_ap";
+ std::string data_name(wifi_name);
+ data_name+="_data";
+ auto factory = cvd::NetlinkClientFactory::Default();
+ 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(data_name.c_str(),
+ eth_name));
+ if (!ni) {
+ ALOGE("open interface '%s' failed", eth_name);
+ return 3;
+ }
+ ni->SetName(data_name.c_str());
+ if (!nm->ApplyChanges(*ni)) {
+ ALOGE("renaming interface '%s' failed", eth_name);
+ return 4;
+ }
+ ni->SetOperational(true);
+ if (!nm->ApplyChanges(*ni)) {
+ ALOGE("unable to ifup '%s'", eth_name);
+ return 5;
+ }
+ cvd::SharedFD bfd = cvd::SharedFD::Socket(AF_UNIX, SOCK_STREAM, 0);
+ if (!bfd->IsOpen()) {
+ ALOGE("unable to get socket (%s)", bfd->StrError());
+ return 6;
+ }
+ std::string bridge_name(wifi_name);
+ bridge_name += "_bridge";
+ if (bfd->Ioctl(SIOCBRADDBR, (void*)bridge_name.c_str()) == -1) {
+ ALOGE("unable create wlan0_bridge (%s)", bfd->StrError());
+ return 7;
+ }
+ bridge_interface(bfd, bridge_name.c_str(), data_index, data_name.c_str());
+ return 0;
+}
diff --git a/guest/commands/wifi_setup/guest_bridge.h b/guest/commands/wifi_setup/guest_bridge.h
new file mode 100644
index 0000000..b515163
--- /dev/null
+++ b/guest/commands/wifi_setup/guest_bridge.h
@@ -0,0 +1,18 @@
+#pragma once
+/*
+ * 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.
+ */
+
+int make_bridge(const char* eth_name, const char* wifi_name);
diff --git a/guest/commands/wifi_setup/wifi_relay.cpp b/guest/commands/wifi_setup/wifi_relay.cpp
index 99d1e8d..6312916 100644
--- a/guest/commands/wifi_setup/wifi_relay.cpp
+++ b/guest/commands/wifi_setup/wifi_relay.cpp
@@ -16,6 +16,7 @@
#include "wifi_relay.h"
+#include "guest/commands/wifi_setup/guest_bridge.h"
#include "guest/commands/wifi_setup/mac80211_hwsim_driver.h"
#include "guest/commands/wifi_setup/nl_client.h"
@@ -241,6 +242,8 @@
exit(1);
}
+ make_bridge("eth1", FLAGS_iface_name.c_str());
+
cvd::NlClient client(NETLINK_GENERIC);
if (!client.Init()) {
LOG(ERROR) << "Could not open Netlink Generic.";