blob: f05cc0b6c0f474a4453651374a84ccbff94a7f75 [file] [log] [blame]
Ratan Guptabbe45792018-03-23 00:22:55 +05301#include <linux/ncsi.h>
2#include <netlink/netlink.h>
3#include <netlink/genl/genl.h>
4#include <netlink/genl/ctrl.h>
5
6#include "ncsi_util.hpp"
7#include "xyz/openbmc_project/Common/error.hpp"
8
9#include <phosphor-logging/elog-errors.hpp>
10#include <phosphor-logging/log.hpp>
11
12namespace phosphor
13{
14namespace network
15{
16namespace ncsi
17{
18
19using namespace phosphor::logging;
20using namespace sdbusplus::xyz::openbmc_project::Common::Error;
21
22namespace internal
23{
24
25constexpr auto DEFAULT_VALUE = -1;
26constexpr auto NONE = 0;
27
28using nlMsgPtr = std::unique_ptr<nl_msg, decltype(&::nlmsg_free)>;
29using nlSocketPtr = std::unique_ptr<nl_sock, decltype(&::nl_socket_free)>;
30
31int applyCmd(int ifindex, int cmd, int package = DEFAULT_VALUE,
32 int channel = DEFAULT_VALUE, int flags = NONE)
33{
34 nlSocketPtr socket(nl_socket_alloc(),&::nl_socket_free);
35 auto ret = genl_connect(socket.get());
36 if (ret < 0)
37 {
38 log<level::ERR>("Failed to open the socket",
39 entry("RC=%d", ret));
40 return ret;
41 }
42
43 auto driverID = genl_ctrl_resolve(socket.get(), "NCSI");
44 if (driverID < 0)
45 {
46 log<level::ERR>("Failed to resolve",
47 entry("RC=%d", ret));
48 return driverID;
49 }
50
51 nlMsgPtr msg(nlmsg_alloc(), &::nlmsg_free);
52
53 auto msgHdr = genlmsg_put(msg.get(), 0, 0, driverID, 0, flags,
54 cmd, 0);
55 if (!msgHdr)
56 {
57 log<level::ERR>("Unable to add the netlink headers",
58 entry("COMMAND=%d", cmd));
59 return -1;
60 }
61
62 if (package != DEFAULT_VALUE)
63 {
64 ret = nla_put_u32(msg.get(), ncsi_nl_attrs::NCSI_ATTR_PACKAGE_ID,
65 package);
66 if (ret < 0)
67 {
68 log<level::ERR>("Failed to set the attribute",
69 entry("RC=%d", ret),
70 entry("PACKAGE=%x", package));
71 return ret;
72 }
73 }
74
75 if (channel != DEFAULT_VALUE)
76 {
77 ret = nla_put_u32(msg.get(), ncsi_nl_attrs::NCSI_ATTR_CHANNEL_ID,
78 channel);
79 if (ret < 0)
80 {
81 log<level::ERR>("Failed to set the attribute",
82 entry("RC=%d", ret),
83 entry("CHANNEL=%x", channel));
84 return ret;
85 }
86 }
87
88 ret = nla_put_u32(msg.get(), ncsi_nl_attrs::NCSI_ATTR_IFINDEX, ifindex);
89 if (ret < 0)
90 {
91 log<level::ERR>("Failed to set the attribute",
92 entry("RC=%d", ret),
93 entry("INTERFACE=%x", ifindex));
94 return ret;
95 }
96
97
98 ret = nl_send_auto(socket.get(), msg.get());
99 if (ret < 0)
100 {
101 log<level::ERR>("Failed to send the message",
102 entry("RC=%d", ret));
103 return ret;
104 }
105
106 ret = nl_recvmsgs_default(socket.get());
107 if (ret < 0)
108 {
109 log<level::ERR>("Failed to recieve the message",
110 entry("RC=%d", ret));
111 }
112 return ret;
113}
114
115}//namespace internal
116
117int setChannel(int ifindex, int package, int channel)
118{
119 return internal::applyCmd(ifindex, ncsi_nl_commands::NCSI_CMD_SET_INTERFACE,
120 package, channel);
121}
122
123int clearInterface(int ifindex)
124{
125 return internal::applyCmd(ifindex,
126 ncsi_nl_commands::NCSI_CMD_CLEAR_INTERFACE);
127}
128
129}//namespace ncsi
130}//namespace network
131}//namespace phosphor