Support ebtable-legacy in allocd
cuttlefish_common.init selects which ebtables program to use, as
ebtables may not be available on all platforms, but instead may be
ebtables-legacy. Since we're calling popen using that program name, this
commit adds a method for choosing which version of ebtables to use with
a new flag, set when allocd is started.
The flag approach was chosen over just using a string to ensure that
there would be no unintended way to influence the arguments to popen,
since the program name can only be one of two choices.
These changes propagate to all users of the ebtables apis, which so far
is limited to only the wireless configurations.
Bug: 148823285
Test: make -j
Test: allocd &;
launch_cvd --use_allocd;
stop_cvd
Change-Id: I9ad10313b8ce7de2ab121ca946420c73a6d9e47c
diff --git a/host/libs/allocd/alloc_utils.cpp b/host/libs/allocd/alloc_utils.cpp
index 534d591..883b42c 100644
--- a/host/libs/allocd/alloc_utils.cpp
+++ b/host/libs/allocd/alloc_utils.cpp
@@ -64,7 +64,7 @@
}
bool CreateWirelessIface(const std::string& name, bool has_ipv4_bridge,
- bool has_ipv6_bridge) {
+ bool has_ipv6_bridge, bool use_ebtables_legacy) {
// assume bridge exists
WirelessNetworkConfig config{false, false, false};
@@ -86,7 +86,7 @@
}
if (!has_ipv4_bridge) {
- if (!CreateEbtables(name, true)) {
+ if (!CreateEbtables(name, true, use_ebtables_legacy)) {
CleanupWirelessIface(name, config);
return false;
}
@@ -94,7 +94,7 @@
}
if (!has_ipv6_bridge) {
- if (CreateEbtables(name, false)) {
+ if (CreateEbtables(name, false, use_ebtables_legacy)) {
CleanupWirelessIface(name, config);
return false;
}
@@ -145,7 +145,8 @@
return true;
}
-bool DestroyMobileIface(const std::string& name, uint16_t id, const std::string& ipaddr) {
+bool DestroyMobileIface(const std::string& name, uint16_t id,
+ const std::string& ipaddr) {
if (id > 63) {
LOG(ERROR) << "ID exceeds maximum value to assign a netmask: " << id;
return false;
@@ -160,7 +161,8 @@
return DestroyIface(name);
}
-bool AddGateway(const std::string& name, const std::string& gateway, const std::string& netmask) {
+bool AddGateway(const std::string& name, const std::string& gateway,
+ const std::string& netmask) {
std::stringstream ss;
ss << "ip addr add " << gateway << netmask << " broadcast + dev " << name;
auto command = ss.str();
@@ -182,13 +184,13 @@
}
bool DestroyWirelessIface(const std::string& name, bool has_ipv4_bridge,
- bool has_ipv6_bridge) {
+ bool has_ipv6_bridge, bool use_ebtables_legacy) {
if (!has_ipv6_bridge) {
- DestroyEbtables(name, false);
+ DestroyEbtables(name, false, use_ebtables_legacy);
}
if (!has_ipv4_bridge) {
- DestroyEbtables(name, true);
+ DestroyEbtables(name, true, use_ebtables_legacy);
}
return DestroyIface(name);
@@ -197,11 +199,11 @@
void CleanupWirelessIface(const std::string& name,
const WirelessNetworkConfig& config) {
if (config.has_broute_ipv6) {
- DestroyEbtables(name, false);
+ DestroyEbtables(name, false, config.use_ebtables_legacy);
}
if (config.has_broute_ipv4) {
- DestroyEbtables(name, true);
+ DestroyEbtables(name, true, config.use_ebtables_legacy);
}
if (config.has_tap) {
@@ -209,17 +211,31 @@
}
}
-bool CreateEbtables(const std::string& name, bool use_ipv4) {
- return EbtablesBroute(name, use_ipv4, true) &&
- EbtablesFilter(name, use_ipv4, true);
+bool CreateEbtables(const std::string& name, bool use_ipv4,
+ bool use_ebtables_legacy) {
+ return EbtablesBroute(name, use_ipv4, true, use_ebtables_legacy) &&
+ EbtablesFilter(name, use_ipv4, true, use_ebtables_legacy);
}
-bool DestroyEbtables(const std::string& name, bool use_ipv4) {
- return EbtablesBroute(name, use_ipv4, false) &&
- EbtablesFilter(name, use_ipv4, false);
+
+bool DestroyEbtables(const std::string& name, bool use_ipv4,
+ bool use_ebtables_legacy) {
+ return EbtablesBroute(name, use_ipv4, false, use_ebtables_legacy) &&
+ EbtablesFilter(name, use_ipv4, false, use_ebtables_legacy);
}
-bool EbtablesBroute(const std::string& name, bool use_ipv4, bool add) {
+
+bool EbtablesBroute(const std::string& name, bool use_ipv4, bool add,
+ bool use_ebtables_legacy) {
std::stringstream ss;
- ss << kEbtablesName << " -t broute " << (add ? "-A" : "-D") << " BROUTING -p "
+ // we don't know the name of the ebtables program, but since we're going to
+ // exec this program name, make sure they can only choose between the two
+ // options we currently support, and not something they can overwrite
+ if (use_ebtables_legacy) {
+ ss << kEbtablesLegacyName;
+ } else {
+ ss << kEbtablesName;
+ }
+
+ ss << " -t broute " << (add ? "-A" : "-D") << " BROUTING -p "
<< (use_ipv4 ? "ipv4" : "ipv6") << " --in-if " << name << " -j DROP";
auto command = ss.str();
int status = RunExternalCommand(command);
@@ -227,9 +243,16 @@
return status == 0;
}
-bool EbtablesFilter(const std::string& name, bool use_ipv4, bool add) {
+bool EbtablesFilter(const std::string& name, bool use_ipv4, bool add,
+ bool use_ebtables_legacy) {
std::stringstream ss;
- ss << kEbtablesName << " -t filter " << (add ? "-A" : "-D") << " FORWARD -p "
+ if (use_ebtables_legacy) {
+ ss << kEbtablesLegacyName;
+ } else {
+ ss << kEbtablesName;
+ }
+
+ ss << " -t filter " << (add ? "-A" : "-D") << " FORWARD -p "
<< (use_ipv4 ? "ipv4" : "ipv6") << " --out-if " << name << " -j DROP";
auto command = ss.str();
int status = RunExternalCommand(command);
@@ -237,7 +260,8 @@
return status == 0;
}
-bool LinkTapToBridge(const std::string& tap_name, const std::string& bridge_name) {
+bool LinkTapToBridge(const std::string& tap_name,
+ const std::string& bridge_name) {
std::stringstream ss;
ss << "ip link set dev " << tap_name << " master " << bridge_name;
auto command = ss.str();
@@ -315,7 +339,8 @@
bool DestroyBridge(const std::string& name) { return DeleteIface(name); }
-bool SetupBridgeGateway(const std::string& bridge_name, const std::string& ipaddr) {
+bool SetupBridgeGateway(const std::string& bridge_name,
+ const std::string& ipaddr) {
GatewayConfig config{false, false, false};
auto gateway = ipaddr + ".1";
auto netmask = "/24";
@@ -421,7 +446,7 @@
return ret;
}
-bool IptableConfig(std::string network, bool add) {
+bool IptableConfig(const std::string& network, bool add) {
std::stringstream ss;
ss << "iptables -t nat " << (add ? "-A" : "-D") << " POSTROUTING -s "
<< network << " -j MASQUERADE";