xref: /openbmc/phosphor-host-ipmid/transporthandler.cpp (revision 69b4c2811a262094addab680c925e63dd3468440)
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