blob: b8ba9a7d523286a5cf6241abfaa472c75fc372f6 [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;
18
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -050019namespace network
20{
21
22/** @brief checks if the given ip is Link Local Ip or not.
Patrick Venture0b02be92018-08-31 11:55:55 -070023 * @param[in] ipaddress - IPAddress.
24 */
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -050025bool isLinkLocalIP(const std::string& ipaddress);
26
Patrick Venture0b02be92018-08-31 11:55:55 -070027} // namespace network
Ratan Guptacc8feb42017-07-25 21:52:10 +053028
Patrick Venture0b02be92018-08-31 11:55:55 -070029// TODO There may be cases where an interface is implemented by multiple
Ratan Guptacc8feb42017-07-25 21:52:10 +053030// objects,to handle such cases we are interested on that object
31// which are on interested busname.
32// Currently mapper doesn't give the readable busname(gives busid) so we can't
33// use busname to find the object,will do later once the support is there.
34
Ratan Gupta01d4bd12017-08-07 15:53:25 +053035DbusObjectInfo getDbusObject(sdbusplus::bus::bus& bus,
36 const std::string& interface,
Ratan Guptacc8feb42017-07-25 21:52:10 +053037 const std::string& serviceRoot,
38 const std::string& match)
39{
40 std::vector<DbusInterface> interfaces;
41 interfaces.emplace_back(interface);
42
Ratan Guptacc8feb42017-07-25 21:52:10 +053043 auto depth = 0;
44
Patrick Venture0b02be92018-08-31 11:55:55 -070045 auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ,
46 MAPPER_INTF, "GetSubTree");
Ratan Guptacc8feb42017-07-25 21:52:10 +053047
48 mapperCall.append(serviceRoot, depth, interfaces);
49
50 auto mapperReply = bus.call(mapperCall);
51 if (mapperReply.is_method_error())
52 {
53 log<level::ERR>("Error in mapper call");
54 elog<InternalFailure>();
55 }
56
57 ObjectTree objectTree;
58 mapperReply.read(objectTree);
59
60 if (objectTree.empty())
61 {
Patrick Venturef0c48782017-09-21 18:48:51 -070062 log<level::ERR>("No Object has implemented the interface",
Ratan Guptacc8feb42017-07-25 21:52:10 +053063 entry("INTERFACE=%s", interface.c_str()));
64 elog<InternalFailure>();
65 }
66
67 DbusObjectInfo objectInfo;
68
69 // if match is empty then return the first object
Patrick Venture0b02be92018-08-31 11:55:55 -070070 if (match == "")
Ratan Guptacc8feb42017-07-25 21:52:10 +053071 {
Patrick Venture0b02be92018-08-31 11:55:55 -070072 objectInfo = std::make_pair(
73 objectTree.begin()->first,
Ratan Guptacc8feb42017-07-25 21:52:10 +053074 std::move(objectTree.begin()->second.begin()->first));
75 return objectInfo;
76 }
77
78 // else search the match string in the object path
Patrick Venture2e633522018-10-13 13:51:06 -070079 auto found = std::find_if(
80 objectTree.begin(), objectTree.end(), [&match](const auto& object) {
81 return (object.first.find(match) != std::string::npos);
82 });
Ratan Guptacc8feb42017-07-25 21:52:10 +053083
Patrick Venture2e633522018-10-13 13:51:06 -070084 if (found == objectTree.end())
Ratan Guptacc8feb42017-07-25 21:52:10 +053085 {
86 log<level::ERR>("Failed to find object which matches",
87 entry("MATCH=%s", match.c_str()));
88 elog<InternalFailure>();
Patrick Venture2e633522018-10-13 13:51:06 -070089 // elog<> throws an exception.
Ratan Guptacc8feb42017-07-25 21:52:10 +053090 }
Patrick Venture2e633522018-10-13 13:51:06 -070091
92 return make_pair(found->first, std::move(found->second.begin()->first));
Ratan Guptacc8feb42017-07-25 21:52:10 +053093}
94
Ratan Guptadd646202017-11-21 17:46:59 +053095DbusObjectInfo getIPObject(sdbusplus::bus::bus& bus,
96 const std::string& interface,
97 const std::string& serviceRoot,
98 const std::string& match)
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -050099{
100 auto objectTree = getAllDbusObjects(bus, serviceRoot, interface, match);
101
102 if (objectTree.empty())
103 {
104 log<level::ERR>("No Object has implemented the IP interface",
105 entry("INTERFACE=%s", interface.c_str()));
106 elog<InternalFailure>();
107 }
108
Ratan Guptadd646202017-11-21 17:46:59 +0530109 DbusObjectInfo objectInfo;
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500110
111 for (auto& object : objectTree)
112 {
113 auto variant = ipmi::getDbusProperty(
Patrick Venture0b02be92018-08-31 11:55:55 -0700114 bus, object.second.begin()->first, object.first,
115 ipmi::network::IP_INTERFACE, "Address");
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500116
Patrick Venture0b02be92018-08-31 11:55:55 -0700117 objectInfo = std::make_pair(object.first, object.second.begin()->first);
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500118
119 // if LinkLocalIP found look for Non-LinkLocalIP
Vernon Maueryf442e112019-04-09 11:44:36 -0700120 if (ipmi::network::isLinkLocalIP(std::get<std::string>(variant)))
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500121 {
122 continue;
123 }
124 else
125 {
126 break;
127 }
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500128 }
Ratan Guptadd646202017-11-21 17:46:59 +0530129 return objectInfo;
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500130}
131
Patrick Venture0b02be92018-08-31 11:55:55 -0700132Value getDbusProperty(sdbusplus::bus::bus& bus, const std::string& service,
133 const std::string& objPath, const std::string& interface,
Kun Yi5dcf41e2019-03-05 14:02:51 -0800134 const std::string& property,
135 std::chrono::microseconds timeout)
Ratan Guptacc8feb42017-07-25 21:52:10 +0530136{
137
138 Value value;
139
Patrick Venture0b02be92018-08-31 11:55:55 -0700140 auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
141 PROP_INTF, METHOD_GET);
Ratan Guptacc8feb42017-07-25 21:52:10 +0530142
143 method.append(interface, property);
144
Kun Yi5dcf41e2019-03-05 14:02:51 -0800145 auto reply = bus.call(method, timeout.count());
Ratan Guptacc8feb42017-07-25 21:52:10 +0530146
147 if (reply.is_method_error())
148 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700149 log<level::ERR>("Failed to get property",
150 entry("PROPERTY=%s", property.c_str()),
151 entry("PATH=%s", objPath.c_str()),
152 entry("INTERFACE=%s", interface.c_str()));
Ratan Guptacc8feb42017-07-25 21:52:10 +0530153 elog<InternalFailure>();
154 }
155
156 reply.read(value);
157
158 return value;
159}
160
Ratan Gupta01d4bd12017-08-07 15:53:25 +0530161PropertyMap getAllDbusProperties(sdbusplus::bus::bus& bus,
162 const std::string& service,
Ratan Guptacc8feb42017-07-25 21:52:10 +0530163 const std::string& objPath,
Kun Yi5dcf41e2019-03-05 14:02:51 -0800164 const std::string& interface,
165 std::chrono::microseconds timeout)
Ratan Guptacc8feb42017-07-25 21:52:10 +0530166{
167 PropertyMap properties;
Ratan Guptacc8feb42017-07-25 21:52:10 +0530168
Patrick Venture0b02be92018-08-31 11:55:55 -0700169 auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
170 PROP_INTF, METHOD_GET_ALL);
Ratan Guptacc8feb42017-07-25 21:52:10 +0530171
172 method.append(interface);
173
Kun Yi5dcf41e2019-03-05 14:02:51 -0800174 auto reply = bus.call(method, timeout.count());
Ratan Guptacc8feb42017-07-25 21:52:10 +0530175
176 if (reply.is_method_error())
177 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700178 log<level::ERR>("Failed to get all properties",
179 entry("PATH=%s", objPath.c_str()),
180 entry("INTERFACE=%s", interface.c_str()));
181 elog<InternalFailure>();
Ratan Guptacc8feb42017-07-25 21:52:10 +0530182 }
183
184 reply.read(properties);
185 return properties;
186}
187
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600188ObjectValueTree getManagedObjects(sdbusplus::bus::bus& bus,
Patrick Venture0b02be92018-08-31 11:55:55 -0700189 const std::string& service,
190 const std::string& objPath)
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600191{
192 ipmi::ObjectValueTree interfaces;
193
Patrick Venture0b02be92018-08-31 11:55:55 -0700194 auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
195 "org.freedesktop.DBus.ObjectManager",
196 "GetManagedObjects");
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600197
198 auto reply = bus.call(method);
199
200 if (reply.is_method_error())
201 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700202 log<level::ERR>("Failed to get managed objects",
203 entry("PATH=%s", objPath.c_str()));
204 elog<InternalFailure>();
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600205 }
206
207 reply.read(interfaces);
208 return interfaces;
209}
210
Patrick Venture0b02be92018-08-31 11:55:55 -0700211void setDbusProperty(sdbusplus::bus::bus& bus, const std::string& service,
212 const std::string& objPath, const std::string& interface,
Kun Yi5dcf41e2019-03-05 14:02:51 -0800213 const std::string& property, const Value& value,
214 std::chrono::microseconds timeout)
Ratan Guptacc8feb42017-07-25 21:52:10 +0530215{
Patrick Venture0b02be92018-08-31 11:55:55 -0700216 auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
217 PROP_INTF, METHOD_SET);
Ratan Guptacc8feb42017-07-25 21:52:10 +0530218
219 method.append(interface, property, value);
220
Kun Yi5dcf41e2019-03-05 14:02:51 -0800221 if (!bus.call(method, timeout.count()))
Ratan Guptacc8feb42017-07-25 21:52:10 +0530222 {
223 log<level::ERR>("Failed to set property",
224 entry("PROPERTY=%s", property.c_str()),
Patrick Venture0b02be92018-08-31 11:55:55 -0700225 entry("PATH=%s", objPath.c_str()),
226 entry("INTERFACE=%s", interface.c_str()));
Ratan Guptacc8feb42017-07-25 21:52:10 +0530227 elog<InternalFailure>();
228 }
Ratan Guptacc8feb42017-07-25 21:52:10 +0530229}
230
Patrick Venture0b02be92018-08-31 11:55:55 -0700231ServiceCache::ServiceCache(const std::string& intf, const std::string& path) :
Vernon Mauery54012502018-11-07 10:17:31 -0800232 intf(intf), path(path), cachedService(std::nullopt),
233 cachedBusName(std::nullopt)
William A. Kennington IIIe47fdfb2018-03-15 17:09:28 -0700234{
235}
236
Patrick Venture0b02be92018-08-31 11:55:55 -0700237ServiceCache::ServiceCache(std::string&& intf, std::string&& path) :
Vernon Mauery54012502018-11-07 10:17:31 -0800238 intf(std::move(intf)), path(std::move(path)), cachedService(std::nullopt),
239 cachedBusName(std::nullopt)
William A. Kennington IIIe47fdfb2018-03-15 17:09:28 -0700240{
241}
242
243const std::string& ServiceCache::getService(sdbusplus::bus::bus& bus)
244{
245 if (!isValid(bus))
246 {
247 cachedBusName = bus.get_unique_name();
248 cachedService = ::ipmi::getService(bus, intf, path);
249 }
250 return cachedService.value();
251}
252
253void ServiceCache::invalidate()
254{
Vernon Mauery54012502018-11-07 10:17:31 -0800255 cachedBusName = std::nullopt;
256 cachedService = std::nullopt;
William A. Kennington IIIe47fdfb2018-03-15 17:09:28 -0700257}
258
Patrick Venture0b02be92018-08-31 11:55:55 -0700259sdbusplus::message::message
260 ServiceCache::newMethodCall(sdbusplus::bus::bus& bus, const char* intf,
261 const char* method)
William A. Kennington IIIe47fdfb2018-03-15 17:09:28 -0700262{
Patrick Venture0b02be92018-08-31 11:55:55 -0700263 return bus.new_method_call(getService(bus).c_str(), path.c_str(), intf,
264 method);
William A. Kennington IIIe47fdfb2018-03-15 17:09:28 -0700265}
266
267bool ServiceCache::isValid(sdbusplus::bus::bus& bus) const
268{
269 return cachedService && cachedBusName == bus.get_unique_name();
270}
271
Patrick Venture0b02be92018-08-31 11:55:55 -0700272std::string getService(sdbusplus::bus::bus& bus, const std::string& intf,
Tom Josephbe703f72017-03-09 12:34:35 +0530273 const std::string& path)
274{
Patrick Venture0b02be92018-08-31 11:55:55 -0700275 auto mapperCall =
276 bus.new_method_call("xyz.openbmc_project.ObjectMapper",
277 "/xyz/openbmc_project/object_mapper",
278 "xyz.openbmc_project.ObjectMapper", "GetObject");
Tom Josephbe703f72017-03-09 12:34:35 +0530279
280 mapperCall.append(path);
281 mapperCall.append(std::vector<std::string>({intf}));
282
283 auto mapperResponseMsg = bus.call(mapperCall);
284
285 if (mapperResponseMsg.is_method_error())
286 {
287 throw std::runtime_error("ERROR in mapper call");
288 }
289
290 std::map<std::string, std::vector<std::string>> mapperResponse;
291 mapperResponseMsg.read(mapperResponse);
292
293 if (mapperResponse.begin() == mapperResponse.end())
294 {
295 throw std::runtime_error("ERROR in reading the mapper response");
296 }
297
298 return mapperResponse.begin()->first;
299}
300
Ratan Guptab8e99552017-07-27 07:07:48 +0530301ipmi::ObjectTree getAllDbusObjects(sdbusplus::bus::bus& bus,
302 const std::string& serviceRoot,
303 const std::string& interface,
304 const std::string& match)
305{
306 std::vector<std::string> interfaces;
307 interfaces.emplace_back(interface);
Ratan Guptacc8feb42017-07-25 21:52:10 +0530308
Ratan Guptab8e99552017-07-27 07:07:48 +0530309 auto depth = 0;
310
Patrick Venture0b02be92018-08-31 11:55:55 -0700311 auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ,
312 MAPPER_INTF, "GetSubTree");
Ratan Guptab8e99552017-07-27 07:07:48 +0530313
314 mapperCall.append(serviceRoot, depth, interfaces);
315
316 auto mapperReply = bus.call(mapperCall);
317 if (mapperReply.is_method_error())
318 {
319 log<level::ERR>("Error in mapper call",
Patrick Venture0b02be92018-08-31 11:55:55 -0700320 entry("SERVICEROOT=%s", serviceRoot.c_str()),
Ratan Guptab8e99552017-07-27 07:07:48 +0530321 entry("INTERFACE=%s", interface.c_str()));
322
323 elog<InternalFailure>();
324 }
325
326 ObjectTree objectTree;
327 mapperReply.read(objectTree);
328
329 for (auto it = objectTree.begin(); it != objectTree.end();)
330 {
331 if (it->first.find(match) == std::string::npos)
332 {
333 it = objectTree.erase(it);
334 }
335 else
336 {
337 ++it;
338 }
339 }
340
341 return objectTree;
342}
343
344void deleteAllDbusObjects(sdbusplus::bus::bus& bus,
345 const std::string& serviceRoot,
346 const std::string& interface,
347 const std::string& match)
348{
349 try
350 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700351 auto objectTree = getAllDbusObjects(bus, serviceRoot, interface, match);
Ratan Guptab8e99552017-07-27 07:07:48 +0530352
353 for (auto& object : objectTree)
354 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700355 method_no_args::callDbusMethod(bus, object.second.begin()->first,
356 object.first, DELETE_INTERFACE,
357 "Delete");
Ratan Guptab8e99552017-07-27 07:07:48 +0530358 }
359 }
Vernon Mauery7a614182018-11-27 12:54:52 -0800360 catch (sdbusplus::exception::exception& e)
Ratan Guptab8e99552017-07-27 07:07:48 +0530361 {
Vernon Mauery7a614182018-11-27 12:54:52 -0800362 log<level::INFO>("sdbusplus exception - Unable to delete the objects",
363 entry("ERROR=%s", e.what()),
Ratan Guptab8e99552017-07-27 07:07:48 +0530364 entry("INTERFACE=%s", interface.c_str()),
365 entry("SERVICE=%s", serviceRoot.c_str()));
366 }
367}
368
Patrick Venture0b02be92018-08-31 11:55:55 -0700369ObjectTree getAllAncestors(sdbusplus::bus::bus& bus, const std::string& path,
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530370 InterfaceList&& interfaces)
371{
Patrick Venture0b02be92018-08-31 11:55:55 -0700372 auto convertToString = [](InterfaceList& interfaces) -> std::string {
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530373 std::string intfStr;
374 for (const auto& intf : interfaces)
375 {
376 intfStr += "," + intf;
377 }
378 return intfStr;
379 };
380
Patrick Venture0b02be92018-08-31 11:55:55 -0700381 auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ,
382 MAPPER_INTF, "GetAncestors");
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530383 mapperCall.append(path, interfaces);
384
385 auto mapperReply = bus.call(mapperCall);
386 if (mapperReply.is_method_error())
387 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700388 log<level::ERR>(
389 "Error in mapper call", entry("PATH=%s", path.c_str()),
390 entry("INTERFACES=%s", convertToString(interfaces).c_str()));
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530391
392 elog<InternalFailure>();
393 }
394
395 ObjectTree objectTree;
396 mapperReply.read(objectTree);
397
398 if (objectTree.empty())
399 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700400 log<level::ERR>(
401 "No Object has implemented the interface",
402 entry("PATH=%s", path.c_str()),
403 entry("INTERFACES=%s", convertToString(interfaces).c_str()));
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530404 elog<InternalFailure>();
405 }
406
407 return objectTree;
408}
Ratan Guptab8e99552017-07-27 07:07:48 +0530409
410namespace method_no_args
411{
412
Patrick Venture0b02be92018-08-31 11:55:55 -0700413void callDbusMethod(sdbusplus::bus::bus& bus, const std::string& service,
414 const std::string& objPath, const std::string& interface,
Ratan Guptab8e99552017-07-27 07:07:48 +0530415 const std::string& method)
416
417{
Patrick Venture0b02be92018-08-31 11:55:55 -0700418 auto busMethod = bus.new_method_call(service.c_str(), objPath.c_str(),
419 interface.c_str(), method.c_str());
Ratan Guptab8e99552017-07-27 07:07:48 +0530420
421 auto reply = bus.call(busMethod);
422
423 if (reply.is_method_error())
424 {
425 log<level::ERR>("Failed to execute method",
426 entry("METHOD=%s", method.c_str()),
427 entry("PATH=%s", objPath.c_str()),
428 entry("INTERFACE=%s", interface.c_str()));
429 elog<InternalFailure>();
430 }
431}
432
Patrick Venture0b02be92018-08-31 11:55:55 -0700433} // namespace method_no_args
Ratan Guptab8e99552017-07-27 07:07:48 +0530434
435namespace network
436{
437
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500438bool isLinkLocalIP(const std::string& address)
439{
440 return address.find(IPV4_PREFIX) == 0 || address.find(IPV6_PREFIX) == 0;
441}
442
Patrick Venture0b02be92018-08-31 11:55:55 -0700443void createIP(sdbusplus::bus::bus& bus, const std::string& service,
444 const std::string& objPath, const std::string& protocolType,
445 const std::string& ipaddress, uint8_t prefix)
Ratan Guptab8e99552017-07-27 07:07:48 +0530446{
447 std::string gateway = "";
448
Patrick Venture0b02be92018-08-31 11:55:55 -0700449 auto busMethod = bus.new_method_call(service.c_str(), objPath.c_str(),
450 IP_CREATE_INTERFACE, "IP");
Ratan Guptab8e99552017-07-27 07:07:48 +0530451
452 busMethod.append(protocolType, ipaddress, prefix, gateway);
453
454 auto reply = bus.call(busMethod);
455
456 if (reply.is_method_error())
457 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700458 log<level::ERR>("Failed to execute method", entry("METHOD=%s", "IP"),
Ratan Guptab8e99552017-07-27 07:07:48 +0530459 entry("PATH=%s", objPath.c_str()));
460 elog<InternalFailure>();
461 }
Ratan Guptab8e99552017-07-27 07:07:48 +0530462}
463
Patrick Venture0b02be92018-08-31 11:55:55 -0700464void createVLAN(sdbusplus::bus::bus& bus, const std::string& service,
465 const std::string& objPath, const std::string& interfaceName,
Ratan Gupta533d03b2017-07-30 10:39:22 +0530466 uint32_t vlanID)
467{
Patrick Venture0b02be92018-08-31 11:55:55 -0700468 auto busMethod = bus.new_method_call(service.c_str(), objPath.c_str(),
469 VLAN_CREATE_INTERFACE, "VLAN");
Ratan Gupta533d03b2017-07-30 10:39:22 +0530470
471 busMethod.append(interfaceName, vlanID);
472
473 auto reply = bus.call(busMethod);
474
475 if (reply.is_method_error())
476 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700477 log<level::ERR>("Failed to execute method", entry("METHOD=%s", "VLAN"),
Ratan Gupta533d03b2017-07-30 10:39:22 +0530478 entry("PATH=%s", objPath.c_str()));
479 elog<InternalFailure>();
480 }
Ratan Gupta533d03b2017-07-30 10:39:22 +0530481}
482
Ratan Guptab8e99552017-07-27 07:07:48 +0530483uint8_t toPrefix(int addressFamily, const std::string& subnetMask)
484{
485 if (addressFamily == AF_INET6)
486 {
487 return 0;
488 }
489
Patrick Venture0b02be92018-08-31 11:55:55 -0700490 uint32_t buff{};
Ratan Guptab8e99552017-07-27 07:07:48 +0530491
492 auto rc = inet_pton(addressFamily, subnetMask.c_str(), &buff);
493 if (rc <= 0)
494 {
495 log<level::ERR>("inet_pton failed:",
Joseph Reynolds510eb9c2018-05-30 11:51:28 -0500496 entry("SUBNETMASK=%s", subnetMask.c_str()));
Ratan Guptab8e99552017-07-27 07:07:48 +0530497 return 0;
498 }
499
500 buff = be32toh(buff);
501 // total no of bits - total no of leading zero == total no of ones
Patrick Venture0b02be92018-08-31 11:55:55 -0700502 if (((sizeof(buff) * 8) - (__builtin_ctz(buff))) ==
503 __builtin_popcount(buff))
Ratan Guptab8e99552017-07-27 07:07:48 +0530504 {
505 return __builtin_popcount(buff);
506 }
507 else
508 {
509 log<level::ERR>("Invalid Mask",
Joseph Reynolds510eb9c2018-05-30 11:51:28 -0500510 entry("SUBNETMASK=%s", subnetMask.c_str()));
Ratan Guptab8e99552017-07-27 07:07:48 +0530511 return 0;
512 }
513}
514
Ratan Gupta533d03b2017-07-30 10:39:22 +0530515uint32_t getVLAN(const std::string& path)
516{
517 // Path would be look like
518 // /xyz/openbmc_project/network/eth0_443/ipv4
519
520 uint32_t vlanID = 0;
521 try
522 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700523 auto intfObjectPath = path.substr(0, path.find(IP_TYPE) - 1);
Ratan Gupta533d03b2017-07-30 10:39:22 +0530524
525 auto intfName = intfObjectPath.substr(intfObjectPath.rfind("/") + 1);
526
527 auto index = intfName.find("_");
528 if (index != std::string::npos)
529 {
530 auto str = intfName.substr(index + 1);
531 vlanID = std::stoul(str);
532 }
533 }
Patrick Venture0b02be92018-08-31 11:55:55 -0700534 catch (std::exception& e)
Ratan Gupta533d03b2017-07-30 10:39:22 +0530535 {
Gunnar Mills8991dd62017-10-25 17:11:29 -0500536 log<level::ERR>("Exception occurred during getVLAN",
Patrick Venture0b02be92018-08-31 11:55:55 -0700537 entry("PATH=%s", path.c_str()),
Gunnar Mills5b801e42017-10-19 17:11:42 -0500538 entry("EXCEPTION=%s", e.what()));
Ratan Gupta533d03b2017-07-30 10:39:22 +0530539 }
540 return vlanID;
541}
542
Ratan Guptab8e99552017-07-27 07:07:48 +0530543} // namespace network
Tom Josephbe703f72017-03-09 12:34:35 +0530544} // namespace ipmi