blob: 7807e7647a1ea9aecdcb8796b7f3614733bd9c63 [file] [log] [blame]
Tom Josephbe703f72017-03-09 12:34:35 +05301#include "utils.hpp"
2
Ratan Guptab8e99552017-07-27 07:07:48 +05303#include <arpa/inet.h>
4#include <dirent.h>
5#include <net/if.h>
6
Patrick Venture2e633522018-10-13 13:51:06 -07007#include <algorithm>
Kun Yi5dcf41e2019-03-05 14:02:51 -08008#include <chrono>
Patrick Venture0b02be92018-08-31 11:55:55 -07009#include <phosphor-logging/elog-errors.hpp>
10#include <phosphor-logging/log.hpp>
William A. Kennington III4c008022018-10-12 17:18:14 -070011#include <sdbusplus/message/types.hpp>
Patrick Venture0b02be92018-08-31 11:55:55 -070012#include <xyz/openbmc_project/Common/error.hpp>
13
Tom Josephbe703f72017-03-09 12:34:35 +053014namespace ipmi
15{
16
Ratan Guptacc8feb42017-07-25 21:52:10 +053017using namespace phosphor::logging;
18using namespace sdbusplus::xyz::openbmc_project::Common::Error;
William A. Kennington III4c008022018-10-12 17:18:14 -070019namespace variant_ns = sdbusplus::message::variant_ns;
Ratan Guptacc8feb42017-07-25 21:52:10 +053020
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -050021namespace network
22{
23
24/** @brief checks if the given ip is Link Local Ip or not.
Patrick Venture0b02be92018-08-31 11:55:55 -070025 * @param[in] ipaddress - IPAddress.
26 */
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -050027bool isLinkLocalIP(const std::string& ipaddress);
28
Patrick Venture0b02be92018-08-31 11:55:55 -070029} // namespace network
Ratan Guptacc8feb42017-07-25 21:52:10 +053030
Patrick Venture0b02be92018-08-31 11:55:55 -070031// TODO There may be cases where an interface is implemented by multiple
Ratan Guptacc8feb42017-07-25 21:52:10 +053032// objects,to handle such cases we are interested on that object
33// which are on interested busname.
34// Currently mapper doesn't give the readable busname(gives busid) so we can't
35// use busname to find the object,will do later once the support is there.
36
Ratan Gupta01d4bd12017-08-07 15:53:25 +053037DbusObjectInfo getDbusObject(sdbusplus::bus::bus& bus,
38 const std::string& interface,
Ratan Guptacc8feb42017-07-25 21:52:10 +053039 const std::string& serviceRoot,
40 const std::string& match)
41{
42 std::vector<DbusInterface> interfaces;
43 interfaces.emplace_back(interface);
44
Ratan Guptacc8feb42017-07-25 21:52:10 +053045 auto depth = 0;
46
Patrick Venture0b02be92018-08-31 11:55:55 -070047 auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ,
48 MAPPER_INTF, "GetSubTree");
Ratan Guptacc8feb42017-07-25 21:52:10 +053049
50 mapperCall.append(serviceRoot, depth, interfaces);
51
52 auto mapperReply = bus.call(mapperCall);
53 if (mapperReply.is_method_error())
54 {
55 log<level::ERR>("Error in mapper call");
56 elog<InternalFailure>();
57 }
58
59 ObjectTree objectTree;
60 mapperReply.read(objectTree);
61
62 if (objectTree.empty())
63 {
Patrick Venturef0c48782017-09-21 18:48:51 -070064 log<level::ERR>("No Object has implemented the interface",
Ratan Guptacc8feb42017-07-25 21:52:10 +053065 entry("INTERFACE=%s", interface.c_str()));
66 elog<InternalFailure>();
67 }
68
69 DbusObjectInfo objectInfo;
70
71 // if match is empty then return the first object
Patrick Venture0b02be92018-08-31 11:55:55 -070072 if (match == "")
Ratan Guptacc8feb42017-07-25 21:52:10 +053073 {
Patrick Venture0b02be92018-08-31 11:55:55 -070074 objectInfo = std::make_pair(
75 objectTree.begin()->first,
Ratan Guptacc8feb42017-07-25 21:52:10 +053076 std::move(objectTree.begin()->second.begin()->first));
77 return objectInfo;
78 }
79
80 // else search the match string in the object path
Patrick Venture2e633522018-10-13 13:51:06 -070081 auto found = std::find_if(
82 objectTree.begin(), objectTree.end(), [&match](const auto& object) {
83 return (object.first.find(match) != std::string::npos);
84 });
Ratan Guptacc8feb42017-07-25 21:52:10 +053085
Patrick Venture2e633522018-10-13 13:51:06 -070086 if (found == objectTree.end())
Ratan Guptacc8feb42017-07-25 21:52:10 +053087 {
88 log<level::ERR>("Failed to find object which matches",
89 entry("MATCH=%s", match.c_str()));
90 elog<InternalFailure>();
Patrick Venture2e633522018-10-13 13:51:06 -070091 // elog<> throws an exception.
Ratan Guptacc8feb42017-07-25 21:52:10 +053092 }
Patrick Venture2e633522018-10-13 13:51:06 -070093
94 return make_pair(found->first, std::move(found->second.begin()->first));
Ratan Guptacc8feb42017-07-25 21:52:10 +053095}
96
Ratan Guptadd646202017-11-21 17:46:59 +053097DbusObjectInfo getIPObject(sdbusplus::bus::bus& bus,
98 const std::string& interface,
99 const std::string& serviceRoot,
100 const std::string& match)
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500101{
102 auto objectTree = getAllDbusObjects(bus, serviceRoot, interface, match);
103
104 if (objectTree.empty())
105 {
106 log<level::ERR>("No Object has implemented the IP interface",
107 entry("INTERFACE=%s", interface.c_str()));
108 elog<InternalFailure>();
109 }
110
Ratan Guptadd646202017-11-21 17:46:59 +0530111 DbusObjectInfo objectInfo;
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500112
113 for (auto& object : objectTree)
114 {
115 auto variant = ipmi::getDbusProperty(
Patrick Venture0b02be92018-08-31 11:55:55 -0700116 bus, object.second.begin()->first, object.first,
117 ipmi::network::IP_INTERFACE, "Address");
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500118
Patrick Venture0b02be92018-08-31 11:55:55 -0700119 objectInfo = std::make_pair(object.first, object.second.begin()->first);
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500120
121 // if LinkLocalIP found look for Non-LinkLocalIP
William A. Kennington III4c008022018-10-12 17:18:14 -0700122 if (ipmi::network::isLinkLocalIP(variant_ns::get<std::string>(variant)))
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500123 {
124 continue;
125 }
126 else
127 {
128 break;
129 }
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500130 }
Ratan Guptadd646202017-11-21 17:46:59 +0530131 return objectInfo;
Nagaraju Goruganti1fe5c832017-09-21 07:44:17 -0500132}
133
Patrick Venture0b02be92018-08-31 11:55:55 -0700134Value getDbusProperty(sdbusplus::bus::bus& bus, const std::string& service,
135 const std::string& objPath, const std::string& interface,
Kun Yi5dcf41e2019-03-05 14:02:51 -0800136 const std::string& property,
137 std::chrono::microseconds timeout)
Ratan Guptacc8feb42017-07-25 21:52:10 +0530138{
139
140 Value value;
141
Patrick Venture0b02be92018-08-31 11:55:55 -0700142 auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
143 PROP_INTF, METHOD_GET);
Ratan Guptacc8feb42017-07-25 21:52:10 +0530144
145 method.append(interface, property);
146
Kun Yi5dcf41e2019-03-05 14:02:51 -0800147 auto reply = bus.call(method, timeout.count());
Ratan Guptacc8feb42017-07-25 21:52:10 +0530148
149 if (reply.is_method_error())
150 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700151 log<level::ERR>("Failed to get property",
152 entry("PROPERTY=%s", property.c_str()),
153 entry("PATH=%s", objPath.c_str()),
154 entry("INTERFACE=%s", interface.c_str()));
Ratan Guptacc8feb42017-07-25 21:52:10 +0530155 elog<InternalFailure>();
156 }
157
158 reply.read(value);
159
160 return value;
161}
162
Ratan Gupta01d4bd12017-08-07 15:53:25 +0530163PropertyMap getAllDbusProperties(sdbusplus::bus::bus& bus,
164 const std::string& service,
Ratan Guptacc8feb42017-07-25 21:52:10 +0530165 const std::string& objPath,
Kun Yi5dcf41e2019-03-05 14:02:51 -0800166 const std::string& interface,
167 std::chrono::microseconds timeout)
Ratan Guptacc8feb42017-07-25 21:52:10 +0530168{
169 PropertyMap properties;
Ratan Guptacc8feb42017-07-25 21:52:10 +0530170
Patrick Venture0b02be92018-08-31 11:55:55 -0700171 auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
172 PROP_INTF, METHOD_GET_ALL);
Ratan Guptacc8feb42017-07-25 21:52:10 +0530173
174 method.append(interface);
175
Kun Yi5dcf41e2019-03-05 14:02:51 -0800176 auto reply = bus.call(method, timeout.count());
Ratan Guptacc8feb42017-07-25 21:52:10 +0530177
178 if (reply.is_method_error())
179 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700180 log<level::ERR>("Failed to get all properties",
181 entry("PATH=%s", objPath.c_str()),
182 entry("INTERFACE=%s", interface.c_str()));
183 elog<InternalFailure>();
Ratan Guptacc8feb42017-07-25 21:52:10 +0530184 }
185
186 reply.read(properties);
187 return properties;
188}
189
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600190ObjectValueTree getManagedObjects(sdbusplus::bus::bus& bus,
Patrick Venture0b02be92018-08-31 11:55:55 -0700191 const std::string& service,
192 const std::string& objPath)
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600193{
194 ipmi::ObjectValueTree interfaces;
195
Patrick Venture0b02be92018-08-31 11:55:55 -0700196 auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
197 "org.freedesktop.DBus.ObjectManager",
198 "GetManagedObjects");
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600199
200 auto reply = bus.call(method);
201
202 if (reply.is_method_error())
203 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700204 log<level::ERR>("Failed to get managed objects",
205 entry("PATH=%s", objPath.c_str()));
206 elog<InternalFailure>();
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600207 }
208
209 reply.read(interfaces);
210 return interfaces;
211}
212
Patrick Venture0b02be92018-08-31 11:55:55 -0700213void setDbusProperty(sdbusplus::bus::bus& bus, const std::string& service,
214 const std::string& objPath, const std::string& interface,
Kun Yi5dcf41e2019-03-05 14:02:51 -0800215 const std::string& property, const Value& value,
216 std::chrono::microseconds timeout)
Ratan Guptacc8feb42017-07-25 21:52:10 +0530217{
Patrick Venture0b02be92018-08-31 11:55:55 -0700218 auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
219 PROP_INTF, METHOD_SET);
Ratan Guptacc8feb42017-07-25 21:52:10 +0530220
221 method.append(interface, property, value);
222
Kun Yi5dcf41e2019-03-05 14:02:51 -0800223 if (!bus.call(method, timeout.count()))
Ratan Guptacc8feb42017-07-25 21:52:10 +0530224 {
225 log<level::ERR>("Failed to set property",
226 entry("PROPERTY=%s", property.c_str()),
Patrick Venture0b02be92018-08-31 11:55:55 -0700227 entry("PATH=%s", objPath.c_str()),
228 entry("INTERFACE=%s", interface.c_str()));
Ratan Guptacc8feb42017-07-25 21:52:10 +0530229 elog<InternalFailure>();
230 }
Ratan Guptacc8feb42017-07-25 21:52:10 +0530231}
232
Patrick Venture0b02be92018-08-31 11:55:55 -0700233ServiceCache::ServiceCache(const std::string& intf, const std::string& path) :
Vernon Mauery54012502018-11-07 10:17:31 -0800234 intf(intf), path(path), cachedService(std::nullopt),
235 cachedBusName(std::nullopt)
William A. Kennington IIIe47fdfb2018-03-15 17:09:28 -0700236{
237}
238
Patrick Venture0b02be92018-08-31 11:55:55 -0700239ServiceCache::ServiceCache(std::string&& intf, std::string&& path) :
Vernon Mauery54012502018-11-07 10:17:31 -0800240 intf(std::move(intf)), path(std::move(path)), cachedService(std::nullopt),
241 cachedBusName(std::nullopt)
William A. Kennington IIIe47fdfb2018-03-15 17:09:28 -0700242{
243}
244
245const std::string& ServiceCache::getService(sdbusplus::bus::bus& bus)
246{
247 if (!isValid(bus))
248 {
249 cachedBusName = bus.get_unique_name();
250 cachedService = ::ipmi::getService(bus, intf, path);
251 }
252 return cachedService.value();
253}
254
255void ServiceCache::invalidate()
256{
Vernon Mauery54012502018-11-07 10:17:31 -0800257 cachedBusName = std::nullopt;
258 cachedService = std::nullopt;
William A. Kennington IIIe47fdfb2018-03-15 17:09:28 -0700259}
260
Patrick Venture0b02be92018-08-31 11:55:55 -0700261sdbusplus::message::message
262 ServiceCache::newMethodCall(sdbusplus::bus::bus& bus, const char* intf,
263 const char* method)
William A. Kennington IIIe47fdfb2018-03-15 17:09:28 -0700264{
Patrick Venture0b02be92018-08-31 11:55:55 -0700265 return bus.new_method_call(getService(bus).c_str(), path.c_str(), intf,
266 method);
William A. Kennington IIIe47fdfb2018-03-15 17:09:28 -0700267}
268
269bool ServiceCache::isValid(sdbusplus::bus::bus& bus) const
270{
271 return cachedService && cachedBusName == bus.get_unique_name();
272}
273
Patrick Venture0b02be92018-08-31 11:55:55 -0700274std::string getService(sdbusplus::bus::bus& bus, const std::string& intf,
Tom Josephbe703f72017-03-09 12:34:35 +0530275 const std::string& path)
276{
Patrick Venture0b02be92018-08-31 11:55:55 -0700277 auto mapperCall =
278 bus.new_method_call("xyz.openbmc_project.ObjectMapper",
279 "/xyz/openbmc_project/object_mapper",
280 "xyz.openbmc_project.ObjectMapper", "GetObject");
Tom Josephbe703f72017-03-09 12:34:35 +0530281
282 mapperCall.append(path);
283 mapperCall.append(std::vector<std::string>({intf}));
284
285 auto mapperResponseMsg = bus.call(mapperCall);
286
287 if (mapperResponseMsg.is_method_error())
288 {
289 throw std::runtime_error("ERROR in mapper call");
290 }
291
292 std::map<std::string, std::vector<std::string>> mapperResponse;
293 mapperResponseMsg.read(mapperResponse);
294
295 if (mapperResponse.begin() == mapperResponse.end())
296 {
297 throw std::runtime_error("ERROR in reading the mapper response");
298 }
299
300 return mapperResponse.begin()->first;
301}
302
Ratan Guptab8e99552017-07-27 07:07:48 +0530303ipmi::ObjectTree getAllDbusObjects(sdbusplus::bus::bus& bus,
304 const std::string& serviceRoot,
305 const std::string& interface,
306 const std::string& match)
307{
308 std::vector<std::string> interfaces;
309 interfaces.emplace_back(interface);
Ratan Guptacc8feb42017-07-25 21:52:10 +0530310
Ratan Guptab8e99552017-07-27 07:07:48 +0530311 auto depth = 0;
312
Patrick Venture0b02be92018-08-31 11:55:55 -0700313 auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ,
314 MAPPER_INTF, "GetSubTree");
Ratan Guptab8e99552017-07-27 07:07:48 +0530315
316 mapperCall.append(serviceRoot, depth, interfaces);
317
318 auto mapperReply = bus.call(mapperCall);
319 if (mapperReply.is_method_error())
320 {
321 log<level::ERR>("Error in mapper call",
Patrick Venture0b02be92018-08-31 11:55:55 -0700322 entry("SERVICEROOT=%s", serviceRoot.c_str()),
Ratan Guptab8e99552017-07-27 07:07:48 +0530323 entry("INTERFACE=%s", interface.c_str()));
324
325 elog<InternalFailure>();
326 }
327
328 ObjectTree objectTree;
329 mapperReply.read(objectTree);
330
331 for (auto it = objectTree.begin(); it != objectTree.end();)
332 {
333 if (it->first.find(match) == std::string::npos)
334 {
335 it = objectTree.erase(it);
336 }
337 else
338 {
339 ++it;
340 }
341 }
342
343 return objectTree;
344}
345
346void deleteAllDbusObjects(sdbusplus::bus::bus& bus,
347 const std::string& serviceRoot,
348 const std::string& interface,
349 const std::string& match)
350{
351 try
352 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700353 auto objectTree = getAllDbusObjects(bus, serviceRoot, interface, match);
Ratan Guptab8e99552017-07-27 07:07:48 +0530354
355 for (auto& object : objectTree)
356 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700357 method_no_args::callDbusMethod(bus, object.second.begin()->first,
358 object.first, DELETE_INTERFACE,
359 "Delete");
Ratan Guptab8e99552017-07-27 07:07:48 +0530360 }
361 }
362 catch (InternalFailure& e)
363 {
364 log<level::INFO>("Unable to delete the objects having",
365 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