1690a2342SPatrick Venture #include "transporthandler.hpp"
2690a2342SPatrick Venture
3c1c7eac4SGeorge Liu #include <ipmid/utils.hpp>
432e8f5d3SGeorge Liu #include <phosphor-logging/lg2.hpp>
5726f2bddSWilliam A. Kennington III #include <stdplus/net/addr/subnet.hpp>
67a3831b5SWilliam A. Kennington III #include <stdplus/raw.hpp>
77a3831b5SWilliam A. Kennington III
87a3831b5SWilliam A. Kennington III #include <array>
9726f2bddSWilliam A. Kennington III #include <fstream>
107a3831b5SWilliam A. Kennington III
11c514d874SWilliam A. Kennington III using phosphor::logging::elog;
12523e2d1bSWilly Tu using sdbusplus::error::xyz::openbmc_project::common::InternalFailure;
137a3831b5SWilliam A. Kennington III using sdbusplus::error::xyz::openbmc_project::common::InvalidArgument;
14523e2d1bSWilly Tu using sdbusplus::server::xyz::openbmc_project::network::EthernetInterface;
15523e2d1bSWilly Tu using sdbusplus::server::xyz::openbmc_project::network::IP;
16523e2d1bSWilly Tu using sdbusplus::server::xyz::openbmc_project::network::Neighbor;
17586d35b4SPatrick Venture
18affadb55SJohnathan Mantey namespace cipher
19affadb55SJohnathan Mantey {
20affadb55SJohnathan Mantey
getCipherList()21affadb55SJohnathan Mantey std::vector<uint8_t> getCipherList()
22affadb55SJohnathan Mantey {
23affadb55SJohnathan Mantey std::vector<uint8_t> cipherList;
24affadb55SJohnathan Mantey
25affadb55SJohnathan Mantey std::ifstream jsonFile(cipher::configFile);
26affadb55SJohnathan Mantey if (!jsonFile.is_open())
27affadb55SJohnathan Mantey {
2832e8f5d3SGeorge Liu lg2::error("Channel Cipher suites file not found");
29affadb55SJohnathan Mantey elog<InternalFailure>();
30affadb55SJohnathan Mantey }
31affadb55SJohnathan Mantey
32affadb55SJohnathan Mantey auto data = Json::parse(jsonFile, nullptr, false);
33affadb55SJohnathan Mantey if (data.is_discarded())
34affadb55SJohnathan Mantey {
3532e8f5d3SGeorge Liu lg2::error("Parsing channel cipher suites JSON failed");
36affadb55SJohnathan Mantey elog<InternalFailure>();
37affadb55SJohnathan Mantey }
38affadb55SJohnathan Mantey
39affadb55SJohnathan Mantey // Byte 1 is reserved
40affadb55SJohnathan Mantey cipherList.push_back(0x00);
41affadb55SJohnathan Mantey
42affadb55SJohnathan Mantey for (const auto& record : data)
43affadb55SJohnathan Mantey {
44affadb55SJohnathan Mantey cipherList.push_back(record.value(cipher, 0));
45affadb55SJohnathan Mantey }
46affadb55SJohnathan Mantey
47affadb55SJohnathan Mantey return cipherList;
48affadb55SJohnathan Mantey }
49affadb55SJohnathan Mantey } // namespace cipher
50affadb55SJohnathan Mantey
51affadb55SJohnathan Mantey namespace ipmi
52affadb55SJohnathan Mantey {
53affadb55SJohnathan Mantey namespace transport
54affadb55SJohnathan Mantey {
55affadb55SJohnathan Mantey
56c514d874SWilliam A. Kennington III /** @brief Valid address origins for IPv4 */
57c514d874SWilliam A. Kennington III const std::unordered_set<IP::AddressOrigin> originsV4 = {
58c514d874SWilliam A. Kennington III IP::AddressOrigin::Static,
59c514d874SWilliam A. Kennington III IP::AddressOrigin::DHCP,
60c514d874SWilliam A. Kennington III };
61c514d874SWilliam A. Kennington III
62b87034e8SJohnathan Mantey static constexpr uint8_t oemCmdStart = 192;
63b87034e8SJohnathan Mantey
64c72f3602SWilliam A. Kennington III // Checks if the ifname is part of the networkd path
65c72f3602SWilliam A. Kennington III // This assumes the path came from the network subtree PATH_ROOT
ifnameInPath(std::string_view ifname,std::string_view path)66c72f3602SWilliam A. Kennington III bool ifnameInPath(std::string_view ifname, std::string_view path)
67c72f3602SWilliam A. Kennington III {
68c72f3602SWilliam A. Kennington III constexpr auto rs = PATH_ROOT.size() + 1; // ROOT + separator
69c72f3602SWilliam A. Kennington III const auto is = rs + ifname.size(); // ROOT + sep + ifname
70c72f3602SWilliam A. Kennington III return path.size() > rs && path.substr(rs).starts_with(ifname) &&
71c72f3602SWilliam A. Kennington III (path.size() == is || path[is] == '/');
72c72f3602SWilliam A. Kennington III }
73c72f3602SWilliam A. Kennington III
maybeGetChannelParams(sdbusplus::bus_t & bus,uint8_t channel)74*69b4c281SPatrick Williams std::optional<ChannelParams> maybeGetChannelParams(sdbusplus::bus_t& bus,
75*69b4c281SPatrick Williams uint8_t channel)
76c514d874SWilliam A. Kennington III {
77c514d874SWilliam A. Kennington III auto ifname = getChannelName(channel);
78c514d874SWilliam A. Kennington III if (ifname.empty())
79c514d874SWilliam A. Kennington III {
80c514d874SWilliam A. Kennington III return std::nullopt;
81c514d874SWilliam A. Kennington III }
82c514d874SWilliam A. Kennington III
83c514d874SWilliam A. Kennington III // Enumerate all VLAN + ETHERNET interfaces
84c1c7eac4SGeorge Liu std::vector<std::string> interfaces = {INTF_VLAN, INTF_ETHERNET};
851318a5edSPatrick Williams ipmi::ObjectTree objs =
861318a5edSPatrick Williams ipmi::getSubTree(bus, interfaces, std::string{PATH_ROOT});
87c514d874SWilliam A. Kennington III
88c514d874SWilliam A. Kennington III ChannelParams params;
89c514d874SWilliam A. Kennington III for (const auto& [path, impls] : objs)
90c514d874SWilliam A. Kennington III {
91c72f3602SWilliam A. Kennington III if (!ifnameInPath(ifname, path))
92c514d874SWilliam A. Kennington III {
93c514d874SWilliam A. Kennington III continue;
94c514d874SWilliam A. Kennington III }
95c514d874SWilliam A. Kennington III for (const auto& [service, intfs] : impls)
96c514d874SWilliam A. Kennington III {
97c514d874SWilliam A. Kennington III bool vlan = false;
98c514d874SWilliam A. Kennington III bool ethernet = false;
99c514d874SWilliam A. Kennington III for (const auto& intf : intfs)
100c514d874SWilliam A. Kennington III {
101c514d874SWilliam A. Kennington III if (intf == INTF_VLAN)
102c514d874SWilliam A. Kennington III {
103c514d874SWilliam A. Kennington III vlan = true;
104c514d874SWilliam A. Kennington III }
105c514d874SWilliam A. Kennington III else if (intf == INTF_ETHERNET)
106c514d874SWilliam A. Kennington III {
107c514d874SWilliam A. Kennington III ethernet = true;
108c514d874SWilliam A. Kennington III }
109c514d874SWilliam A. Kennington III }
110c514d874SWilliam A. Kennington III if (params.service.empty() && (vlan || ethernet))
111c514d874SWilliam A. Kennington III {
112c514d874SWilliam A. Kennington III params.service = service;
113c514d874SWilliam A. Kennington III }
114c514d874SWilliam A. Kennington III if (params.ifPath.empty() && !vlan && ethernet)
115c514d874SWilliam A. Kennington III {
116c514d874SWilliam A. Kennington III params.ifPath = path;
117c514d874SWilliam A. Kennington III }
118c514d874SWilliam A. Kennington III if (params.logicalPath.empty() && vlan)
119c514d874SWilliam A. Kennington III {
120c514d874SWilliam A. Kennington III params.logicalPath = path;
121c514d874SWilliam A. Kennington III }
122c514d874SWilliam A. Kennington III }
123c514d874SWilliam A. Kennington III }
124c514d874SWilliam A. Kennington III
125c514d874SWilliam A. Kennington III // We must have a path for the underlying interface
126c514d874SWilliam A. Kennington III if (params.ifPath.empty())
127c514d874SWilliam A. Kennington III {
128c514d874SWilliam A. Kennington III return std::nullopt;
129c514d874SWilliam A. Kennington III }
130c514d874SWilliam A. Kennington III // We don't have a VLAN so the logical path is the same
131c514d874SWilliam A. Kennington III if (params.logicalPath.empty())
132c514d874SWilliam A. Kennington III {
133c514d874SWilliam A. Kennington III params.logicalPath = params.ifPath;
134c514d874SWilliam A. Kennington III }
135c514d874SWilliam A. Kennington III
136c514d874SWilliam A. Kennington III params.id = channel;
137c514d874SWilliam A. Kennington III params.ifname = std::move(ifname);
13811d68897SWilly Tu return params;
139c514d874SWilliam A. Kennington III }
140c514d874SWilliam A. Kennington III
getChannelParams(sdbusplus::bus_t & bus,uint8_t channel)1415d82f474SPatrick Williams ChannelParams getChannelParams(sdbusplus::bus_t& bus, uint8_t channel)
142c514d874SWilliam A. Kennington III {
143c514d874SWilliam A. Kennington III auto params = maybeGetChannelParams(bus, channel);
144c514d874SWilliam A. Kennington III if (!params)
145c514d874SWilliam A. Kennington III {
14632e8f5d3SGeorge Liu lg2::error("Failed to get channel params: {CHANNEL}", "CHANNEL",
14732e8f5d3SGeorge Liu channel);
148c514d874SWilliam A. Kennington III elog<InternalFailure>();
149c514d874SWilliam A. Kennington III }
150c514d874SWilliam A. Kennington III return std::move(*params);
151c514d874SWilliam A. Kennington III }
152c514d874SWilliam A. Kennington III
153a8a2e5f6SWilliam A. Kennington III /** @brief Get / Set the Property value from phosphor-networkd EthernetInterface
154a8a2e5f6SWilliam A. Kennington III */
155a8a2e5f6SWilliam A. Kennington III template <typename T>
getEthProp(sdbusplus::bus_t & bus,const ChannelParams & params,const std::string & prop)156a8a2e5f6SWilliam A. Kennington III static T getEthProp(sdbusplus::bus_t& bus, const ChannelParams& params,
157a8a2e5f6SWilliam A. Kennington III const std::string& prop)
158a8a2e5f6SWilliam A. Kennington III {
159a8a2e5f6SWilliam A. Kennington III return std::get<T>(getDbusProperty(bus, params.service, params.logicalPath,
160a8a2e5f6SWilliam A. Kennington III INTF_ETHERNET, prop));
161a8a2e5f6SWilliam A. Kennington III }
162a8a2e5f6SWilliam A. Kennington III template <typename T>
setEthProp(sdbusplus::bus_t & bus,const ChannelParams & params,const std::string & prop,const T & t)163a8a2e5f6SWilliam A. Kennington III static void setEthProp(sdbusplus::bus_t& bus, const ChannelParams& params,
164a8a2e5f6SWilliam A. Kennington III const std::string& prop, const T& t)
165a8a2e5f6SWilliam A. Kennington III {
166a8a2e5f6SWilliam A. Kennington III return setDbusProperty(bus, params.service, params.logicalPath,
167a8a2e5f6SWilliam A. Kennington III INTF_ETHERNET, prop, t);
168a8a2e5f6SWilliam A. Kennington III }
169a8a2e5f6SWilliam A. Kennington III
170c514d874SWilliam A. Kennington III /** @brief Determines the MAC of the ethernet interface
171c514d874SWilliam A. Kennington III *
172c514d874SWilliam A. Kennington III * @param[in] bus - The bus object used for lookups
173c514d874SWilliam A. Kennington III * @param[in] params - The parameters for the channel
174c514d874SWilliam A. Kennington III * @return The configured mac address
175c514d874SWilliam A. Kennington III */
getMACProperty(sdbusplus::bus_t & bus,const ChannelParams & params)176726f2bddSWilliam A. Kennington III stdplus::EtherAddr getMACProperty(sdbusplus::bus_t& bus,
177726f2bddSWilliam A. Kennington III const ChannelParams& params)
178c514d874SWilliam A. Kennington III {
179726f2bddSWilliam A. Kennington III auto prop = getDbusProperty(bus, params.service, params.ifPath, INTF_MAC,
180726f2bddSWilliam A. Kennington III "MACAddress");
181726f2bddSWilliam A. Kennington III return stdplus::fromStr<stdplus::EtherAddr>(std::get<std::string>(prop));
182c514d874SWilliam A. Kennington III }
183c514d874SWilliam A. Kennington III
184c514d874SWilliam A. Kennington III /** @brief Sets the system value for MAC address on the given interface
185c514d874SWilliam A. Kennington III *
186c514d874SWilliam A. Kennington III * @param[in] bus - The bus object used for lookups
187c514d874SWilliam A. Kennington III * @param[in] params - The parameters for the channel
188c514d874SWilliam A. Kennington III * @param[in] mac - MAC address to apply
189c514d874SWilliam A. Kennington III */
setMACProperty(sdbusplus::bus_t & bus,const ChannelParams & params,stdplus::EtherAddr mac)1905d82f474SPatrick Williams void setMACProperty(sdbusplus::bus_t& bus, const ChannelParams& params,
191726f2bddSWilliam A. Kennington III stdplus::EtherAddr mac)
192c514d874SWilliam A. Kennington III {
193c514d874SWilliam A. Kennington III setDbusProperty(bus, params.service, params.ifPath, INTF_MAC, "MACAddress",
194726f2bddSWilliam A. Kennington III stdplus::toStr(mac));
195c514d874SWilliam A. Kennington III }
196c514d874SWilliam A. Kennington III
deleteObjectIfExists(sdbusplus::bus_t & bus,const std::string & service,const std::string & path)1975d82f474SPatrick Williams void deleteObjectIfExists(sdbusplus::bus_t& bus, const std::string& service,
198c514d874SWilliam A. Kennington III const std::string& path)
199c514d874SWilliam A. Kennington III {
200c514d874SWilliam A. Kennington III if (path.empty())
201c514d874SWilliam A. Kennington III {
202c514d874SWilliam A. Kennington III return;
203c514d874SWilliam A. Kennington III }
204c514d874SWilliam A. Kennington III try
205c514d874SWilliam A. Kennington III {
206c514d874SWilliam A. Kennington III auto req = bus.new_method_call(service.c_str(), path.c_str(),
207c514d874SWilliam A. Kennington III ipmi::DELETE_INTERFACE, "Delete");
208c514d874SWilliam A. Kennington III bus.call_noreply(req);
209c514d874SWilliam A. Kennington III }
2105d82f474SPatrick Williams catch (const sdbusplus::exception_t& e)
211c514d874SWilliam A. Kennington III {
21284c49dc1Sjayaprakash Mutyala if (strcmp(e.name(),
21384c49dc1Sjayaprakash Mutyala "xyz.openbmc_project.Common.Error.InternalFailure") != 0 &&
21484c49dc1Sjayaprakash Mutyala strcmp(e.name(), "org.freedesktop.DBus.Error.UnknownObject") != 0)
215c514d874SWilliam A. Kennington III {
216c514d874SWilliam A. Kennington III // We want to rethrow real errors
217c514d874SWilliam A. Kennington III throw;
218c514d874SWilliam A. Kennington III }
219c514d874SWilliam A. Kennington III }
220c514d874SWilliam A. Kennington III }
221c514d874SWilliam A. Kennington III
222c514d874SWilliam A. Kennington III /** @brief Sets the address info configured for the interface
223c514d874SWilliam A. Kennington III * If a previous address path exists then it will be removed
224c514d874SWilliam A. Kennington III * before the new address is added.
225c514d874SWilliam A. Kennington III *
226c514d874SWilliam A. Kennington III * @param[in] bus - The bus object used for lookups
227c514d874SWilliam A. Kennington III * @param[in] params - The parameters for the channel
228c514d874SWilliam A. Kennington III * @param[in] address - The address of the new IP
229c514d874SWilliam A. Kennington III * @param[in] prefix - The prefix of the new IP
230c514d874SWilliam A. Kennington III */
231c514d874SWilliam A. Kennington III template <int family>
createIfAddr(sdbusplus::bus_t & bus,const ChannelParams & params,typename AddrFamily<family>::addr address,uint8_t prefix)2325d82f474SPatrick Williams void createIfAddr(sdbusplus::bus_t& bus, const ChannelParams& params,
233726f2bddSWilliam A. Kennington III typename AddrFamily<family>::addr address, uint8_t prefix)
234c514d874SWilliam A. Kennington III {
2351318a5edSPatrick Williams auto newreq =
2361318a5edSPatrick Williams bus.new_method_call(params.service.c_str(), params.logicalPath.c_str(),
237c514d874SWilliam A. Kennington III INTF_IP_CREATE, "IP");
238c514d874SWilliam A. Kennington III std::string protocol =
239523e2d1bSWilly Tu sdbusplus::common::xyz::openbmc_project::network::convertForMessage(
240c514d874SWilliam A. Kennington III AddrFamily<family>::protocol);
241726f2bddSWilliam A. Kennington III stdplus::ToStrHandle<stdplus::ToStr<typename AddrFamily<family>::addr>> tsh;
242726f2bddSWilliam A. Kennington III newreq.append(protocol, tsh(address), prefix, "");
243c514d874SWilliam A. Kennington III bus.call_noreply(newreq);
244c514d874SWilliam A. Kennington III }
245c514d874SWilliam A. Kennington III
246c514d874SWilliam A. Kennington III /** @brief Trivial helper for getting the IPv4 address from getIfAddrs()
247c514d874SWilliam A. Kennington III *
248c514d874SWilliam A. Kennington III * @param[in] bus - The bus object used for lookups
249c514d874SWilliam A. Kennington III * @param[in] params - The parameters for the channel
250c514d874SWilliam A. Kennington III * @return The address and prefix if found
251c514d874SWilliam A. Kennington III */
getIfAddr4(sdbusplus::bus_t & bus,const ChannelParams & params)2525d82f474SPatrick Williams auto getIfAddr4(sdbusplus::bus_t& bus, const ChannelParams& params)
253c514d874SWilliam A. Kennington III {
2548bd9a9bcSChanh Nguyen std::optional<IfAddr<AF_INET>> ifaddr4 = std::nullopt;
2558bd9a9bcSChanh Nguyen IP::AddressOrigin src;
2568bd9a9bcSChanh Nguyen
2578bd9a9bcSChanh Nguyen try
2588bd9a9bcSChanh Nguyen {
2598bd9a9bcSChanh Nguyen src = std::get<bool>(
2608bd9a9bcSChanh Nguyen getDbusProperty(bus, params.service, params.logicalPath,
2618bd9a9bcSChanh Nguyen INTF_ETHERNET, "DHCP4"))
2628bd9a9bcSChanh Nguyen ? IP::AddressOrigin::DHCP
2638bd9a9bcSChanh Nguyen : IP::AddressOrigin::Static;
2648bd9a9bcSChanh Nguyen }
2658bd9a9bcSChanh Nguyen catch (const sdbusplus::exception_t& e)
2668bd9a9bcSChanh Nguyen {
2678bd9a9bcSChanh Nguyen lg2::error("Failed to get IPv4 source");
2688bd9a9bcSChanh Nguyen return ifaddr4;
2698bd9a9bcSChanh Nguyen }
2708bd9a9bcSChanh Nguyen
2718bd9a9bcSChanh Nguyen for (uint8_t i = 0; i < MAX_IPV4_ADDRESSES; ++i)
2728bd9a9bcSChanh Nguyen {
2738bd9a9bcSChanh Nguyen ifaddr4 = getIfAddr<AF_INET>(bus, params, i, originsV4);
274befca3c3SVince Chang if (ifaddr4 && src == ifaddr4->origin)
2758bd9a9bcSChanh Nguyen {
2768bd9a9bcSChanh Nguyen break;
2778bd9a9bcSChanh Nguyen }
2788bd9a9bcSChanh Nguyen else
2798bd9a9bcSChanh Nguyen {
2808bd9a9bcSChanh Nguyen ifaddr4 = std::nullopt;
2818bd9a9bcSChanh Nguyen }
2828bd9a9bcSChanh Nguyen }
2838bd9a9bcSChanh Nguyen return ifaddr4;
284c514d874SWilliam A. Kennington III }
285c514d874SWilliam A. Kennington III
286c514d874SWilliam A. Kennington III /** @brief Reconfigures the IPv4 address info configured for the interface
287c514d874SWilliam A. Kennington III *
288c514d874SWilliam A. Kennington III * @param[in] bus - The bus object used for lookups
289c514d874SWilliam A. Kennington III * @param[in] params - The parameters for the channel
290c514d874SWilliam A. Kennington III * @param[in] address - The new address if specified
291c514d874SWilliam A. Kennington III * @param[in] prefix - The new address prefix if specified
292c514d874SWilliam A. Kennington III */
reconfigureIfAddr4(sdbusplus::bus_t & bus,const ChannelParams & params,std::optional<stdplus::In4Addr> address,std::optional<uint8_t> prefix)2935d82f474SPatrick Williams void reconfigureIfAddr4(sdbusplus::bus_t& bus, const ChannelParams& params,
294726f2bddSWilliam A. Kennington III std::optional<stdplus::In4Addr> address,
295c514d874SWilliam A. Kennington III std::optional<uint8_t> prefix)
296c514d874SWilliam A. Kennington III {
297c514d874SWilliam A. Kennington III auto ifaddr = getIfAddr4(bus, params);
298c514d874SWilliam A. Kennington III if (!ifaddr && !address)
299c514d874SWilliam A. Kennington III {
30032e8f5d3SGeorge Liu lg2::error("Missing address for IPv4 assignment");
301c514d874SWilliam A. Kennington III elog<InternalFailure>();
302c514d874SWilliam A. Kennington III }
303c514d874SWilliam A. Kennington III uint8_t fallbackPrefix = AddrFamily<AF_INET>::defaultPrefix;
304befca3c3SVince Chang auto addr = stdplus::In4Addr{};
305c514d874SWilliam A. Kennington III if (ifaddr)
306c514d874SWilliam A. Kennington III {
307befca3c3SVince Chang addr = ifaddr->address;
308c514d874SWilliam A. Kennington III fallbackPrefix = ifaddr->prefix;
309c514d874SWilliam A. Kennington III deleteObjectIfExists(bus, params.service, ifaddr->path);
310c514d874SWilliam A. Kennington III }
311befca3c3SVince Chang addr = address.value_or(addr);
312726f2bddSWilliam A. Kennington III if (addr != stdplus::In4Addr{})
313cbfa6e1dSJohnathan Mantey {
314726f2bddSWilliam A. Kennington III createIfAddr<AF_INET>(bus, params, addr,
315c514d874SWilliam A. Kennington III prefix.value_or(fallbackPrefix));
316c514d874SWilliam A. Kennington III }
317cbfa6e1dSJohnathan Mantey }
318c514d874SWilliam A. Kennington III
3194bbc3db6SWilliam A. Kennington III template <int family>
findGatewayNeighbor(sdbusplus::bus_t & bus,const ChannelParams & params,ObjectLookupCache & neighbors)320*69b4c281SPatrick Williams std::optional<IfNeigh<family>> findGatewayNeighbor(sdbusplus::bus_t& bus,
321*69b4c281SPatrick Williams const ChannelParams& params,
3224bbc3db6SWilliam A. Kennington III ObjectLookupCache& neighbors)
3234bbc3db6SWilliam A. Kennington III {
3244bbc3db6SWilliam A. Kennington III auto gateway = getGatewayProperty<family>(bus, params);
3254bbc3db6SWilliam A. Kennington III if (!gateway)
3264bbc3db6SWilliam A. Kennington III {
3274bbc3db6SWilliam A. Kennington III return std::nullopt;
3284bbc3db6SWilliam A. Kennington III }
3294bbc3db6SWilliam A. Kennington III
3304bbc3db6SWilliam A. Kennington III return findStaticNeighbor<family>(bus, params, *gateway, neighbors);
3314bbc3db6SWilliam A. Kennington III }
3324bbc3db6SWilliam A. Kennington III
3334bbc3db6SWilliam A. Kennington III template <int family>
getGatewayNeighbor(sdbusplus::bus_t & bus,const ChannelParams & params)334*69b4c281SPatrick Williams std::optional<IfNeigh<family>> getGatewayNeighbor(sdbusplus::bus_t& bus,
335*69b4c281SPatrick Williams const ChannelParams& params)
3364bbc3db6SWilliam A. Kennington III {
3374bbc3db6SWilliam A. Kennington III ObjectLookupCache neighbors(bus, params, INTF_NEIGHBOR);
3384bbc3db6SWilliam A. Kennington III return findGatewayNeighbor<family>(bus, params, neighbors);
3394bbc3db6SWilliam A. Kennington III }
3404bbc3db6SWilliam A. Kennington III
3414bbc3db6SWilliam A. Kennington III template <int family>
reconfigureGatewayMAC(sdbusplus::bus_t & bus,const ChannelParams & params,stdplus::EtherAddr mac)3425d82f474SPatrick Williams void reconfigureGatewayMAC(sdbusplus::bus_t& bus, const ChannelParams& params,
343726f2bddSWilliam A. Kennington III stdplus::EtherAddr mac)
3444bbc3db6SWilliam A. Kennington III {
3454bbc3db6SWilliam A. Kennington III auto gateway = getGatewayProperty<family>(bus, params);
3464bbc3db6SWilliam A. Kennington III if (!gateway)
3474bbc3db6SWilliam A. Kennington III {
34832e8f5d3SGeorge Liu lg2::error("Tried to set Gateway MAC without Gateway");
3494bbc3db6SWilliam A. Kennington III elog<InternalFailure>();
3504bbc3db6SWilliam A. Kennington III }
3514bbc3db6SWilliam A. Kennington III
3524bbc3db6SWilliam A. Kennington III ObjectLookupCache neighbors(bus, params, INTF_NEIGHBOR);
3531318a5edSPatrick Williams auto neighbor =
3541318a5edSPatrick Williams findStaticNeighbor<family>(bus, params, *gateway, neighbors);
3554bbc3db6SWilliam A. Kennington III if (neighbor)
3564bbc3db6SWilliam A. Kennington III {
3574bbc3db6SWilliam A. Kennington III deleteObjectIfExists(bus, params.service, neighbor->path);
3584bbc3db6SWilliam A. Kennington III }
3594bbc3db6SWilliam A. Kennington III
3604bbc3db6SWilliam A. Kennington III createNeighbor<family>(bus, params, *gateway, mac);
3614bbc3db6SWilliam A. Kennington III }
3624bbc3db6SWilliam A. Kennington III
36316064aa1SWilliam A. Kennington III /** @brief Deconfigures the IPv6 address info configured for the interface
36416064aa1SWilliam A. Kennington III *
36516064aa1SWilliam A. Kennington III * @param[in] bus - The bus object used for lookups
36616064aa1SWilliam A. Kennington III * @param[in] params - The parameters for the channel
36716064aa1SWilliam A. Kennington III * @param[in] idx - The address index to operate on
36816064aa1SWilliam A. Kennington III */
deconfigureIfAddr6(sdbusplus::bus_t & bus,const ChannelParams & params,uint8_t idx)3695d82f474SPatrick Williams void deconfigureIfAddr6(sdbusplus::bus_t& bus, const ChannelParams& params,
37016064aa1SWilliam A. Kennington III uint8_t idx)
37116064aa1SWilliam A. Kennington III {
37216064aa1SWilliam A. Kennington III auto ifaddr = getIfAddr<AF_INET6>(bus, params, idx, originsV6Static);
37316064aa1SWilliam A. Kennington III if (ifaddr)
37416064aa1SWilliam A. Kennington III {
37516064aa1SWilliam A. Kennington III deleteObjectIfExists(bus, params.service, ifaddr->path);
37616064aa1SWilliam A. Kennington III }
37716064aa1SWilliam A. Kennington III }
37816064aa1SWilliam A. Kennington III
37916064aa1SWilliam A. Kennington III /** @brief Reconfigures the IPv6 address info configured for the interface
38016064aa1SWilliam A. Kennington III *
38116064aa1SWilliam A. Kennington III * @param[in] bus - The bus object used for lookups
38216064aa1SWilliam A. Kennington III * @param[in] params - The parameters for the channel
38316064aa1SWilliam A. Kennington III * @param[in] idx - The address index to operate on
38416064aa1SWilliam A. Kennington III * @param[in] address - The new address
38516064aa1SWilliam A. Kennington III * @param[in] prefix - The new address prefix
38616064aa1SWilliam A. Kennington III */
reconfigureIfAddr6(sdbusplus::bus_t & bus,const ChannelParams & params,uint8_t idx,stdplus::In6Addr address,uint8_t prefix)3875d82f474SPatrick Williams void reconfigureIfAddr6(sdbusplus::bus_t& bus, const ChannelParams& params,
388726f2bddSWilliam A. Kennington III uint8_t idx, stdplus::In6Addr address, uint8_t prefix)
38916064aa1SWilliam A. Kennington III {
39016064aa1SWilliam A. Kennington III deconfigureIfAddr6(bus, params, idx);
39116064aa1SWilliam A. Kennington III createIfAddr<AF_INET6>(bus, params, address, prefix);
39216064aa1SWilliam A. Kennington III }
39316064aa1SWilliam A. Kennington III
39416064aa1SWilliam A. Kennington III /** @brief Converts the AddressOrigin into an IPv6Source
39516064aa1SWilliam A. Kennington III *
39616064aa1SWilliam A. Kennington III * @param[in] origin - The DBus Address Origin to convert
39716064aa1SWilliam A. Kennington III * @return The IPv6Source version of the origin
39816064aa1SWilliam A. Kennington III */
originToSourceType(IP::AddressOrigin origin)39916064aa1SWilliam A. Kennington III IPv6Source originToSourceType(IP::AddressOrigin origin)
40016064aa1SWilliam A. Kennington III {
40116064aa1SWilliam A. Kennington III switch (origin)
40216064aa1SWilliam A. Kennington III {
40316064aa1SWilliam A. Kennington III case IP::AddressOrigin::Static:
40416064aa1SWilliam A. Kennington III return IPv6Source::Static;
40516064aa1SWilliam A. Kennington III case IP::AddressOrigin::DHCP:
40616064aa1SWilliam A. Kennington III return IPv6Source::DHCP;
40716064aa1SWilliam A. Kennington III case IP::AddressOrigin::SLAAC:
40816064aa1SWilliam A. Kennington III return IPv6Source::SLAAC;
40916064aa1SWilliam A. Kennington III default:
41016064aa1SWilliam A. Kennington III {
411523e2d1bSWilly Tu auto originStr = sdbusplus::common::xyz::openbmc_project::network::
41216064aa1SWilliam A. Kennington III convertForMessage(origin);
41332e8f5d3SGeorge Liu lg2::error("Invalid IP::AddressOrigin conversion to IPv6Source, "
41432e8f5d3SGeorge Liu "origin: {ORIGIN}",
41532e8f5d3SGeorge Liu "ORIGIN", originStr);
41616064aa1SWilliam A. Kennington III elog<InternalFailure>();
41716064aa1SWilliam A. Kennington III }
41816064aa1SWilliam A. Kennington III }
41916064aa1SWilliam A. Kennington III }
42016064aa1SWilliam A. Kennington III
42116064aa1SWilliam A. Kennington III /** @brief Packs the IPMI message response with IPv6 address data
42216064aa1SWilliam A. Kennington III *
42316064aa1SWilliam A. Kennington III * @param[out] ret - The IPMI response payload to be packed
42416064aa1SWilliam A. Kennington III * @param[in] channel - The channel id corresponding to an ethernet interface
42516064aa1SWilliam A. Kennington III * @param[in] set - The set selector for determining address index
42616064aa1SWilliam A. Kennington III * @param[in] origins - Set of valid origins for address filtering
42716064aa1SWilliam A. Kennington III */
getLanIPv6Address(message::Payload & ret,uint8_t channel,uint8_t set,const std::unordered_set<IP::AddressOrigin> & origins)42816064aa1SWilliam A. Kennington III void getLanIPv6Address(message::Payload& ret, uint8_t channel, uint8_t set,
42916064aa1SWilliam A. Kennington III const std::unordered_set<IP::AddressOrigin>& origins)
43016064aa1SWilliam A. Kennington III {
43116064aa1SWilliam A. Kennington III auto source = IPv6Source::Static;
43216064aa1SWilliam A. Kennington III bool enabled = false;
433726f2bddSWilliam A. Kennington III stdplus::In6Addr addr{};
4345aae092cSJohnathan Mantey uint8_t prefix{};
43516064aa1SWilliam A. Kennington III auto status = IPv6AddressStatus::Disabled;
43616064aa1SWilliam A. Kennington III
43716064aa1SWilliam A. Kennington III auto ifaddr = channelCall<getIfAddr<AF_INET6>>(channel, set, origins);
43816064aa1SWilliam A. Kennington III if (ifaddr)
43916064aa1SWilliam A. Kennington III {
44016064aa1SWilliam A. Kennington III source = originToSourceType(ifaddr->origin);
441846af864SJohnathan Mantey enabled = (origins == originsV6Static);
44216064aa1SWilliam A. Kennington III addr = ifaddr->address;
44316064aa1SWilliam A. Kennington III prefix = ifaddr->prefix;
44416064aa1SWilliam A. Kennington III status = IPv6AddressStatus::Active;
44516064aa1SWilliam A. Kennington III }
44616064aa1SWilliam A. Kennington III
44716064aa1SWilliam A. Kennington III ret.pack(set);
4487a0e5dfcSWilliam A. Kennington III ret.pack(types::enum_cast<uint4_t>(source), uint3_t{}, enabled);
449726f2bddSWilliam A. Kennington III ret.pack(stdplus::raw::asView<char>(addr));
45016064aa1SWilliam A. Kennington III ret.pack(prefix);
4517a0e5dfcSWilliam A. Kennington III ret.pack(types::enum_cast<uint8_t>(status));
45216064aa1SWilliam A. Kennington III }
45316064aa1SWilliam A. Kennington III
454c514d874SWilliam A. Kennington III /** @brief Gets the vlan ID configured on the interface
455c514d874SWilliam A. Kennington III *
456c514d874SWilliam A. Kennington III * @param[in] bus - The bus object used for lookups
457c514d874SWilliam A. Kennington III * @param[in] params - The parameters for the channel
458c514d874SWilliam A. Kennington III * @return VLAN id or the standard 0 for no VLAN
459c514d874SWilliam A. Kennington III */
getVLANProperty(sdbusplus::bus_t & bus,const ChannelParams & params)4605d82f474SPatrick Williams uint16_t getVLANProperty(sdbusplus::bus_t& bus, const ChannelParams& params)
461c514d874SWilliam A. Kennington III {
462c514d874SWilliam A. Kennington III // VLAN devices will always have a separate logical object
463c514d874SWilliam A. Kennington III if (params.ifPath == params.logicalPath)
464c514d874SWilliam A. Kennington III {
465c514d874SWilliam A. Kennington III return 0;
466c514d874SWilliam A. Kennington III }
467c514d874SWilliam A. Kennington III
468c514d874SWilliam A. Kennington III auto vlan = std::get<uint32_t>(getDbusProperty(
469c514d874SWilliam A. Kennington III bus, params.service, params.logicalPath, INTF_VLAN, "Id"));
470c514d874SWilliam A. Kennington III if ((vlan & VLAN_VALUE_MASK) != vlan)
471c514d874SWilliam A. Kennington III {
472af4a7750SVernon Mauery lg2::error("networkd returned an invalid vlan: {VLAN} "
473af4a7750SVernon Mauery "(CH={CHANNEL}, IF={IFNAME})",
474af4a7750SVernon Mauery "CHANNEL", params.id, "IFNAME", params.ifname, "VLAN", vlan);
475c514d874SWilliam A. Kennington III elog<InternalFailure>();
476c514d874SWilliam A. Kennington III }
477c514d874SWilliam A. Kennington III return vlan;
478c514d874SWilliam A. Kennington III }
479c514d874SWilliam A. Kennington III
480c514d874SWilliam A. Kennington III /** @brief Deletes all of the possible configuration parameters for a channel
481c514d874SWilliam A. Kennington III *
482c514d874SWilliam A. Kennington III * @param[in] bus - The bus object used for lookups
483c514d874SWilliam A. Kennington III * @param[in] params - The parameters for the channel
484c514d874SWilliam A. Kennington III */
deconfigureChannel(sdbusplus::bus_t & bus,ChannelParams & params)4855d82f474SPatrick Williams void deconfigureChannel(sdbusplus::bus_t& bus, ChannelParams& params)
486c514d874SWilliam A. Kennington III {
487c514d874SWilliam A. Kennington III // Delete all objects associated with the interface
488c1c7eac4SGeorge Liu ObjectTree objs =
489c1c7eac4SGeorge Liu ipmi::getSubTree(bus, std::vector<std::string>{DELETE_INTERFACE},
490c1c7eac4SGeorge Liu std::string{PATH_ROOT});
491c514d874SWilliam A. Kennington III for (const auto& [path, impls] : objs)
492c514d874SWilliam A. Kennington III {
493c72f3602SWilliam A. Kennington III if (!ifnameInPath(params.ifname, path))
494c514d874SWilliam A. Kennington III {
495c514d874SWilliam A. Kennington III continue;
496c514d874SWilliam A. Kennington III }
497c514d874SWilliam A. Kennington III for (const auto& [service, intfs] : impls)
498c514d874SWilliam A. Kennington III {
499c514d874SWilliam A. Kennington III deleteObjectIfExists(bus, service, path);
500c514d874SWilliam A. Kennington III }
501c514d874SWilliam A. Kennington III // Update params to reflect the deletion of vlan
502c514d874SWilliam A. Kennington III if (path == params.logicalPath)
503c514d874SWilliam A. Kennington III {
504c514d874SWilliam A. Kennington III params.logicalPath = params.ifPath;
505c514d874SWilliam A. Kennington III }
506c514d874SWilliam A. Kennington III }
507c514d874SWilliam A. Kennington III
508c514d874SWilliam A. Kennington III // Clear out any settings on the lower physical interface
509a8a2e5f6SWilliam A. Kennington III setEthProp(bus, params, "DHCP4", false);
510a8a2e5f6SWilliam A. Kennington III setEthProp(bus, params, "DHCP6", false);
511a8a2e5f6SWilliam A. Kennington III setEthProp(bus, params, "IPv6AcceptRA", false);
512c514d874SWilliam A. Kennington III }
513c514d874SWilliam A. Kennington III
514c514d874SWilliam A. Kennington III /** @brief Creates a new VLAN on the specified interface
515c514d874SWilliam A. Kennington III *
516c514d874SWilliam A. Kennington III * @param[in] bus - The bus object used for lookups
517c514d874SWilliam A. Kennington III * @param[in] params - The parameters for the channel
518c514d874SWilliam A. Kennington III * @param[in] vlan - The id of the new vlan
519c514d874SWilliam A. Kennington III */
createVLAN(sdbusplus::bus_t & bus,ChannelParams & params,uint16_t vlan)5205d82f474SPatrick Williams void createVLAN(sdbusplus::bus_t& bus, ChannelParams& params, uint16_t vlan)
521c514d874SWilliam A. Kennington III {
522c514d874SWilliam A. Kennington III if (vlan == 0)
523c514d874SWilliam A. Kennington III {
524c514d874SWilliam A. Kennington III return;
525c514d874SWilliam A. Kennington III }
526c514d874SWilliam A. Kennington III
527c72f3602SWilliam A. Kennington III auto req = bus.new_method_call(params.service.c_str(), PATH_ROOT.c_str(),
528c514d874SWilliam A. Kennington III INTF_VLAN_CREATE, "VLAN");
529c514d874SWilliam A. Kennington III req.append(params.ifname, static_cast<uint32_t>(vlan));
530c514d874SWilliam A. Kennington III auto reply = bus.call(req);
531c514d874SWilliam A. Kennington III sdbusplus::message::object_path newPath;
532c514d874SWilliam A. Kennington III reply.read(newPath);
533c514d874SWilliam A. Kennington III params.logicalPath = std::move(newPath);
534c514d874SWilliam A. Kennington III }
535c514d874SWilliam A. Kennington III
536c514d874SWilliam A. Kennington III /** @brief Performs the necessary reconfiguration to change the VLAN
537c514d874SWilliam A. Kennington III *
538c514d874SWilliam A. Kennington III * @param[in] bus - The bus object used for lookups
539c514d874SWilliam A. Kennington III * @param[in] params - The parameters for the channel
540c514d874SWilliam A. Kennington III * @param[in] vlan - The new vlan id to use
541c514d874SWilliam A. Kennington III */
reconfigureVLAN(sdbusplus::bus_t & bus,ChannelParams & params,uint16_t vlan)5425d82f474SPatrick Williams void reconfigureVLAN(sdbusplus::bus_t& bus, ChannelParams& params,
543c514d874SWilliam A. Kennington III uint16_t vlan)
544c514d874SWilliam A. Kennington III {
545c514d874SWilliam A. Kennington III // Unfortunatetly we don't have built-in functions to migrate our interface
546c514d874SWilliam A. Kennington III // customizations to new VLAN interfaces, or have some kind of decoupling.
547c514d874SWilliam A. Kennington III // We therefore must retain all of our old information, setup the new VLAN
548c514d874SWilliam A. Kennington III // configuration, then restore the old info.
549c514d874SWilliam A. Kennington III
550c514d874SWilliam A. Kennington III // Save info from the old logical interface
551a8a2e5f6SWilliam A. Kennington III bool dhcp4 = getEthProp<bool>(bus, params, "DHCP4");
552a8a2e5f6SWilliam A. Kennington III bool dhcp6 = getEthProp<bool>(bus, params, "DHCP6");
553a8a2e5f6SWilliam A. Kennington III bool ra = getEthProp<bool>(bus, params, "IPv6AcceptRA");
554c514d874SWilliam A. Kennington III ObjectLookupCache ips(bus, params, INTF_IP);
555c514d874SWilliam A. Kennington III auto ifaddr4 = findIfAddr<AF_INET>(bus, params, 0, originsV4, ips);
55616064aa1SWilliam A. Kennington III std::vector<IfAddr<AF_INET6>> ifaddrs6;
55716064aa1SWilliam A. Kennington III for (uint8_t i = 0; i < MAX_IPV6_STATIC_ADDRESSES; ++i)
55816064aa1SWilliam A. Kennington III {
5591318a5edSPatrick Williams auto ifaddr6 =
5601318a5edSPatrick Williams findIfAddr<AF_INET6>(bus, params, i, originsV6Static, ips);
56116064aa1SWilliam A. Kennington III if (!ifaddr6)
56216064aa1SWilliam A. Kennington III {
56316064aa1SWilliam A. Kennington III break;
56416064aa1SWilliam A. Kennington III }
56516064aa1SWilliam A. Kennington III ifaddrs6.push_back(std::move(*ifaddr6));
56616064aa1SWilliam A. Kennington III }
5674bbc3db6SWilliam A. Kennington III ObjectLookupCache neighbors(bus, params, INTF_NEIGHBOR);
5684bbc3db6SWilliam A. Kennington III auto neighbor4 = findGatewayNeighbor<AF_INET>(bus, params, neighbors);
56916064aa1SWilliam A. Kennington III auto neighbor6 = findGatewayNeighbor<AF_INET6>(bus, params, neighbors);
570c514d874SWilliam A. Kennington III
571c514d874SWilliam A. Kennington III deconfigureChannel(bus, params);
572c514d874SWilliam A. Kennington III createVLAN(bus, params, vlan);
573c514d874SWilliam A. Kennington III
574c514d874SWilliam A. Kennington III // Re-establish the saved settings
575a8a2e5f6SWilliam A. Kennington III setEthProp(bus, params, "DHCP4", dhcp4);
576a8a2e5f6SWilliam A. Kennington III setEthProp(bus, params, "DHCP6", dhcp6);
577a8a2e5f6SWilliam A. Kennington III setEthProp(bus, params, "IPv6AcceptRA", ra);
578c514d874SWilliam A. Kennington III if (ifaddr4)
579c514d874SWilliam A. Kennington III {
580c514d874SWilliam A. Kennington III createIfAddr<AF_INET>(bus, params, ifaddr4->address, ifaddr4->prefix);
581c514d874SWilliam A. Kennington III }
58216064aa1SWilliam A. Kennington III for (const auto& ifaddr6 : ifaddrs6)
58316064aa1SWilliam A. Kennington III {
58416064aa1SWilliam A. Kennington III createIfAddr<AF_INET6>(bus, params, ifaddr6.address, ifaddr6.prefix);
58516064aa1SWilliam A. Kennington III }
5864bbc3db6SWilliam A. Kennington III if (neighbor4)
5874bbc3db6SWilliam A. Kennington III {
5884bbc3db6SWilliam A. Kennington III createNeighbor<AF_INET>(bus, params, neighbor4->ip, neighbor4->mac);
5894bbc3db6SWilliam A. Kennington III }
59016064aa1SWilliam A. Kennington III if (neighbor6)
59116064aa1SWilliam A. Kennington III {
59216064aa1SWilliam A. Kennington III createNeighbor<AF_INET6>(bus, params, neighbor6->ip, neighbor6->mac);
59316064aa1SWilliam A. Kennington III }
594c514d874SWilliam A. Kennington III }
595c514d874SWilliam A. Kennington III
596c514d874SWilliam A. Kennington III // We need to store this value so it can be returned to the client
597c514d874SWilliam A. Kennington III // It is volatile so safe to store in daemon memory.
598c514d874SWilliam A. Kennington III static std::unordered_map<uint8_t, SetStatus> setStatus;
599c514d874SWilliam A. Kennington III
600c514d874SWilliam A. Kennington III // Until we have good support for fixed versions of IPMI tool
601c514d874SWilliam A. Kennington III // we need to return the VLAN id for disabled VLANs. The value is only
602c514d874SWilliam A. Kennington III // used for verification that a disable operation succeeded and will only
603c514d874SWilliam A. Kennington III // be sent if our system indicates that vlans are disabled.
604c514d874SWilliam A. Kennington III static std::unordered_map<uint8_t, uint16_t> lastDisabledVlan;
605c514d874SWilliam A. Kennington III
606c514d874SWilliam A. Kennington III /** @brief Gets the set status for the channel if it exists
607c514d874SWilliam A. Kennington III * Otherise populates and returns the default value.
608c514d874SWilliam A. Kennington III *
609c514d874SWilliam A. Kennington III * @param[in] channel - The channel id corresponding to an ethernet interface
610c514d874SWilliam A. Kennington III * @return A reference to the SetStatus for the channel
611c514d874SWilliam A. Kennington III */
getSetStatus(uint8_t channel)612c514d874SWilliam A. Kennington III SetStatus& getSetStatus(uint8_t channel)
613c514d874SWilliam A. Kennington III {
614c514d874SWilliam A. Kennington III auto it = setStatus.find(channel);
615c514d874SWilliam A. Kennington III if (it != setStatus.end())
616c514d874SWilliam A. Kennington III {
617c514d874SWilliam A. Kennington III return it->second;
618c514d874SWilliam A. Kennington III }
619c514d874SWilliam A. Kennington III return setStatus[channel] = SetStatus::Complete;
620c514d874SWilliam A. Kennington III }
621c514d874SWilliam A. Kennington III
6227a3831b5SWilliam A. Kennington III /** @brief Unpacks the trivially copyable type from the message */
6237a3831b5SWilliam A. Kennington III template <typename T>
unpackT(message::Payload & req)6247a3831b5SWilliam A. Kennington III static T unpackT(message::Payload& req)
6257a3831b5SWilliam A. Kennington III {
6267a3831b5SWilliam A. Kennington III std::array<uint8_t, sizeof(T)> bytes;
6277a3831b5SWilliam A. Kennington III if (req.unpack(bytes) != 0)
6287a3831b5SWilliam A. Kennington III {
6297a3831b5SWilliam A. Kennington III throw ccReqDataLenInvalid;
6307a3831b5SWilliam A. Kennington III }
6317a3831b5SWilliam A. Kennington III return stdplus::raw::copyFrom<T>(bytes);
6327a3831b5SWilliam A. Kennington III }
6337a3831b5SWilliam A. Kennington III
6347a3831b5SWilliam A. Kennington III /** @brief Ensure the message is fully unpacked */
unpackFinal(message::Payload & req)6357a3831b5SWilliam A. Kennington III static void unpackFinal(message::Payload& req)
6367a3831b5SWilliam A. Kennington III {
6377a3831b5SWilliam A. Kennington III if (!req.fullyUnpacked())
6387a3831b5SWilliam A. Kennington III {
6397a3831b5SWilliam A. Kennington III throw ccReqDataTruncated;
6407a3831b5SWilliam A. Kennington III }
6417a3831b5SWilliam A. Kennington III }
6427a3831b5SWilliam A. Kennington III
643b87034e8SJohnathan Mantey /**
644b87034e8SJohnathan Mantey * Define placeholder command handlers for the OEM Extension bytes for the Set
645b87034e8SJohnathan Mantey * LAN Configuration Parameters and Get LAN Configuration Parameters
646b87034e8SJohnathan Mantey * commands. Using "weak" linking allows the placeholder setLanOem/getLanOem
647b87034e8SJohnathan Mantey * functions below to be overridden.
648b87034e8SJohnathan Mantey * To create handlers for your own proprietary command set:
649b87034e8SJohnathan Mantey * Create/modify a phosphor-ipmi-host Bitbake append file within your Yocto
650b87034e8SJohnathan Mantey * recipe
651b87034e8SJohnathan Mantey * Create C++ file(s) that define IPMI handler functions matching the
652b87034e8SJohnathan Mantey * function names below (i.e. setLanOem). The default name for the
653b87034e8SJohnathan Mantey * transport IPMI commands is transporthandler_oem.cpp.
654b87034e8SJohnathan Mantey * Add:
655efe26686SJohnathan Mantey * EXTRA_OEMESON:append = "-Dtransport-oem=enabled"
656efe26686SJohnathan Mantey * Create a do_configure:prepend()/do_install:append() method in your
657b87034e8SJohnathan Mantey * bbappend file to copy the file to the build directory.
658b87034e8SJohnathan Mantey * Add:
659b87034e8SJohnathan Mantey * PROJECT_SRC_DIR := "${THISDIR}/${PN}"
660b87034e8SJohnathan Mantey * # Copy the "strong" functions into the working directory, overriding the
661b87034e8SJohnathan Mantey * # placeholder functions.
662efe26686SJohnathan Mantey * do_configure:prepend(){
663b87034e8SJohnathan Mantey * cp -f ${PROJECT_SRC_DIR}/transporthandler_oem.cpp ${S}
664b87034e8SJohnathan Mantey * }
665b87034e8SJohnathan Mantey *
666b87034e8SJohnathan Mantey * # Clean up after complilation has completed
667efe26686SJohnathan Mantey * do_install:append(){
668b87034e8SJohnathan Mantey * rm -f ${S}/transporthandler_oem.cpp
669b87034e8SJohnathan Mantey * }
670b87034e8SJohnathan Mantey *
671b87034e8SJohnathan Mantey */
672b87034e8SJohnathan Mantey
673b87034e8SJohnathan Mantey /**
674b87034e8SJohnathan Mantey * Define the placeholder OEM commands as having weak linkage. Create
675b87034e8SJohnathan Mantey * setLanOem, and getLanOem functions in the transporthandler_oem.cpp
676b87034e8SJohnathan Mantey * file. The functions defined there must not have the "weak" attribute
677b87034e8SJohnathan Mantey * applied to them.
678b87034e8SJohnathan Mantey */
679b87034e8SJohnathan Mantey RspType<> setLanOem(uint8_t channel, uint8_t parameter, message::Payload& req)
680b87034e8SJohnathan Mantey __attribute__((weak));
681*69b4c281SPatrick Williams RspType<message::Payload> getLanOem(uint8_t channel, uint8_t parameter,
682*69b4c281SPatrick Williams uint8_t set, uint8_t block)
683b87034e8SJohnathan Mantey __attribute__((weak));
684b87034e8SJohnathan Mantey
setLanOem(uint8_t,uint8_t,message::Payload & req)68511d68897SWilly Tu RspType<> setLanOem(uint8_t, uint8_t, message::Payload& req)
686b87034e8SJohnathan Mantey {
687b87034e8SJohnathan Mantey req.trailingOk = true;
688b87034e8SJohnathan Mantey return response(ccParamNotSupported);
689b87034e8SJohnathan Mantey }
690b87034e8SJohnathan Mantey
getLanOem(uint8_t,uint8_t,uint8_t,uint8_t)69111d68897SWilly Tu RspType<message::Payload> getLanOem(uint8_t, uint8_t, uint8_t, uint8_t)
692b87034e8SJohnathan Mantey {
693b87034e8SJohnathan Mantey return response(ccParamNotSupported);
694b87034e8SJohnathan Mantey }
695b87034e8SJohnathan Mantey
696cf19d146SJian Zhang /**
697cf19d146SJian Zhang * @brief is a valid LAN channel.
698cf19d146SJian Zhang *
699cf19d146SJian Zhang * This function checks whether the input channel is a valid LAN channel or not.
700cf19d146SJian Zhang *
701cf19d146SJian Zhang * @param[in] channel: the channel number.
702cf19d146SJian Zhang * @return nullopt if the channel is invalid, false if the channel is not a LAN
703cf19d146SJian Zhang * channel, true if the channel is a LAN channel.
704cf19d146SJian Zhang **/
isLanChannel(uint8_t channel)705cf19d146SJian Zhang std::optional<bool> isLanChannel(uint8_t channel)
706cf19d146SJian Zhang {
707cf19d146SJian Zhang ChannelInfo chInfo;
708cf19d146SJian Zhang auto cc = getChannelInfo(channel, chInfo);
709cf19d146SJian Zhang if (cc != ccSuccess)
710cf19d146SJian Zhang {
711cf19d146SJian Zhang return std::nullopt;
712cf19d146SJian Zhang }
713cf19d146SJian Zhang
714cf19d146SJian Zhang return chInfo.mediumType ==
715cf19d146SJian Zhang static_cast<uint8_t>(EChannelMediumType::lan8032);
716cf19d146SJian Zhang }
717cf19d146SJian Zhang
setLanInt(Context::ptr ctx,uint4_t channelBits,uint4_t reserved1,uint8_t parameter,message::Payload & req)7187a3831b5SWilliam A. Kennington III RspType<> setLanInt(Context::ptr ctx, uint4_t channelBits, uint4_t reserved1,
719cc76925eSvijayabharathix shetty uint8_t parameter, message::Payload& req)
720c514d874SWilliam A. Kennington III {
721cc76925eSvijayabharathix shetty const uint8_t channel = convertCurrentChannelNum(
722cc76925eSvijayabharathix shetty static_cast<uint8_t>(channelBits), ctx->channel);
723cc76925eSvijayabharathix shetty if (reserved1 || !isValidChannel(channel))
724c514d874SWilliam A. Kennington III {
72532e8f5d3SGeorge Liu lg2::error("Set Lan - Invalid field in request");
726c514d874SWilliam A. Kennington III req.trailingOk = true;
727c514d874SWilliam A. Kennington III return responseInvalidFieldRequest();
728c514d874SWilliam A. Kennington III }
729c514d874SWilliam A. Kennington III
730cf19d146SJian Zhang if (!isLanChannel(channel).value_or(false))
731cf19d146SJian Zhang {
73232e8f5d3SGeorge Liu lg2::error("Set Lan - Not a LAN channel");
733cf19d146SJian Zhang return responseInvalidFieldRequest();
734cf19d146SJian Zhang }
735cf19d146SJian Zhang
736c514d874SWilliam A. Kennington III switch (static_cast<LanParam>(parameter))
737c514d874SWilliam A. Kennington III {
738c514d874SWilliam A. Kennington III case LanParam::SetStatus:
739c514d874SWilliam A. Kennington III {
740c514d874SWilliam A. Kennington III uint2_t flag;
741c514d874SWilliam A. Kennington III uint6_t rsvd;
7427a3831b5SWilliam A. Kennington III if (req.unpack(flag, rsvd) != 0)
743c514d874SWilliam A. Kennington III {
744c514d874SWilliam A. Kennington III return responseReqDataLenInvalid();
745c514d874SWilliam A. Kennington III }
7467a3831b5SWilliam A. Kennington III unpackFinal(req);
7474a15685eSJohnathan Mantey if (rsvd)
7484a15685eSJohnathan Mantey {
7494a15685eSJohnathan Mantey return responseInvalidFieldRequest();
7504a15685eSJohnathan Mantey }
751c514d874SWilliam A. Kennington III auto status = static_cast<SetStatus>(static_cast<uint8_t>(flag));
752c514d874SWilliam A. Kennington III switch (status)
753c514d874SWilliam A. Kennington III {
754c514d874SWilliam A. Kennington III case SetStatus::Complete:
755c514d874SWilliam A. Kennington III {
756c514d874SWilliam A. Kennington III getSetStatus(channel) = status;
757c514d874SWilliam A. Kennington III return responseSuccess();
758c514d874SWilliam A. Kennington III }
759c514d874SWilliam A. Kennington III case SetStatus::InProgress:
760c514d874SWilliam A. Kennington III {
761c514d874SWilliam A. Kennington III auto& storedStatus = getSetStatus(channel);
762c514d874SWilliam A. Kennington III if (storedStatus == SetStatus::InProgress)
763c514d874SWilliam A. Kennington III {
764c514d874SWilliam A. Kennington III return response(ccParamSetLocked);
765c514d874SWilliam A. Kennington III }
766c514d874SWilliam A. Kennington III storedStatus = status;
767c514d874SWilliam A. Kennington III return responseSuccess();
768c514d874SWilliam A. Kennington III }
769c514d874SWilliam A. Kennington III case SetStatus::Commit:
770c514d874SWilliam A. Kennington III if (getSetStatus(channel) != SetStatus::InProgress)
771c514d874SWilliam A. Kennington III {
772c514d874SWilliam A. Kennington III return responseInvalidFieldRequest();
773c514d874SWilliam A. Kennington III }
774c514d874SWilliam A. Kennington III return responseSuccess();
775c514d874SWilliam A. Kennington III }
776c514d874SWilliam A. Kennington III return response(ccParamNotSupported);
777c514d874SWilliam A. Kennington III }
778c514d874SWilliam A. Kennington III case LanParam::AuthSupport:
779c514d874SWilliam A. Kennington III {
780c514d874SWilliam A. Kennington III req.trailingOk = true;
781c514d874SWilliam A. Kennington III return response(ccParamReadOnly);
782c514d874SWilliam A. Kennington III }
783c514d874SWilliam A. Kennington III case LanParam::AuthEnables:
784c514d874SWilliam A. Kennington III {
785c514d874SWilliam A. Kennington III req.trailingOk = true;
78676ce9c78SJohnathan Mantey return response(ccParamReadOnly);
787c514d874SWilliam A. Kennington III }
788c514d874SWilliam A. Kennington III case LanParam::IP:
789c514d874SWilliam A. Kennington III {
790a8a2e5f6SWilliam A. Kennington III if (channelCall<getEthProp<bool>>(channel, "DHCP4"))
791930104a8SJohnathan Mantey {
792930104a8SJohnathan Mantey return responseCommandNotAvailable();
793930104a8SJohnathan Mantey }
794726f2bddSWilliam A. Kennington III auto ip = unpackT<stdplus::In4Addr>(req);
7957a3831b5SWilliam A. Kennington III unpackFinal(req);
796c514d874SWilliam A. Kennington III channelCall<reconfigureIfAddr4>(channel, ip, std::nullopt);
797c514d874SWilliam A. Kennington III return responseSuccess();
798c514d874SWilliam A. Kennington III }
799c514d874SWilliam A. Kennington III case LanParam::IPSrc:
800c514d874SWilliam A. Kennington III {
801c514d874SWilliam A. Kennington III uint4_t flag;
802c514d874SWilliam A. Kennington III uint4_t rsvd;
8037a3831b5SWilliam A. Kennington III if (req.unpack(flag, rsvd) != 0)
804c514d874SWilliam A. Kennington III {
805c514d874SWilliam A. Kennington III return responseReqDataLenInvalid();
806c514d874SWilliam A. Kennington III }
8077a3831b5SWilliam A. Kennington III unpackFinal(req);
8084a15685eSJohnathan Mantey if (rsvd)
8094a15685eSJohnathan Mantey {
8104a15685eSJohnathan Mantey return responseInvalidFieldRequest();
8114a15685eSJohnathan Mantey }
812c514d874SWilliam A. Kennington III switch (static_cast<IPSrc>(static_cast<uint8_t>(flag)))
813c514d874SWilliam A. Kennington III {
814c514d874SWilliam A. Kennington III case IPSrc::DHCP:
81565265369SJohnathan Mantey // The IPSrc IPMI command is only for IPv4
81665265369SJohnathan Mantey // management. Modifying IPv6 state is done using
81765265369SJohnathan Mantey // a completely different Set LAN Configuration
81865265369SJohnathan Mantey // subcommand.
819a8a2e5f6SWilliam A. Kennington III channelCall<setEthProp<bool>>(channel, "DHCP4", true);
820c514d874SWilliam A. Kennington III return responseSuccess();
821c514d874SWilliam A. Kennington III case IPSrc::Unspecified:
822c514d874SWilliam A. Kennington III case IPSrc::Static:
823a8a2e5f6SWilliam A. Kennington III channelCall<setEthProp<bool>>(channel, "DHCP4", false);
824c514d874SWilliam A. Kennington III return responseSuccess();
8258a860ea3SRajashekar Gade Reddy case IPSrc::BIOS:
8268a860ea3SRajashekar Gade Reddy case IPSrc::BMC:
8278a860ea3SRajashekar Gade Reddy return responseInvalidFieldRequest();
8288a860ea3SRajashekar Gade Reddy }
829c514d874SWilliam A. Kennington III return response(ccParamNotSupported);
830c514d874SWilliam A. Kennington III }
831c514d874SWilliam A. Kennington III case LanParam::MAC:
832c514d874SWilliam A. Kennington III {
833726f2bddSWilliam A. Kennington III auto mac = unpackT<stdplus::EtherAddr>(req);
8347a3831b5SWilliam A. Kennington III unpackFinal(req);
835c514d874SWilliam A. Kennington III channelCall<setMACProperty>(channel, mac);
836c514d874SWilliam A. Kennington III return responseSuccess();
837c514d874SWilliam A. Kennington III }
838c514d874SWilliam A. Kennington III case LanParam::SubnetMask:
839c514d874SWilliam A. Kennington III {
840a8a2e5f6SWilliam A. Kennington III if (channelCall<getEthProp<bool>>(channel, "DHCP4"))
841930104a8SJohnathan Mantey {
842930104a8SJohnathan Mantey return responseCommandNotAvailable();
843930104a8SJohnathan Mantey }
844726f2bddSWilliam A. Kennington III auto pfx = stdplus::maskToPfx(unpackT<stdplus::In4Addr>(req));
8457a3831b5SWilliam A. Kennington III unpackFinal(req);
846726f2bddSWilliam A. Kennington III channelCall<reconfigureIfAddr4>(channel, std::nullopt, pfx);
847c514d874SWilliam A. Kennington III return responseSuccess();
848c514d874SWilliam A. Kennington III }
849c514d874SWilliam A. Kennington III case LanParam::Gateway1:
850c514d874SWilliam A. Kennington III {
851a8a2e5f6SWilliam A. Kennington III if (channelCall<getEthProp<bool>>(channel, "DHCP4"))
852930104a8SJohnathan Mantey {
853930104a8SJohnathan Mantey return responseCommandNotAvailable();
854930104a8SJohnathan Mantey }
855726f2bddSWilliam A. Kennington III auto gateway = unpackT<stdplus::In4Addr>(req);
8567a3831b5SWilliam A. Kennington III unpackFinal(req);
857c514d874SWilliam A. Kennington III channelCall<setGatewayProperty<AF_INET>>(channel, gateway);
858c514d874SWilliam A. Kennington III return responseSuccess();
859c514d874SWilliam A. Kennington III }
8604bbc3db6SWilliam A. Kennington III case LanParam::Gateway1MAC:
8614bbc3db6SWilliam A. Kennington III {
862726f2bddSWilliam A. Kennington III auto gatewayMAC = unpackT<stdplus::EtherAddr>(req);
8637a3831b5SWilliam A. Kennington III unpackFinal(req);
8644bbc3db6SWilliam A. Kennington III channelCall<reconfigureGatewayMAC<AF_INET>>(channel, gatewayMAC);
8654bbc3db6SWilliam A. Kennington III return responseSuccess();
8664bbc3db6SWilliam A. Kennington III }
867c514d874SWilliam A. Kennington III case LanParam::VLANId:
868c514d874SWilliam A. Kennington III {
8697a3831b5SWilliam A. Kennington III uint12_t vlanData;
8707a3831b5SWilliam A. Kennington III uint3_t rsvd;
8717a3831b5SWilliam A. Kennington III bool vlanEnable;
8728e8c8e29SSuryakanth Sekar
8737a3831b5SWilliam A. Kennington III if (req.unpack(vlanData, rsvd, vlanEnable) != 0)
874c514d874SWilliam A. Kennington III {
875c514d874SWilliam A. Kennington III return responseReqDataLenInvalid();
876c514d874SWilliam A. Kennington III }
8777a3831b5SWilliam A. Kennington III unpackFinal(req);
8788e8c8e29SSuryakanth Sekar
8797a3831b5SWilliam A. Kennington III if (rsvd)
880c514d874SWilliam A. Kennington III {
8818e8c8e29SSuryakanth Sekar return responseInvalidFieldRequest();
882c514d874SWilliam A. Kennington III }
8838e8c8e29SSuryakanth Sekar
8848e8c8e29SSuryakanth Sekar uint16_t vlan = static_cast<uint16_t>(vlanData);
8858e8c8e29SSuryakanth Sekar
8868e8c8e29SSuryakanth Sekar if (!vlanEnable)
8878e8c8e29SSuryakanth Sekar {
8888e8c8e29SSuryakanth Sekar lastDisabledVlan[channel] = vlan;
8898e8c8e29SSuryakanth Sekar vlan = 0;
8908e8c8e29SSuryakanth Sekar }
8910d1d7ad2SJayaprakash Mutyala else if (vlan == 0 || vlan == VLAN_VALUE_MASK)
8920d1d7ad2SJayaprakash Mutyala {
8930d1d7ad2SJayaprakash Mutyala return responseInvalidFieldRequest();
8940d1d7ad2SJayaprakash Mutyala }
8958e8c8e29SSuryakanth Sekar
89684c49dc1Sjayaprakash Mutyala channelCall<reconfigureVLAN>(channel, vlan);
897c514d874SWilliam A. Kennington III return responseSuccess();
898c514d874SWilliam A. Kennington III }
899c514d874SWilliam A. Kennington III case LanParam::CiphersuiteSupport:
900c514d874SWilliam A. Kennington III case LanParam::CiphersuiteEntries:
90116064aa1SWilliam A. Kennington III case LanParam::IPFamilySupport:
902c514d874SWilliam A. Kennington III {
903c514d874SWilliam A. Kennington III req.trailingOk = true;
904c514d874SWilliam A. Kennington III return response(ccParamReadOnly);
905c514d874SWilliam A. Kennington III }
90616064aa1SWilliam A. Kennington III case LanParam::IPFamilyEnables:
90716064aa1SWilliam A. Kennington III {
90816064aa1SWilliam A. Kennington III uint8_t enables;
9097a3831b5SWilliam A. Kennington III if (req.unpack(enables) != 0)
91016064aa1SWilliam A. Kennington III {
91116064aa1SWilliam A. Kennington III return responseReqDataLenInvalid();
91216064aa1SWilliam A. Kennington III }
9137a3831b5SWilliam A. Kennington III unpackFinal(req);
91416064aa1SWilliam A. Kennington III switch (static_cast<IPFamilyEnables>(enables))
91516064aa1SWilliam A. Kennington III {
91616064aa1SWilliam A. Kennington III case IPFamilyEnables::DualStack:
91716064aa1SWilliam A. Kennington III return responseSuccess();
91816064aa1SWilliam A. Kennington III case IPFamilyEnables::IPv4Only:
91916064aa1SWilliam A. Kennington III case IPFamilyEnables::IPv6Only:
92016064aa1SWilliam A. Kennington III return response(ccParamNotSupported);
92116064aa1SWilliam A. Kennington III }
92216064aa1SWilliam A. Kennington III return response(ccParamNotSupported);
92316064aa1SWilliam A. Kennington III }
92416064aa1SWilliam A. Kennington III case LanParam::IPv6Status:
92516064aa1SWilliam A. Kennington III {
92616064aa1SWilliam A. Kennington III req.trailingOk = true;
92716064aa1SWilliam A. Kennington III return response(ccParamReadOnly);
92816064aa1SWilliam A. Kennington III }
92916064aa1SWilliam A. Kennington III case LanParam::IPv6StaticAddresses:
93016064aa1SWilliam A. Kennington III {
93116064aa1SWilliam A. Kennington III uint8_t set;
93216064aa1SWilliam A. Kennington III uint7_t rsvd;
93316064aa1SWilliam A. Kennington III bool enabled;
93416064aa1SWilliam A. Kennington III uint8_t prefix;
93516064aa1SWilliam A. Kennington III uint8_t status;
9367a3831b5SWilliam A. Kennington III if (req.unpack(set, rsvd, enabled) != 0)
93716064aa1SWilliam A. Kennington III {
93816064aa1SWilliam A. Kennington III return responseReqDataLenInvalid();
93916064aa1SWilliam A. Kennington III }
940726f2bddSWilliam A. Kennington III auto ip = unpackT<stdplus::In6Addr>(req);
9417a3831b5SWilliam A. Kennington III if (req.unpack(prefix, status) != 0)
9427a3831b5SWilliam A. Kennington III {
9437a3831b5SWilliam A. Kennington III return responseReqDataLenInvalid();
9447a3831b5SWilliam A. Kennington III }
9457a3831b5SWilliam A. Kennington III unpackFinal(req);
9464a15685eSJohnathan Mantey if (rsvd)
9474a15685eSJohnathan Mantey {
9484a15685eSJohnathan Mantey return responseInvalidFieldRequest();
9494a15685eSJohnathan Mantey }
95016064aa1SWilliam A. Kennington III if (enabled)
95116064aa1SWilliam A. Kennington III {
9526d4a44edSJiaqing Zhao if (prefix < MIN_IPV6_PREFIX_LENGTH ||
9536d4a44edSJiaqing Zhao prefix > MAX_IPV6_PREFIX_LENGTH)
9546d4a44edSJiaqing Zhao {
9556d4a44edSJiaqing Zhao return responseParmOutOfRange();
9566d4a44edSJiaqing Zhao }
95716064aa1SWilliam A. Kennington III channelCall<reconfigureIfAddr6>(channel, set, ip, prefix);
95816064aa1SWilliam A. Kennington III }
95916064aa1SWilliam A. Kennington III else
96016064aa1SWilliam A. Kennington III {
96116064aa1SWilliam A. Kennington III channelCall<deconfigureIfAddr6>(channel, set);
96216064aa1SWilliam A. Kennington III }
96316064aa1SWilliam A. Kennington III return responseSuccess();
96416064aa1SWilliam A. Kennington III }
96516064aa1SWilliam A. Kennington III case LanParam::IPv6DynamicAddresses:
96616064aa1SWilliam A. Kennington III {
96716064aa1SWilliam A. Kennington III req.trailingOk = true;
96816064aa1SWilliam A. Kennington III return response(ccParamReadOnly);
96916064aa1SWilliam A. Kennington III }
97016064aa1SWilliam A. Kennington III case LanParam::IPv6RouterControl:
97116064aa1SWilliam A. Kennington III {
97216064aa1SWilliam A. Kennington III std::bitset<8> control;
9733b7a4078SJohnathan Mantey constexpr uint8_t reservedRACCBits = 0xfc;
9747a3831b5SWilliam A. Kennington III if (req.unpack(control) != 0)
97516064aa1SWilliam A. Kennington III {
97616064aa1SWilliam A. Kennington III return responseReqDataLenInvalid();
97716064aa1SWilliam A. Kennington III }
9787a3831b5SWilliam A. Kennington III unpackFinal(req);
9791318a5edSPatrick Williams if (std::bitset<8> expected(
9801318a5edSPatrick Williams control & std::bitset<8>(reservedRACCBits));
9813b7a4078SJohnathan Mantey expected.any())
98216064aa1SWilliam A. Kennington III {
9833b7a4078SJohnathan Mantey return response(ccParamNotSupported);
98416064aa1SWilliam A. Kennington III }
9853b7a4078SJohnathan Mantey
9863b7a4078SJohnathan Mantey bool enableRA = control[IPv6RouterControlFlag::Dynamic];
987a8a2e5f6SWilliam A. Kennington III channelCall<setEthProp<bool>>(channel, "IPv6AcceptRA", enableRA);
988a8a2e5f6SWilliam A. Kennington III channelCall<setEthProp<bool>>(channel, "DHCP6", enableRA);
98916064aa1SWilliam A. Kennington III return responseSuccess();
99016064aa1SWilliam A. Kennington III }
99116064aa1SWilliam A. Kennington III case LanParam::IPv6StaticRouter1IP:
99216064aa1SWilliam A. Kennington III {
993726f2bddSWilliam A. Kennington III auto gateway = unpackT<stdplus::In6Addr>(req);
9947a3831b5SWilliam A. Kennington III unpackFinal(req);
99516064aa1SWilliam A. Kennington III channelCall<setGatewayProperty<AF_INET6>>(channel, gateway);
99616064aa1SWilliam A. Kennington III return responseSuccess();
99716064aa1SWilliam A. Kennington III }
99816064aa1SWilliam A. Kennington III case LanParam::IPv6StaticRouter1MAC:
99916064aa1SWilliam A. Kennington III {
1000726f2bddSWilliam A. Kennington III auto mac = unpackT<stdplus::EtherAddr>(req);
10017a3831b5SWilliam A. Kennington III unpackFinal(req);
100216064aa1SWilliam A. Kennington III channelCall<reconfigureGatewayMAC<AF_INET6>>(channel, mac);
100316064aa1SWilliam A. Kennington III return responseSuccess();
100416064aa1SWilliam A. Kennington III }
100516064aa1SWilliam A. Kennington III case LanParam::IPv6StaticRouter1PrefixLength:
100616064aa1SWilliam A. Kennington III {
100716064aa1SWilliam A. Kennington III uint8_t prefix;
10087a3831b5SWilliam A. Kennington III if (req.unpack(prefix) != 0)
100916064aa1SWilliam A. Kennington III {
101016064aa1SWilliam A. Kennington III return responseReqDataLenInvalid();
101116064aa1SWilliam A. Kennington III }
10127a3831b5SWilliam A. Kennington III unpackFinal(req);
101316064aa1SWilliam A. Kennington III if (prefix != 0)
101416064aa1SWilliam A. Kennington III {
101516064aa1SWilliam A. Kennington III return responseInvalidFieldRequest();
101616064aa1SWilliam A. Kennington III }
101716064aa1SWilliam A. Kennington III return responseSuccess();
101816064aa1SWilliam A. Kennington III }
101916064aa1SWilliam A. Kennington III case LanParam::IPv6StaticRouter1PrefixValue:
102016064aa1SWilliam A. Kennington III {
1021726f2bddSWilliam A. Kennington III unpackT<stdplus::In6Addr>(req);
10227a3831b5SWilliam A. Kennington III unpackFinal(req);
102316064aa1SWilliam A. Kennington III // Accept any prefix value since our prefix length has to be 0
102416064aa1SWilliam A. Kennington III return responseSuccess();
102516064aa1SWilliam A. Kennington III }
1026b741b990Sjayaprakash Mutyala case LanParam::cipherSuitePrivilegeLevels:
1027b741b990Sjayaprakash Mutyala {
10287a3831b5SWilliam A. Kennington III uint8_t rsvd;
1029b741b990Sjayaprakash Mutyala std::array<uint4_t, ipmi::maxCSRecords> cipherSuitePrivs;
1030b741b990Sjayaprakash Mutyala
10317a3831b5SWilliam A. Kennington III if (req.unpack(rsvd, cipherSuitePrivs))
1032b741b990Sjayaprakash Mutyala {
1033b741b990Sjayaprakash Mutyala return responseReqDataLenInvalid();
1034b741b990Sjayaprakash Mutyala }
10357a3831b5SWilliam A. Kennington III unpackFinal(req);
1036b741b990Sjayaprakash Mutyala
10377a3831b5SWilliam A. Kennington III if (rsvd)
1038b741b990Sjayaprakash Mutyala {
1039b741b990Sjayaprakash Mutyala return responseInvalidFieldRequest();
1040b741b990Sjayaprakash Mutyala }
1041b741b990Sjayaprakash Mutyala
10421318a5edSPatrick Williams uint8_t resp =
10431318a5edSPatrick Williams getCipherConfigObject(csPrivFileName, csPrivDefaultFileName)
1044b741b990Sjayaprakash Mutyala .setCSPrivilegeLevels(channel, cipherSuitePrivs);
1045b741b990Sjayaprakash Mutyala if (!resp)
1046b741b990Sjayaprakash Mutyala {
1047b741b990Sjayaprakash Mutyala return responseSuccess();
1048b741b990Sjayaprakash Mutyala }
1049b741b990Sjayaprakash Mutyala else
1050b741b990Sjayaprakash Mutyala {
1051b741b990Sjayaprakash Mutyala req.trailingOk = true;
1052b741b990Sjayaprakash Mutyala return response(resp);
1053b741b990Sjayaprakash Mutyala }
1054b741b990Sjayaprakash Mutyala }
1055c514d874SWilliam A. Kennington III }
1056c514d874SWilliam A. Kennington III
10573771f5f2SPavanKumarIntel if (parameter >= oemCmdStart)
1058b87034e8SJohnathan Mantey {
1059b87034e8SJohnathan Mantey return setLanOem(channel, parameter, req);
1060b87034e8SJohnathan Mantey }
1061b87034e8SJohnathan Mantey
1062c514d874SWilliam A. Kennington III req.trailingOk = true;
1063c514d874SWilliam A. Kennington III return response(ccParamNotSupported);
1064c514d874SWilliam A. Kennington III }
1065c514d874SWilliam A. Kennington III
setLan(Context::ptr ctx,uint4_t channelBits,uint4_t reserved1,uint8_t parameter,message::Payload & req)10667a3831b5SWilliam A. Kennington III RspType<> setLan(Context::ptr ctx, uint4_t channelBits, uint4_t reserved1,
10677a3831b5SWilliam A. Kennington III uint8_t parameter, message::Payload& req)
10687a3831b5SWilliam A. Kennington III {
10697a3831b5SWilliam A. Kennington III try
10707a3831b5SWilliam A. Kennington III {
10717a3831b5SWilliam A. Kennington III return setLanInt(ctx, channelBits, reserved1, parameter, req);
10727a3831b5SWilliam A. Kennington III }
10737a3831b5SWilliam A. Kennington III catch (ipmi::Cc cc)
10747a3831b5SWilliam A. Kennington III {
10757a3831b5SWilliam A. Kennington III return response(cc);
10767a3831b5SWilliam A. Kennington III }
10777a3831b5SWilliam A. Kennington III catch (const sdbusplus::exception_t& e)
10787a3831b5SWilliam A. Kennington III {
10797a3831b5SWilliam A. Kennington III if (std::string_view{InvalidArgument::errName} == e.name())
10807a3831b5SWilliam A. Kennington III {
10817a3831b5SWilliam A. Kennington III return responseInvalidFieldRequest();
10827a3831b5SWilliam A. Kennington III }
10837a3831b5SWilliam A. Kennington III throw;
10847a3831b5SWilliam A. Kennington III }
10857a3831b5SWilliam A. Kennington III }
10867a3831b5SWilliam A. Kennington III
getLan(Context::ptr ctx,uint4_t channelBits,uint3_t reserved,bool revOnly,uint8_t parameter,uint8_t set,uint8_t block)1087cc76925eSvijayabharathix shetty RspType<message::Payload> getLan(Context::ptr ctx, uint4_t channelBits,
1088cc76925eSvijayabharathix shetty uint3_t reserved, bool revOnly,
1089c514d874SWilliam A. Kennington III uint8_t parameter, uint8_t set, uint8_t block)
1090c514d874SWilliam A. Kennington III {
1091c514d874SWilliam A. Kennington III message::Payload ret;
1092c514d874SWilliam A. Kennington III constexpr uint8_t current_revision = 0x11;
1093c514d874SWilliam A. Kennington III ret.pack(current_revision);
1094c514d874SWilliam A. Kennington III
1095c514d874SWilliam A. Kennington III if (revOnly)
1096c514d874SWilliam A. Kennington III {
1097c514d874SWilliam A. Kennington III return responseSuccess(std::move(ret));
1098c514d874SWilliam A. Kennington III }
1099c514d874SWilliam A. Kennington III
1100cc76925eSvijayabharathix shetty const uint8_t channel = convertCurrentChannelNum(
1101cc76925eSvijayabharathix shetty static_cast<uint8_t>(channelBits), ctx->channel);
1102cc76925eSvijayabharathix shetty if (reserved || !isValidChannel(channel))
1103c514d874SWilliam A. Kennington III {
110432e8f5d3SGeorge Liu lg2::error("Get Lan - Invalid field in request");
1105c514d874SWilliam A. Kennington III return responseInvalidFieldRequest();
1106c514d874SWilliam A. Kennington III }
1107c514d874SWilliam A. Kennington III
1108cf19d146SJian Zhang if (!isLanChannel(channel).value_or(false))
1109cf19d146SJian Zhang {
111032e8f5d3SGeorge Liu lg2::error("Set Lan - Not a LAN channel");
1111cf19d146SJian Zhang return responseInvalidFieldRequest();
1112cf19d146SJian Zhang }
1113cf19d146SJian Zhang
1114affadb55SJohnathan Mantey static std::vector<uint8_t> cipherList;
1115affadb55SJohnathan Mantey static bool listInit = false;
1116affadb55SJohnathan Mantey if (!listInit)
1117affadb55SJohnathan Mantey {
1118affadb55SJohnathan Mantey try
1119affadb55SJohnathan Mantey {
1120affadb55SJohnathan Mantey cipherList = cipher::getCipherList();
1121affadb55SJohnathan Mantey listInit = true;
1122affadb55SJohnathan Mantey }
1123affadb55SJohnathan Mantey catch (const std::exception& e)
1124fbc6c9d7SPatrick Williams {}
1125affadb55SJohnathan Mantey }
1126affadb55SJohnathan Mantey
1127c514d874SWilliam A. Kennington III switch (static_cast<LanParam>(parameter))
1128c514d874SWilliam A. Kennington III {
1129c514d874SWilliam A. Kennington III case LanParam::SetStatus:
1130c514d874SWilliam A. Kennington III {
1131c514d874SWilliam A. Kennington III SetStatus status;
1132c514d874SWilliam A. Kennington III try
1133c514d874SWilliam A. Kennington III {
1134c514d874SWilliam A. Kennington III status = setStatus.at(channel);
1135c514d874SWilliam A. Kennington III }
1136c514d874SWilliam A. Kennington III catch (const std::out_of_range&)
1137c514d874SWilliam A. Kennington III {
1138c514d874SWilliam A. Kennington III status = SetStatus::Complete;
1139c514d874SWilliam A. Kennington III }
11407a0e5dfcSWilliam A. Kennington III ret.pack(types::enum_cast<uint2_t>(status), uint6_t{});
1141c514d874SWilliam A. Kennington III return responseSuccess(std::move(ret));
1142c514d874SWilliam A. Kennington III }
1143c514d874SWilliam A. Kennington III case LanParam::AuthSupport:
1144c514d874SWilliam A. Kennington III {
1145c514d874SWilliam A. Kennington III std::bitset<6> support;
1146c514d874SWilliam A. Kennington III ret.pack(support, uint2_t{});
1147c514d874SWilliam A. Kennington III return responseSuccess(std::move(ret));
1148c514d874SWilliam A. Kennington III }
1149c514d874SWilliam A. Kennington III case LanParam::AuthEnables:
1150c514d874SWilliam A. Kennington III {
1151c514d874SWilliam A. Kennington III std::bitset<6> enables;
1152c514d874SWilliam A. Kennington III ret.pack(enables, uint2_t{}); // Callback
1153c514d874SWilliam A. Kennington III ret.pack(enables, uint2_t{}); // User
1154c514d874SWilliam A. Kennington III ret.pack(enables, uint2_t{}); // Operator
1155c514d874SWilliam A. Kennington III ret.pack(enables, uint2_t{}); // Admin
1156c514d874SWilliam A. Kennington III ret.pack(enables, uint2_t{}); // OEM
1157c514d874SWilliam A. Kennington III return responseSuccess(std::move(ret));
1158c514d874SWilliam A. Kennington III }
1159c514d874SWilliam A. Kennington III case LanParam::IP:
1160c514d874SWilliam A. Kennington III {
1161c514d874SWilliam A. Kennington III auto ifaddr = channelCall<getIfAddr4>(channel);
1162726f2bddSWilliam A. Kennington III stdplus::In4Addr addr{};
1163c514d874SWilliam A. Kennington III if (ifaddr)
1164c514d874SWilliam A. Kennington III {
1165c514d874SWilliam A. Kennington III addr = ifaddr->address;
1166c514d874SWilliam A. Kennington III }
11677a3831b5SWilliam A. Kennington III ret.pack(stdplus::raw::asView<char>(addr));
1168c514d874SWilliam A. Kennington III return responseSuccess(std::move(ret));
1169c514d874SWilliam A. Kennington III }
1170c514d874SWilliam A. Kennington III case LanParam::IPSrc:
1171c514d874SWilliam A. Kennington III {
1172a8a2e5f6SWilliam A. Kennington III auto src = channelCall<getEthProp<bool>>(channel, "DHCP4")
1173a8a2e5f6SWilliam A. Kennington III ? IPSrc::DHCP
1174a8a2e5f6SWilliam A. Kennington III : IPSrc::Static;
11757a0e5dfcSWilliam A. Kennington III ret.pack(types::enum_cast<uint4_t>(src), uint4_t{});
1176c514d874SWilliam A. Kennington III return responseSuccess(std::move(ret));
1177c514d874SWilliam A. Kennington III }
1178c514d874SWilliam A. Kennington III case LanParam::MAC:
1179c514d874SWilliam A. Kennington III {
1180726f2bddSWilliam A. Kennington III auto mac = channelCall<getMACProperty>(channel);
11817a3831b5SWilliam A. Kennington III ret.pack(stdplus::raw::asView<char>(mac));
1182c514d874SWilliam A. Kennington III return responseSuccess(std::move(ret));
1183c514d874SWilliam A. Kennington III }
1184c514d874SWilliam A. Kennington III case LanParam::SubnetMask:
1185c514d874SWilliam A. Kennington III {
1186c514d874SWilliam A. Kennington III auto ifaddr = channelCall<getIfAddr4>(channel);
1187c514d874SWilliam A. Kennington III uint8_t prefix = AddrFamily<AF_INET>::defaultPrefix;
1188c514d874SWilliam A. Kennington III if (ifaddr)
1189c514d874SWilliam A. Kennington III {
1190c514d874SWilliam A. Kennington III prefix = ifaddr->prefix;
1191c514d874SWilliam A. Kennington III }
1192726f2bddSWilliam A. Kennington III auto netmask = stdplus::pfxToMask<stdplus::In4Addr>(prefix);
11937a3831b5SWilliam A. Kennington III ret.pack(stdplus::raw::asView<char>(netmask));
1194c514d874SWilliam A. Kennington III return responseSuccess(std::move(ret));
1195c514d874SWilliam A. Kennington III }
1196c514d874SWilliam A. Kennington III case LanParam::Gateway1:
1197c514d874SWilliam A. Kennington III {
1198726f2bddSWilliam A. Kennington III auto gateway = channelCall<getGatewayProperty<AF_INET>>(channel);
1199726f2bddSWilliam A. Kennington III ret.pack(stdplus::raw::asView<char>(
1200726f2bddSWilliam A. Kennington III gateway.value_or(stdplus::In4Addr{})));
1201c514d874SWilliam A. Kennington III return responseSuccess(std::move(ret));
1202c514d874SWilliam A. Kennington III }
12034bbc3db6SWilliam A. Kennington III case LanParam::Gateway1MAC:
12044bbc3db6SWilliam A. Kennington III {
1205726f2bddSWilliam A. Kennington III stdplus::EtherAddr mac{};
12064bbc3db6SWilliam A. Kennington III auto neighbor = channelCall<getGatewayNeighbor<AF_INET>>(channel);
12074bbc3db6SWilliam A. Kennington III if (neighbor)
12084bbc3db6SWilliam A. Kennington III {
12094bbc3db6SWilliam A. Kennington III mac = neighbor->mac;
12104bbc3db6SWilliam A. Kennington III }
12117a3831b5SWilliam A. Kennington III ret.pack(stdplus::raw::asView<char>(mac));
12124bbc3db6SWilliam A. Kennington III return responseSuccess(std::move(ret));
12134bbc3db6SWilliam A. Kennington III }
1214c514d874SWilliam A. Kennington III case LanParam::VLANId:
1215c514d874SWilliam A. Kennington III {
1216c514d874SWilliam A. Kennington III uint16_t vlan = channelCall<getVLANProperty>(channel);
1217c514d874SWilliam A. Kennington III if (vlan != 0)
1218c514d874SWilliam A. Kennington III {
1219c514d874SWilliam A. Kennington III vlan |= VLAN_ENABLE_FLAG;
1220c514d874SWilliam A. Kennington III }
1221c514d874SWilliam A. Kennington III else
1222c514d874SWilliam A. Kennington III {
1223c514d874SWilliam A. Kennington III vlan = lastDisabledVlan[channel];
1224c514d874SWilliam A. Kennington III }
1225c514d874SWilliam A. Kennington III ret.pack(vlan);
1226c514d874SWilliam A. Kennington III return responseSuccess(std::move(ret));
1227c514d874SWilliam A. Kennington III }
1228c514d874SWilliam A. Kennington III case LanParam::CiphersuiteSupport:
1229affadb55SJohnathan Mantey {
12301d8579c6Ssrikanta mondal if (getChannelSessionSupport(channel) ==
12311d8579c6Ssrikanta mondal EChannelSessSupported::none)
12321d8579c6Ssrikanta mondal {
12331d8579c6Ssrikanta mondal return responseInvalidFieldRequest();
12341d8579c6Ssrikanta mondal }
1235affadb55SJohnathan Mantey if (!listInit)
1236affadb55SJohnathan Mantey {
1237affadb55SJohnathan Mantey return responseUnspecifiedError();
1238affadb55SJohnathan Mantey }
1239affadb55SJohnathan Mantey ret.pack(static_cast<uint8_t>(cipherList.size() - 1));
1240affadb55SJohnathan Mantey return responseSuccess(std::move(ret));
1241affadb55SJohnathan Mantey }
1242c514d874SWilliam A. Kennington III case LanParam::CiphersuiteEntries:
1243affadb55SJohnathan Mantey {
12441d8579c6Ssrikanta mondal if (getChannelSessionSupport(channel) ==
12451d8579c6Ssrikanta mondal EChannelSessSupported::none)
12461d8579c6Ssrikanta mondal {
12471d8579c6Ssrikanta mondal return responseInvalidFieldRequest();
12481d8579c6Ssrikanta mondal }
1249affadb55SJohnathan Mantey if (!listInit)
1250affadb55SJohnathan Mantey {
1251affadb55SJohnathan Mantey return responseUnspecifiedError();
1252affadb55SJohnathan Mantey }
1253affadb55SJohnathan Mantey ret.pack(cipherList);
1254affadb55SJohnathan Mantey return responseSuccess(std::move(ret));
1255affadb55SJohnathan Mantey }
125616064aa1SWilliam A. Kennington III case LanParam::IPFamilySupport:
125716064aa1SWilliam A. Kennington III {
125816064aa1SWilliam A. Kennington III std::bitset<8> support;
125916064aa1SWilliam A. Kennington III support[IPFamilySupportFlag::IPv6Only] = 0;
126016064aa1SWilliam A. Kennington III support[IPFamilySupportFlag::DualStack] = 1;
126116064aa1SWilliam A. Kennington III support[IPFamilySupportFlag::IPv6Alerts] = 1;
126216064aa1SWilliam A. Kennington III ret.pack(support);
126316064aa1SWilliam A. Kennington III return responseSuccess(std::move(ret));
126416064aa1SWilliam A. Kennington III }
126516064aa1SWilliam A. Kennington III case LanParam::IPFamilyEnables:
126616064aa1SWilliam A. Kennington III {
126716064aa1SWilliam A. Kennington III ret.pack(static_cast<uint8_t>(IPFamilyEnables::DualStack));
126816064aa1SWilliam A. Kennington III return responseSuccess(std::move(ret));
126916064aa1SWilliam A. Kennington III }
127016064aa1SWilliam A. Kennington III case LanParam::IPv6Status:
127116064aa1SWilliam A. Kennington III {
127216064aa1SWilliam A. Kennington III ret.pack(MAX_IPV6_STATIC_ADDRESSES);
127316064aa1SWilliam A. Kennington III ret.pack(MAX_IPV6_DYNAMIC_ADDRESSES);
127416064aa1SWilliam A. Kennington III std::bitset<8> support;
127516064aa1SWilliam A. Kennington III support[IPv6StatusFlag::DHCP] = 1;
127616064aa1SWilliam A. Kennington III support[IPv6StatusFlag::SLAAC] = 1;
127716064aa1SWilliam A. Kennington III ret.pack(support);
127816064aa1SWilliam A. Kennington III return responseSuccess(std::move(ret));
127916064aa1SWilliam A. Kennington III }
128016064aa1SWilliam A. Kennington III case LanParam::IPv6StaticAddresses:
128116064aa1SWilliam A. Kennington III {
128216064aa1SWilliam A. Kennington III if (set >= MAX_IPV6_STATIC_ADDRESSES)
128316064aa1SWilliam A. Kennington III {
128416064aa1SWilliam A. Kennington III return responseParmOutOfRange();
128516064aa1SWilliam A. Kennington III }
128616064aa1SWilliam A. Kennington III getLanIPv6Address(ret, channel, set, originsV6Static);
128716064aa1SWilliam A. Kennington III return responseSuccess(std::move(ret));
128816064aa1SWilliam A. Kennington III }
128916064aa1SWilliam A. Kennington III case LanParam::IPv6DynamicAddresses:
129016064aa1SWilliam A. Kennington III {
129116064aa1SWilliam A. Kennington III if (set >= MAX_IPV6_DYNAMIC_ADDRESSES)
129216064aa1SWilliam A. Kennington III {
129316064aa1SWilliam A. Kennington III return responseParmOutOfRange();
129416064aa1SWilliam A. Kennington III }
129516064aa1SWilliam A. Kennington III getLanIPv6Address(ret, channel, set, originsV6Dynamic);
129616064aa1SWilliam A. Kennington III return responseSuccess(std::move(ret));
129716064aa1SWilliam A. Kennington III }
129816064aa1SWilliam A. Kennington III case LanParam::IPv6RouterControl:
129916064aa1SWilliam A. Kennington III {
130016064aa1SWilliam A. Kennington III std::bitset<8> control;
13013b7a4078SJohnathan Mantey control[IPv6RouterControlFlag::Dynamic] =
1302a8a2e5f6SWilliam A. Kennington III channelCall<getEthProp<bool>>(channel, "IPv6AcceptRA");
130316064aa1SWilliam A. Kennington III control[IPv6RouterControlFlag::Static] = 1;
130416064aa1SWilliam A. Kennington III ret.pack(control);
130516064aa1SWilliam A. Kennington III return responseSuccess(std::move(ret));
130616064aa1SWilliam A. Kennington III }
130716064aa1SWilliam A. Kennington III case LanParam::IPv6StaticRouter1IP:
130816064aa1SWilliam A. Kennington III {
1309726f2bddSWilliam A. Kennington III stdplus::In6Addr gateway{};
1310a8a2e5f6SWilliam A. Kennington III if (!channelCall<getEthProp<bool>>(channel, "IPv6AcceptRA"))
131116064aa1SWilliam A. Kennington III {
131216064aa1SWilliam A. Kennington III gateway =
131316064aa1SWilliam A. Kennington III channelCall<getGatewayProperty<AF_INET6>>(channel).value_or(
1314726f2bddSWilliam A. Kennington III stdplus::In6Addr{});
131516064aa1SWilliam A. Kennington III }
13167a3831b5SWilliam A. Kennington III ret.pack(stdplus::raw::asView<char>(gateway));
131716064aa1SWilliam A. Kennington III return responseSuccess(std::move(ret));
131816064aa1SWilliam A. Kennington III }
131916064aa1SWilliam A. Kennington III case LanParam::IPv6StaticRouter1MAC:
132016064aa1SWilliam A. Kennington III {
1321726f2bddSWilliam A. Kennington III stdplus::EtherAddr mac{};
132216064aa1SWilliam A. Kennington III auto neighbor = channelCall<getGatewayNeighbor<AF_INET6>>(channel);
132316064aa1SWilliam A. Kennington III if (neighbor)
132416064aa1SWilliam A. Kennington III {
132516064aa1SWilliam A. Kennington III mac = neighbor->mac;
132616064aa1SWilliam A. Kennington III }
13277a3831b5SWilliam A. Kennington III ret.pack(stdplus::raw::asView<char>(mac));
132816064aa1SWilliam A. Kennington III return responseSuccess(std::move(ret));
132916064aa1SWilliam A. Kennington III }
133016064aa1SWilliam A. Kennington III case LanParam::IPv6StaticRouter1PrefixLength:
133116064aa1SWilliam A. Kennington III {
1332796e8240SJian Zhang ret.pack(uint8_t{0});
133316064aa1SWilliam A. Kennington III return responseSuccess(std::move(ret));
133416064aa1SWilliam A. Kennington III }
133516064aa1SWilliam A. Kennington III case LanParam::IPv6StaticRouter1PrefixValue:
133616064aa1SWilliam A. Kennington III {
1337726f2bddSWilliam A. Kennington III ret.pack(stdplus::raw::asView<char>(stdplus::In6Addr{}));
133816064aa1SWilliam A. Kennington III return responseSuccess(std::move(ret));
133916064aa1SWilliam A. Kennington III }
1340b741b990Sjayaprakash Mutyala case LanParam::cipherSuitePrivilegeLevels:
1341b741b990Sjayaprakash Mutyala {
1342b741b990Sjayaprakash Mutyala std::array<uint4_t, ipmi::maxCSRecords> csPrivilegeLevels;
1343b741b990Sjayaprakash Mutyala
1344b741b990Sjayaprakash Mutyala uint8_t resp =
1345b741b990Sjayaprakash Mutyala getCipherConfigObject(csPrivFileName, csPrivDefaultFileName)
1346b741b990Sjayaprakash Mutyala .getCSPrivilegeLevels(channel, csPrivilegeLevels);
1347b741b990Sjayaprakash Mutyala if (!resp)
1348b741b990Sjayaprakash Mutyala {
1349b741b990Sjayaprakash Mutyala constexpr uint8_t reserved1 = 0x00;
1350b741b990Sjayaprakash Mutyala ret.pack(reserved1, csPrivilegeLevels);
1351b741b990Sjayaprakash Mutyala return responseSuccess(std::move(ret));
1352b741b990Sjayaprakash Mutyala }
1353b741b990Sjayaprakash Mutyala else
1354b741b990Sjayaprakash Mutyala {
1355b741b990Sjayaprakash Mutyala return response(resp);
1356b741b990Sjayaprakash Mutyala }
1357b741b990Sjayaprakash Mutyala }
1358c514d874SWilliam A. Kennington III }
1359c514d874SWilliam A. Kennington III
13603771f5f2SPavanKumarIntel if (parameter >= oemCmdStart)
1361b87034e8SJohnathan Mantey {
1362b87034e8SJohnathan Mantey return getLanOem(channel, parameter, set, block);
1363b87034e8SJohnathan Mantey }
1364b87034e8SJohnathan Mantey
1365c514d874SWilliam A. Kennington III return response(ccParamNotSupported);
1366c514d874SWilliam A. Kennington III }
1367c514d874SWilliam A. Kennington III
136823f44657SJian Zhang constexpr const char* solInterface = "xyz.openbmc_project.Ipmi.SOL";
136923f44657SJian Zhang constexpr const char* solPath = "/xyz/openbmc_project/ipmi/sol/";
137023f44657SJian Zhang constexpr const uint16_t solDefaultPort = 623;
137123f44657SJian Zhang
setSolConfParams(Context::ptr ctx,uint4_t channelBits,uint4_t,uint8_t parameter,message::Payload & req)137223f44657SJian Zhang RspType<> setSolConfParams(Context::ptr ctx, uint4_t channelBits,
137311d68897SWilly Tu uint4_t /*reserved*/, uint8_t parameter,
137423f44657SJian Zhang message::Payload& req)
137523f44657SJian Zhang {
137623f44657SJian Zhang const uint8_t channel = convertCurrentChannelNum(
137723f44657SJian Zhang static_cast<uint8_t>(channelBits), ctx->channel);
137823f44657SJian Zhang
137923f44657SJian Zhang if (!isValidChannel(channel))
138023f44657SJian Zhang {
138132e8f5d3SGeorge Liu lg2::error("Set Sol Config - Invalid channel in request");
138223f44657SJian Zhang return responseInvalidFieldRequest();
138323f44657SJian Zhang }
138423f44657SJian Zhang
138523f44657SJian Zhang std::string solService{};
138623f44657SJian Zhang std::string solPathWitheEthName = solPath + ipmi::getChannelName(channel);
138723f44657SJian Zhang
138823f44657SJian Zhang if (ipmi::getService(ctx, solInterface, solPathWitheEthName, solService))
138923f44657SJian Zhang {
139032e8f5d3SGeorge Liu lg2::error("Set Sol Config - Invalid solInterface, service: {SERVICE}, "
139132e8f5d3SGeorge Liu "object path: {OBJPATH}, interface: {INTERFACE}",
139232e8f5d3SGeorge Liu "SERVICE", solService, "OBJPATH", solPathWitheEthName,
139332e8f5d3SGeorge Liu "INTERFACE", solInterface);
139423f44657SJian Zhang return responseInvalidFieldRequest();
139523f44657SJian Zhang }
139623f44657SJian Zhang
139723f44657SJian Zhang switch (static_cast<SolConfParam>(parameter))
139823f44657SJian Zhang {
139923f44657SJian Zhang case SolConfParam::Progress:
140023f44657SJian Zhang {
140123f44657SJian Zhang uint8_t progress;
140223f44657SJian Zhang if (req.unpack(progress) != 0 || !req.fullyUnpacked())
140323f44657SJian Zhang {
140423f44657SJian Zhang return responseReqDataLenInvalid();
140523f44657SJian Zhang }
140623f44657SJian Zhang
140723f44657SJian Zhang if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName,
140823f44657SJian Zhang solInterface, "Progress", progress))
140923f44657SJian Zhang {
141023f44657SJian Zhang return responseUnspecifiedError();
141123f44657SJian Zhang }
141223f44657SJian Zhang break;
141323f44657SJian Zhang }
141423f44657SJian Zhang case SolConfParam::Enable:
141523f44657SJian Zhang {
141623f44657SJian Zhang bool enable;
141723f44657SJian Zhang uint7_t reserved2;
141823f44657SJian Zhang
141923f44657SJian Zhang if (req.unpack(enable, reserved2) != 0 || !req.fullyUnpacked())
142023f44657SJian Zhang {
142123f44657SJian Zhang return responseReqDataLenInvalid();
142223f44657SJian Zhang }
142323f44657SJian Zhang
142423f44657SJian Zhang if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName,
142523f44657SJian Zhang solInterface, "Enable", enable))
142623f44657SJian Zhang {
142723f44657SJian Zhang return responseUnspecifiedError();
142823f44657SJian Zhang }
142923f44657SJian Zhang break;
143023f44657SJian Zhang }
143123f44657SJian Zhang case SolConfParam::Authentication:
143223f44657SJian Zhang {
143323f44657SJian Zhang uint4_t privilegeBits{};
143423f44657SJian Zhang uint2_t reserved2{};
143523f44657SJian Zhang bool forceAuth = false;
143623f44657SJian Zhang bool forceEncrypt = false;
143723f44657SJian Zhang
143823f44657SJian Zhang if (req.unpack(privilegeBits, reserved2, forceAuth, forceEncrypt) !=
143923f44657SJian Zhang 0 ||
144023f44657SJian Zhang !req.fullyUnpacked())
144123f44657SJian Zhang {
144223f44657SJian Zhang return responseReqDataLenInvalid();
144323f44657SJian Zhang }
144423f44657SJian Zhang
144523f44657SJian Zhang uint8_t privilege = static_cast<uint8_t>(privilegeBits);
1446a48bf776SJonathan Doman if (privilege < static_cast<uint8_t>(Privilege::User) ||
144723f44657SJian Zhang privilege > static_cast<uint8_t>(Privilege::Oem))
144823f44657SJian Zhang {
144923f44657SJian Zhang return ipmi::responseInvalidFieldRequest();
145023f44657SJian Zhang }
145123f44657SJian Zhang
145223f44657SJian Zhang if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName,
145323f44657SJian Zhang solInterface, "Privilege", privilege))
145423f44657SJian Zhang {
145523f44657SJian Zhang return responseUnspecifiedError();
145623f44657SJian Zhang }
145723f44657SJian Zhang
145823f44657SJian Zhang if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName,
145923f44657SJian Zhang solInterface, "ForceEncryption",
146023f44657SJian Zhang forceEncrypt))
146123f44657SJian Zhang {
146223f44657SJian Zhang return responseUnspecifiedError();
146323f44657SJian Zhang }
146423f44657SJian Zhang
146523f44657SJian Zhang if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName,
146623f44657SJian Zhang solInterface, "ForceAuthentication",
146723f44657SJian Zhang forceAuth))
146823f44657SJian Zhang {
146923f44657SJian Zhang return responseUnspecifiedError();
147023f44657SJian Zhang }
147123f44657SJian Zhang break;
147223f44657SJian Zhang }
147323f44657SJian Zhang case SolConfParam::Accumulate:
147423f44657SJian Zhang {
147523f44657SJian Zhang uint8_t interval;
147623f44657SJian Zhang uint8_t threshold;
147723f44657SJian Zhang if (req.unpack(interval, threshold) != 0 || !req.fullyUnpacked())
147823f44657SJian Zhang {
147923f44657SJian Zhang return responseReqDataLenInvalid();
148023f44657SJian Zhang }
148123f44657SJian Zhang
148223f44657SJian Zhang if (threshold == 0)
148323f44657SJian Zhang {
148423f44657SJian Zhang return responseInvalidFieldRequest();
148523f44657SJian Zhang }
148623f44657SJian Zhang
148723f44657SJian Zhang if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName,
148823f44657SJian Zhang solInterface, "AccumulateIntervalMS",
148923f44657SJian Zhang interval))
149023f44657SJian Zhang {
149123f44657SJian Zhang return responseUnspecifiedError();
149223f44657SJian Zhang }
149323f44657SJian Zhang
149423f44657SJian Zhang if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName,
149523f44657SJian Zhang solInterface, "Threshold", threshold))
149623f44657SJian Zhang {
149723f44657SJian Zhang return responseUnspecifiedError();
149823f44657SJian Zhang }
149923f44657SJian Zhang break;
150023f44657SJian Zhang }
150123f44657SJian Zhang case SolConfParam::Retry:
150223f44657SJian Zhang {
150323f44657SJian Zhang uint3_t countBits;
150423f44657SJian Zhang uint5_t reserved2;
150523f44657SJian Zhang uint8_t interval;
150623f44657SJian Zhang
150723f44657SJian Zhang if (req.unpack(countBits, reserved2, interval) != 0 ||
150823f44657SJian Zhang !req.fullyUnpacked())
150923f44657SJian Zhang {
151023f44657SJian Zhang return responseReqDataLenInvalid();
151123f44657SJian Zhang }
151223f44657SJian Zhang
151323f44657SJian Zhang uint8_t count = static_cast<uint8_t>(countBits);
151423f44657SJian Zhang if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName,
151523f44657SJian Zhang solInterface, "RetryCount", count))
151623f44657SJian Zhang {
151723f44657SJian Zhang return responseUnspecifiedError();
151823f44657SJian Zhang }
151923f44657SJian Zhang
152023f44657SJian Zhang if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName,
152123f44657SJian Zhang solInterface, "RetryIntervalMS",
152223f44657SJian Zhang interval))
152323f44657SJian Zhang {
152423f44657SJian Zhang return responseUnspecifiedError();
152523f44657SJian Zhang }
152623f44657SJian Zhang break;
152723f44657SJian Zhang }
152823f44657SJian Zhang case SolConfParam::Port:
152923f44657SJian Zhang {
153023f44657SJian Zhang return response(ipmiCCWriteReadParameter);
153123f44657SJian Zhang }
153223f44657SJian Zhang case SolConfParam::NonVbitrate:
153323f44657SJian Zhang case SolConfParam::Vbitrate:
153423f44657SJian Zhang case SolConfParam::Channel:
153523f44657SJian Zhang default:
153623f44657SJian Zhang return response(ipmiCCParamNotSupported);
153723f44657SJian Zhang }
153823f44657SJian Zhang return responseSuccess();
153923f44657SJian Zhang }
154023f44657SJian Zhang
getSolConfParams(Context::ptr ctx,uint4_t channelBits,uint3_t,bool revOnly,uint8_t parameter,uint8_t,uint8_t)15411318a5edSPatrick Williams RspType<message::Payload> getSolConfParams(
15421318a5edSPatrick Williams Context::ptr ctx, uint4_t channelBits, uint3_t /*reserved*/, bool revOnly,
15431318a5edSPatrick Williams uint8_t parameter, uint8_t /*set*/, uint8_t /*block*/)
154423f44657SJian Zhang {
154523f44657SJian Zhang message::Payload ret;
154623f44657SJian Zhang constexpr uint8_t current_revision = 0x11;
154723f44657SJian Zhang ret.pack(current_revision);
154823f44657SJian Zhang if (revOnly)
154923f44657SJian Zhang {
155023f44657SJian Zhang return responseSuccess(std::move(ret));
155123f44657SJian Zhang }
155223f44657SJian Zhang
155323f44657SJian Zhang const uint8_t channel = convertCurrentChannelNum(
155423f44657SJian Zhang static_cast<uint8_t>(channelBits), ctx->channel);
155523f44657SJian Zhang
155623f44657SJian Zhang if (!isValidChannel(channel))
155723f44657SJian Zhang {
155832e8f5d3SGeorge Liu lg2::error("Get Sol Config - Invalid channel in request");
155923f44657SJian Zhang return responseInvalidFieldRequest();
156023f44657SJian Zhang }
156123f44657SJian Zhang
156223f44657SJian Zhang std::string solService{};
156323f44657SJian Zhang std::string solPathWitheEthName = solPath + ipmi::getChannelName(channel);
156423f44657SJian Zhang
156523f44657SJian Zhang if (ipmi::getService(ctx, solInterface, solPathWitheEthName, solService))
156623f44657SJian Zhang {
156732e8f5d3SGeorge Liu lg2::error("Set Sol Config - Invalid solInterface, service: {SERVICE}, "
156832e8f5d3SGeorge Liu "object path: {OBJPATH}, interface: {INTERFACE}",
156932e8f5d3SGeorge Liu "SERVICE", solService, "OBJPATH", solPathWitheEthName,
157032e8f5d3SGeorge Liu "INTERFACE", solInterface);
157123f44657SJian Zhang return responseInvalidFieldRequest();
157223f44657SJian Zhang }
157323f44657SJian Zhang
157423f44657SJian Zhang switch (static_cast<SolConfParam>(parameter))
157523f44657SJian Zhang {
157623f44657SJian Zhang case SolConfParam::Progress:
157723f44657SJian Zhang {
157823f44657SJian Zhang uint8_t progress;
157923f44657SJian Zhang if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName,
158023f44657SJian Zhang solInterface, "Progress", progress))
158123f44657SJian Zhang {
158223f44657SJian Zhang return responseUnspecifiedError();
158323f44657SJian Zhang }
158423f44657SJian Zhang ret.pack(progress);
158523f44657SJian Zhang return responseSuccess(std::move(ret));
158623f44657SJian Zhang }
158723f44657SJian Zhang case SolConfParam::Enable:
158823f44657SJian Zhang {
158923f44657SJian Zhang bool enable{};
159023f44657SJian Zhang if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName,
159123f44657SJian Zhang solInterface, "Enable", enable))
159223f44657SJian Zhang {
159323f44657SJian Zhang return responseUnspecifiedError();
159423f44657SJian Zhang }
159523f44657SJian Zhang ret.pack(enable, uint7_t{});
159623f44657SJian Zhang return responseSuccess(std::move(ret));
159723f44657SJian Zhang }
159823f44657SJian Zhang case SolConfParam::Authentication:
159923f44657SJian Zhang {
160023f44657SJian Zhang // 4bits, cast when pack
160123f44657SJian Zhang uint8_t privilege;
160223f44657SJian Zhang bool forceAuth = false;
160323f44657SJian Zhang bool forceEncrypt = false;
160423f44657SJian Zhang
160523f44657SJian Zhang if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName,
160623f44657SJian Zhang solInterface, "Privilege", privilege))
160723f44657SJian Zhang {
160823f44657SJian Zhang return responseUnspecifiedError();
160923f44657SJian Zhang }
161023f44657SJian Zhang
161123f44657SJian Zhang if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName,
161223f44657SJian Zhang solInterface, "ForceAuthentication",
161323f44657SJian Zhang forceAuth))
161423f44657SJian Zhang {
161523f44657SJian Zhang return responseUnspecifiedError();
161623f44657SJian Zhang }
161723f44657SJian Zhang
161823f44657SJian Zhang if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName,
161923f44657SJian Zhang solInterface, "ForceEncryption",
162023f44657SJian Zhang forceEncrypt))
162123f44657SJian Zhang {
162223f44657SJian Zhang return responseUnspecifiedError();
162323f44657SJian Zhang }
162423f44657SJian Zhang ret.pack(uint4_t{privilege}, uint2_t{}, forceAuth, forceEncrypt);
162523f44657SJian Zhang return responseSuccess(std::move(ret));
162623f44657SJian Zhang }
162723f44657SJian Zhang case SolConfParam::Accumulate:
162823f44657SJian Zhang {
162923f44657SJian Zhang uint8_t interval{}, threshold{};
163023f44657SJian Zhang
163123f44657SJian Zhang if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName,
163223f44657SJian Zhang solInterface, "AccumulateIntervalMS",
163323f44657SJian Zhang interval))
163423f44657SJian Zhang {
163523f44657SJian Zhang return responseUnspecifiedError();
163623f44657SJian Zhang }
163723f44657SJian Zhang
163823f44657SJian Zhang if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName,
163923f44657SJian Zhang solInterface, "Threshold", threshold))
164023f44657SJian Zhang {
164123f44657SJian Zhang return responseUnspecifiedError();
164223f44657SJian Zhang }
164323f44657SJian Zhang ret.pack(interval, threshold);
164423f44657SJian Zhang return responseSuccess(std::move(ret));
164523f44657SJian Zhang }
164623f44657SJian Zhang case SolConfParam::Retry:
164723f44657SJian Zhang {
164823f44657SJian Zhang // 3bits, cast when cast
164923f44657SJian Zhang uint8_t count{};
165023f44657SJian Zhang uint8_t interval{};
165123f44657SJian Zhang
165223f44657SJian Zhang if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName,
165323f44657SJian Zhang solInterface, "RetryCount", count))
165423f44657SJian Zhang {
165523f44657SJian Zhang return responseUnspecifiedError();
165623f44657SJian Zhang }
165723f44657SJian Zhang
165823f44657SJian Zhang if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName,
165923f44657SJian Zhang solInterface, "RetryIntervalMS",
166023f44657SJian Zhang interval))
166123f44657SJian Zhang {
166223f44657SJian Zhang return responseUnspecifiedError();
166323f44657SJian Zhang }
166423f44657SJian Zhang ret.pack(uint3_t{count}, uint5_t{}, interval);
166523f44657SJian Zhang return responseSuccess(std::move(ret));
166623f44657SJian Zhang }
166723f44657SJian Zhang case SolConfParam::Port:
166823f44657SJian Zhang {
166923f44657SJian Zhang auto port = solDefaultPort;
167023f44657SJian Zhang ret.pack(static_cast<uint16_t>(port));
167123f44657SJian Zhang return responseSuccess(std::move(ret));
167223f44657SJian Zhang }
167323f44657SJian Zhang case SolConfParam::Channel:
167423f44657SJian Zhang {
167523f44657SJian Zhang ret.pack(channel);
167623f44657SJian Zhang return responseSuccess(std::move(ret));
167723f44657SJian Zhang }
167823f44657SJian Zhang case SolConfParam::NonVbitrate:
1679a48bf776SJonathan Doman {
1680a48bf776SJonathan Doman uint64_t baudRate;
1681a48bf776SJonathan Doman uint8_t encodedBitRate = 0;
1682a48bf776SJonathan Doman if (ipmi::getDbusProperty(
1683a48bf776SJonathan Doman ctx, "xyz.openbmc_project.Console.default",
1684a48bf776SJonathan Doman "/xyz/openbmc_project/console/default",
1685a48bf776SJonathan Doman "xyz.openbmc_project.Console.UART", "Baud", baudRate))
1686a48bf776SJonathan Doman {
1687a48bf776SJonathan Doman return ipmi::responseUnspecifiedError();
1688a48bf776SJonathan Doman }
1689a48bf776SJonathan Doman switch (baudRate)
1690a48bf776SJonathan Doman {
1691a48bf776SJonathan Doman case 9600:
1692a48bf776SJonathan Doman encodedBitRate = 0x06;
1693a48bf776SJonathan Doman break;
1694a48bf776SJonathan Doman case 19200:
1695a48bf776SJonathan Doman encodedBitRate = 0x07;
1696a48bf776SJonathan Doman break;
1697a48bf776SJonathan Doman case 38400:
1698a48bf776SJonathan Doman encodedBitRate = 0x08;
1699a48bf776SJonathan Doman break;
1700a48bf776SJonathan Doman case 57600:
1701a48bf776SJonathan Doman encodedBitRate = 0x09;
1702a48bf776SJonathan Doman break;
1703a48bf776SJonathan Doman case 115200:
1704a48bf776SJonathan Doman encodedBitRate = 0x0a;
1705a48bf776SJonathan Doman break;
1706a48bf776SJonathan Doman default:
1707a48bf776SJonathan Doman break;
1708a48bf776SJonathan Doman }
1709a48bf776SJonathan Doman ret.pack(encodedBitRate);
1710a48bf776SJonathan Doman return responseSuccess(std::move(ret));
1711a48bf776SJonathan Doman }
171223f44657SJian Zhang case SolConfParam::Vbitrate:
171323f44657SJian Zhang default:
171423f44657SJian Zhang return response(ipmiCCParamNotSupported);
171523f44657SJian Zhang }
171623f44657SJian Zhang
171723f44657SJian Zhang return response(ccParamNotSupported);
171823f44657SJian Zhang }
171923f44657SJian Zhang
1720c514d874SWilliam A. Kennington III } // namespace transport
1721c514d874SWilliam A. Kennington III } // namespace ipmi
172298a23840SMatthew Barth
17235087b075SGeorge Liu void registerNetFnTransportFunctions() __attribute__((constructor));
172498a23840SMatthew Barth
registerNetFnTransportFunctions()17255087b075SGeorge Liu void registerNetFnTransportFunctions()
172698a23840SMatthew Barth {
1727c514d874SWilliam A. Kennington III ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnTransport,
1728c514d874SWilliam A. Kennington III ipmi::transport::cmdSetLanConfigParameters,
1729c514d874SWilliam A. Kennington III ipmi::Privilege::Admin, ipmi::transport::setLan);
1730c514d874SWilliam A. Kennington III ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnTransport,
1731c514d874SWilliam A. Kennington III ipmi::transport::cmdGetLanConfigParameters,
173234698d57SJohnathan Mantey ipmi::Privilege::Operator, ipmi::transport::getLan);
173323f44657SJian Zhang ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnTransport,
173423f44657SJian Zhang ipmi::transport::cmdSetSolConfigParameters,
173523f44657SJian Zhang ipmi::Privilege::Admin,
173623f44657SJian Zhang ipmi::transport::setSolConfParams);
173723f44657SJian Zhang ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnTransport,
173823f44657SJian Zhang ipmi::transport::cmdGetSolConfigParameters,
173923f44657SJian Zhang ipmi::Privilege::User,
174023f44657SJian Zhang ipmi::transport::getSolConfParams);
174198a23840SMatthew Barth }
1742