blob: 06eb254642aa4de3b8f18bc7e4cec31795e181ed [file] [log] [blame]
Patrick Venture189d44e2018-07-09 12:30:59 -07001#include "ncsi_util.hpp"
2
Eddie Jamesfa1f5c02020-09-17 15:12:46 -05003#include <fmt/format.h>
Ratan Guptabbe45792018-03-23 00:22:55 +05304#include <linux/ncsi.h>
Ratan Guptabbe45792018-03-23 00:22:55 +05305#include <netlink/genl/ctrl.h>
Gunnar Mills57d9c502018-09-14 14:42:34 -05006#include <netlink/genl/genl.h>
7#include <netlink/netlink.h>
Ratan Guptabbe45792018-03-23 00:22:55 +05308
Eddie Jamesfa1f5c02020-09-17 15:12:46 -05009#include <iomanip>
Manojkiran Edae5a867a2020-06-01 18:08:30 +053010#include <iostream>
Jiaqing Zhao7c44a782022-04-10 15:30:04 +080011#include <vector>
Ratan Guptabbe45792018-03-23 00:22:55 +053012
13namespace phosphor
14{
15namespace network
16{
17namespace ncsi
18{
19
Gunnar Mills57d9c502018-09-14 14:42:34 -050020using CallBack = int (*)(struct nl_msg* msg, void* arg);
Ratan Guptaaac603e2018-03-23 00:25:54 +053021
22namespace internal
23{
Ratan Guptabbe45792018-03-23 00:22:55 +053024
Eddie Jamesfa1f5c02020-09-17 15:12:46 -050025struct NCSIPacketHeader
26{
27 uint8_t MCID;
28 uint8_t revision;
29 uint8_t reserved;
30 uint8_t id;
31 uint8_t type;
32 uint8_t channel;
33 uint16_t length;
34 uint32_t rsvd[2];
35};
36
37class Command
38{
39 public:
40 Command() = delete;
41 ~Command() = default;
42 Command(const Command&) = delete;
43 Command& operator=(const Command&) = delete;
44 Command(Command&&) = default;
45 Command& operator=(Command&&) = default;
46 Command(
47 int c, int nc = DEFAULT_VALUE,
48 std::span<const unsigned char> p = std::span<const unsigned char>()) :
49 cmd(c),
50 ncsi_cmd(nc), payload(p)
51 {
52 }
53
54 int cmd;
55 int ncsi_cmd;
56 std::span<const unsigned char> payload;
57};
58
Ratan Guptabbe45792018-03-23 00:22:55 +053059using nlMsgPtr = std::unique_ptr<nl_msg, decltype(&::nlmsg_free)>;
60using nlSocketPtr = std::unique_ptr<nl_sock, decltype(&::nl_socket_free)>;
61
Eddie Jamesfa1f5c02020-09-17 15:12:46 -050062CallBack infoCallBack = [](struct nl_msg* msg, void* arg) {
Ratan Guptaaac603e2018-03-23 00:25:54 +053063 using namespace phosphor::network::ncsi;
64 auto nlh = nlmsg_hdr(msg);
65
Gunnar Mills57d9c502018-09-14 14:42:34 -050066 struct nlattr* tb[NCSI_ATTR_MAX + 1] = {nullptr};
67 struct nla_policy ncsiPolicy[NCSI_ATTR_MAX + 1] = {
William A. Kennington III05368f12021-05-13 18:40:47 -070068 {NLA_UNSPEC, 0, 0}, {NLA_U32, 0, 0}, {NLA_NESTED, 0, 0},
69 {NLA_U32, 0, 0}, {NLA_U32, 0, 0},
Ratan Guptaaac603e2018-03-23 00:25:54 +053070 };
71
Gunnar Mills57d9c502018-09-14 14:42:34 -050072 struct nlattr* packagetb[NCSI_PKG_ATTR_MAX + 1] = {nullptr};
73 struct nla_policy packagePolicy[NCSI_PKG_ATTR_MAX + 1] = {
William A. Kennington III05368f12021-05-13 18:40:47 -070074 {NLA_UNSPEC, 0, 0}, {NLA_NESTED, 0, 0}, {NLA_U32, 0, 0},
75 {NLA_FLAG, 0, 0}, {NLA_NESTED, 0, 0},
Ratan Guptaaac603e2018-03-23 00:25:54 +053076 };
77
Gunnar Mills57d9c502018-09-14 14:42:34 -050078 struct nlattr* channeltb[NCSI_CHANNEL_ATTR_MAX + 1] = {nullptr};
79 struct nla_policy channelPolicy[NCSI_CHANNEL_ATTR_MAX + 1] = {
William A. Kennington III05368f12021-05-13 18:40:47 -070080 {NLA_UNSPEC, 0, 0}, {NLA_NESTED, 0, 0}, {NLA_U32, 0, 0},
81 {NLA_FLAG, 0, 0}, {NLA_NESTED, 0, 0}, {NLA_UNSPEC, 0, 0},
Ratan Guptaaac603e2018-03-23 00:25:54 +053082 };
83
Eddie Jamesfa1f5c02020-09-17 15:12:46 -050084 *(int*)arg = 0;
85
Ratan Guptaaac603e2018-03-23 00:25:54 +053086 auto ret = genlmsg_parse(nlh, 0, tb, NCSI_ATTR_MAX, ncsiPolicy);
87 if (!tb[NCSI_ATTR_PACKAGE_LIST])
88 {
Manojkiran Edae5a867a2020-06-01 18:08:30 +053089 std::cerr << "No Packages" << std::endl;
Ratan Guptaaac603e2018-03-23 00:25:54 +053090 return -1;
91 }
92
93 auto attrTgt = static_cast<nlattr*>(nla_data(tb[NCSI_ATTR_PACKAGE_LIST]));
94 if (!attrTgt)
95 {
Manojkiran Edae5a867a2020-06-01 18:08:30 +053096 std::cerr << "Package list attribute is null" << std::endl;
Ratan Guptaaac603e2018-03-23 00:25:54 +053097 return -1;
98 }
99
100 auto rem = nla_len(tb[NCSI_ATTR_PACKAGE_LIST]);
101 nla_for_each_nested(attrTgt, tb[NCSI_ATTR_PACKAGE_LIST], rem)
102 {
103 ret = nla_parse_nested(packagetb, NCSI_PKG_ATTR_MAX, attrTgt,
104 packagePolicy);
105 if (ret < 0)
106 {
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530107 std::cerr << "Failed to parse package nested" << std::endl;
Ratan Guptaaac603e2018-03-23 00:25:54 +0530108 return -1;
109 }
110
111 if (packagetb[NCSI_PKG_ATTR_ID])
112 {
113 auto attrID = nla_get_u32(packagetb[NCSI_PKG_ATTR_ID]);
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530114 std::cout << "Package has id : " << std::hex << attrID << std::endl;
Ratan Guptaaac603e2018-03-23 00:25:54 +0530115 }
116 else
117 {
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530118 std::cout << "Package with no id" << std::endl;
Ratan Guptaaac603e2018-03-23 00:25:54 +0530119 }
120
121 if (packagetb[NCSI_PKG_ATTR_FORCED])
122 {
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530123 std::cout << "This package is forced" << std::endl;
Ratan Guptaaac603e2018-03-23 00:25:54 +0530124 }
125
126 auto channelListTarget = static_cast<nlattr*>(
Gunnar Mills57d9c502018-09-14 14:42:34 -0500127 nla_data(packagetb[NCSI_PKG_ATTR_CHANNEL_LIST]));
Ratan Guptaaac603e2018-03-23 00:25:54 +0530128
129 auto channelrem = nla_len(packagetb[NCSI_PKG_ATTR_CHANNEL_LIST]);
130 nla_for_each_nested(channelListTarget,
131 packagetb[NCSI_PKG_ATTR_CHANNEL_LIST], channelrem)
132 {
133 ret = nla_parse_nested(channeltb, NCSI_CHANNEL_ATTR_MAX,
134 channelListTarget, channelPolicy);
135 if (ret < 0)
136 {
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530137 std::cerr << "Failed to parse channel nested" << std::endl;
Ratan Guptaaac603e2018-03-23 00:25:54 +0530138 return -1;
139 }
140
141 if (channeltb[NCSI_CHANNEL_ATTR_ID])
142 {
143 auto channel = nla_get_u32(channeltb[NCSI_CHANNEL_ATTR_ID]);
144 if (channeltb[NCSI_CHANNEL_ATTR_ACTIVE])
145 {
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530146 std::cout << "Channel Active : " << std::hex << channel
147 << std::endl;
Ratan Guptaaac603e2018-03-23 00:25:54 +0530148 }
149 else
150 {
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530151 std::cout << "Channel Not Active : " << std::hex << channel
152 << std::endl;
Ratan Guptaaac603e2018-03-23 00:25:54 +0530153 }
154
155 if (channeltb[NCSI_CHANNEL_ATTR_FORCED])
156 {
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530157 std::cout << "Channel is forced" << std::endl;
Ratan Guptaaac603e2018-03-23 00:25:54 +0530158 }
Ratan Guptaaac603e2018-03-23 00:25:54 +0530159 }
160 else
161 {
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530162 std::cout << "Channel with no ID" << std::endl;
Ratan Guptaaac603e2018-03-23 00:25:54 +0530163 }
Ratan Guptaed5d7ff2018-03-23 00:27:52 +0530164
Ratan Guptaaac603e2018-03-23 00:25:54 +0530165 if (channeltb[NCSI_CHANNEL_ATTR_VERSION_MAJOR])
166 {
Gunnar Mills57d9c502018-09-14 14:42:34 -0500167 auto major =
168 nla_get_u32(channeltb[NCSI_CHANNEL_ATTR_VERSION_MAJOR]);
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530169 std::cout << "Channel Major Version : " << std::hex << major
170 << std::endl;
Ratan Guptaaac603e2018-03-23 00:25:54 +0530171 }
172 if (channeltb[NCSI_CHANNEL_ATTR_VERSION_MINOR])
173 {
Gunnar Mills57d9c502018-09-14 14:42:34 -0500174 auto minor =
175 nla_get_u32(channeltb[NCSI_CHANNEL_ATTR_VERSION_MINOR]);
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530176 std::cout << "Channel Minor Version : " << std::hex << minor
177 << std::endl;
Ratan Guptaaac603e2018-03-23 00:25:54 +0530178 }
179 if (channeltb[NCSI_CHANNEL_ATTR_VERSION_STR])
180 {
Gunnar Mills57d9c502018-09-14 14:42:34 -0500181 auto str =
182 nla_get_string(channeltb[NCSI_CHANNEL_ATTR_VERSION_STR]);
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530183 std::cout << "Channel Version Str :" << str << std::endl;
Ratan Guptaaac603e2018-03-23 00:25:54 +0530184 }
185 if (channeltb[NCSI_CHANNEL_ATTR_LINK_STATE])
186 {
Ratan Guptaed5d7ff2018-03-23 00:27:52 +0530187
Gunnar Mills57d9c502018-09-14 14:42:34 -0500188 auto link =
189 nla_get_u32(channeltb[NCSI_CHANNEL_ATTR_LINK_STATE]);
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530190 std::cout << "Channel Link State : " << std::hex << link
191 << std::endl;
Ratan Guptaaac603e2018-03-23 00:25:54 +0530192 }
193 if (channeltb[NCSI_CHANNEL_ATTR_VLAN_LIST])
194 {
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530195 std::cout << "Active Vlan ids" << std::endl;
Ratan Guptaaac603e2018-03-23 00:25:54 +0530196 auto vids = channeltb[NCSI_CHANNEL_ATTR_VLAN_LIST];
197 auto vid = static_cast<nlattr*>(nla_data(vids));
198 auto len = nla_len(vids);
199 while (nla_ok(vid, len))
200 {
201 auto id = nla_get_u16(vid);
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530202 std::cout << "VID : " << id << std::endl;
Ratan Guptaaac603e2018-03-23 00:25:54 +0530203 vid = nla_next(vid, &len);
204 }
205 }
Ratan Guptaaac603e2018-03-23 00:25:54 +0530206 }
Ratan Guptaaac603e2018-03-23 00:25:54 +0530207 }
208 return (int)NL_SKIP;
209};
210
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500211CallBack sendCallBack = [](struct nl_msg* msg, void* arg) {
212 using namespace phosphor::network::ncsi;
213 auto nlh = nlmsg_hdr(msg);
214 struct nlattr* tb[NCSI_ATTR_MAX + 1] = {nullptr};
215 static struct nla_policy ncsiPolicy[NCSI_ATTR_MAX + 1] = {
216 {NLA_UNSPEC, 0, 0}, {NLA_U32, 0, 0}, {NLA_NESTED, 0, 0},
217 {NLA_U32, 0, 0}, {NLA_U32, 0, 0}, {NLA_BINARY, 0, 0},
218 {NLA_FLAG, 0, 0}, {NLA_U32, 0, 0}, {NLA_U32, 0, 0},
219 };
220
221 *(int*)arg = 0;
222
223 auto ret = genlmsg_parse(nlh, 0, tb, NCSI_ATTR_MAX, ncsiPolicy);
224 if (ret)
225 {
226 std::cerr << "Failed to parse package" << std::endl;
227 return ret;
228 }
229
230 auto data_len = nla_len(tb[NCSI_ATTR_DATA]) - sizeof(NCSIPacketHeader);
231 unsigned char* data =
232 (unsigned char*)nla_data(tb[NCSI_ATTR_DATA]) + sizeof(NCSIPacketHeader);
233 auto s = std::span<const unsigned char>(data, data_len);
234
235 // Dump the response to stdout. Enhancement: option to save response data
236 std::cout << "Response : " << std::dec << data_len << " bytes" << std::endl;
237 fmt::print("{:02x}", fmt::join(s.begin(), s.end(), " "));
238 std::cout << std::endl;
239
240 return 0;
241};
242
243int applyCmd(int ifindex, const Command& cmd, int package = DEFAULT_VALUE,
Ratan Guptaaac603e2018-03-23 00:25:54 +0530244 int channel = DEFAULT_VALUE, int flags = NONE,
245 CallBack function = nullptr)
Ratan Guptabbe45792018-03-23 00:22:55 +0530246{
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500247 int cb_ret = 0;
Gunnar Mills57d9c502018-09-14 14:42:34 -0500248 nlSocketPtr socket(nl_socket_alloc(), &::nl_socket_free);
Johnathan Manteyd49c5c62021-06-23 09:14:42 -0700249 if (socket == nullptr)
250 {
Jiaqing Zhao7c44a782022-04-10 15:30:04 +0800251 std::cerr << "Unable to allocate memory for the socket" << std::endl;
Johnathan Manteyd49c5c62021-06-23 09:14:42 -0700252 return -ENOMEM;
253 }
254
Ratan Guptabbe45792018-03-23 00:22:55 +0530255 auto ret = genl_connect(socket.get());
256 if (ret < 0)
257 {
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530258 std::cerr << "Failed to open the socket , RC : " << ret << std::endl;
Ratan Guptabbe45792018-03-23 00:22:55 +0530259 return ret;
260 }
261
262 auto driverID = genl_ctrl_resolve(socket.get(), "NCSI");
263 if (driverID < 0)
264 {
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530265 std::cerr << "Failed to resolve, RC : " << ret << std::endl;
Ratan Guptabbe45792018-03-23 00:22:55 +0530266 return driverID;
267 }
268
269 nlMsgPtr msg(nlmsg_alloc(), &::nlmsg_free);
Johnathan Manteyd49c5c62021-06-23 09:14:42 -0700270 if (msg == nullptr)
271 {
Jiaqing Zhao7c44a782022-04-10 15:30:04 +0800272 std::cerr << "Unable to allocate memory for the message" << std::endl;
Johnathan Manteyd49c5c62021-06-23 09:14:42 -0700273 return -ENOMEM;
274 }
Ratan Guptabbe45792018-03-23 00:22:55 +0530275
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500276 auto msgHdr = genlmsg_put(msg.get(), 0, 0, driverID, 0, flags, cmd.cmd, 0);
Ratan Guptabbe45792018-03-23 00:22:55 +0530277 if (!msgHdr)
278 {
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500279 std::cerr << "Unable to add the netlink headers , COMMAND : " << cmd.cmd
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530280 << std::endl;
Johnathan Manteyd49c5c62021-06-23 09:14:42 -0700281 return -ENOMEM;
Ratan Guptabbe45792018-03-23 00:22:55 +0530282 }
283
284 if (package != DEFAULT_VALUE)
285 {
286 ret = nla_put_u32(msg.get(), ncsi_nl_attrs::NCSI_ATTR_PACKAGE_ID,
287 package);
288 if (ret < 0)
289 {
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530290 std::cerr << "Failed to set the attribute , RC : " << ret
291 << "PACKAGE " << std::hex << package << std::endl;
Ratan Guptabbe45792018-03-23 00:22:55 +0530292 return ret;
293 }
294 }
295
296 if (channel != DEFAULT_VALUE)
297 {
298 ret = nla_put_u32(msg.get(), ncsi_nl_attrs::NCSI_ATTR_CHANNEL_ID,
299 channel);
300 if (ret < 0)
301 {
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530302 std::cerr << "Failed to set the attribute , RC : " << ret
303 << "CHANNEL : " << std::hex << channel << std::endl;
Ratan Guptabbe45792018-03-23 00:22:55 +0530304 return ret;
305 }
306 }
307
308 ret = nla_put_u32(msg.get(), ncsi_nl_attrs::NCSI_ATTR_IFINDEX, ifindex);
309 if (ret < 0)
310 {
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530311 std::cerr << "Failed to set the attribute , RC : " << ret
312 << "INTERFACE : " << std::hex << ifindex << std::endl;
Ratan Guptabbe45792018-03-23 00:22:55 +0530313 return ret;
314 }
315
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500316 if (cmd.ncsi_cmd != DEFAULT_VALUE)
317 {
318 std::vector<unsigned char> pl(sizeof(NCSIPacketHeader) +
319 cmd.payload.size());
320 NCSIPacketHeader* hdr = (NCSIPacketHeader*)pl.data();
321
322 std::copy(cmd.payload.begin(), cmd.payload.end(),
323 pl.begin() + sizeof(NCSIPacketHeader));
324
325 hdr->type = cmd.ncsi_cmd;
326 hdr->length = htons(cmd.payload.size());
327
328 ret = nla_put(msg.get(), ncsi_nl_attrs::NCSI_ATTR_DATA, pl.size(),
329 pl.data());
330 if (ret < 0)
331 {
332 std::cerr << "Failed to set the data attribute, RC : " << ret
333 << std::endl;
334 return ret;
335 }
336
337 nl_socket_disable_seq_check(socket.get());
338 }
339
Ratan Guptaaac603e2018-03-23 00:25:54 +0530340 if (function)
341 {
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500342 cb_ret = 1;
343
Ratan Guptaaac603e2018-03-23 00:25:54 +0530344 // Add a callback function to the socket
Gunnar Mills57d9c502018-09-14 14:42:34 -0500345 nl_socket_modify_cb(socket.get(), NL_CB_VALID, NL_CB_CUSTOM, function,
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500346 &cb_ret);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530347 }
Ratan Guptabbe45792018-03-23 00:22:55 +0530348
349 ret = nl_send_auto(socket.get(), msg.get());
350 if (ret < 0)
351 {
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530352 std::cerr << "Failed to send the message , RC : " << ret << std::endl;
Ratan Guptabbe45792018-03-23 00:22:55 +0530353 return ret;
354 }
355
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500356 do
Ratan Guptabbe45792018-03-23 00:22:55 +0530357 {
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500358 ret = nl_recvmsgs_default(socket.get());
359 if (ret < 0)
360 {
361 std::cerr << "Failed to receive the message , RC : " << ret
362 << std::endl;
363 break;
364 }
365 } while (cb_ret);
366
Ratan Guptabbe45792018-03-23 00:22:55 +0530367 return ret;
368}
369
Gunnar Mills57d9c502018-09-14 14:42:34 -0500370} // namespace internal
Ratan Guptabbe45792018-03-23 00:22:55 +0530371
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500372int sendOemCommand(int ifindex, int package, int channel,
373 std::span<const unsigned char> payload)
374{
375 constexpr auto cmd = 0x50;
376
377 std::cout << "Send OEM Command, CHANNEL : " << std::hex << channel
378 << ", PACKAGE : " << std::hex << package
379 << ", IFINDEX: " << std::hex << ifindex << std::endl;
380 if (!payload.empty())
381 {
382 std::cout << "Payload :";
383 for (auto& i : payload)
384 {
385 std::cout << " " << std::hex << std::setfill('0') << std::setw(2)
386 << (int)i;
387 }
388 std::cout << std::endl;
389 }
390
391 return internal::applyCmd(
392 ifindex,
393 internal::Command(ncsi_nl_commands::NCSI_CMD_SEND_CMD, cmd, payload),
394 package, channel, NONE, internal::sendCallBack);
395}
396
Ratan Guptabbe45792018-03-23 00:22:55 +0530397int setChannel(int ifindex, int package, int channel)
398{
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530399 std::cout << "Set Channel : " << std::hex << channel
400 << ", PACKAGE : " << std::hex << package
401 << ", IFINDEX : " << std::hex << ifindex << std::endl;
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500402 return internal::applyCmd(
403 ifindex, internal::Command(ncsi_nl_commands::NCSI_CMD_SET_INTERFACE),
404 package, channel);
Ratan Guptabbe45792018-03-23 00:22:55 +0530405}
406
407int clearInterface(int ifindex)
408{
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530409 std::cout << "ClearInterface , IFINDEX :" << std::hex << ifindex
410 << std::endl;
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500411 return internal::applyCmd(
412 ifindex, internal::Command(ncsi_nl_commands::NCSI_CMD_CLEAR_INTERFACE));
Ratan Guptabbe45792018-03-23 00:22:55 +0530413}
414
Ratan Guptaaac603e2018-03-23 00:25:54 +0530415int getInfo(int ifindex, int package)
416{
Manojkiran Edae5a867a2020-06-01 18:08:30 +0530417 std::cout << "Get Info , PACKAGE : " << std::hex << package
418 << ", IFINDEX : " << std::hex << ifindex << std::endl;
Ratan Guptaaac603e2018-03-23 00:25:54 +0530419 if (package == DEFAULT_VALUE)
420 {
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500421 return internal::applyCmd(
422 ifindex, internal::Command(ncsi_nl_commands::NCSI_CMD_PKG_INFO),
423 package, DEFAULT_VALUE, NLM_F_DUMP, internal::infoCallBack);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530424 }
425 else
426 {
427 return internal::applyCmd(ifindex, ncsi_nl_commands::NCSI_CMD_PKG_INFO,
428 package, DEFAULT_VALUE, NONE,
429 internal::infoCallBack);
430 }
431}
432
Gunnar Mills57d9c502018-09-14 14:42:34 -0500433} // namespace ncsi
434} // namespace network
435} // namespace phosphor