Skip to content

Commit b3c1501

Browse files
committed
cvdalloc supports bridged Wi-Fi.
Bridged Wi-Fi necessitates ensuring cvdalloc can handle setting up bridges and dnsmasq(8) properly. The existing alloc_utils does this, but assumes it gets run as root. If cvdalloc were setuid root, then this isn't an issue. However, we use capabilities and thus need more permissions: one to set up the raw DHCP socket, another to allow binding to low ports, again for DHCP. alloc_utils also defaults to putting the logs and lease files in /var/run which would otherwise require root, but we can just put those in CvdDir instead. The rest of the support necessary for bridged Wi-Fi is much like non-bridged Wi-Fi.
1 parent da30d89 commit b3c1501

File tree

7 files changed

+69
-21
lines changed

7 files changed

+69
-21
lines changed

base/cvd/allocd/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ cc_library(
4545
],
4646
deps = [
4747
"//cuttlefish/common/libs/fs",
48+
"//cuttlefish/host/commands/cvd/utils:common",
4849
"//cuttlefish/host/libs/config:logging",
4950
"//libbase",
5051
],

base/cvd/allocd/alloc_utils.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
#include "android-base/logging.h"
2222

23+
#include "cuttlefish/host/commands/cvd/utils/common.h"
24+
2325
namespace cuttlefish {
2426

2527
int RunExternalCommand(const std::string& command) {
@@ -364,7 +366,7 @@ bool SetupBridgeGateway(const std::string& bridge_name,
364366

365367
config.has_gateway = true;
366368

367-
if (StartDnsmasq(bridge_name, gateway, dhcp_range)) {
369+
if (!StartDnsmasq(bridge_name, gateway, dhcp_range)) {
368370
CleanupBridgeGateway(bridge_name, ipaddr, config);
369371
return false;
370372
}
@@ -419,8 +421,10 @@ bool StartDnsmasq(const std::string& bridge_name, const std::string& gateway,
419421
" --dhcp-option=\"option:dns-server," << dns_servers << "\""
420422
" --dhcp-option=\"option6:dns-server," << dns6_servers << "\""
421423
" --conf-file=\"\""
422-
" --pid-file=/var/run/cuttlefish-dnsmasq-" << bridge_name << ".pid"
423-
" --dhcp-leasefile=/var/run/cuttlefish-dnsmasq-" << bridge_name << ".leases"
424+
" --pid-file=" << CvdDir()
425+
<< "/cuttlefish-dnsmasq-" << bridge_name << ".pid"
426+
" --dhcp-leasefile=" << CvdDir()
427+
<< "/cuttlefish-dnsmasq-" << bridge_name << ".leases"
424428
" --dhcp-no-override ";
425429
// clang-format on
426430

base/cvd/cuttlefish/host/commands/cvdalloc/cvdalloc.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,23 +41,26 @@ void Usage() {
4141
LOG(ERROR) << "Should only be invoked from run_cvd.";
4242
}
4343

44-
Result<void> Allocate(int id, const std::string &bridge_name) {
44+
Result<void> Allocate(int id, const std::string &ethernet_bridge_name,
45+
const std::string &wireless_bridge_name) {
4546
LOG(INFO) << "cvdalloc: allocating network resources";
4647

47-
CreateBridge(bridge_name);
4848
CF_EXPECT(CreateMobileIface(CvdallocInterfaceName("mtap", id), id,
4949
kCvdallocMobileIpPrefix));
50-
CF_EXPECT(CreateMobileIface(CvdallocInterfaceName("wtap", id), id,
51-
kCvdallocWirelessIpPrefix));
50+
CreateEthernetBridgeIface(wireless_bridge_name, kCvdallocWirelessIpPrefix);
51+
CF_EXPECT(CreateEthernetIface(CvdallocInterfaceName("wtap", id),
52+
wireless_bridge_name, true, true, false));
5253
CF_EXPECT(CreateMobileIface(CvdallocInterfaceName("wifiap", id), id,
5354
kCvdallocWirelessApIpPrefix));
54-
CF_EXPECT(CreateEthernetIface(CvdallocInterfaceName("etap", id), bridge_name,
55-
true, true, false));
55+
CreateEthernetBridgeIface(ethernet_bridge_name, kCvdallocEthernetIpPrefix);
56+
CF_EXPECT(CreateEthernetIface(CvdallocInterfaceName("etap", id),
57+
ethernet_bridge_name, true, true, false));
5658

5759
return {};
5860
}
5961

60-
Result<void> Teardown(int id, const std::string &bridge_name) {
62+
Result<void> Teardown(int id, const std::string &ethernet_bridge_name,
63+
const std::string &wireless_bridge_name) {
6164
LOG(INFO) << "cvdalloc: tearing down resources";
6265

6366
DestroyMobileIface(CvdallocInterfaceName("mtap", id), id,
@@ -67,7 +70,8 @@ Result<void> Teardown(int id, const std::string &bridge_name) {
6770
DestroyMobileIface(CvdallocInterfaceName("wifiap", id), id,
6871
kCvdallocWirelessApIpPrefix);
6972
DestroyEthernetIface(CvdallocInterfaceName("etap", id), true, true, false);
70-
DestroyBridge(bridge_name);
73+
DestroyBridge(ethernet_bridge_name);
74+
DestroyBridge(wireless_bridge_name);
7175

7276
return {};
7377
}
@@ -115,13 +119,15 @@ Result<int> CvdallocMain(int argc, char *argv[]) {
115119
return CF_ERRNO("Couldn't elevate permissions: " << strerror(errno));
116120
}
117121

118-
std::string bridge_name = "cvd-pi-br";
122+
std::string ethernet_bridge_name = "cvd-pi-ebr";
123+
std::string wireless_bridge_name = "cvd-pi-wbr";
119124

120-
absl::Cleanup teardown = [id, bridge_name, sock]() {
121-
Teardown(id, bridge_name);
125+
absl::Cleanup teardown = [id, ethernet_bridge_name, wireless_bridge_name]() {
126+
LOG(INFO) << "cvdalloc: teardown started";
127+
Teardown(id, ethernet_bridge_name, wireless_bridge_name);
122128
};
123129

124-
CF_EXPECT(Allocate(id, bridge_name));
130+
CF_EXPECT(Allocate(id, ethernet_bridge_name, wireless_bridge_name));
125131
CF_EXPECT(cvdalloc::Post(sock));
126132

127133
LOG(INFO) << "cvdalloc: waiting to teardown";

base/cvd/cuttlefish/host/commands/cvdalloc/interface.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,17 @@ std::string InstanceToWifiAddress(int num) {
4646
std::string InstanceToWifiBroadcast(int num) {
4747
return absl::StrFormat("%s.%d", kCvdallocWirelessApIpPrefix, 4 * num - 1);
4848
}
49+
50+
std::string InstanceToBridgedWifiGatewayAddress(int num) {
51+
return absl::StrFormat("%s.%d", kCvdallocWirelessIpPrefix, 1);
52+
}
53+
54+
std::string InstanceToBridgedWifiAddress(int num) {
55+
return absl::StrFormat("%s.%d", kCvdallocWirelessIpPrefix, 4 * num - 2);
56+
}
57+
58+
std::string InstanceToBridgedWifiBroadcast(int num) {
59+
return absl::StrFormat("%s.%d", kCvdallocWirelessIpPrefix, 4 * num - 1);
60+
}
61+
4962
} // namespace cuttlefish

base/cvd/cuttlefish/host/commands/cvdalloc/interface.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,8 @@ std::string InstanceToMobileBroadcast(int num);
3232
std::string InstanceToWifiGatewayAddress(int num);
3333
std::string InstanceToWifiAddress(int num);
3434
std::string InstanceToWifiBroadcast(int num);
35+
std::string InstanceToBridgedWifiGatewayAddress(int num);
36+
std::string InstanceToBridgedWifiAddress(int num);
37+
std::string InstanceToBridgedWifiBroadcast(int num);
3538

3639
} // namespace cuttlefish

base/cvd/cuttlefish/host/commands/cvdalloc/privilege.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,18 @@ static int SetAmbientCapabilities() {
6868
return -1;
6969
}
7070

71+
r = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_NET_BIND_SERVICE, 0, 0);
72+
if (r == -1) {
73+
PLOG(INFO) << "prctl";
74+
return -1;
75+
}
76+
77+
r = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_NET_RAW, 0, 0);
78+
if (r == -1) {
79+
PLOG(INFO) << "prctl";
80+
return -1;
81+
}
82+
7183
return 1;
7284
}
7385
#endif
@@ -84,7 +96,8 @@ Result<void> ValidateCvdallocBinary(std::string_view path) {
8496
CF_EXPECTF(
8597
s != 1 && (cap.data[0].permitted & (1 << CAP_NET_ADMIN)) != 0,
8698
"cvdalloc binary does not have permissions to allocate resources.\n"
87-
"As root, please\n\n setcap cap_net_admin=+ep `realpath {}`",
99+
"As root, please\n\n setcap cap_net_admin,cap_net_bind_service,"
100+
"cap_net_raw=+ep `realpath {}`",
88101
path);
89102
#else
90103
CF_EXPECTF(

base/cvd/cuttlefish/host/libs/config/openwrt_args.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,20 @@ std::unordered_map<std::string, std::string> OpenwrtArgsFromConfig(
5757
// (AOSP) external/openwrt-prebuilts/shared/uci-defaults/0_default_config
5858
if (instance.use_bridged_wifi_tap()) {
5959
openwrt_args["bridged_wifi_tap"] = "true";
60-
openwrt_args["wan_gateway"] = getIpAddress(96, 1);
61-
// TODO(seungjaeyoo) : Remove config after using DHCP server outside OpenWRT
62-
// instead.
63-
openwrt_args["wan_ipaddr"] = getIpAddress(96, d_class_base + 2);
64-
openwrt_args["wan_broadcast"] = getIpAddress(96, d_class_base + 3);
6560

61+
if (instance.use_cvdalloc()) {
62+
openwrt_args["wan_gateway"] =
63+
InstanceToBridgedWifiGatewayAddress(instance_num);
64+
openwrt_args["wan_ipaddr"] = InstanceToBridgedWifiAddress(instance_num);
65+
openwrt_args["wan_broadcast"] =
66+
InstanceToBridgedWifiBroadcast(instance_num);
67+
} else {
68+
openwrt_args["wan_gateway"] = getIpAddress(96, 1);
69+
// TODO(seungjaeyoo) : Remove config after using DHCP server outside
70+
// OpenWRT instead.
71+
openwrt_args["wan_ipaddr"] = getIpAddress(96, d_class_base + 2);
72+
openwrt_args["wan_broadcast"] = getIpAddress(96, d_class_base + 3);
73+
}
6674
} else {
6775
openwrt_args["bridged_wifi_tap"] = "false";
6876

0 commit comments

Comments
 (0)