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