blob: 3ff79eddf783594fb2bc4d605b6a5afea1ed13ad [file] [log] [blame]
Ratan Guptab8e99552017-07-27 07:07:48 +05301#include <arpa/inet.h>
2#include <dirent.h>
3#include <net/if.h>
4
Patrick Venture2e633522018-10-13 13:51:06 -07005#include <algorithm>
Kun Yi5dcf41e2019-03-05 14:02:51 -08006#include <chrono>
Vernon Mauery6a98fe72019-03-11 15:57:48 -07007#include <ipmid/utils.hpp>
Patrick Venture0b02be92018-08-31 11:55:55 -07008#include <phosphor-logging/elog-errors.hpp>
9#include <phosphor-logging/log.hpp>
William A. Kennington III4c008022018-10-12 17:18:14 -070010#include <sdbusplus/message/types.hpp>
Patrick Venture0b02be92018-08-31 11:55:55 -070011#include <xyz/openbmc_project/Common/error.hpp>
12
Tom Josephbe703f72017-03-09 12:34:35 +053013namespace ipmi
14{
15
Ratan Guptacc8feb42017-07-25 21:52:10 +053016using namespace phosphor::logging;
17using namespace sdbusplus::xyz::openbmc_project::Common::Error;
William A. Kennington III4c008022018-10-12 17:18:14 -070018namespace variant_ns = sdbusplus::message::variant_ns;
Ratan Guptacc8feb42017-07-25 21:52:10 +053019
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -050020namespace network
21{
22
23/** @brief checks if the given ip is Link Local Ip or not.
Patrick Venture0b02be92018-08-31 11:55:55 -070024 * @param[in] ipaddress - IPAddress.
25 */
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -050026bool isLinkLocalIP(const std::string& ipaddress);
27
Patrick Venture0b02be92018-08-31 11:55:55 -070028} // namespace network
Ratan Guptacc8feb42017-07-25 21:52:10 +053029
Patrick Venture0b02be92018-08-31 11:55:55 -070030// TODO There may be cases where an interface is implemented by multiple
Ratan Guptacc8feb42017-07-25 21:52:10 +053031// objects,to handle such cases we are interested on that object
32// which are on interested busname.
33// Currently mapper doesn't give the readable busname(gives busid) so we can't
34// use busname to find the object,will do later once the support is there.
35
Ratan Gupta01d4bd12017-08-07 15:53:25 +053036DbusObjectInfo getDbusObject(sdbusplus::bus::bus& bus,
37 const std::string& interface,
Ratan Guptacc8feb42017-07-25 21:52:10 +053038 const std::string& serviceRoot,
39 const std::string& match)
40{
41 std::vector<DbusInterface> interfaces;
42 interfaces.emplace_back(interface);
43
Ratan Guptacc8feb42017-07-25 21:52:10 +053044 auto depth = 0;
45
Patrick Venture0b02be92018-08-31 11:55:55 -070046 auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ,
47 MAPPER_INTF, "GetSubTree");
Ratan Guptacc8feb42017-07-25 21:52:10 +053048
49 mapperCall.append(serviceRoot, depth, interfaces);
50
51 auto mapperReply = bus.call(mapperCall);
52 if (mapperReply.is_method_error())
53 {
54 log<level::ERR>("Error in mapper call");
55 elog<InternalFailure>();
56 }
57
58 ObjectTree objectTree;
59 mapperReply.read(objectTree);
60
61 if (objectTree.empty())
62 {
Patrick Venturef0c48782017-09-21 18:48:51 -070063 log<level::ERR>("No Object has implemented the interface",
Ratan Guptacc8feb42017-07-25 21:52:10 +053064 entry("INTERFACE=%s", interface.c_str()));
65 elog<InternalFailure>();
66 }
67
68 DbusObjectInfo objectInfo;
69
70 // if match is empty then return the first object
Patrick Venture0b02be92018-08-31 11:55:55 -070071 if (match == "")
Ratan Guptacc8feb42017-07-25 21:52:10 +053072 {
Patrick Venture0b02be92018-08-31 11:55:55 -070073 objectInfo = std::make_pair(
74 objectTree.begin()->first,
Ratan Guptacc8feb42017-07-25 21:52:10 +053075 std::move(objectTree.begin()->second.begin()->first));
76 return objectInfo;
77 }
78
79 // else search the match string in the object path
Patrick Venture2e633522018-10-13 13:51:06 -070080 auto found = std::find_if(
81 objectTree.begin(), objectTree.end(), [&match](const auto& object) {
82 return (object.first.find(match) != std::string::npos);
83 });
Ratan Guptacc8feb42017-07-25 21:52:10 +053084
Patrick Venture2e633522018-10-13 13:51:06 -070085 if (found == objectTree.end())
Ratan Guptacc8feb42017-07-25 21:52:10 +053086 {
87 log<level::ERR>("Failed to find object which matches",
88 entry("MATCH=%s", match.c_str()));
89 elog<InternalFailure>();
Patrick Venture2e633522018-10-13 13:51:06 -070090 // elog<> throws an exception.
Ratan Guptacc8feb42017-07-25 21:52:10 +053091 }
Patrick Venture2e633522018-10-13 13:51:06 -070092
93 return make_pair(found->first, std::move(found->second.begin()->first));
Ratan Guptacc8feb42017-07-25 21:52:10 +053094}
95
Ratan Guptadd646202017-11-21 17:46:59 +053096DbusObjectInfo getIPObject(sdbusplus::bus::bus& bus,
97 const std::string& interface,
98 const std::string& serviceRoot,
99 const std::string& match)
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500100{
101 auto objectTree = getAllDbusObjects(bus, serviceRoot, interface, match);
102
103 if (objectTree.empty())
104 {
105 log<level::ERR>("No Object has implemented the IP interface",
106 entry("INTERFACE=%s", interface.c_str()));
107 elog<InternalFailure>();
108 }
109
Ratan Guptadd646202017-11-21 17:46:59 +0530110 DbusObjectInfo objectInfo;
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500111
112 for (auto& object : objectTree)
113 {
114 auto variant = ipmi::getDbusProperty(
Patrick Venture0b02be92018-08-31 11:55:55 -0700115 bus, object.second.begin()->first, object.first,
116 ipmi::network::IP_INTERFACE, "Address");
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500117
Patrick Venture0b02be92018-08-31 11:55:55 -0700118 objectInfo = std::make_pair(object.first, object.second.begin()->first);
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500119
120 // if LinkLocalIP found look for Non-LinkLocalIP
William A. Kennington III4c008022018-10-12 17:18:14 -0700121 if (ipmi::network::isLinkLocalIP(variant_ns::get<std::string>(variant)))
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500122 {
123 continue;
124 }
125 else
126 {
127 break;
128 }
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500129 }
Ratan Guptadd646202017-11-21 17:46:59 +0530130 return objectInfo;
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500131}
132
Patrick Venture0b02be92018-08-31 11:55:55 -0700133Value getDbusProperty(sdbusplus::bus::bus& bus, const std::string& service,
134 const std::string& objPath, const std::string& interface,
Kun Yi5dcf41e2019-03-05 14:02:51 -0800135 const std::string& property,
136 std::chrono::microseconds timeout)
Ratan Guptacc8feb42017-07-25 21:52:10 +0530137{
138
139 Value value;
140
Patrick Venture0b02be92018-08-31 11:55:55 -0700141 auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
142 PROP_INTF, METHOD_GET);
Ratan Guptacc8feb42017-07-25 21:52:10 +0530143
144 method.append(interface, property);
145
Kun Yi5dcf41e2019-03-05 14:02:51 -0800146 auto reply = bus.call(method, timeout.count());
Ratan Guptacc8feb42017-07-25 21:52:10 +0530147
148 if (reply.is_method_error())
149 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700150 log<level::ERR>("Failed to get property",
151 entry("PROPERTY=%s", property.c_str()),
152 entry("PATH=%s", objPath.c_str()),
153 entry("INTERFACE=%s", interface.c_str()));
Ratan Guptacc8feb42017-07-25 21:52:10 +0530154 elog<InternalFailure>();
155 }
156
157 reply.read(value);
158
159 return value;
160}
161
Ratan Gupta01d4bd12017-08-07 15:53:25 +0530162PropertyMap getAllDbusProperties(sdbusplus::bus::bus& bus,
163 const std::string& service,
Ratan Guptacc8feb42017-07-25 21:52:10 +0530164 const std::string& objPath,
Kun Yi5dcf41e2019-03-05 14:02:51 -0800165 const std::string& interface,
166 std::chrono::microseconds timeout)
Ratan Guptacc8feb42017-07-25 21:52:10 +0530167{
168 PropertyMap properties;
Ratan Guptacc8feb42017-07-25 21:52:10 +0530169
Patrick Venture0b02be92018-08-31 11:55:55 -0700170 auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
171 PROP_INTF, METHOD_GET_ALL);
Ratan Guptacc8feb42017-07-25 21:52:10 +0530172
173 method.append(interface);
174
Kun Yi5dcf41e2019-03-05 14:02:51 -0800175 auto reply = bus.call(method, timeout.count());
Ratan Guptacc8feb42017-07-25 21:52:10 +0530176
177 if (reply.is_method_error())
178 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700179 log<level::ERR>("Failed to get all properties",
180 entry("PATH=%s", objPath.c_str()),
181 entry("INTERFACE=%s", interface.c_str()));
182 elog<InternalFailure>();
Ratan Guptacc8feb42017-07-25 21:52:10 +0530183 }
184
185 reply.read(properties);
186 return properties;
187}
188
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600189ObjectValueTree getManagedObjects(sdbusplus::bus::bus& bus,
Patrick Venture0b02be92018-08-31 11:55:55 -0700190 const std::string& service,
191 const std::string& objPath)
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600192{
193 ipmi::ObjectValueTree interfaces;
194
Patrick Venture0b02be92018-08-31 11:55:55 -0700195 auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
196 "org.freedesktop.DBus.ObjectManager",
197 "GetManagedObjects");
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600198
199 auto reply = bus.call(method);
200
201 if (reply.is_method_error())
202 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700203 log<level::ERR>("Failed to get managed objects",
204 entry("PATH=%s", objPath.c_str()));
205 elog<InternalFailure>();
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600206 }
207
208 reply.read(interfaces);
209 return interfaces;
210}
211
Patrick Venture0b02be92018-08-31 11:55:55 -0700212void setDbusProperty(sdbusplus::bus::bus& bus, const std::string& service,
213 const std::string& objPath, const std::string& interface,
Kun Yi5dcf41e2019-03-05 14:02:51 -0800214 const std::string& property, const Value& value,
215 std::chrono::microseconds timeout)
Ratan Guptacc8feb42017-07-25 21:52:10 +0530216{
Patrick Venture0b02be92018-08-31 11:55:55 -0700217 auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
218 PROP_INTF, METHOD_SET);
Ratan Guptacc8feb42017-07-25 21:52:10 +0530219
220 method.append(interface, property, value);
221
Kun Yi5dcf41e2019-03-05 14:02:51 -0800222 if (!bus.call(method, timeout.count()))
Ratan Guptacc8feb42017-07-25 21:52:10 +0530223 {
224 log<level::ERR>("Failed to set property",
225 entry("PROPERTY=%s", property.c_str()),
Patrick Venture0b02be92018-08-31 11:55:55 -0700226 entry("PATH=%s", objPath.c_str()),
227 entry("INTERFACE=%s", interface.c_str()));
Ratan Guptacc8feb42017-07-25 21:52:10 +0530228 elog<InternalFailure>();
229 }
Ratan Guptacc8feb42017-07-25 21:52:10 +0530230}
231
Patrick Venture0b02be92018-08-31 11:55:55 -0700232ServiceCache::ServiceCache(const std::string& intf, const std::string& path) :
Vernon Mauery54012502018-11-07 10:17:31 -0800233 intf(intf), path(path), cachedService(std::nullopt),
234 cachedBusName(std::nullopt)
William A. Kennington IIIe47fdfb2018-03-15 17:09:28 -0700235{
236}
237
Patrick Venture0b02be92018-08-31 11:55:55 -0700238ServiceCache::ServiceCache(std::string&& intf, std::string&& path) :
Vernon Mauery54012502018-11-07 10:17:31 -0800239 intf(std::move(intf)), path(std::move(path)), cachedService(std::nullopt),
240 cachedBusName(std::nullopt)
William A. Kennington IIIe47fdfb2018-03-15 17:09:28 -0700241{
242}
243
244const std::string& ServiceCache::getService(sdbusplus::bus::bus& bus)
245{
246 if (!isValid(bus))
247 {
248 cachedBusName = bus.get_unique_name();
249 cachedService = ::ipmi::getService(bus, intf, path);
250 }
251 return cachedService.value();
252}
253
254void ServiceCache::invalidate()
255{
Vernon Mauery54012502018-11-07 10:17:31 -0800256 cachedBusName = std::nullopt;
257 cachedService = std::nullopt;
William A. Kennington IIIe47fdfb2018-03-15 17:09:28 -0700258}
259
Patrick Venture0b02be92018-08-31 11:55:55 -0700260sdbusplus::message::message
261 ServiceCache::newMethodCall(sdbusplus::bus::bus& bus, const char* intf,
262 const char* method)
William A. Kennington IIIe47fdfb2018-03-15 17:09:28 -0700263{
Patrick Venture0b02be92018-08-31 11:55:55 -0700264 return bus.new_method_call(getService(bus).c_str(), path.c_str(), intf,
265 method);
William A. Kennington IIIe47fdfb2018-03-15 17:09:28 -0700266}
267
268bool ServiceCache::isValid(sdbusplus::bus::bus& bus) const
269{
270 return cachedService && cachedBusName == bus.get_unique_name();
271}
272
Patrick Venture0b02be92018-08-31 11:55:55 -0700273std::string getService(sdbusplus::bus::bus& bus, const std::string& intf,
Tom Josephbe703f72017-03-09 12:34:35 +0530274 const std::string& path)
275{
Patrick Venture0b02be92018-08-31 11:55:55 -0700276 auto mapperCall =
277 bus.new_method_call("xyz.openbmc_project.ObjectMapper",
278 "/xyz/openbmc_project/object_mapper",
279 "xyz.openbmc_project.ObjectMapper", "GetObject");
Tom Josephbe703f72017-03-09 12:34:35 +0530280
281 mapperCall.append(path);
282 mapperCall.append(std::vector<std::string>({intf}));
283
284 auto mapperResponseMsg = bus.call(mapperCall);
285
286 if (mapperResponseMsg.is_method_error())
287 {
288 throw std::runtime_error("ERROR in mapper call");
289 }
290
291 std::map<std::string, std::vector<std::string>> mapperResponse;
292 mapperResponseMsg.read(mapperResponse);
293
294 if (mapperResponse.begin() == mapperResponse.end())
295 {
296 throw std::runtime_error("ERROR in reading the mapper response");
297 }
298
299 return mapperResponse.begin()->first;
300}
301
Ratan Guptab8e99552017-07-27 07:07:48 +0530302ipmi::ObjectTree getAllDbusObjects(sdbusplus::bus::bus& bus,
303 const std::string& serviceRoot,
304 const std::string& interface,
305 const std::string& match)
306{
307 std::vector<std::string> interfaces;
308 interfaces.emplace_back(interface);
Ratan Guptacc8feb42017-07-25 21:52:10 +0530309
Ratan Guptab8e99552017-07-27 07:07:48 +0530310 auto depth = 0;
311
Patrick Venture0b02be92018-08-31 11:55:55 -0700312 auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ,
313 MAPPER_INTF, "GetSubTree");
Ratan Guptab8e99552017-07-27 07:07:48 +0530314
315 mapperCall.append(serviceRoot, depth, interfaces);
316
317 auto mapperReply = bus.call(mapperCall);
318 if (mapperReply.is_method_error())
319 {
320 log<level::ERR>("Error in mapper call",
Patrick Venture0b02be92018-08-31 11:55:55 -0700321 entry("SERVICEROOT=%s", serviceRoot.c_str()),
Ratan Guptab8e99552017-07-27 07:07:48 +0530322 entry("INTERFACE=%s", interface.c_str()));
323
324 elog<InternalFailure>();
325 }
326
327 ObjectTree objectTree;
328 mapperReply.read(objectTree);
329
330 for (auto it = objectTree.begin(); it != objectTree.end();)
331 {
332 if (it->first.find(match) == std::string::npos)
333 {
334 it = objectTree.erase(it);
335 }
336 else
337 {
338 ++it;
339 }
340 }
341
342 return objectTree;
343}
344
345void deleteAllDbusObjects(sdbusplus::bus::bus& bus,
346 const std::string& serviceRoot,
347 const std::string& interface,
348 const std::string& match)
349{
350 try
351 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700352 auto objectTree = getAllDbusObjects(bus, serviceRoot, interface, match);
Ratan Guptab8e99552017-07-27 07:07:48 +0530353
354 for (auto& object : objectTree)
355 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700356 method_no_args::callDbusMethod(bus, object.second.begin()->first,
357 object.first, DELETE_INTERFACE,
358 "Delete");
Ratan Guptab8e99552017-07-27 07:07:48 +0530359 }
360 }
Vernon Mauery7a614182018-11-27 12:54:52 -0800361 catch (sdbusplus::exception::exception& e)
Ratan Guptab8e99552017-07-27 07:07:48 +0530362 {
Vernon Mauery7a614182018-11-27 12:54:52 -0800363 log<level::INFO>("sdbusplus exception - Unable to delete the objects",
364 entry("ERROR=%s", e.what()),
Ratan Guptab8e99552017-07-27 07:07:48 +0530365 entry("INTERFACE=%s", interface.c_str()),
366 entry("SERVICE=%s", serviceRoot.c_str()));
367 }
368}
369
Patrick Venture0b02be92018-08-31 11:55:55 -0700370ObjectTree getAllAncestors(sdbusplus::bus::bus& bus, const std::string& path,
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530371 InterfaceList&& interfaces)
372{
Patrick Venture0b02be92018-08-31 11:55:55 -0700373 auto convertToString = [](InterfaceList& interfaces) -> std::string {
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530374 std::string intfStr;
375 for (const auto& intf : interfaces)
376 {
377 intfStr += "," + intf;
378 }
379 return intfStr;
380 };
381
Patrick Venture0b02be92018-08-31 11:55:55 -0700382 auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ,
383 MAPPER_INTF, "GetAncestors");
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530384 mapperCall.append(path, interfaces);
385
386 auto mapperReply = bus.call(mapperCall);
387 if (mapperReply.is_method_error())
388 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700389 log<level::ERR>(
390 "Error in mapper call", entry("PATH=%s", path.c_str()),
391 entry("INTERFACES=%s", convertToString(interfaces).c_str()));
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530392
393 elog<InternalFailure>();
394 }
395
396 ObjectTree objectTree;
397 mapperReply.read(objectTree);
398
399 if (objectTree.empty())
400 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700401 log<level::ERR>(
402 "No Object has implemented the interface",
403 entry("PATH=%s", path.c_str()),
404 entry("INTERFACES=%s", convertToString(interfaces).c_str()));
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530405 elog<InternalFailure>();
406 }
407
408 return objectTree;
409}
Ratan Guptab8e99552017-07-27 07:07:48 +0530410
411namespace method_no_args
412{
413
Patrick Venture0b02be92018-08-31 11:55:55 -0700414void callDbusMethod(sdbusplus::bus::bus& bus, const std::string& service,
415 const std::string& objPath, const std::string& interface,
Ratan Guptab8e99552017-07-27 07:07:48 +0530416 const std::string& method)
417
418{
Patrick Venture0b02be92018-08-31 11:55:55 -0700419 auto busMethod = bus.new_method_call(service.c_str(), objPath.c_str(),
420 interface.c_str(), method.c_str());
Ratan Guptab8e99552017-07-27 07:07:48 +0530421
422 auto reply = bus.call(busMethod);
423
424 if (reply.is_method_error())
425 {
426 log<level::ERR>("Failed to execute method",
427 entry("METHOD=%s", method.c_str()),
428 entry("PATH=%s", objPath.c_str()),
429 entry("INTERFACE=%s", interface.c_str()));
430 elog<InternalFailure>();
431 }
432}
433
Patrick Venture0b02be92018-08-31 11:55:55 -0700434} // namespace method_no_args
Ratan Guptab8e99552017-07-27 07:07:48 +0530435
436namespace network
437{
438
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500439bool isLinkLocalIP(const std::string& address)
440{
441 return address.find(IPV4_PREFIX) == 0 || address.find(IPV6_PREFIX) == 0;
442}
443
Patrick Venture0b02be92018-08-31 11:55:55 -0700444void createIP(sdbusplus::bus::bus& bus, const std::string& service,
445 const std::string& objPath, const std::string& protocolType,
446 const std::string& ipaddress, uint8_t prefix)
Ratan Guptab8e99552017-07-27 07:07:48 +0530447{
448 std::string gateway = "";
449
Patrick Venture0b02be92018-08-31 11:55:55 -0700450 auto busMethod = bus.new_method_call(service.c_str(), objPath.c_str(),
451 IP_CREATE_INTERFACE, "IP");
Ratan Guptab8e99552017-07-27 07:07:48 +0530452
453 busMethod.append(protocolType, ipaddress, prefix, gateway);
454
455 auto reply = bus.call(busMethod);
456
457 if (reply.is_method_error())
458 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700459 log<level::ERR>("Failed to execute method", entry("METHOD=%s", "IP"),
Ratan Guptab8e99552017-07-27 07:07:48 +0530460 entry("PATH=%s", objPath.c_str()));
461 elog<InternalFailure>();
462 }
Ratan Guptab8e99552017-07-27 07:07:48 +0530463}
464
Patrick Venture0b02be92018-08-31 11:55:55 -0700465void createVLAN(sdbusplus::bus::bus& bus, const std::string& service,
466 const std::string& objPath, const std::string& interfaceName,
Ratan Gupta533d03b2017-07-30 10:39:22 +0530467 uint32_t vlanID)
468{
Patrick Venture0b02be92018-08-31 11:55:55 -0700469 auto busMethod = bus.new_method_call(service.c_str(), objPath.c_str(),
470 VLAN_CREATE_INTERFACE, "VLAN");
Ratan Gupta533d03b2017-07-30 10:39:22 +0530471
472 busMethod.append(interfaceName, vlanID);
473
474 auto reply = bus.call(busMethod);
475
476 if (reply.is_method_error())
477 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700478 log<level::ERR>("Failed to execute method", entry("METHOD=%s", "VLAN"),
Ratan Gupta533d03b2017-07-30 10:39:22 +0530479 entry("PATH=%s", objPath.c_str()));
480 elog<InternalFailure>();
481 }
Ratan Gupta533d03b2017-07-30 10:39:22 +0530482}
483
Ratan Guptab8e99552017-07-27 07:07:48 +0530484uint8_t toPrefix(int addressFamily, const std::string& subnetMask)
485{
486 if (addressFamily == AF_INET6)
487 {
488 return 0;
489 }
490
Patrick Venture0b02be92018-08-31 11:55:55 -0700491 uint32_t buff{};
Ratan Guptab8e99552017-07-27 07:07:48 +0530492
493 auto rc = inet_pton(addressFamily, subnetMask.c_str(), &buff);
494 if (rc <= 0)
495 {
496 log<level::ERR>("inet_pton failed:",
Joseph Reynolds510eb9c2018-05-30 11:51:28 -0500497 entry("SUBNETMASK=%s", subnetMask.c_str()));
Ratan Guptab8e99552017-07-27 07:07:48 +0530498 return 0;
499 }
500
501 buff = be32toh(buff);
502 // total no of bits - total no of leading zero == total no of ones
Patrick Venture0b02be92018-08-31 11:55:55 -0700503 if (((sizeof(buff) * 8) - (__builtin_ctz(buff))) ==
504 __builtin_popcount(buff))
Ratan Guptab8e99552017-07-27 07:07:48 +0530505 {
506 return __builtin_popcount(buff);
507 }
508 else
509 {
510 log<level::ERR>("Invalid Mask",
Joseph Reynolds510eb9c2018-05-30 11:51:28 -0500511 entry("SUBNETMASK=%s", subnetMask.c_str()));
Ratan Guptab8e99552017-07-27 07:07:48 +0530512 return 0;
513 }
514}
515
Ratan Gupta533d03b2017-07-30 10:39:22 +0530516uint32_t getVLAN(const std::string& path)
517{
518 // Path would be look like
519 // /xyz/openbmc_project/network/eth0_443/ipv4
520
521 uint32_t vlanID = 0;
522 try
523 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700524 auto intfObjectPath = path.substr(0, path.find(IP_TYPE) - 1);
Ratan Gupta533d03b2017-07-30 10:39:22 +0530525
526 auto intfName = intfObjectPath.substr(intfObjectPath.rfind("/") + 1);
527
528 auto index = intfName.find("_");
529 if (index != std::string::npos)
530 {
531 auto str = intfName.substr(index + 1);
532 vlanID = std::stoul(str);
533 }
534 }
Patrick Venture0b02be92018-08-31 11:55:55 -0700535 catch (std::exception& e)
Ratan Gupta533d03b2017-07-30 10:39:22 +0530536 {
Gunnar Mills8991dd62017-10-25 17:11:29 -0500537 log<level::ERR>("Exception occurred during getVLAN",
Patrick Venture0b02be92018-08-31 11:55:55 -0700538 entry("PATH=%s", path.c_str()),
Gunnar Mills5b801e42017-10-19 17:11:42 -0500539 entry("EXCEPTION=%s", e.what()));
Ratan Gupta533d03b2017-07-30 10:39:22 +0530540 }
541 return vlanID;
542}
543
Ratan Guptab8e99552017-07-27 07:07:48 +0530544} // namespace network
Tom Josephbe703f72017-03-09 12:34:35 +0530545} // namespace ipmi