/* * Copyright (C) 2020 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 "host/commands/assemble_cvd/alloc.h" #include #include #include "common/libs/fs/shared_fd.h" #include "host/libs/allocd/request.h" #include "host/libs/allocd/utils.h" namespace cuttlefish { static std::string StrForInstance(const std::string& prefix, int num) { std::ostringstream stream; stream << prefix << std::setfill('0') << std::setw(2) << num; return stream.str(); } IfaceConfig DefaultNetworkInterfaces(int num) { IfaceConfig config{}; config.mobile_tap.name = StrForInstance("cvd-mtap-", num); config.mobile_tap.resource_id = 0; config.mobile_tap.session_id = 0; config.wireless_tap.name = StrForInstance("cvd-wtap-", num); config.wireless_tap.resource_id = 0; config.wireless_tap.session_id = 0; config.ethernet_tap.name = StrForInstance("cvd-etap-", num); config.ethernet_tap.resource_id = 0; config.ethernet_tap.session_id = 0; return config; } std::optional AllocateNetworkInterfaces() { IfaceConfig config{}; SharedFD allocd_sock = SharedFD::SocketLocalClient( kDefaultLocation, false, SOCK_STREAM); CHECK(allocd_sock->IsOpen()) << "Unable to connect to allocd on " << kDefaultLocation << ": " << allocd_sock->StrError(); Json::Value resource_config; Json::Value request_list; Json::Value req; req["request_type"] = "create_interface"; req["uid"] = geteuid(); req["iface_type"] = "mtap"; request_list.append(req); req["iface_type"] = "wtap"; request_list.append(req); req["iface_type"] = "etap"; request_list.append(req); resource_config["config_request"]["request_list"] = request_list; CHECK(SendJsonMsg(allocd_sock, resource_config)) << "Failed to send JSON to allocd"; auto resp_opt = RecvJsonMsg(allocd_sock); CHECK(resp_opt.has_value()) << "Bad response from allocd"; auto resp = resp_opt.value(); CHECK(resp.isMember("config_status") && !resp["config_status"].isString()) << "Bad response from allocd: " << resp; CHECK_EQ( resp["config_status"].asString(), StatusToStr(RequestStatus::Success)) <<"Failed to allocate interfaces " << resp; CHECK(resp.isMember("session_id") && resp["session_id"].isUInt()) << "Bad response from allocd: " << resp; auto session_id = resp["session_id"].asUInt(); CHECK(resp.isMember("response_list") && resp["response_list"].isArray()) << "Bad response from allocd: " << resp; Json::Value resp_list = resp["response_list"]; Json::Value mtap_resp; Json::Value wtap_resp; Json::Value etap_resp; for (Json::Value::ArrayIndex i = 0; i != resp_list.size(); ++i) { auto ty = StrToIfaceTy(resp_list[i]["iface_type"].asString()); switch (ty) { case IfaceType::mtap: { mtap_resp = resp_list[i]; break; } case IfaceType::wtap: { wtap_resp = resp_list[i]; break; } case IfaceType::etap: { etap_resp = resp_list[i]; break; } default: { break; } } } if (!mtap_resp.isMember("iface_type")) { LOG(ERROR) << "Missing mtap response from allocd"; return std::nullopt; } if (!wtap_resp.isMember("iface_type")) { LOG(ERROR) << "Missing wtap response from allocd"; return std::nullopt; } if (!etap_resp.isMember("iface_type")) { LOG(ERROR) << "Missing etap response from allocd"; return std::nullopt; } config.mobile_tap.name = mtap_resp["iface_name"].asString(); config.mobile_tap.resource_id = mtap_resp["resource_id"].asUInt(); config.mobile_tap.session_id = session_id; config.wireless_tap.name = wtap_resp["iface_name"].asString(); config.wireless_tap.resource_id = wtap_resp["resource_id"].asUInt(); config.wireless_tap.session_id = session_id; config.ethernet_tap.name = etap_resp["iface_name"].asString(); config.ethernet_tap.resource_id = etap_resp["resource_id"].asUInt(); config.ethernet_tap.session_id = session_id; return config; } } // namespace cuttlefish