1 #include "hyp_network_manager.hpp" 2 3 #include <phosphor-logging/elog-errors.hpp> 4 #include <phosphor-logging/elog.hpp> 5 #include <phosphor-logging/log.hpp> 6 #include <sdbusplus/bus.hpp> 7 #include <sdbusplus/server/object.hpp> 8 #include <xyz/openbmc_project/Common/error.hpp> 9 10 using sdbusplus::exception::SdBusError; 11 12 class HypNetworkMgr; 13 14 namespace phosphor 15 { 16 namespace network 17 { 18 using namespace phosphor::logging; 19 using InternalFailure = 20 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; 21 22 const std::string intType = "Integer"; 23 const std::string strType = "String"; 24 const std::string enumType = "Enumeration"; 25 26 using ObjectTree = 27 std::map<std::string, std::map<std::string, std::vector<std::string>>>; 28 29 auto HypNetworkMgr::getDBusProp(const std::string& objectName, 30 const std::string& interface, 31 const std::string& kw) 32 { 33 auto bus = sdbusplus::bus::new_default(); 34 auto properties = bus.new_method_call( 35 "xyz.openbmc_project.BIOSConfigManager", objectName.c_str(), 36 "org.freedesktop.DBus.Properties", "Get"); 37 properties.append(interface); 38 properties.append(kw); 39 auto result = bus.call(properties); 40 41 if (result.is_method_error()) 42 { 43 throw std::runtime_error("Get api failed"); 44 } 45 return result; 46 } 47 48 void HypNetworkMgr::setBIOSTableAttr( 49 std::string attrName, std::variant<std::string, int64_t> attrValue, 50 std::string attrType) 51 { 52 auto findAttr = biosTableAttrs.find(attrName); 53 if (findAttr != biosTableAttrs.end()) 54 { 55 if (attrType == intType) 56 { 57 int64_t value = std::get<int64_t>(attrValue); 58 if (value != std::get<int64_t>(findAttr->second)) 59 { 60 biosTableAttrs.erase(findAttr); 61 biosTableAttrs.emplace(attrName, value); 62 } 63 } 64 else if (attrType == strType) 65 { 66 std::string value = std::get<std::string>(attrValue); 67 if (value != std::get<std::string>(findAttr->second)) 68 { 69 biosTableAttrs.erase(findAttr); 70 biosTableAttrs.emplace(attrName, value); 71 } 72 } 73 } 74 else 75 { 76 log<level::INFO>( 77 "setBIOSTableAttr: Attribute is not found in biosTableAttrs"), 78 entry("attrName : ", attrName.c_str()); 79 } 80 } 81 82 void HypNetworkMgr::setDefaultBIOSTableAttrsOnIntf(const std::string& intf) 83 { 84 biosTableAttrs.emplace("vmi_" + intf + "_ipv4_ipaddr", "0.0.0.0"); 85 biosTableAttrs.emplace("vmi_" + intf + "_ipv4_gateway", "0.0.0.0"); 86 biosTableAttrs.emplace("vmi_" + intf + "_ipv4_prefix_length", 0); 87 biosTableAttrs.emplace("vmi_" + intf + "_ipv4_method", "IPv4Static"); 88 } 89 90 void HypNetworkMgr::setDefaultHostnameInBIOSTableAttrs() 91 { 92 biosTableAttrs.emplace("vmi_hostname", ""); 93 } 94 95 void HypNetworkMgr::setBIOSTableAttrs() 96 { 97 try 98 { 99 constexpr auto biosMgrIntf = "xyz.openbmc_project.BIOSConfig.Manager"; 100 constexpr auto biosMgrObj = "/xyz/openbmc_project/bios_config"; 101 102 constexpr auto mapperBus = "xyz.openbmc_project.ObjectMapper"; 103 constexpr auto mapperObj = "/xyz/openbmc_project/object_mapper"; 104 constexpr auto mapperIntf = "xyz.openbmc_project.ObjectMapper"; 105 106 std::vector<std::string> interfaces; 107 interfaces.emplace_back(biosMgrIntf); 108 auto depth = 0; 109 110 auto mapperCall = 111 bus.new_method_call(mapperBus, mapperObj, mapperIntf, "GetSubTree"); 112 113 mapperCall.append(biosMgrObj, depth, interfaces); 114 115 auto mapperReply = bus.call(mapperCall); 116 if (mapperReply.is_method_error()) 117 { 118 log<level::ERR>("Error in mapper call"); 119 elog<InternalFailure>(); 120 } 121 122 ObjectTree objectTree; 123 mapperReply.read(objectTree); 124 125 if (objectTree.empty()) 126 { 127 log<level::ERR>("No Object has implemented the interface", 128 entry("INTERFACE=%s", biosMgrIntf)); 129 elog<InternalFailure>(); 130 } 131 132 std::string objPath; 133 134 if (1 == objectTree.size()) 135 { 136 objPath = objectTree.begin()->first; 137 } 138 else 139 { 140 // If there are more than 2 objects, object path must contain the 141 // interface name 142 for (auto const& object : objectTree) 143 { 144 log<level::INFO>("interface", entry("INT=%s", biosMgrIntf)); 145 log<level::INFO>("object", 146 entry("OBJ=%s", object.first.c_str())); 147 148 if (std::string::npos != object.first.find(biosMgrIntf)) 149 { 150 objPath = object.first; 151 break; 152 } 153 } 154 155 if (objPath.empty()) 156 { 157 log<level::ERR>("Can't find the object for the interface", 158 entry("intfName=%s", biosMgrIntf)); 159 elog<InternalFailure>(); 160 } 161 } 162 163 std::variant<BiosBaseTableType> response; 164 getDBusProp(objPath, biosMgrIntf, "BaseBIOSTable").read(response); 165 166 const BiosBaseTableType* baseBiosTable = 167 std::get_if<BiosBaseTableType>(&response); 168 169 if (baseBiosTable == nullptr) 170 { 171 log<level::ERR>("BaseBiosTable is empty. No attributes found!"); 172 return; 173 } 174 175 for (const BiosBaseTableItemType& item : *baseBiosTable) 176 { 177 if (item.first.rfind("vmi", 0) == 0) // starts with the prefix 178 { 179 const std::string& itemType = 180 std::get<biosBaseAttrType>(item.second); 181 182 if (itemType.compare(itemType.size() - intType.size(), 183 intType.size(), intType) == 0) 184 { 185 const int64_t* currValue = std::get_if<int64_t>( 186 &std::get<biosBaseCurrValue>(item.second)); 187 if (currValue != nullptr) 188 { 189 biosTableAttrs.emplace(item.first, *currValue); 190 } 191 } 192 else if ((itemType.compare(itemType.size() - strType.size(), 193 strType.size(), strType) == 0) || 194 (itemType.compare(itemType.size() - enumType.size(), 195 enumType.size(), enumType) == 0)) 196 { 197 const std::string* currValue = std::get_if<std::string>( 198 &std::get<biosBaseCurrValue>(item.second)); 199 if (currValue != nullptr) 200 { 201 biosTableAttrs.emplace(item.first, *currValue); 202 } 203 } 204 else 205 { 206 log<level::ERR>("Unsupported datatype: The attribute is of " 207 "unknown type"); 208 } 209 } 210 } 211 } 212 catch (const SdBusError& e) 213 { 214 log<level::ERR>("Error in making dbus call"); 215 throw std::runtime_error("DBus call failed"); 216 } 217 } 218 219 biosTableType HypNetworkMgr::getBIOSTableAttrs() 220 { 221 return biosTableAttrs; 222 } 223 224 void HypNetworkMgr::createIfObjects() 225 { 226 setBIOSTableAttrs(); 227 228 if ((getBIOSTableAttrs()).size() == 0) 229 { 230 setDefaultHostnameInBIOSTableAttrs(); 231 } 232 233 // The hypervisor can support maximum of 234 // 2 ethernet interfaces. Both eth0/1 objects are 235 // created during init time to support the static 236 // network configurations on the both. 237 // create eth0 and eth1 objects 238 log<level::INFO>("Create eth0 and eth1 objects"); 239 } 240 241 void HypNetworkMgr::createSysConfObj() 242 { 243 systemConf.reset(nullptr); 244 this->systemConf = std::make_unique<phosphor::network::HypSysConfig>( 245 bus, objectPath + "/config", *this); 246 } 247 248 } // namespace network 249 } // namespace phosphor 250