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";
diff --git a/host/libs/allocd/alloc_utils.h b/host/libs/allocd/alloc_utils.h
index 41b9475..5c1fd76 100644
--- a/host/libs/allocd/alloc_utils.h
+++ b/host/libs/allocd/alloc_utils.h
@@ -29,10 +29,8 @@
namespace cuttlefish {
-
-// TODO (paulkirth): Need to have the name of the ebtables program set
-// somewhere, for now hardcode it, until resolved
constexpr char kEbtablesName[] = "ebtables";
+constexpr char kEbtablesLegacyName[] = "ebtables-legacy";
// Wireless network prefix
constexpr char kWirelessIp[] = "192.168.96";
@@ -52,6 +50,7 @@
bool has_broute_ipv4 = false;
bool has_broute_ipv6 = false;
bool has_tap = false;
+ bool use_ebtables_legacy = false;
};
// struct for managing configuration state
@@ -76,24 +75,31 @@
bool CreateBridge(const std::string& name);
bool DestroyBridge(const std::string& name);
-bool CreateEbtables(const std::string& name, bool use_ipv4);
-bool DestroyEbtables(const std::string& name, bool use_ipv4);
-bool EbtablesBroute(const std::string& name, bool use_ipv4, bool add);
-bool EbtablesFilter(const std::string& name, bool use_ipv4, bool add);
+bool CreateEbtables(const std::string& name, bool use_ipv,
+ bool use_ebtables_legacy);
+bool DestroyEbtables(const std::string& name, bool use_ipv4,
+ bool use_ebtables_legacy);
+bool EbtablesBroute(const std::string& name, bool use_ipv4, bool add,
+ bool use_ebtables_legacy);
+bool EbtablesFilter(const std::string& name, bool use_ipv4, bool add,
+ bool use_ebtables_legacy);
-bool CreateMobileIface(const std::string& name, uint16_t id, const std::string& ipaddr);
-bool DestroyMobileIface(const std::string& name, uint16_t id, const std::string& ipaddr);
+bool CreateMobileIface(const std::string& name, uint16_t id,
+ const std::string& ipaddr);
+bool DestroyMobileIface(const std::string& name, uint16_t id,
+ const std::string& ipaddr);
bool CreateWirelessIface(const std::string& name, bool has_ipv4_bridge,
- bool has_ipv6_bridge);
+ bool has_ipv6_bridge, bool use_ebtables_legacy);
bool DestroyWirelessIface(const std::string& name, bool has_ipv4_bridge,
- bool use_ipv6);
+ bool use_ipv6, bool use_ebtables_legacy);
void CleanupWirelessIface(const std::string& name,
const WirelessNetworkConfig& config);
bool IptableConfig(const std::string& network, bool add);
-bool LinkTapToBridge(const std::string& tap_name, const std::string& bridge_name);
+bool LinkTapToBridge(const std::string& tap_name,
+ const std::string& bridge_name);
bool SetupBridgeGateway(const std::string& name, const std::string& ipaddr);
void CleanupBridgeGateway(const std::string& name, const std::string& ipaddr,
@@ -102,8 +108,10 @@
bool CreateWirelessBridgeIface(const std::string& name);
bool DestroyWirelessBridgeIface(const std::string& name);
-bool AddGateway(const std::string& name, const std::string& gateway, const std::string& netmask);
-bool DestroyGateway(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);
+bool DestroyGateway(const std::string& name, const std::string& gateway,
+ const std::string& netmask);
bool StartDnsmasq(const std::string& bridge_name, const std::string& gateway,
const std::string& dhcp_range);
diff --git a/host/libs/allocd/allocd.cpp b/host/libs/allocd/allocd.cpp
index 064a1bd..6025dab 100644
--- a/host/libs/allocd/allocd.cpp
+++ b/host/libs/allocd/allocd.cpp
@@ -39,8 +39,8 @@
#include "host/libs/allocd/resource_manager.h"
#include "host/libs/config/logging.h"
-using namespace cuttlefish;
-DEFINE_string(socket_path, kDefaultLocation, "Socket path");
+DEFINE_string(socket_path, cuttlefish::kDefaultLocation, "Socket path");
+DEFINE_bool(ebtables_legacy, false, "use ebtables-legacy instead of ebtables");
int main(int argc, char* argv[]) {
::android::base::InitLogging(argv, android::base::StderrLogger);
@@ -49,8 +49,9 @@
cuttlefish::SharedFD FinalFD;
{
- ResourceManager m;
+ cuttlefish::ResourceManager m;
m.SetSocketLocation(FLAGS_socket_path);
+ m.SetUseEbtablesLegacy(FLAGS_ebtables_legacy);
m.JsonServer();
}
diff --git a/host/libs/allocd/resource.cpp b/host/libs/allocd/resource.cpp
index 510963a..5a8b475 100644
--- a/host/libs/allocd/resource.cpp
+++ b/host/libs/allocd/resource.cpp
@@ -31,11 +31,13 @@
}
bool WirelessIface::AcquireResource() {
- return CreateWirelessIface(GetName(), has_ipv4_, has_ipv6_);
+ return CreateWirelessIface(GetName(), has_ipv4_, has_ipv6_,
+ use_ebtables_legacy_);
}
bool WirelessIface::ReleaseResource() {
- return DestroyWirelessIface(GetName(), has_ipv4_, has_ipv6_);
+ return DestroyWirelessIface(GetName(), has_ipv4_, has_ipv6_,
+ use_ebtables_legacy_);
}
} // namespace cuttlefish
diff --git a/host/libs/allocd/resource.h b/host/libs/allocd/resource.h
index 768e915..a92d38b 100644
--- a/host/libs/allocd/resource.h
+++ b/host/libs/allocd/resource.h
@@ -73,9 +73,6 @@
private:
uint16_t iface_id_;
std::string ipaddr_;
- // bool has_gateway_;
- // bool has_iptable_;
- // bool has_tap;
};
class WirelessIface : public StaticResource {
@@ -95,15 +92,23 @@
uint16_t GetIfaceId() { return iface_id_; }
std::string GetIpAddr() { return ipaddr_; }
+ void SetHasIpv4(bool ipv4) { has_ipv4_ = ipv4; }
+ void SetHasIpv6(bool ipv6) { has_ipv6_ = ipv6; }
+ void SetUseEbtablesLegacy(bool use_legacy) {
+ use_ebtables_legacy_ = use_legacy;
+ }
+
+ bool GetHasIpv4() { return has_ipv4_; }
+ bool GetHasIpv6() { return has_ipv6_; }
+ bool GetUseEbtablesLegacy() { return use_ebtables_legacy_; }
+
private:
static constexpr char kNetmask[] = "/24";
uint16_t iface_id_;
std::string ipaddr_;
bool has_ipv4_ = true;
bool has_ipv6_ = true;
- // bool has_gateway_;
- // bool has_iptable_;
- // bool has_tap;
+ bool use_ebtables_legacy_ = false;
};
} // namespace cuttlefish
diff --git a/host/libs/allocd/resource_manager.cpp b/host/libs/allocd/resource_manager.cpp
index 3fbae35..1ec6ac1 100644
--- a/host/libs/allocd/resource_manager.cpp
+++ b/host/libs/allocd/resource_manager.cpp
@@ -63,6 +63,10 @@
location = sock_name;
}
+void ResourceManager::SetUseEbtablesLegacy(bool use_legacy) {
+ use_ebtables_legacy_ = use_legacy;
+}
+
uint32_t ResourceManager::AllocateResourceID() {
return global_resource_id_.fetch_add(1, std::memory_order_relaxed);
}
@@ -73,30 +77,30 @@
bool ResourceManager::AddInterface(const std::string& iface, IfaceType ty,
uint32_t resource_id, uid_t uid) {
- bool didInsert = active_interfaces_.insert(iface).second;
bool allocatedIface = false;
-
std::shared_ptr<StaticResource> res = nullptr;
+ bool didInsert = active_interfaces_.insert(iface).second;
if (didInsert) {
const char* idp = iface.c_str() + (iface.size() - 3);
int small_id = atoi(idp);
- // allocatedIface = create_tap(iface);
switch (ty) {
case IfaceType::mtap: {
res = std::make_shared<MobileIface>(iface, uid, small_id, resource_id,
kMobileIp);
allocatedIface = res->AcquireResource();
pending_add_.insert({resource_id, res});
- // allocatedIface = CreateMobileIface(iface, small_id, kMobileIp);
break;
}
case IfaceType::wtap: {
- res = std::make_shared<WirelessIface>(iface, uid, small_id, resource_id,
- kMobileIp);
+ auto w = std::make_shared<WirelessIface>(iface, uid, small_id,
+ resource_id, kMobileIp);
+ w->SetUseEbtablesLegacy(use_ebtables_legacy_);
+ w->SetHasIpv4(use_ipv4_bridge_);
+ w->SetHasIpv6(use_ipv6_bridge_);
+ res = w;
allocatedIface = res->AcquireResource();
pending_add_.insert({resource_id, res});
- // allocatedIface = CreateWirelessIface(iface, use_ipv4_, use_ipv6_);
break;
}
case IfaceType::wbr: {
@@ -135,8 +139,8 @@
break;
}
case IfaceType::wtap: {
- removedIface =
- DestroyWirelessIface(iface, use_ipv4_bridge_, use_ipv6_bridge_);
+ removedIface = DestroyWirelessIface(
+ iface, use_ipv4_bridge_, use_ipv6_bridge_, use_ebtables_legacy_);
break;
}
case IfaceType::wbr: {
@@ -242,16 +246,15 @@
Json::Value req_list = req["config_request"]["request_list"];
- Json::ArrayIndex size = req_list.size();
-
Json::Value config_response;
Json::Value response_list;
+ Json::ArrayIndex req_list_size = req_list.size();
// sentinel value, so we can populate the list of responses correctly
// without trying to satisfy requests that will be aborted
bool transaction_failed = false;
- for (Json::ArrayIndex i = 0; i < size; ++i) {
+ for (Json::ArrayIndex i = 0; i < req_list_size; ++i) {
LOG(INFO) << "Processing Request: " << i;
auto req = req_list[i];
auto req_ty_str = req["request_type"].asString();
@@ -272,7 +275,7 @@
break;
}
case RequestType::Shutdown: {
- if (i != 0 || size != 1) {
+ if (i != 0 || req_list_size != 1) {
response["request_type"] = req_ty_str;
response["request_status"] = "failed";
response["error"] =
@@ -357,10 +360,10 @@
}
bool ResourceManager::CheckCredentials(SharedFD client_socket, uid_t uid) {
-
uid_t sock_uid = GetUserIDFromSock(client_socket);
if (sock_uid == -1) {
+ LOG(WARNING) << "Invalid Socket UID: " << uid;
return false;
}
@@ -456,7 +459,6 @@
resp["error"] = "";
}
- // SendJsonMsg(client_socket, resp);
return resp;
}
diff --git a/host/libs/allocd/resource_manager.h b/host/libs/allocd/resource_manager.h
index 617e9f3..32f06cf 100644
--- a/host/libs/allocd/resource_manager.h
+++ b/host/libs/allocd/resource_manager.h
@@ -100,6 +100,8 @@
void SetSocketLocation(const std::string& sock_name);
+ void SetUseEbtablesLegacy(bool use_legacy);
+
void JsonServer();
private:
@@ -146,6 +148,7 @@
std::string location = kDefaultLocation;
bool use_ipv4_bridge_ = true;
bool use_ipv6_bridge_ = true;
+ bool use_ebtables_legacy_ = false;
cuttlefish::SharedFD shutdown_socket_;
};