| Patrick Venture | 690a234 | 2020-05-17 11:51:31 -0700 | [diff] [blame] | 1 | #include "transporthandler.hpp" | 
|  | 2 |  | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 3 | #include <stdplus/raw.hpp> | 
|  | 4 |  | 
|  | 5 | #include <array> | 
|  | 6 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 7 | using phosphor::logging::commit; | 
|  | 8 | using phosphor::logging::elog; | 
|  | 9 | using phosphor::logging::entry; | 
|  | 10 | using phosphor::logging::level; | 
|  | 11 | using phosphor::logging::log; | 
| Willy Tu | 523e2d1 | 2023-09-05 11:36:48 -0700 | [diff] [blame] | 12 | using sdbusplus::error::xyz::openbmc_project::common::InternalFailure; | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 13 | using sdbusplus::error::xyz::openbmc_project::common::InvalidArgument; | 
| Willy Tu | 523e2d1 | 2023-09-05 11:36:48 -0700 | [diff] [blame] | 14 | using sdbusplus::server::xyz::openbmc_project::network::EthernetInterface; | 
|  | 15 | using sdbusplus::server::xyz::openbmc_project::network::IP; | 
|  | 16 | using sdbusplus::server::xyz::openbmc_project::network::Neighbor; | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 17 |  | 
| Johnathan Mantey | affadb5 | 2019-10-07 10:13:53 -0700 | [diff] [blame] | 18 | namespace cipher | 
|  | 19 | { | 
|  | 20 |  | 
|  | 21 | std::vector<uint8_t> getCipherList() | 
|  | 22 | { | 
|  | 23 | std::vector<uint8_t> cipherList; | 
|  | 24 |  | 
|  | 25 | std::ifstream jsonFile(cipher::configFile); | 
|  | 26 | if (!jsonFile.is_open()) | 
|  | 27 | { | 
|  | 28 | log<level::ERR>("Channel Cipher suites file not found"); | 
|  | 29 | elog<InternalFailure>(); | 
|  | 30 | } | 
|  | 31 |  | 
|  | 32 | auto data = Json::parse(jsonFile, nullptr, false); | 
|  | 33 | if (data.is_discarded()) | 
|  | 34 | { | 
|  | 35 | log<level::ERR>("Parsing channel cipher suites JSON failed"); | 
|  | 36 | elog<InternalFailure>(); | 
|  | 37 | } | 
|  | 38 |  | 
|  | 39 | // Byte 1 is reserved | 
|  | 40 | cipherList.push_back(0x00); | 
|  | 41 |  | 
|  | 42 | for (const auto& record : data) | 
|  | 43 | { | 
|  | 44 | cipherList.push_back(record.value(cipher, 0)); | 
|  | 45 | } | 
|  | 46 |  | 
|  | 47 | return cipherList; | 
|  | 48 | } | 
|  | 49 | } // namespace cipher | 
|  | 50 |  | 
|  | 51 | namespace ipmi | 
|  | 52 | { | 
|  | 53 | namespace transport | 
|  | 54 | { | 
|  | 55 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 56 | /** @brief Valid address origins for IPv4 */ | 
|  | 57 | const std::unordered_set<IP::AddressOrigin> originsV4 = { | 
|  | 58 | IP::AddressOrigin::Static, | 
|  | 59 | IP::AddressOrigin::DHCP, | 
|  | 60 | }; | 
|  | 61 |  | 
| Johnathan Mantey | b87034e | 2019-09-16 10:50:50 -0700 | [diff] [blame] | 62 | static constexpr uint8_t oemCmdStart = 192; | 
|  | 63 | static constexpr uint8_t oemCmdEnd = 255; | 
|  | 64 |  | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 65 | std::optional<ChannelParams> maybeGetChannelParams(sdbusplus::bus_t& bus, | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 66 | uint8_t channel) | 
|  | 67 | { | 
|  | 68 | auto ifname = getChannelName(channel); | 
|  | 69 | if (ifname.empty()) | 
| Patrick Venture | c7c1c3c | 2017-11-15 14:29:18 -0800 | [diff] [blame] | 70 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 71 | return std::nullopt; | 
| Patrick Venture | c7c1c3c | 2017-11-15 14:29:18 -0800 | [diff] [blame] | 72 | } | 
| Patrick Venture | c7c1c3c | 2017-11-15 14:29:18 -0800 | [diff] [blame] | 73 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 74 | // Enumerate all VLAN + ETHERNET interfaces | 
|  | 75 | auto req = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ, MAPPER_INTF, | 
|  | 76 | "GetSubTree"); | 
|  | 77 | req.append(PATH_ROOT, 0, | 
|  | 78 | std::vector<std::string>{INTF_VLAN, INTF_ETHERNET}); | 
|  | 79 | auto reply = bus.call(req); | 
|  | 80 | ObjectTree objs; | 
|  | 81 | reply.read(objs); | 
|  | 82 |  | 
|  | 83 | ChannelParams params; | 
|  | 84 | for (const auto& [path, impls] : objs) | 
|  | 85 | { | 
|  | 86 | if (path.find(ifname) == path.npos) | 
|  | 87 | { | 
|  | 88 | continue; | 
|  | 89 | } | 
|  | 90 | for (const auto& [service, intfs] : impls) | 
|  | 91 | { | 
|  | 92 | bool vlan = false; | 
|  | 93 | bool ethernet = false; | 
|  | 94 | for (const auto& intf : intfs) | 
|  | 95 | { | 
|  | 96 | if (intf == INTF_VLAN) | 
|  | 97 | { | 
|  | 98 | vlan = true; | 
|  | 99 | } | 
|  | 100 | else if (intf == INTF_ETHERNET) | 
|  | 101 | { | 
|  | 102 | ethernet = true; | 
|  | 103 | } | 
|  | 104 | } | 
|  | 105 | if (params.service.empty() && (vlan || ethernet)) | 
|  | 106 | { | 
|  | 107 | params.service = service; | 
|  | 108 | } | 
|  | 109 | if (params.ifPath.empty() && !vlan && ethernet) | 
|  | 110 | { | 
|  | 111 | params.ifPath = path; | 
|  | 112 | } | 
|  | 113 | if (params.logicalPath.empty() && vlan) | 
|  | 114 | { | 
|  | 115 | params.logicalPath = path; | 
|  | 116 | } | 
|  | 117 | } | 
|  | 118 | } | 
|  | 119 |  | 
|  | 120 | // We must have a path for the underlying interface | 
|  | 121 | if (params.ifPath.empty()) | 
|  | 122 | { | 
|  | 123 | return std::nullopt; | 
|  | 124 | } | 
|  | 125 | // We don't have a VLAN so the logical path is the same | 
|  | 126 | if (params.logicalPath.empty()) | 
|  | 127 | { | 
|  | 128 | params.logicalPath = params.ifPath; | 
|  | 129 | } | 
|  | 130 |  | 
|  | 131 | params.id = channel; | 
|  | 132 | params.ifname = std::move(ifname); | 
| Willy Tu | 11d6889 | 2022-01-20 10:37:34 -0800 | [diff] [blame] | 133 | return params; | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 134 | } | 
|  | 135 |  | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 136 | ChannelParams getChannelParams(sdbusplus::bus_t& bus, uint8_t channel) | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 137 | { | 
|  | 138 | auto params = maybeGetChannelParams(bus, channel); | 
|  | 139 | if (!params) | 
|  | 140 | { | 
|  | 141 | log<level::ERR>("Failed to get channel params", | 
|  | 142 | entry("CHANNEL=%" PRIu8, channel)); | 
|  | 143 | elog<InternalFailure>(); | 
|  | 144 | } | 
|  | 145 | return std::move(*params); | 
|  | 146 | } | 
|  | 147 |  | 
|  | 148 | /** @brief Wraps the phosphor logging method to insert some additional metadata | 
|  | 149 | * | 
|  | 150 | *  @param[in] params - The parameters for the channel | 
|  | 151 | *  ... | 
|  | 152 | */ | 
|  | 153 | template <auto level, typename... Args> | 
|  | 154 | auto logWithChannel(const ChannelParams& params, Args&&... args) | 
|  | 155 | { | 
|  | 156 | return log<level>(std::forward<Args>(args)..., | 
|  | 157 | entry("CHANNEL=%d", params.id), | 
|  | 158 | entry("IFNAME=%s", params.ifname.c_str())); | 
|  | 159 | } | 
|  | 160 | template <auto level, typename... Args> | 
|  | 161 | auto logWithChannel(const std::optional<ChannelParams>& params, Args&&... args) | 
|  | 162 | { | 
|  | 163 | if (params) | 
|  | 164 | { | 
|  | 165 | return logWithChannel<level>(*params, std::forward<Args>(args)...); | 
|  | 166 | } | 
|  | 167 | return log<level>(std::forward<Args>(args)...); | 
|  | 168 | } | 
|  | 169 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 170 | ether_addr stringToMAC(const char* mac) | 
|  | 171 | { | 
|  | 172 | const ether_addr* ret = ether_aton(mac); | 
|  | 173 | if (ret == nullptr) | 
|  | 174 | { | 
|  | 175 | log<level::ERR>("Invalid MAC Address", entry("MAC=%s", mac)); | 
|  | 176 | elog<InternalFailure>(); | 
|  | 177 | } | 
|  | 178 | return *ret; | 
|  | 179 | } | 
|  | 180 |  | 
| William A. Kennington III | a8a2e5f | 2023-06-21 17:50:01 -0700 | [diff] [blame] | 181 | /** @brief Get / Set the Property value from phosphor-networkd EthernetInterface | 
|  | 182 | */ | 
|  | 183 | template <typename T> | 
|  | 184 | static T getEthProp(sdbusplus::bus_t& bus, const ChannelParams& params, | 
|  | 185 | const std::string& prop) | 
|  | 186 | { | 
|  | 187 | return std::get<T>(getDbusProperty(bus, params.service, params.logicalPath, | 
|  | 188 | INTF_ETHERNET, prop)); | 
|  | 189 | } | 
|  | 190 | template <typename T> | 
|  | 191 | static void setEthProp(sdbusplus::bus_t& bus, const ChannelParams& params, | 
|  | 192 | const std::string& prop, const T& t) | 
|  | 193 | { | 
|  | 194 | return setDbusProperty(bus, params.service, params.logicalPath, | 
|  | 195 | INTF_ETHERNET, prop, t); | 
|  | 196 | } | 
|  | 197 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 198 | /** @brief Determines the MAC of the ethernet interface | 
|  | 199 | * | 
|  | 200 | *  @param[in] bus    - The bus object used for lookups | 
|  | 201 | *  @param[in] params - The parameters for the channel | 
|  | 202 | *  @return The configured mac address | 
|  | 203 | */ | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 204 | ether_addr getMACProperty(sdbusplus::bus_t& bus, const ChannelParams& params) | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 205 | { | 
|  | 206 | auto macStr = std::get<std::string>(getDbusProperty( | 
|  | 207 | bus, params.service, params.ifPath, INTF_MAC, "MACAddress")); | 
|  | 208 | return stringToMAC(macStr.c_str()); | 
|  | 209 | } | 
|  | 210 |  | 
|  | 211 | /** @brief Sets the system value for MAC address on the given interface | 
|  | 212 | * | 
|  | 213 | *  @param[in] bus    - The bus object used for lookups | 
|  | 214 | *  @param[in] params - The parameters for the channel | 
|  | 215 | *  @param[in] mac    - MAC address to apply | 
|  | 216 | */ | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 217 | void setMACProperty(sdbusplus::bus_t& bus, const ChannelParams& params, | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 218 | const ether_addr& mac) | 
|  | 219 | { | 
|  | 220 | std::string macStr = ether_ntoa(&mac); | 
|  | 221 | setDbusProperty(bus, params.service, params.ifPath, INTF_MAC, "MACAddress", | 
|  | 222 | macStr); | 
|  | 223 | } | 
|  | 224 |  | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 225 | void deleteObjectIfExists(sdbusplus::bus_t& bus, const std::string& service, | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 226 | const std::string& path) | 
|  | 227 | { | 
|  | 228 | if (path.empty()) | 
|  | 229 | { | 
|  | 230 | return; | 
|  | 231 | } | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 232 | try | 
| tomjose | 26e1773 | 2016-03-03 08:52:51 -0600 | [diff] [blame] | 233 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 234 | auto req = bus.new_method_call(service.c_str(), path.c_str(), | 
|  | 235 | ipmi::DELETE_INTERFACE, "Delete"); | 
|  | 236 | bus.call_noreply(req); | 
|  | 237 | } | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 238 | catch (const sdbusplus::exception_t& e) | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 239 | { | 
| jayaprakash Mutyala | 84c49dc | 2020-05-18 23:12:13 +0000 | [diff] [blame] | 240 | if (strcmp(e.name(), | 
|  | 241 | "xyz.openbmc_project.Common.Error.InternalFailure") != 0 && | 
|  | 242 | strcmp(e.name(), "org.freedesktop.DBus.Error.UnknownObject") != 0) | 
| tomjose | 26e1773 | 2016-03-03 08:52:51 -0600 | [diff] [blame] | 243 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 244 | // We want to rethrow real errors | 
|  | 245 | throw; | 
| tomjose | 26e1773 | 2016-03-03 08:52:51 -0600 | [diff] [blame] | 246 | } | 
|  | 247 | } | 
| tomjose | 26e1773 | 2016-03-03 08:52:51 -0600 | [diff] [blame] | 248 | } | 
|  | 249 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 250 | /** @brief Sets the address info configured for the interface | 
|  | 251 | *         If a previous address path exists then it will be removed | 
|  | 252 | *         before the new address is added. | 
|  | 253 | * | 
|  | 254 | *  @param[in] bus     - The bus object used for lookups | 
|  | 255 | *  @param[in] params  - The parameters for the channel | 
|  | 256 | *  @param[in] address - The address of the new IP | 
|  | 257 | *  @param[in] prefix  - The prefix of the new IP | 
|  | 258 | */ | 
|  | 259 | template <int family> | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 260 | void createIfAddr(sdbusplus::bus_t& bus, const ChannelParams& params, | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 261 | const typename AddrFamily<family>::addr& address, | 
|  | 262 | uint8_t prefix) | 
| Tom Joseph | a30c8d3 | 2018-03-22 02:15:03 +0530 | [diff] [blame] | 263 | { | 
| Patrick Williams | fbc6c9d | 2023-05-10 07:50:16 -0500 | [diff] [blame] | 264 | auto newreq = bus.new_method_call(params.service.c_str(), | 
|  | 265 | params.logicalPath.c_str(), | 
|  | 266 | INTF_IP_CREATE, "IP"); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 267 | std::string protocol = | 
| Willy Tu | 523e2d1 | 2023-09-05 11:36:48 -0700 | [diff] [blame] | 268 | sdbusplus::common::xyz::openbmc_project::network::convertForMessage( | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 269 | AddrFamily<family>::protocol); | 
|  | 270 | newreq.append(protocol, addrToString<family>(address), prefix, ""); | 
|  | 271 | bus.call_noreply(newreq); | 
|  | 272 | } | 
| Tom Joseph | a30c8d3 | 2018-03-22 02:15:03 +0530 | [diff] [blame] | 273 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 274 | /** @brief Trivial helper for getting the IPv4 address from getIfAddrs() | 
|  | 275 | * | 
|  | 276 | *  @param[in] bus    - The bus object used for lookups | 
|  | 277 | *  @param[in] params - The parameters for the channel | 
|  | 278 | *  @return The address and prefix if found | 
|  | 279 | */ | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 280 | auto getIfAddr4(sdbusplus::bus_t& bus, const ChannelParams& params) | 
| Tom Joseph | a30c8d3 | 2018-03-22 02:15:03 +0530 | [diff] [blame] | 281 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 282 | return getIfAddr<AF_INET>(bus, params, 0, originsV4); | 
|  | 283 | } | 
| Tom Joseph | a30c8d3 | 2018-03-22 02:15:03 +0530 | [diff] [blame] | 284 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 285 | /** @brief Reconfigures the IPv4 address info configured for the interface | 
|  | 286 | * | 
|  | 287 | *  @param[in] bus     - The bus object used for lookups | 
|  | 288 | *  @param[in] params  - The parameters for the channel | 
|  | 289 | *  @param[in] address - The new address if specified | 
|  | 290 | *  @param[in] prefix  - The new address prefix if specified | 
|  | 291 | */ | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 292 | void reconfigureIfAddr4(sdbusplus::bus_t& bus, const ChannelParams& params, | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 293 | const std::optional<in_addr>& address, | 
|  | 294 | std::optional<uint8_t> prefix) | 
|  | 295 | { | 
|  | 296 | auto ifaddr = getIfAddr4(bus, params); | 
|  | 297 | if (!ifaddr && !address) | 
| Tom Joseph | a30c8d3 | 2018-03-22 02:15:03 +0530 | [diff] [blame] | 298 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 299 | log<level::ERR>("Missing address for IPv4 assignment"); | 
| Tom Joseph | a30c8d3 | 2018-03-22 02:15:03 +0530 | [diff] [blame] | 300 | elog<InternalFailure>(); | 
|  | 301 | } | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 302 | uint8_t fallbackPrefix = AddrFamily<AF_INET>::defaultPrefix; | 
|  | 303 | if (ifaddr) | 
| Tom Joseph | a30c8d3 | 2018-03-22 02:15:03 +0530 | [diff] [blame] | 304 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 305 | fallbackPrefix = ifaddr->prefix; | 
|  | 306 | deleteObjectIfExists(bus, params.service, ifaddr->path); | 
|  | 307 | } | 
| Johnathan Mantey | cbfa6e1 | 2023-06-01 06:57:25 -0700 | [diff] [blame] | 308 |  | 
| Jian Zhang | d05b9dd | 2023-07-04 14:48:40 +0800 | [diff] [blame] | 309 | if (struct in_addr nullIPv4{0}; | 
| Jayaprakash Mutyala | 4e02b43 | 2023-07-13 13:50:40 +0000 | [diff] [blame] | 310 | (address == std::nullopt && prefix != std::nullopt) || | 
|  | 311 | (address != std::nullopt && | 
|  | 312 | (address.value().s_addr != nullIPv4.s_addr))) | 
| Johnathan Mantey | cbfa6e1 | 2023-06-01 06:57:25 -0700 | [diff] [blame] | 313 | { | 
|  | 314 | createIfAddr<AF_INET>(bus, params, address.value_or(ifaddr->address), | 
|  | 315 | prefix.value_or(fallbackPrefix)); | 
|  | 316 | } | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 317 | } | 
|  | 318 |  | 
| William A. Kennington III | 4bbc3db | 2019-04-15 00:02:10 -0700 | [diff] [blame] | 319 | template <int family> | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 320 | std::optional<IfNeigh<family>> findGatewayNeighbor(sdbusplus::bus_t& bus, | 
| William A. Kennington III | 4bbc3db | 2019-04-15 00:02:10 -0700 | [diff] [blame] | 321 | const ChannelParams& params, | 
|  | 322 | ObjectLookupCache& neighbors) | 
|  | 323 | { | 
|  | 324 | auto gateway = getGatewayProperty<family>(bus, params); | 
|  | 325 | if (!gateway) | 
|  | 326 | { | 
|  | 327 | return std::nullopt; | 
|  | 328 | } | 
|  | 329 |  | 
|  | 330 | return findStaticNeighbor<family>(bus, params, *gateway, neighbors); | 
|  | 331 | } | 
|  | 332 |  | 
|  | 333 | template <int family> | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 334 | std::optional<IfNeigh<family>> getGatewayNeighbor(sdbusplus::bus_t& bus, | 
| William A. Kennington III | 4bbc3db | 2019-04-15 00:02:10 -0700 | [diff] [blame] | 335 | const ChannelParams& params) | 
|  | 336 | { | 
|  | 337 | ObjectLookupCache neighbors(bus, params, INTF_NEIGHBOR); | 
|  | 338 | return findGatewayNeighbor<family>(bus, params, neighbors); | 
|  | 339 | } | 
|  | 340 |  | 
|  | 341 | template <int family> | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 342 | void reconfigureGatewayMAC(sdbusplus::bus_t& bus, const ChannelParams& params, | 
|  | 343 | const ether_addr& mac) | 
| William A. Kennington III | 4bbc3db | 2019-04-15 00:02:10 -0700 | [diff] [blame] | 344 | { | 
|  | 345 | auto gateway = getGatewayProperty<family>(bus, params); | 
|  | 346 | if (!gateway) | 
|  | 347 | { | 
|  | 348 | log<level::ERR>("Tried to set Gateway MAC without Gateway"); | 
|  | 349 | elog<InternalFailure>(); | 
|  | 350 | } | 
|  | 351 |  | 
|  | 352 | ObjectLookupCache neighbors(bus, params, INTF_NEIGHBOR); | 
| Patrick Williams | fbc6c9d | 2023-05-10 07:50:16 -0500 | [diff] [blame] | 353 | auto neighbor = findStaticNeighbor<family>(bus, params, *gateway, | 
|  | 354 | neighbors); | 
| William A. Kennington III | 4bbc3db | 2019-04-15 00:02:10 -0700 | [diff] [blame] | 355 | if (neighbor) | 
|  | 356 | { | 
|  | 357 | deleteObjectIfExists(bus, params.service, neighbor->path); | 
|  | 358 | } | 
|  | 359 |  | 
|  | 360 | createNeighbor<family>(bus, params, *gateway, mac); | 
|  | 361 | } | 
|  | 362 |  | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 363 | /** @brief Deconfigures the IPv6 address info configured for the interface | 
|  | 364 | * | 
|  | 365 | *  @param[in] bus     - The bus object used for lookups | 
|  | 366 | *  @param[in] params  - The parameters for the channel | 
|  | 367 | *  @param[in] idx     - The address index to operate on | 
|  | 368 | */ | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 369 | void deconfigureIfAddr6(sdbusplus::bus_t& bus, const ChannelParams& params, | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 370 | uint8_t idx) | 
|  | 371 | { | 
|  | 372 | auto ifaddr = getIfAddr<AF_INET6>(bus, params, idx, originsV6Static); | 
|  | 373 | if (ifaddr) | 
|  | 374 | { | 
|  | 375 | deleteObjectIfExists(bus, params.service, ifaddr->path); | 
|  | 376 | } | 
|  | 377 | } | 
|  | 378 |  | 
|  | 379 | /** @brief Reconfigures the IPv6 address info configured for the interface | 
|  | 380 | * | 
|  | 381 | *  @param[in] bus     - The bus object used for lookups | 
|  | 382 | *  @param[in] params  - The parameters for the channel | 
|  | 383 | *  @param[in] idx     - The address index to operate on | 
|  | 384 | *  @param[in] address - The new address | 
|  | 385 | *  @param[in] prefix  - The new address prefix | 
|  | 386 | */ | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 387 | void reconfigureIfAddr6(sdbusplus::bus_t& bus, const ChannelParams& params, | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 388 | uint8_t idx, const in6_addr& address, uint8_t prefix) | 
|  | 389 | { | 
|  | 390 | deconfigureIfAddr6(bus, params, idx); | 
|  | 391 | createIfAddr<AF_INET6>(bus, params, address, prefix); | 
|  | 392 | } | 
|  | 393 |  | 
|  | 394 | /** @brief Converts the AddressOrigin into an IPv6Source | 
|  | 395 | * | 
|  | 396 | *  @param[in] origin - The DBus Address Origin to convert | 
|  | 397 | *  @return The IPv6Source version of the origin | 
|  | 398 | */ | 
|  | 399 | IPv6Source originToSourceType(IP::AddressOrigin origin) | 
|  | 400 | { | 
|  | 401 | switch (origin) | 
|  | 402 | { | 
|  | 403 | case IP::AddressOrigin::Static: | 
|  | 404 | return IPv6Source::Static; | 
|  | 405 | case IP::AddressOrigin::DHCP: | 
|  | 406 | return IPv6Source::DHCP; | 
|  | 407 | case IP::AddressOrigin::SLAAC: | 
|  | 408 | return IPv6Source::SLAAC; | 
|  | 409 | default: | 
|  | 410 | { | 
| Willy Tu | 523e2d1 | 2023-09-05 11:36:48 -0700 | [diff] [blame] | 411 | auto originStr = sdbusplus::common::xyz::openbmc_project::network:: | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 412 | convertForMessage(origin); | 
|  | 413 | log<level::ERR>( | 
|  | 414 | "Invalid IP::AddressOrigin conversion to IPv6Source", | 
|  | 415 | entry("ORIGIN=%s", originStr.c_str())); | 
|  | 416 | elog<InternalFailure>(); | 
|  | 417 | } | 
|  | 418 | } | 
|  | 419 | } | 
|  | 420 |  | 
|  | 421 | /** @brief Packs the IPMI message response with IPv6 address data | 
|  | 422 | * | 
|  | 423 | *  @param[out] ret     - The IPMI response payload to be packed | 
|  | 424 | *  @param[in]  channel - The channel id corresponding to an ethernet interface | 
|  | 425 | *  @param[in]  set     - The set selector for determining address index | 
|  | 426 | *  @param[in]  origins - Set of valid origins for address filtering | 
|  | 427 | */ | 
|  | 428 | void getLanIPv6Address(message::Payload& ret, uint8_t channel, uint8_t set, | 
|  | 429 | const std::unordered_set<IP::AddressOrigin>& origins) | 
|  | 430 | { | 
|  | 431 | auto source = IPv6Source::Static; | 
|  | 432 | bool enabled = false; | 
|  | 433 | in6_addr addr{}; | 
| Johnathan Mantey | 5aae092 | 2021-10-21 13:05:36 -0700 | [diff] [blame] | 434 | uint8_t prefix{}; | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 435 | auto status = IPv6AddressStatus::Disabled; | 
|  | 436 |  | 
|  | 437 | auto ifaddr = channelCall<getIfAddr<AF_INET6>>(channel, set, origins); | 
|  | 438 | if (ifaddr) | 
|  | 439 | { | 
|  | 440 | source = originToSourceType(ifaddr->origin); | 
| Johnathan Mantey | 846af86 | 2021-10-21 12:48:54 -0700 | [diff] [blame] | 441 | enabled = (origins == originsV6Static); | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 442 | addr = ifaddr->address; | 
|  | 443 | prefix = ifaddr->prefix; | 
|  | 444 | status = IPv6AddressStatus::Active; | 
|  | 445 | } | 
|  | 446 |  | 
|  | 447 | ret.pack(set); | 
| William A. Kennington III | 7a0e5df | 2021-05-19 13:31:29 -0700 | [diff] [blame] | 448 | ret.pack(types::enum_cast<uint4_t>(source), uint3_t{}, enabled); | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 449 | ret.pack(std::string_view(reinterpret_cast<char*>(&addr), sizeof(addr))); | 
|  | 450 | ret.pack(prefix); | 
| William A. Kennington III | 7a0e5df | 2021-05-19 13:31:29 -0700 | [diff] [blame] | 451 | ret.pack(types::enum_cast<uint8_t>(status)); | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 452 | } | 
|  | 453 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 454 | /** @brief Gets the vlan ID configured on the interface | 
|  | 455 | * | 
|  | 456 | *  @param[in] bus    - The bus object used for lookups | 
|  | 457 | *  @param[in] params - The parameters for the channel | 
|  | 458 | *  @return VLAN id or the standard 0 for no VLAN | 
|  | 459 | */ | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 460 | uint16_t getVLANProperty(sdbusplus::bus_t& bus, const ChannelParams& params) | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 461 | { | 
|  | 462 | // VLAN devices will always have a separate logical object | 
|  | 463 | if (params.ifPath == params.logicalPath) | 
|  | 464 | { | 
|  | 465 | return 0; | 
|  | 466 | } | 
|  | 467 |  | 
|  | 468 | auto vlan = std::get<uint32_t>(getDbusProperty( | 
|  | 469 | bus, params.service, params.logicalPath, INTF_VLAN, "Id")); | 
|  | 470 | if ((vlan & VLAN_VALUE_MASK) != vlan) | 
|  | 471 | { | 
|  | 472 | logWithChannel<level::ERR>(params, "networkd returned an invalid vlan", | 
|  | 473 | entry("VLAN=%" PRIu32, vlan)); | 
| Tom Joseph | a30c8d3 | 2018-03-22 02:15:03 +0530 | [diff] [blame] | 474 | elog<InternalFailure>(); | 
|  | 475 | } | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 476 | return vlan; | 
| Tom Joseph | a30c8d3 | 2018-03-22 02:15:03 +0530 | [diff] [blame] | 477 | } | 
|  | 478 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 479 | /** @brief Deletes all of the possible configuration parameters for a channel | 
|  | 480 | * | 
|  | 481 | *  @param[in] bus    - The bus object used for lookups | 
|  | 482 | *  @param[in] params - The parameters for the channel | 
|  | 483 | */ | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 484 | void deconfigureChannel(sdbusplus::bus_t& bus, ChannelParams& params) | 
| Adriana Kobylak | 5d6481f | 2015-10-29 21:44:55 -0500 | [diff] [blame] | 485 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 486 | // Delete all objects associated with the interface | 
|  | 487 | auto objreq = bus.new_method_call(MAPPER_BUS_NAME, MAPPER_OBJ, MAPPER_INTF, | 
|  | 488 | "GetSubTree"); | 
|  | 489 | objreq.append(PATH_ROOT, 0, std::vector<std::string>{DELETE_INTERFACE}); | 
|  | 490 | auto objreply = bus.call(objreq); | 
|  | 491 | ObjectTree objs; | 
|  | 492 | objreply.read(objs); | 
|  | 493 | for (const auto& [path, impls] : objs) | 
|  | 494 | { | 
|  | 495 | if (path.find(params.ifname) == path.npos) | 
|  | 496 | { | 
|  | 497 | continue; | 
|  | 498 | } | 
|  | 499 | for (const auto& [service, intfs] : impls) | 
|  | 500 | { | 
|  | 501 | deleteObjectIfExists(bus, service, path); | 
|  | 502 | } | 
|  | 503 | // Update params to reflect the deletion of vlan | 
|  | 504 | if (path == params.logicalPath) | 
|  | 505 | { | 
|  | 506 | params.logicalPath = params.ifPath; | 
|  | 507 | } | 
|  | 508 | } | 
|  | 509 |  | 
|  | 510 | // Clear out any settings on the lower physical interface | 
| William A. Kennington III | a8a2e5f | 2023-06-21 17:50:01 -0700 | [diff] [blame] | 511 | setEthProp(bus, params, "DHCP4", false); | 
|  | 512 | setEthProp(bus, params, "DHCP6", false); | 
|  | 513 | setEthProp(bus, params, "IPv6AcceptRA", false); | 
| Adriana Kobylak | 5d6481f | 2015-10-29 21:44:55 -0500 | [diff] [blame] | 514 | } | 
|  | 515 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 516 | /** @brief Creates a new VLAN on the specified interface | 
|  | 517 | * | 
|  | 518 | *  @param[in] bus    - The bus object used for lookups | 
|  | 519 | *  @param[in] params - The parameters for the channel | 
|  | 520 | *  @param[in] vlan   - The id of the new vlan | 
|  | 521 | */ | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 522 | void createVLAN(sdbusplus::bus_t& bus, ChannelParams& params, uint16_t vlan) | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 523 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 524 | if (vlan == 0) | 
| Richard Marian Thomaiyar | 75b480b | 2019-01-22 00:20:15 +0530 | [diff] [blame] | 525 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 526 | return; | 
| Richard Marian Thomaiyar | 75b480b | 2019-01-22 00:20:15 +0530 | [diff] [blame] | 527 | } | 
|  | 528 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 529 | auto req = bus.new_method_call(params.service.c_str(), PATH_ROOT, | 
|  | 530 | INTF_VLAN_CREATE, "VLAN"); | 
|  | 531 | req.append(params.ifname, static_cast<uint32_t>(vlan)); | 
|  | 532 | auto reply = bus.call(req); | 
|  | 533 | sdbusplus::message::object_path newPath; | 
|  | 534 | reply.read(newPath); | 
|  | 535 | params.logicalPath = std::move(newPath); | 
| Richard Marian Thomaiyar | 75b480b | 2019-01-22 00:20:15 +0530 | [diff] [blame] | 536 | } | 
|  | 537 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 538 | /** @brief Performs the necessary reconfiguration to change the VLAN | 
|  | 539 | * | 
|  | 540 | *  @param[in] bus    - The bus object used for lookups | 
|  | 541 | *  @param[in] params - The parameters for the channel | 
|  | 542 | *  @param[in] vlan   - The new vlan id to use | 
|  | 543 | */ | 
| Patrick Williams | 5d82f47 | 2022-07-22 19:26:53 -0500 | [diff] [blame] | 544 | void reconfigureVLAN(sdbusplus::bus_t& bus, ChannelParams& params, | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 545 | uint16_t vlan) | 
| Adriana Kobylak | 5d6481f | 2015-10-29 21:44:55 -0500 | [diff] [blame] | 546 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 547 | // Unfortunatetly we don't have built-in functions to migrate our interface | 
|  | 548 | // customizations to new VLAN interfaces, or have some kind of decoupling. | 
|  | 549 | // We therefore must retain all of our old information, setup the new VLAN | 
|  | 550 | // configuration, then restore the old info. | 
| Nan Li | 3d0df91 | 2016-10-18 19:51:41 +0800 | [diff] [blame] | 551 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 552 | // Save info from the old logical interface | 
| William A. Kennington III | a8a2e5f | 2023-06-21 17:50:01 -0700 | [diff] [blame] | 553 | bool dhcp4 = getEthProp<bool>(bus, params, "DHCP4"); | 
|  | 554 | bool dhcp6 = getEthProp<bool>(bus, params, "DHCP6"); | 
|  | 555 | bool ra = getEthProp<bool>(bus, params, "IPv6AcceptRA"); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 556 | ObjectLookupCache ips(bus, params, INTF_IP); | 
|  | 557 | auto ifaddr4 = findIfAddr<AF_INET>(bus, params, 0, originsV4, ips); | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 558 | std::vector<IfAddr<AF_INET6>> ifaddrs6; | 
|  | 559 | for (uint8_t i = 0; i < MAX_IPV6_STATIC_ADDRESSES; ++i) | 
|  | 560 | { | 
| Patrick Williams | fbc6c9d | 2023-05-10 07:50:16 -0500 | [diff] [blame] | 561 | auto ifaddr6 = findIfAddr<AF_INET6>(bus, params, i, originsV6Static, | 
|  | 562 | ips); | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 563 | if (!ifaddr6) | 
|  | 564 | { | 
|  | 565 | break; | 
|  | 566 | } | 
|  | 567 | ifaddrs6.push_back(std::move(*ifaddr6)); | 
|  | 568 | } | 
| William A. Kennington III | 4bbc3db | 2019-04-15 00:02:10 -0700 | [diff] [blame] | 569 | ObjectLookupCache neighbors(bus, params, INTF_NEIGHBOR); | 
|  | 570 | auto neighbor4 = findGatewayNeighbor<AF_INET>(bus, params, neighbors); | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 571 | auto neighbor6 = findGatewayNeighbor<AF_INET6>(bus, params, neighbors); | 
| Adriana Kobylak | 5d6481f | 2015-10-29 21:44:55 -0500 | [diff] [blame] | 572 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 573 | deconfigureChannel(bus, params); | 
|  | 574 | createVLAN(bus, params, vlan); | 
| Adriana Kobylak | 5d6481f | 2015-10-29 21:44:55 -0500 | [diff] [blame] | 575 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 576 | // Re-establish the saved settings | 
| William A. Kennington III | a8a2e5f | 2023-06-21 17:50:01 -0700 | [diff] [blame] | 577 | setEthProp(bus, params, "DHCP4", dhcp4); | 
|  | 578 | setEthProp(bus, params, "DHCP6", dhcp6); | 
|  | 579 | setEthProp(bus, params, "IPv6AcceptRA", ra); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 580 | if (ifaddr4) | 
| Patrick Venture | c7c1c3c | 2017-11-15 14:29:18 -0800 | [diff] [blame] | 581 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 582 | createIfAddr<AF_INET>(bus, params, ifaddr4->address, ifaddr4->prefix); | 
| Patrick Venture | c7c1c3c | 2017-11-15 14:29:18 -0800 | [diff] [blame] | 583 | } | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 584 | for (const auto& ifaddr6 : ifaddrs6) | 
|  | 585 | { | 
|  | 586 | createIfAddr<AF_INET6>(bus, params, ifaddr6.address, ifaddr6.prefix); | 
|  | 587 | } | 
| William A. Kennington III | 4bbc3db | 2019-04-15 00:02:10 -0700 | [diff] [blame] | 588 | if (neighbor4) | 
|  | 589 | { | 
|  | 590 | createNeighbor<AF_INET>(bus, params, neighbor4->ip, neighbor4->mac); | 
|  | 591 | } | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 592 | if (neighbor6) | 
|  | 593 | { | 
|  | 594 | createNeighbor<AF_INET6>(bus, params, neighbor6->ip, neighbor6->mac); | 
|  | 595 | } | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 596 | } | 
| Patrick Venture | c7c1c3c | 2017-11-15 14:29:18 -0800 | [diff] [blame] | 597 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 598 | /** @brief Turns a prefix into a netmask | 
|  | 599 | * | 
|  | 600 | *  @param[in] prefix - The prefix length | 
|  | 601 | *  @return The netmask | 
|  | 602 | */ | 
|  | 603 | in_addr prefixToNetmask(uint8_t prefix) | 
|  | 604 | { | 
|  | 605 | if (prefix > 32) | 
| Adriana Kobylak | 5d6481f | 2015-10-29 21:44:55 -0500 | [diff] [blame] | 606 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 607 | log<level::ERR>("Invalid prefix", entry("PREFIX=%" PRIu8, prefix)); | 
|  | 608 | elog<InternalFailure>(); | 
|  | 609 | } | 
|  | 610 | if (prefix == 0) | 
|  | 611 | { | 
|  | 612 | // Avoids 32-bit lshift by 32 UB | 
|  | 613 | return {}; | 
|  | 614 | } | 
|  | 615 | return {htobe32(~UINT32_C(0) << (32 - prefix))}; | 
|  | 616 | } | 
|  | 617 |  | 
|  | 618 | /** @brief Turns a a netmask into a prefix length | 
|  | 619 | * | 
|  | 620 | *  @param[in] netmask - The netmask in byte form | 
|  | 621 | *  @return The prefix length | 
|  | 622 | */ | 
|  | 623 | uint8_t netmaskToPrefix(in_addr netmask) | 
|  | 624 | { | 
|  | 625 | uint32_t x = be32toh(netmask.s_addr); | 
|  | 626 | if ((~x & (~x + 1)) != 0) | 
|  | 627 | { | 
|  | 628 | char maskStr[INET_ADDRSTRLEN]; | 
|  | 629 | inet_ntop(AF_INET, &netmask, maskStr, sizeof(maskStr)); | 
|  | 630 | log<level::ERR>("Invalid netmask", entry("NETMASK=%s", maskStr)); | 
|  | 631 | elog<InternalFailure>(); | 
|  | 632 | } | 
| Johnathan Mantey | 62c05dd | 2019-11-20 14:07:44 -0800 | [diff] [blame] | 633 | return static_cast<bool>(x) | 
|  | 634 | ? AddrFamily<AF_INET>::defaultPrefix - __builtin_ctz(x) | 
|  | 635 | : 0; | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 636 | } | 
|  | 637 |  | 
|  | 638 | // We need to store this value so it can be returned to the client | 
|  | 639 | // It is volatile so safe to store in daemon memory. | 
|  | 640 | static std::unordered_map<uint8_t, SetStatus> setStatus; | 
|  | 641 |  | 
|  | 642 | // Until we have good support for fixed versions of IPMI tool | 
|  | 643 | // we need to return the VLAN id for disabled VLANs. The value is only | 
|  | 644 | // used for verification that a disable operation succeeded and will only | 
|  | 645 | // be sent if our system indicates that vlans are disabled. | 
|  | 646 | static std::unordered_map<uint8_t, uint16_t> lastDisabledVlan; | 
|  | 647 |  | 
|  | 648 | /** @brief Gets the set status for the channel if it exists | 
|  | 649 | *         Otherise populates and returns the default value. | 
|  | 650 | * | 
|  | 651 | *  @param[in] channel - The channel id corresponding to an ethernet interface | 
|  | 652 | *  @return A reference to the SetStatus for the channel | 
|  | 653 | */ | 
|  | 654 | SetStatus& getSetStatus(uint8_t channel) | 
|  | 655 | { | 
|  | 656 | auto it = setStatus.find(channel); | 
|  | 657 | if (it != setStatus.end()) | 
|  | 658 | { | 
|  | 659 | return it->second; | 
|  | 660 | } | 
|  | 661 | return setStatus[channel] = SetStatus::Complete; | 
|  | 662 | } | 
|  | 663 |  | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 664 | /** @brief Unpacks the trivially copyable type from the message */ | 
|  | 665 | template <typename T> | 
|  | 666 | static T unpackT(message::Payload& req) | 
|  | 667 | { | 
|  | 668 | std::array<uint8_t, sizeof(T)> bytes; | 
|  | 669 | if (req.unpack(bytes) != 0) | 
|  | 670 | { | 
|  | 671 | throw ccReqDataLenInvalid; | 
|  | 672 | } | 
|  | 673 | return stdplus::raw::copyFrom<T>(bytes); | 
|  | 674 | } | 
|  | 675 |  | 
|  | 676 | /** @brief Ensure the message is fully unpacked */ | 
|  | 677 | static void unpackFinal(message::Payload& req) | 
|  | 678 | { | 
|  | 679 | if (!req.fullyUnpacked()) | 
|  | 680 | { | 
|  | 681 | throw ccReqDataTruncated; | 
|  | 682 | } | 
|  | 683 | } | 
|  | 684 |  | 
| Johnathan Mantey | b87034e | 2019-09-16 10:50:50 -0700 | [diff] [blame] | 685 | /** | 
|  | 686 | * Define placeholder command handlers for the OEM Extension bytes for the Set | 
|  | 687 | * LAN Configuration Parameters and Get LAN Configuration Parameters | 
|  | 688 | * commands. Using "weak" linking allows the placeholder setLanOem/getLanOem | 
|  | 689 | * functions below to be overridden. | 
|  | 690 | * To create handlers for your own proprietary command set: | 
|  | 691 | *   Create/modify a phosphor-ipmi-host Bitbake append file within your Yocto | 
|  | 692 | *   recipe | 
|  | 693 | *   Create C++ file(s) that define IPMI handler functions matching the | 
|  | 694 | *     function names below (i.e. setLanOem). The default name for the | 
|  | 695 | *     transport IPMI commands is transporthandler_oem.cpp. | 
|  | 696 | *   Add: | 
| Johnathan Mantey | efe2668 | 2022-08-11 14:30:45 -0700 | [diff] [blame] | 697 | *      EXTRA_OEMESON:append = "-Dtransport-oem=enabled" | 
|  | 698 | *   Create a do_configure:prepend()/do_install:append() method in your | 
| Johnathan Mantey | b87034e | 2019-09-16 10:50:50 -0700 | [diff] [blame] | 699 | *   bbappend file to copy the file to the build directory. | 
|  | 700 | *   Add: | 
|  | 701 | *   PROJECT_SRC_DIR := "${THISDIR}/${PN}" | 
|  | 702 | *   # Copy the "strong" functions into the working directory, overriding the | 
|  | 703 | *   # placeholder functions. | 
| Johnathan Mantey | efe2668 | 2022-08-11 14:30:45 -0700 | [diff] [blame] | 704 | *   do_configure:prepend(){ | 
| Johnathan Mantey | b87034e | 2019-09-16 10:50:50 -0700 | [diff] [blame] | 705 | *      cp -f ${PROJECT_SRC_DIR}/transporthandler_oem.cpp ${S} | 
|  | 706 | *   } | 
|  | 707 | * | 
|  | 708 | *   # Clean up after complilation has completed | 
| Johnathan Mantey | efe2668 | 2022-08-11 14:30:45 -0700 | [diff] [blame] | 709 | *   do_install:append(){ | 
| Johnathan Mantey | b87034e | 2019-09-16 10:50:50 -0700 | [diff] [blame] | 710 | *      rm -f ${S}/transporthandler_oem.cpp | 
|  | 711 | *   } | 
|  | 712 | * | 
|  | 713 | */ | 
|  | 714 |  | 
|  | 715 | /** | 
|  | 716 | * Define the placeholder OEM commands as having weak linkage. Create | 
|  | 717 | * setLanOem, and getLanOem functions in the transporthandler_oem.cpp | 
|  | 718 | * file. The functions defined there must not have the "weak" attribute | 
|  | 719 | * applied to them. | 
|  | 720 | */ | 
|  | 721 | RspType<> setLanOem(uint8_t channel, uint8_t parameter, message::Payload& req) | 
|  | 722 | __attribute__((weak)); | 
|  | 723 | RspType<message::Payload> getLanOem(uint8_t channel, uint8_t parameter, | 
|  | 724 | uint8_t set, uint8_t block) | 
|  | 725 | __attribute__((weak)); | 
|  | 726 |  | 
| Willy Tu | 11d6889 | 2022-01-20 10:37:34 -0800 | [diff] [blame] | 727 | RspType<> setLanOem(uint8_t, uint8_t, message::Payload& req) | 
| Johnathan Mantey | b87034e | 2019-09-16 10:50:50 -0700 | [diff] [blame] | 728 | { | 
|  | 729 | req.trailingOk = true; | 
|  | 730 | return response(ccParamNotSupported); | 
|  | 731 | } | 
|  | 732 |  | 
| Willy Tu | 11d6889 | 2022-01-20 10:37:34 -0800 | [diff] [blame] | 733 | RspType<message::Payload> getLanOem(uint8_t, uint8_t, uint8_t, uint8_t) | 
| Johnathan Mantey | b87034e | 2019-09-16 10:50:50 -0700 | [diff] [blame] | 734 | { | 
|  | 735 | return response(ccParamNotSupported); | 
|  | 736 | } | 
| Rajashekar Gade Reddy | 0b993fd | 2019-12-24 16:37:15 +0530 | [diff] [blame] | 737 | /** | 
|  | 738 | * @brief is MAC address valid. | 
|  | 739 | * | 
|  | 740 | * This function checks whether the MAC address is valid or not. | 
|  | 741 | * | 
|  | 742 | * @param[in] mac - MAC address. | 
|  | 743 | * @return true if MAC address is valid else retun false. | 
|  | 744 | **/ | 
|  | 745 | bool isValidMACAddress(const ether_addr& mac) | 
|  | 746 | { | 
|  | 747 | // check if mac address is empty | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 748 | if (stdplus::raw::equal(mac, ether_addr{})) | 
| Rajashekar Gade Reddy | 0b993fd | 2019-12-24 16:37:15 +0530 | [diff] [blame] | 749 | { | 
|  | 750 | return false; | 
|  | 751 | } | 
|  | 752 | // we accept only unicast MAC addresses and  same thing has been checked in | 
|  | 753 | // phosphor-network layer. If the least significant bit of the first octet | 
|  | 754 | // is set to 1, it is multicast MAC else it is unicast MAC address. | 
|  | 755 | if (mac.ether_addr_octet[0] & 1) | 
|  | 756 | { | 
|  | 757 | return false; | 
|  | 758 | } | 
|  | 759 | return true; | 
|  | 760 | } | 
| Johnathan Mantey | b87034e | 2019-09-16 10:50:50 -0700 | [diff] [blame] | 761 |  | 
| Jian Zhang | cf19d14 | 2023-07-31 10:22:53 +0800 | [diff] [blame] | 762 | /** | 
|  | 763 | * @brief is a valid LAN channel. | 
|  | 764 | * | 
|  | 765 | * This function checks whether the input channel is a valid LAN channel or not. | 
|  | 766 | * | 
|  | 767 | * @param[in] channel: the channel number. | 
|  | 768 | * @return nullopt if the channel is invalid, false if the channel is not a LAN | 
|  | 769 | * channel, true if the channel is a LAN channel. | 
|  | 770 | **/ | 
|  | 771 | std::optional<bool> isLanChannel(uint8_t channel) | 
|  | 772 | { | 
|  | 773 | ChannelInfo chInfo; | 
|  | 774 | auto cc = getChannelInfo(channel, chInfo); | 
|  | 775 | if (cc != ccSuccess) | 
|  | 776 | { | 
|  | 777 | return std::nullopt; | 
|  | 778 | } | 
|  | 779 |  | 
|  | 780 | return chInfo.mediumType == | 
|  | 781 | static_cast<uint8_t>(EChannelMediumType::lan8032); | 
|  | 782 | } | 
|  | 783 |  | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 784 | RspType<> setLanInt(Context::ptr ctx, uint4_t channelBits, uint4_t reserved1, | 
|  | 785 | uint8_t parameter, message::Payload& req) | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 786 | { | 
| vijayabharathix shetty | cc76925 | 2020-02-27 17:52:20 +0000 | [diff] [blame] | 787 | const uint8_t channel = convertCurrentChannelNum( | 
|  | 788 | static_cast<uint8_t>(channelBits), ctx->channel); | 
|  | 789 | if (reserved1 || !isValidChannel(channel)) | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 790 | { | 
| vijayabharathix shetty | cc76925 | 2020-02-27 17:52:20 +0000 | [diff] [blame] | 791 | log<level::ERR>("Set Lan - Invalid field in request"); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 792 | req.trailingOk = true; | 
|  | 793 | return responseInvalidFieldRequest(); | 
|  | 794 | } | 
|  | 795 |  | 
| Jian Zhang | cf19d14 | 2023-07-31 10:22:53 +0800 | [diff] [blame] | 796 | if (!isLanChannel(channel).value_or(false)) | 
|  | 797 | { | 
|  | 798 | log<level::ERR>("Set Lan - Not a LAN channel"); | 
|  | 799 | return responseInvalidFieldRequest(); | 
|  | 800 | } | 
|  | 801 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 802 | switch (static_cast<LanParam>(parameter)) | 
|  | 803 | { | 
|  | 804 | case LanParam::SetStatus: | 
|  | 805 | { | 
|  | 806 | uint2_t flag; | 
|  | 807 | uint6_t rsvd; | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 808 | if (req.unpack(flag, rsvd) != 0) | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 809 | { | 
|  | 810 | return responseReqDataLenInvalid(); | 
|  | 811 | } | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 812 | unpackFinal(req); | 
| Johnathan Mantey | 4a15685 | 2019-12-11 13:47:43 -0800 | [diff] [blame] | 813 | if (rsvd) | 
|  | 814 | { | 
|  | 815 | return responseInvalidFieldRequest(); | 
|  | 816 | } | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 817 | auto status = static_cast<SetStatus>(static_cast<uint8_t>(flag)); | 
|  | 818 | switch (status) | 
|  | 819 | { | 
|  | 820 | case SetStatus::Complete: | 
|  | 821 | { | 
|  | 822 | getSetStatus(channel) = status; | 
|  | 823 | return responseSuccess(); | 
|  | 824 | } | 
|  | 825 | case SetStatus::InProgress: | 
|  | 826 | { | 
|  | 827 | auto& storedStatus = getSetStatus(channel); | 
|  | 828 | if (storedStatus == SetStatus::InProgress) | 
|  | 829 | { | 
|  | 830 | return response(ccParamSetLocked); | 
|  | 831 | } | 
|  | 832 | storedStatus = status; | 
|  | 833 | return responseSuccess(); | 
|  | 834 | } | 
|  | 835 | case SetStatus::Commit: | 
|  | 836 | if (getSetStatus(channel) != SetStatus::InProgress) | 
|  | 837 | { | 
|  | 838 | return responseInvalidFieldRequest(); | 
|  | 839 | } | 
|  | 840 | return responseSuccess(); | 
|  | 841 | } | 
|  | 842 | return response(ccParamNotSupported); | 
|  | 843 | } | 
|  | 844 | case LanParam::AuthSupport: | 
|  | 845 | { | 
|  | 846 | req.trailingOk = true; | 
|  | 847 | return response(ccParamReadOnly); | 
|  | 848 | } | 
|  | 849 | case LanParam::AuthEnables: | 
|  | 850 | { | 
|  | 851 | req.trailingOk = true; | 
| Johnathan Mantey | 76ce9c7 | 2019-11-14 14:41:46 -0800 | [diff] [blame] | 852 | return response(ccParamReadOnly); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 853 | } | 
| William A. Kennington III | aab2023 | 2018-11-19 18:20:39 -0800 | [diff] [blame] | 854 | case LanParam::IP: | 
| Hariharasubramanian R | 8395191 | 2016-01-20 07:06:36 -0600 | [diff] [blame] | 855 | { | 
| William A. Kennington III | a8a2e5f | 2023-06-21 17:50:01 -0700 | [diff] [blame] | 856 | if (channelCall<getEthProp<bool>>(channel, "DHCP4")) | 
| Johnathan Mantey | 930104a | 2019-12-17 09:18:34 -0800 | [diff] [blame] | 857 | { | 
|  | 858 | return responseCommandNotAvailable(); | 
|  | 859 | } | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 860 | auto ip = unpackT<in_addr>(req); | 
|  | 861 | unpackFinal(req); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 862 | channelCall<reconfigureIfAddr4>(channel, ip, std::nullopt); | 
|  | 863 | return responseSuccess(); | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 864 | } | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 865 | case LanParam::IPSrc: | 
| Ratan Gupta | cc6cdbf | 2017-09-01 23:06:25 +0530 | [diff] [blame] | 866 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 867 | uint4_t flag; | 
|  | 868 | uint4_t rsvd; | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 869 | if (req.unpack(flag, rsvd) != 0) | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 870 | { | 
|  | 871 | return responseReqDataLenInvalid(); | 
|  | 872 | } | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 873 | unpackFinal(req); | 
| Johnathan Mantey | 4a15685 | 2019-12-11 13:47:43 -0800 | [diff] [blame] | 874 | if (rsvd) | 
|  | 875 | { | 
|  | 876 | return responseInvalidFieldRequest(); | 
|  | 877 | } | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 878 | switch (static_cast<IPSrc>(static_cast<uint8_t>(flag))) | 
|  | 879 | { | 
|  | 880 | case IPSrc::DHCP: | 
| Johnathan Mantey | 6526536 | 2019-11-14 11:24:19 -0800 | [diff] [blame] | 881 | // The IPSrc IPMI command is only for IPv4 | 
|  | 882 | // management. Modifying IPv6 state is done using | 
|  | 883 | // a completely different Set LAN Configuration | 
|  | 884 | // subcommand. | 
| William A. Kennington III | a8a2e5f | 2023-06-21 17:50:01 -0700 | [diff] [blame] | 885 | channelCall<setEthProp<bool>>(channel, "DHCP4", true); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 886 | return responseSuccess(); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 887 | case IPSrc::Unspecified: | 
|  | 888 | case IPSrc::Static: | 
| William A. Kennington III | a8a2e5f | 2023-06-21 17:50:01 -0700 | [diff] [blame] | 889 | channelCall<setEthProp<bool>>(channel, "DHCP4", false); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 890 | return responseSuccess(); | 
| Rajashekar Gade Reddy | 8a860ea | 2019-12-24 11:31:19 +0530 | [diff] [blame] | 891 | case IPSrc::BIOS: | 
|  | 892 | case IPSrc::BMC: | 
| Rajashekar Gade Reddy | 8a860ea | 2019-12-24 11:31:19 +0530 | [diff] [blame] | 893 | return responseInvalidFieldRequest(); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 894 | } | 
|  | 895 | return response(ccParamNotSupported); | 
| Ratan Gupta | cc6cdbf | 2017-09-01 23:06:25 +0530 | [diff] [blame] | 896 | } | 
| William A. Kennington III | aab2023 | 2018-11-19 18:20:39 -0800 | [diff] [blame] | 897 | case LanParam::MAC: | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 898 | { | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 899 | auto mac = unpackT<ether_addr>(req); | 
|  | 900 | unpackFinal(req); | 
| Rajashekar Gade Reddy | 0b993fd | 2019-12-24 16:37:15 +0530 | [diff] [blame] | 901 | if (!isValidMACAddress(mac)) | 
|  | 902 | { | 
|  | 903 | return responseInvalidFieldRequest(); | 
|  | 904 | } | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 905 | channelCall<setMACProperty>(channel, mac); | 
|  | 906 | return responseSuccess(); | 
| Ratan Gupta | 533d03b | 2017-07-30 10:39:22 +0530 | [diff] [blame] | 907 | } | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 908 | case LanParam::SubnetMask: | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 909 | { | 
| William A. Kennington III | a8a2e5f | 2023-06-21 17:50:01 -0700 | [diff] [blame] | 910 | if (channelCall<getEthProp<bool>>(channel, "DHCP4")) | 
| Johnathan Mantey | 930104a | 2019-12-17 09:18:34 -0800 | [diff] [blame] | 911 | { | 
|  | 912 | return responseCommandNotAvailable(); | 
|  | 913 | } | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 914 | auto netmask = unpackT<in_addr>(req); | 
|  | 915 | unpackFinal(req); | 
| Jiaqing Zhao | 6d4a44e | 2022-01-24 15:04:00 +0800 | [diff] [blame] | 916 | uint8_t prefix = netmaskToPrefix(netmask); | 
|  | 917 | if (prefix < MIN_IPV4_PREFIX_LENGTH) | 
|  | 918 | { | 
|  | 919 | return responseInvalidFieldRequest(); | 
|  | 920 | } | 
|  | 921 | channelCall<reconfigureIfAddr4>(channel, std::nullopt, prefix); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 922 | return responseSuccess(); | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 923 | } | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 924 | case LanParam::Gateway1: | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 925 | { | 
| William A. Kennington III | a8a2e5f | 2023-06-21 17:50:01 -0700 | [diff] [blame] | 926 | if (channelCall<getEthProp<bool>>(channel, "DHCP4")) | 
| Johnathan Mantey | 930104a | 2019-12-17 09:18:34 -0800 | [diff] [blame] | 927 | { | 
|  | 928 | return responseCommandNotAvailable(); | 
|  | 929 | } | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 930 | auto gateway = unpackT<in_addr>(req); | 
|  | 931 | unpackFinal(req); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 932 | channelCall<setGatewayProperty<AF_INET>>(channel, gateway); | 
|  | 933 | return responseSuccess(); | 
|  | 934 | } | 
| William A. Kennington III | 4bbc3db | 2019-04-15 00:02:10 -0700 | [diff] [blame] | 935 | case LanParam::Gateway1MAC: | 
|  | 936 | { | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 937 | auto gatewayMAC = unpackT<ether_addr>(req); | 
|  | 938 | unpackFinal(req); | 
| William A. Kennington III | 4bbc3db | 2019-04-15 00:02:10 -0700 | [diff] [blame] | 939 | channelCall<reconfigureGatewayMAC<AF_INET>>(channel, gatewayMAC); | 
|  | 940 | return responseSuccess(); | 
|  | 941 | } | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 942 | case LanParam::VLANId: | 
|  | 943 | { | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 944 | uint12_t vlanData; | 
|  | 945 | uint3_t rsvd; | 
|  | 946 | bool vlanEnable; | 
| Suryakanth Sekar | 8e8c8e2 | 2019-08-30 11:54:20 +0530 | [diff] [blame] | 947 |  | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 948 | if (req.unpack(vlanData, rsvd, vlanEnable) != 0) | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 949 | { | 
|  | 950 | return responseReqDataLenInvalid(); | 
|  | 951 | } | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 952 | unpackFinal(req); | 
| Suryakanth Sekar | 8e8c8e2 | 2019-08-30 11:54:20 +0530 | [diff] [blame] | 953 |  | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 954 | if (rsvd) | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 955 | { | 
| Suryakanth Sekar | 8e8c8e2 | 2019-08-30 11:54:20 +0530 | [diff] [blame] | 956 | return responseInvalidFieldRequest(); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 957 | } | 
| Suryakanth Sekar | 8e8c8e2 | 2019-08-30 11:54:20 +0530 | [diff] [blame] | 958 |  | 
|  | 959 | uint16_t vlan = static_cast<uint16_t>(vlanData); | 
|  | 960 |  | 
|  | 961 | if (!vlanEnable) | 
|  | 962 | { | 
|  | 963 | lastDisabledVlan[channel] = vlan; | 
|  | 964 | vlan = 0; | 
|  | 965 | } | 
| jayaprakash Mutyala | 84c49dc | 2020-05-18 23:12:13 +0000 | [diff] [blame] | 966 | else if (vlan == 0 || vlan == VLAN_VALUE_MASK) | 
|  | 967 | { | 
|  | 968 | return responseInvalidFieldRequest(); | 
|  | 969 | } | 
| Suryakanth Sekar | 8e8c8e2 | 2019-08-30 11:54:20 +0530 | [diff] [blame] | 970 |  | 
| jayaprakash Mutyala | 84c49dc | 2020-05-18 23:12:13 +0000 | [diff] [blame] | 971 | channelCall<reconfigureVLAN>(channel, vlan); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 972 | return responseSuccess(); | 
|  | 973 | } | 
|  | 974 | case LanParam::CiphersuiteSupport: | 
|  | 975 | case LanParam::CiphersuiteEntries: | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 976 | case LanParam::IPFamilySupport: | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 977 | { | 
|  | 978 | req.trailingOk = true; | 
|  | 979 | return response(ccParamReadOnly); | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 980 | } | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 981 | case LanParam::IPFamilyEnables: | 
|  | 982 | { | 
|  | 983 | uint8_t enables; | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 984 | if (req.unpack(enables) != 0) | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 985 | { | 
|  | 986 | return responseReqDataLenInvalid(); | 
|  | 987 | } | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 988 | unpackFinal(req); | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 989 | switch (static_cast<IPFamilyEnables>(enables)) | 
|  | 990 | { | 
|  | 991 | case IPFamilyEnables::DualStack: | 
|  | 992 | return responseSuccess(); | 
|  | 993 | case IPFamilyEnables::IPv4Only: | 
|  | 994 | case IPFamilyEnables::IPv6Only: | 
|  | 995 | return response(ccParamNotSupported); | 
|  | 996 | } | 
|  | 997 | return response(ccParamNotSupported); | 
|  | 998 | } | 
|  | 999 | case LanParam::IPv6Status: | 
|  | 1000 | { | 
|  | 1001 | req.trailingOk = true; | 
|  | 1002 | return response(ccParamReadOnly); | 
|  | 1003 | } | 
|  | 1004 | case LanParam::IPv6StaticAddresses: | 
|  | 1005 | { | 
|  | 1006 | uint8_t set; | 
|  | 1007 | uint7_t rsvd; | 
|  | 1008 | bool enabled; | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 1009 | uint8_t prefix; | 
|  | 1010 | uint8_t status; | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1011 | if (req.unpack(set, rsvd, enabled) != 0) | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 1012 | { | 
|  | 1013 | return responseReqDataLenInvalid(); | 
|  | 1014 | } | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1015 | auto ip = unpackT<in6_addr>(req); | 
|  | 1016 | if (req.unpack(prefix, status) != 0) | 
|  | 1017 | { | 
|  | 1018 | return responseReqDataLenInvalid(); | 
|  | 1019 | } | 
|  | 1020 | unpackFinal(req); | 
| Johnathan Mantey | 4a15685 | 2019-12-11 13:47:43 -0800 | [diff] [blame] | 1021 | if (rsvd) | 
|  | 1022 | { | 
|  | 1023 | return responseInvalidFieldRequest(); | 
|  | 1024 | } | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 1025 | if (enabled) | 
|  | 1026 | { | 
| Jiaqing Zhao | 6d4a44e | 2022-01-24 15:04:00 +0800 | [diff] [blame] | 1027 | if (prefix < MIN_IPV6_PREFIX_LENGTH || | 
|  | 1028 | prefix > MAX_IPV6_PREFIX_LENGTH) | 
|  | 1029 | { | 
|  | 1030 | return responseParmOutOfRange(); | 
|  | 1031 | } | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1032 | channelCall<reconfigureIfAddr6>(channel, set, ip, prefix); | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 1033 | } | 
|  | 1034 | else | 
|  | 1035 | { | 
|  | 1036 | channelCall<deconfigureIfAddr6>(channel, set); | 
|  | 1037 | } | 
|  | 1038 | return responseSuccess(); | 
|  | 1039 | } | 
|  | 1040 | case LanParam::IPv6DynamicAddresses: | 
|  | 1041 | { | 
|  | 1042 | req.trailingOk = true; | 
|  | 1043 | return response(ccParamReadOnly); | 
|  | 1044 | } | 
|  | 1045 | case LanParam::IPv6RouterControl: | 
|  | 1046 | { | 
|  | 1047 | std::bitset<8> control; | 
| Johnathan Mantey | 3b7a407 | 2021-01-26 14:24:53 -0800 | [diff] [blame] | 1048 | constexpr uint8_t reservedRACCBits = 0xfc; | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1049 | if (req.unpack(control) != 0) | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 1050 | { | 
|  | 1051 | return responseReqDataLenInvalid(); | 
|  | 1052 | } | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1053 | unpackFinal(req); | 
| Johnathan Mantey | 3b7a407 | 2021-01-26 14:24:53 -0800 | [diff] [blame] | 1054 | if (std::bitset<8> expected(control & | 
|  | 1055 | std::bitset<8>(reservedRACCBits)); | 
|  | 1056 | expected.any()) | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 1057 | { | 
| Johnathan Mantey | 3b7a407 | 2021-01-26 14:24:53 -0800 | [diff] [blame] | 1058 | return response(ccParamNotSupported); | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 1059 | } | 
| Johnathan Mantey | 3b7a407 | 2021-01-26 14:24:53 -0800 | [diff] [blame] | 1060 |  | 
|  | 1061 | bool enableRA = control[IPv6RouterControlFlag::Dynamic]; | 
| William A. Kennington III | a8a2e5f | 2023-06-21 17:50:01 -0700 | [diff] [blame] | 1062 | channelCall<setEthProp<bool>>(channel, "IPv6AcceptRA", enableRA); | 
|  | 1063 | channelCall<setEthProp<bool>>(channel, "DHCP6", enableRA); | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 1064 | return responseSuccess(); | 
|  | 1065 | } | 
|  | 1066 | case LanParam::IPv6StaticRouter1IP: | 
|  | 1067 | { | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1068 | auto gateway = unpackT<in6_addr>(req); | 
|  | 1069 | unpackFinal(req); | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 1070 | channelCall<setGatewayProperty<AF_INET6>>(channel, gateway); | 
|  | 1071 | return responseSuccess(); | 
|  | 1072 | } | 
|  | 1073 | case LanParam::IPv6StaticRouter1MAC: | 
|  | 1074 | { | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1075 | auto mac = unpackT<ether_addr>(req); | 
|  | 1076 | unpackFinal(req); | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 1077 | channelCall<reconfigureGatewayMAC<AF_INET6>>(channel, mac); | 
|  | 1078 | return responseSuccess(); | 
|  | 1079 | } | 
|  | 1080 | case LanParam::IPv6StaticRouter1PrefixLength: | 
|  | 1081 | { | 
|  | 1082 | uint8_t prefix; | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1083 | if (req.unpack(prefix) != 0) | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 1084 | { | 
|  | 1085 | return responseReqDataLenInvalid(); | 
|  | 1086 | } | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1087 | unpackFinal(req); | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 1088 | if (prefix != 0) | 
|  | 1089 | { | 
|  | 1090 | return responseInvalidFieldRequest(); | 
|  | 1091 | } | 
|  | 1092 | return responseSuccess(); | 
|  | 1093 | } | 
|  | 1094 | case LanParam::IPv6StaticRouter1PrefixValue: | 
|  | 1095 | { | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1096 | unpackT<in6_addr>(req); | 
|  | 1097 | unpackFinal(req); | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 1098 | // Accept any prefix value since our prefix length has to be 0 | 
|  | 1099 | return responseSuccess(); | 
|  | 1100 | } | 
| jayaprakash Mutyala | b741b99 | 2019-12-02 17:29:09 +0000 | [diff] [blame] | 1101 | case LanParam::cipherSuitePrivilegeLevels: | 
|  | 1102 | { | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1103 | uint8_t rsvd; | 
| jayaprakash Mutyala | b741b99 | 2019-12-02 17:29:09 +0000 | [diff] [blame] | 1104 | std::array<uint4_t, ipmi::maxCSRecords> cipherSuitePrivs; | 
|  | 1105 |  | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1106 | if (req.unpack(rsvd, cipherSuitePrivs)) | 
| jayaprakash Mutyala | b741b99 | 2019-12-02 17:29:09 +0000 | [diff] [blame] | 1107 | { | 
|  | 1108 | return responseReqDataLenInvalid(); | 
|  | 1109 | } | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1110 | unpackFinal(req); | 
| jayaprakash Mutyala | b741b99 | 2019-12-02 17:29:09 +0000 | [diff] [blame] | 1111 |  | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1112 | if (rsvd) | 
| jayaprakash Mutyala | b741b99 | 2019-12-02 17:29:09 +0000 | [diff] [blame] | 1113 | { | 
|  | 1114 | return responseInvalidFieldRequest(); | 
|  | 1115 | } | 
|  | 1116 |  | 
| Patrick Williams | fbc6c9d | 2023-05-10 07:50:16 -0500 | [diff] [blame] | 1117 | uint8_t resp = getCipherConfigObject(csPrivFileName, | 
|  | 1118 | csPrivDefaultFileName) | 
|  | 1119 | .setCSPrivilegeLevels(channel, cipherSuitePrivs); | 
| jayaprakash Mutyala | b741b99 | 2019-12-02 17:29:09 +0000 | [diff] [blame] | 1120 | if (!resp) | 
|  | 1121 | { | 
|  | 1122 | return responseSuccess(); | 
|  | 1123 | } | 
|  | 1124 | else | 
|  | 1125 | { | 
|  | 1126 | req.trailingOk = true; | 
|  | 1127 | return response(resp); | 
|  | 1128 | } | 
|  | 1129 | } | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 1130 | } | 
| vishwa | 1eaea4f | 2016-02-26 11:57:40 -0600 | [diff] [blame] | 1131 |  | 
| Johnathan Mantey | b87034e | 2019-09-16 10:50:50 -0700 | [diff] [blame] | 1132 | if ((parameter >= oemCmdStart) && (parameter <= oemCmdEnd)) | 
|  | 1133 | { | 
|  | 1134 | return setLanOem(channel, parameter, req); | 
|  | 1135 | } | 
|  | 1136 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1137 | req.trailingOk = true; | 
|  | 1138 | return response(ccParamNotSupported); | 
| Adriana Kobylak | 5d6481f | 2015-10-29 21:44:55 -0500 | [diff] [blame] | 1139 | } | 
|  | 1140 |  | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1141 | RspType<> setLan(Context::ptr ctx, uint4_t channelBits, uint4_t reserved1, | 
|  | 1142 | uint8_t parameter, message::Payload& req) | 
|  | 1143 | { | 
|  | 1144 | try | 
|  | 1145 | { | 
|  | 1146 | return setLanInt(ctx, channelBits, reserved1, parameter, req); | 
|  | 1147 | } | 
|  | 1148 | catch (ipmi::Cc cc) | 
|  | 1149 | { | 
|  | 1150 | return response(cc); | 
|  | 1151 | } | 
|  | 1152 | catch (const sdbusplus::exception_t& e) | 
|  | 1153 | { | 
|  | 1154 | if (std::string_view{InvalidArgument::errName} == e.name()) | 
|  | 1155 | { | 
|  | 1156 | return responseInvalidFieldRequest(); | 
|  | 1157 | } | 
|  | 1158 | throw; | 
|  | 1159 | } | 
|  | 1160 | } | 
|  | 1161 |  | 
| vijayabharathix shetty | cc76925 | 2020-02-27 17:52:20 +0000 | [diff] [blame] | 1162 | RspType<message::Payload> getLan(Context::ptr ctx, uint4_t channelBits, | 
|  | 1163 | uint3_t reserved, bool revOnly, | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1164 | uint8_t parameter, uint8_t set, uint8_t block) | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 1165 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1166 | message::Payload ret; | 
|  | 1167 | constexpr uint8_t current_revision = 0x11; | 
|  | 1168 | ret.pack(current_revision); | 
| Adriana Kobylak | 5d6481f | 2015-10-29 21:44:55 -0500 | [diff] [blame] | 1169 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1170 | if (revOnly) | 
| Suryakanth Sekar | e405440 | 2019-08-08 15:16:52 +0530 | [diff] [blame] | 1171 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1172 | return responseSuccess(std::move(ret)); | 
| Suryakanth Sekar | e405440 | 2019-08-08 15:16:52 +0530 | [diff] [blame] | 1173 | } | 
| Adriana Kobylak | 5d6481f | 2015-10-29 21:44:55 -0500 | [diff] [blame] | 1174 |  | 
| vijayabharathix shetty | cc76925 | 2020-02-27 17:52:20 +0000 | [diff] [blame] | 1175 | const uint8_t channel = convertCurrentChannelNum( | 
|  | 1176 | static_cast<uint8_t>(channelBits), ctx->channel); | 
|  | 1177 | if (reserved || !isValidChannel(channel)) | 
| Adriana Kobylak | 5d6481f | 2015-10-29 21:44:55 -0500 | [diff] [blame] | 1178 | { | 
| vijayabharathix shetty | cc76925 | 2020-02-27 17:52:20 +0000 | [diff] [blame] | 1179 | log<level::ERR>("Get Lan - Invalid field in request"); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1180 | return responseInvalidFieldRequest(); | 
| Adriana Kobylak | 5d6481f | 2015-10-29 21:44:55 -0500 | [diff] [blame] | 1181 | } | 
|  | 1182 |  | 
| Jian Zhang | cf19d14 | 2023-07-31 10:22:53 +0800 | [diff] [blame] | 1183 | if (!isLanChannel(channel).value_or(false)) | 
|  | 1184 | { | 
|  | 1185 | log<level::ERR>("Set Lan - Not a LAN channel"); | 
|  | 1186 | return responseInvalidFieldRequest(); | 
|  | 1187 | } | 
|  | 1188 |  | 
| Johnathan Mantey | affadb5 | 2019-10-07 10:13:53 -0700 | [diff] [blame] | 1189 | static std::vector<uint8_t> cipherList; | 
|  | 1190 | static bool listInit = false; | 
|  | 1191 | if (!listInit) | 
|  | 1192 | { | 
|  | 1193 | try | 
|  | 1194 | { | 
|  | 1195 | cipherList = cipher::getCipherList(); | 
|  | 1196 | listInit = true; | 
|  | 1197 | } | 
|  | 1198 | catch (const std::exception& e) | 
| Patrick Williams | fbc6c9d | 2023-05-10 07:50:16 -0500 | [diff] [blame] | 1199 | {} | 
| Johnathan Mantey | affadb5 | 2019-10-07 10:13:53 -0700 | [diff] [blame] | 1200 | } | 
|  | 1201 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1202 | switch (static_cast<LanParam>(parameter)) | 
| Tom Joseph | a30c8d3 | 2018-03-22 02:15:03 +0530 | [diff] [blame] | 1203 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1204 | case LanParam::SetStatus: | 
| Tom Joseph | a30c8d3 | 2018-03-22 02:15:03 +0530 | [diff] [blame] | 1205 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1206 | SetStatus status; | 
|  | 1207 | try | 
|  | 1208 | { | 
|  | 1209 | status = setStatus.at(channel); | 
|  | 1210 | } | 
|  | 1211 | catch (const std::out_of_range&) | 
|  | 1212 | { | 
|  | 1213 | status = SetStatus::Complete; | 
|  | 1214 | } | 
| William A. Kennington III | 7a0e5df | 2021-05-19 13:31:29 -0700 | [diff] [blame] | 1215 | ret.pack(types::enum_cast<uint2_t>(status), uint6_t{}); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1216 | return responseSuccess(std::move(ret)); | 
| Tom Joseph | a30c8d3 | 2018-03-22 02:15:03 +0530 | [diff] [blame] | 1217 | } | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1218 | case LanParam::AuthSupport: | 
| Tom Joseph | a30c8d3 | 2018-03-22 02:15:03 +0530 | [diff] [blame] | 1219 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1220 | std::bitset<6> support; | 
|  | 1221 | ret.pack(support, uint2_t{}); | 
|  | 1222 | return responseSuccess(std::move(ret)); | 
| Tom Joseph | a30c8d3 | 2018-03-22 02:15:03 +0530 | [diff] [blame] | 1223 | } | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1224 | case LanParam::AuthEnables: | 
| vishwa | 1eaea4f | 2016-02-26 11:57:40 -0600 | [diff] [blame] | 1225 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1226 | std::bitset<6> enables; | 
|  | 1227 | ret.pack(enables, uint2_t{}); // Callback | 
|  | 1228 | ret.pack(enables, uint2_t{}); // User | 
|  | 1229 | ret.pack(enables, uint2_t{}); // Operator | 
|  | 1230 | ret.pack(enables, uint2_t{}); // Admin | 
|  | 1231 | ret.pack(enables, uint2_t{}); // OEM | 
|  | 1232 | return responseSuccess(std::move(ret)); | 
| William A. Kennington III | 39f94ef | 2018-11-19 22:36:16 -0800 | [diff] [blame] | 1233 | } | 
| William A. Kennington III | aab2023 | 2018-11-19 18:20:39 -0800 | [diff] [blame] | 1234 | case LanParam::IP: | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1235 | { | 
|  | 1236 | auto ifaddr = channelCall<getIfAddr4>(channel); | 
|  | 1237 | in_addr addr{}; | 
|  | 1238 | if (ifaddr) | 
|  | 1239 | { | 
|  | 1240 | addr = ifaddr->address; | 
|  | 1241 | } | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1242 | ret.pack(stdplus::raw::asView<char>(addr)); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1243 | return responseSuccess(std::move(ret)); | 
|  | 1244 | } | 
|  | 1245 | case LanParam::IPSrc: | 
|  | 1246 | { | 
| William A. Kennington III | a8a2e5f | 2023-06-21 17:50:01 -0700 | [diff] [blame] | 1247 | auto src = channelCall<getEthProp<bool>>(channel, "DHCP4") | 
|  | 1248 | ? IPSrc::DHCP | 
|  | 1249 | : IPSrc::Static; | 
| William A. Kennington III | 7a0e5df | 2021-05-19 13:31:29 -0700 | [diff] [blame] | 1250 | ret.pack(types::enum_cast<uint4_t>(src), uint4_t{}); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1251 | return responseSuccess(std::move(ret)); | 
|  | 1252 | } | 
| William A. Kennington III | aab2023 | 2018-11-19 18:20:39 -0800 | [diff] [blame] | 1253 | case LanParam::MAC: | 
| William A. Kennington III | 39f94ef | 2018-11-19 22:36:16 -0800 | [diff] [blame] | 1254 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1255 | ether_addr mac = channelCall<getMACProperty>(channel); | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1256 | ret.pack(stdplus::raw::asView<char>(mac)); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1257 | return responseSuccess(std::move(ret)); | 
|  | 1258 | } | 
|  | 1259 | case LanParam::SubnetMask: | 
|  | 1260 | { | 
|  | 1261 | auto ifaddr = channelCall<getIfAddr4>(channel); | 
|  | 1262 | uint8_t prefix = AddrFamily<AF_INET>::defaultPrefix; | 
|  | 1263 | if (ifaddr) | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 1264 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1265 | prefix = ifaddr->prefix; | 
|  | 1266 | } | 
|  | 1267 | in_addr netmask = prefixToNetmask(prefix); | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1268 | ret.pack(stdplus::raw::asView<char>(netmask)); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1269 | return responseSuccess(std::move(ret)); | 
|  | 1270 | } | 
|  | 1271 | case LanParam::Gateway1: | 
|  | 1272 | { | 
|  | 1273 | auto gateway = | 
|  | 1274 | channelCall<getGatewayProperty<AF_INET>>(channel).value_or( | 
|  | 1275 | in_addr{}); | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1276 | ret.pack(stdplus::raw::asView<char>(gateway)); | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1277 | return responseSuccess(std::move(ret)); | 
|  | 1278 | } | 
| William A. Kennington III | 4bbc3db | 2019-04-15 00:02:10 -0700 | [diff] [blame] | 1279 | case LanParam::Gateway1MAC: | 
|  | 1280 | { | 
|  | 1281 | ether_addr mac{}; | 
|  | 1282 | auto neighbor = channelCall<getGatewayNeighbor<AF_INET>>(channel); | 
|  | 1283 | if (neighbor) | 
|  | 1284 | { | 
|  | 1285 | mac = neighbor->mac; | 
|  | 1286 | } | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1287 | ret.pack(stdplus::raw::asView<char>(mac)); | 
| William A. Kennington III | 4bbc3db | 2019-04-15 00:02:10 -0700 | [diff] [blame] | 1288 | return responseSuccess(std::move(ret)); | 
|  | 1289 | } | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1290 | case LanParam::VLANId: | 
|  | 1291 | { | 
|  | 1292 | uint16_t vlan = channelCall<getVLANProperty>(channel); | 
|  | 1293 | if (vlan != 0) | 
|  | 1294 | { | 
|  | 1295 | vlan |= VLAN_ENABLE_FLAG; | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 1296 | } | 
|  | 1297 | else | 
|  | 1298 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1299 | vlan = lastDisabledVlan[channel]; | 
| Ratan Gupta | b8e9955 | 2017-07-27 07:07:48 +0530 | [diff] [blame] | 1300 | } | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1301 | ret.pack(vlan); | 
|  | 1302 | return responseSuccess(std::move(ret)); | 
| Adriana Kobylak | 342df10 | 2016-02-10 13:48:16 -0600 | [diff] [blame] | 1303 | } | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1304 | case LanParam::CiphersuiteSupport: | 
| Johnathan Mantey | affadb5 | 2019-10-07 10:13:53 -0700 | [diff] [blame] | 1305 | { | 
| srikanta mondal | 1d8579c | 2020-04-15 17:13:25 +0000 | [diff] [blame] | 1306 | if (getChannelSessionSupport(channel) == | 
|  | 1307 | EChannelSessSupported::none) | 
|  | 1308 | { | 
|  | 1309 | return responseInvalidFieldRequest(); | 
|  | 1310 | } | 
| Johnathan Mantey | affadb5 | 2019-10-07 10:13:53 -0700 | [diff] [blame] | 1311 | if (!listInit) | 
|  | 1312 | { | 
|  | 1313 | return responseUnspecifiedError(); | 
|  | 1314 | } | 
|  | 1315 | ret.pack(static_cast<uint8_t>(cipherList.size() - 1)); | 
|  | 1316 | return responseSuccess(std::move(ret)); | 
|  | 1317 | } | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1318 | case LanParam::CiphersuiteEntries: | 
| Johnathan Mantey | affadb5 | 2019-10-07 10:13:53 -0700 | [diff] [blame] | 1319 | { | 
| srikanta mondal | 1d8579c | 2020-04-15 17:13:25 +0000 | [diff] [blame] | 1320 | if (getChannelSessionSupport(channel) == | 
|  | 1321 | EChannelSessSupported::none) | 
|  | 1322 | { | 
|  | 1323 | return responseInvalidFieldRequest(); | 
|  | 1324 | } | 
| Johnathan Mantey | affadb5 | 2019-10-07 10:13:53 -0700 | [diff] [blame] | 1325 | if (!listInit) | 
|  | 1326 | { | 
|  | 1327 | return responseUnspecifiedError(); | 
|  | 1328 | } | 
|  | 1329 | ret.pack(cipherList); | 
|  | 1330 | return responseSuccess(std::move(ret)); | 
|  | 1331 | } | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 1332 | case LanParam::IPFamilySupport: | 
|  | 1333 | { | 
|  | 1334 | std::bitset<8> support; | 
|  | 1335 | support[IPFamilySupportFlag::IPv6Only] = 0; | 
|  | 1336 | support[IPFamilySupportFlag::DualStack] = 1; | 
|  | 1337 | support[IPFamilySupportFlag::IPv6Alerts] = 1; | 
|  | 1338 | ret.pack(support); | 
|  | 1339 | return responseSuccess(std::move(ret)); | 
|  | 1340 | } | 
|  | 1341 | case LanParam::IPFamilyEnables: | 
|  | 1342 | { | 
|  | 1343 | ret.pack(static_cast<uint8_t>(IPFamilyEnables::DualStack)); | 
|  | 1344 | return responseSuccess(std::move(ret)); | 
|  | 1345 | } | 
|  | 1346 | case LanParam::IPv6Status: | 
|  | 1347 | { | 
|  | 1348 | ret.pack(MAX_IPV6_STATIC_ADDRESSES); | 
|  | 1349 | ret.pack(MAX_IPV6_DYNAMIC_ADDRESSES); | 
|  | 1350 | std::bitset<8> support; | 
|  | 1351 | support[IPv6StatusFlag::DHCP] = 1; | 
|  | 1352 | support[IPv6StatusFlag::SLAAC] = 1; | 
|  | 1353 | ret.pack(support); | 
|  | 1354 | return responseSuccess(std::move(ret)); | 
|  | 1355 | } | 
|  | 1356 | case LanParam::IPv6StaticAddresses: | 
|  | 1357 | { | 
|  | 1358 | if (set >= MAX_IPV6_STATIC_ADDRESSES) | 
|  | 1359 | { | 
|  | 1360 | return responseParmOutOfRange(); | 
|  | 1361 | } | 
|  | 1362 | getLanIPv6Address(ret, channel, set, originsV6Static); | 
|  | 1363 | return responseSuccess(std::move(ret)); | 
|  | 1364 | } | 
|  | 1365 | case LanParam::IPv6DynamicAddresses: | 
|  | 1366 | { | 
|  | 1367 | if (set >= MAX_IPV6_DYNAMIC_ADDRESSES) | 
|  | 1368 | { | 
|  | 1369 | return responseParmOutOfRange(); | 
|  | 1370 | } | 
|  | 1371 | getLanIPv6Address(ret, channel, set, originsV6Dynamic); | 
|  | 1372 | return responseSuccess(std::move(ret)); | 
|  | 1373 | } | 
|  | 1374 | case LanParam::IPv6RouterControl: | 
|  | 1375 | { | 
|  | 1376 | std::bitset<8> control; | 
| Johnathan Mantey | 3b7a407 | 2021-01-26 14:24:53 -0800 | [diff] [blame] | 1377 | control[IPv6RouterControlFlag::Dynamic] = | 
| William A. Kennington III | a8a2e5f | 2023-06-21 17:50:01 -0700 | [diff] [blame] | 1378 | channelCall<getEthProp<bool>>(channel, "IPv6AcceptRA"); | 
| Johnathan Mantey | 3b7a407 | 2021-01-26 14:24:53 -0800 | [diff] [blame] | 1379 | control[IPv6RouterControlFlag::Static] = 1; | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 1380 | ret.pack(control); | 
|  | 1381 | return responseSuccess(std::move(ret)); | 
|  | 1382 | } | 
|  | 1383 | case LanParam::IPv6StaticRouter1IP: | 
|  | 1384 | { | 
|  | 1385 | in6_addr gateway{}; | 
| William A. Kennington III | a8a2e5f | 2023-06-21 17:50:01 -0700 | [diff] [blame] | 1386 | if (!channelCall<getEthProp<bool>>(channel, "IPv6AcceptRA")) | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 1387 | { | 
|  | 1388 | gateway = | 
|  | 1389 | channelCall<getGatewayProperty<AF_INET6>>(channel).value_or( | 
|  | 1390 | in6_addr{}); | 
|  | 1391 | } | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1392 | ret.pack(stdplus::raw::asView<char>(gateway)); | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 1393 | return responseSuccess(std::move(ret)); | 
|  | 1394 | } | 
|  | 1395 | case LanParam::IPv6StaticRouter1MAC: | 
|  | 1396 | { | 
|  | 1397 | ether_addr mac{}; | 
|  | 1398 | auto neighbor = channelCall<getGatewayNeighbor<AF_INET6>>(channel); | 
|  | 1399 | if (neighbor) | 
|  | 1400 | { | 
|  | 1401 | mac = neighbor->mac; | 
|  | 1402 | } | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1403 | ret.pack(stdplus::raw::asView<char>(mac)); | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 1404 | return responseSuccess(std::move(ret)); | 
|  | 1405 | } | 
|  | 1406 | case LanParam::IPv6StaticRouter1PrefixLength: | 
|  | 1407 | { | 
|  | 1408 | ret.pack(UINT8_C(0)); | 
|  | 1409 | return responseSuccess(std::move(ret)); | 
|  | 1410 | } | 
|  | 1411 | case LanParam::IPv6StaticRouter1PrefixValue: | 
|  | 1412 | { | 
|  | 1413 | in6_addr prefix{}; | 
| William A. Kennington III | 7a3831b | 2023-06-21 01:10:49 -0700 | [diff] [blame^] | 1414 | ret.pack(stdplus::raw::asView<char>(prefix)); | 
| William A. Kennington III | 16064aa | 2019-04-13 17:44:53 -0700 | [diff] [blame] | 1415 | return responseSuccess(std::move(ret)); | 
|  | 1416 | } | 
| jayaprakash Mutyala | b741b99 | 2019-12-02 17:29:09 +0000 | [diff] [blame] | 1417 | case LanParam::cipherSuitePrivilegeLevels: | 
|  | 1418 | { | 
|  | 1419 | std::array<uint4_t, ipmi::maxCSRecords> csPrivilegeLevels; | 
|  | 1420 |  | 
|  | 1421 | uint8_t resp = | 
|  | 1422 | getCipherConfigObject(csPrivFileName, csPrivDefaultFileName) | 
|  | 1423 | .getCSPrivilegeLevels(channel, csPrivilegeLevels); | 
|  | 1424 | if (!resp) | 
|  | 1425 | { | 
|  | 1426 | constexpr uint8_t reserved1 = 0x00; | 
|  | 1427 | ret.pack(reserved1, csPrivilegeLevels); | 
|  | 1428 | return responseSuccess(std::move(ret)); | 
|  | 1429 | } | 
|  | 1430 | else | 
|  | 1431 | { | 
|  | 1432 | return response(resp); | 
|  | 1433 | } | 
|  | 1434 | } | 
| Adriana Kobylak | 5d6481f | 2015-10-29 21:44:55 -0500 | [diff] [blame] | 1435 | } | 
|  | 1436 |  | 
| Johnathan Mantey | b87034e | 2019-09-16 10:50:50 -0700 | [diff] [blame] | 1437 | if ((parameter >= oemCmdStart) && (parameter <= oemCmdEnd)) | 
|  | 1438 | { | 
|  | 1439 | return getLanOem(channel, parameter, set, block); | 
|  | 1440 | } | 
|  | 1441 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1442 | return response(ccParamNotSupported); | 
| Adriana Kobylak | 5d6481f | 2015-10-29 21:44:55 -0500 | [diff] [blame] | 1443 | } | 
|  | 1444 |  | 
| Jian Zhang | 23f4465 | 2022-03-17 17:13:10 +0800 | [diff] [blame] | 1445 | constexpr const char* solInterface = "xyz.openbmc_project.Ipmi.SOL"; | 
|  | 1446 | constexpr const char* solPath = "/xyz/openbmc_project/ipmi/sol/"; | 
|  | 1447 | constexpr const uint16_t solDefaultPort = 623; | 
|  | 1448 |  | 
|  | 1449 | RspType<> setSolConfParams(Context::ptr ctx, uint4_t channelBits, | 
| Willy Tu | 11d6889 | 2022-01-20 10:37:34 -0800 | [diff] [blame] | 1450 | uint4_t /*reserved*/, uint8_t parameter, | 
| Jian Zhang | 23f4465 | 2022-03-17 17:13:10 +0800 | [diff] [blame] | 1451 | message::Payload& req) | 
|  | 1452 | { | 
|  | 1453 | const uint8_t channel = convertCurrentChannelNum( | 
|  | 1454 | static_cast<uint8_t>(channelBits), ctx->channel); | 
|  | 1455 |  | 
|  | 1456 | if (!isValidChannel(channel)) | 
|  | 1457 | { | 
|  | 1458 | log<level::ERR>("Set Sol Config - Invalid channel in request"); | 
|  | 1459 | return responseInvalidFieldRequest(); | 
|  | 1460 | } | 
|  | 1461 |  | 
|  | 1462 | std::string solService{}; | 
|  | 1463 | std::string solPathWitheEthName = solPath + ipmi::getChannelName(channel); | 
|  | 1464 |  | 
|  | 1465 | if (ipmi::getService(ctx, solInterface, solPathWitheEthName, solService)) | 
|  | 1466 | { | 
|  | 1467 | log<level::ERR>("Set Sol Config - Invalid solInterface", | 
|  | 1468 | entry("SERVICE=%s", solService.c_str()), | 
|  | 1469 | entry("OBJPATH=%s", solPathWitheEthName.c_str()), | 
|  | 1470 | entry("INTERFACE=%s", solInterface)); | 
|  | 1471 | return responseInvalidFieldRequest(); | 
|  | 1472 | } | 
|  | 1473 |  | 
|  | 1474 | switch (static_cast<SolConfParam>(parameter)) | 
|  | 1475 | { | 
|  | 1476 | case SolConfParam::Progress: | 
|  | 1477 | { | 
|  | 1478 | uint8_t progress; | 
|  | 1479 | if (req.unpack(progress) != 0 || !req.fullyUnpacked()) | 
|  | 1480 | { | 
|  | 1481 | return responseReqDataLenInvalid(); | 
|  | 1482 | } | 
|  | 1483 |  | 
|  | 1484 | if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName, | 
|  | 1485 | solInterface, "Progress", progress)) | 
|  | 1486 | { | 
|  | 1487 | return responseUnspecifiedError(); | 
|  | 1488 | } | 
|  | 1489 | break; | 
|  | 1490 | } | 
|  | 1491 | case SolConfParam::Enable: | 
|  | 1492 | { | 
|  | 1493 | bool enable; | 
|  | 1494 | uint7_t reserved2; | 
|  | 1495 |  | 
|  | 1496 | if (req.unpack(enable, reserved2) != 0 || !req.fullyUnpacked()) | 
|  | 1497 | { | 
|  | 1498 | return responseReqDataLenInvalid(); | 
|  | 1499 | } | 
|  | 1500 |  | 
|  | 1501 | if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName, | 
|  | 1502 | solInterface, "Enable", enable)) | 
|  | 1503 | { | 
|  | 1504 | return responseUnspecifiedError(); | 
|  | 1505 | } | 
|  | 1506 | break; | 
|  | 1507 | } | 
|  | 1508 | case SolConfParam::Authentication: | 
|  | 1509 | { | 
|  | 1510 | uint4_t privilegeBits{}; | 
|  | 1511 | uint2_t reserved2{}; | 
|  | 1512 | bool forceAuth = false; | 
|  | 1513 | bool forceEncrypt = false; | 
|  | 1514 |  | 
|  | 1515 | if (req.unpack(privilegeBits, reserved2, forceAuth, forceEncrypt) != | 
|  | 1516 | 0 || | 
|  | 1517 | !req.fullyUnpacked()) | 
|  | 1518 | { | 
|  | 1519 | return responseReqDataLenInvalid(); | 
|  | 1520 | } | 
|  | 1521 |  | 
|  | 1522 | uint8_t privilege = static_cast<uint8_t>(privilegeBits); | 
| Jonathan Doman | a48bf77 | 2023-05-26 17:54:57 -0700 | [diff] [blame] | 1523 | if (privilege < static_cast<uint8_t>(Privilege::User) || | 
| Jian Zhang | 23f4465 | 2022-03-17 17:13:10 +0800 | [diff] [blame] | 1524 | privilege > static_cast<uint8_t>(Privilege::Oem)) | 
|  | 1525 | { | 
|  | 1526 | return ipmi::responseInvalidFieldRequest(); | 
|  | 1527 | } | 
|  | 1528 |  | 
|  | 1529 | if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName, | 
|  | 1530 | solInterface, "Privilege", privilege)) | 
|  | 1531 | { | 
|  | 1532 | return responseUnspecifiedError(); | 
|  | 1533 | } | 
|  | 1534 |  | 
|  | 1535 | if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName, | 
|  | 1536 | solInterface, "ForceEncryption", | 
|  | 1537 | forceEncrypt)) | 
|  | 1538 | { | 
|  | 1539 | return responseUnspecifiedError(); | 
|  | 1540 | } | 
|  | 1541 |  | 
|  | 1542 | if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName, | 
|  | 1543 | solInterface, "ForceAuthentication", | 
|  | 1544 | forceAuth)) | 
|  | 1545 | { | 
|  | 1546 | return responseUnspecifiedError(); | 
|  | 1547 | } | 
|  | 1548 | break; | 
|  | 1549 | } | 
|  | 1550 | case SolConfParam::Accumulate: | 
|  | 1551 | { | 
|  | 1552 | uint8_t interval; | 
|  | 1553 | uint8_t threshold; | 
|  | 1554 | if (req.unpack(interval, threshold) != 0 || !req.fullyUnpacked()) | 
|  | 1555 | { | 
|  | 1556 | return responseReqDataLenInvalid(); | 
|  | 1557 | } | 
|  | 1558 |  | 
|  | 1559 | if (threshold == 0) | 
|  | 1560 | { | 
|  | 1561 | return responseInvalidFieldRequest(); | 
|  | 1562 | } | 
|  | 1563 |  | 
|  | 1564 | if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName, | 
|  | 1565 | solInterface, "AccumulateIntervalMS", | 
|  | 1566 | interval)) | 
|  | 1567 | { | 
|  | 1568 | return responseUnspecifiedError(); | 
|  | 1569 | } | 
|  | 1570 |  | 
|  | 1571 | if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName, | 
|  | 1572 | solInterface, "Threshold", threshold)) | 
|  | 1573 | { | 
|  | 1574 | return responseUnspecifiedError(); | 
|  | 1575 | } | 
|  | 1576 | break; | 
|  | 1577 | } | 
|  | 1578 | case SolConfParam::Retry: | 
|  | 1579 | { | 
|  | 1580 | uint3_t countBits; | 
|  | 1581 | uint5_t reserved2; | 
|  | 1582 | uint8_t interval; | 
|  | 1583 |  | 
|  | 1584 | if (req.unpack(countBits, reserved2, interval) != 0 || | 
|  | 1585 | !req.fullyUnpacked()) | 
|  | 1586 | { | 
|  | 1587 | return responseReqDataLenInvalid(); | 
|  | 1588 | } | 
|  | 1589 |  | 
|  | 1590 | uint8_t count = static_cast<uint8_t>(countBits); | 
|  | 1591 | if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName, | 
|  | 1592 | solInterface, "RetryCount", count)) | 
|  | 1593 | { | 
|  | 1594 | return responseUnspecifiedError(); | 
|  | 1595 | } | 
|  | 1596 |  | 
|  | 1597 | if (ipmi::setDbusProperty(ctx, solService, solPathWitheEthName, | 
|  | 1598 | solInterface, "RetryIntervalMS", | 
|  | 1599 | interval)) | 
|  | 1600 | { | 
|  | 1601 | return responseUnspecifiedError(); | 
|  | 1602 | } | 
|  | 1603 | break; | 
|  | 1604 | } | 
|  | 1605 | case SolConfParam::Port: | 
|  | 1606 | { | 
|  | 1607 | return response(ipmiCCWriteReadParameter); | 
|  | 1608 | } | 
|  | 1609 | case SolConfParam::NonVbitrate: | 
|  | 1610 | case SolConfParam::Vbitrate: | 
|  | 1611 | case SolConfParam::Channel: | 
|  | 1612 | default: | 
|  | 1613 | return response(ipmiCCParamNotSupported); | 
|  | 1614 | } | 
|  | 1615 | return responseSuccess(); | 
|  | 1616 | } | 
|  | 1617 |  | 
|  | 1618 | RspType<message::Payload> getSolConfParams(Context::ptr ctx, | 
|  | 1619 | uint4_t channelBits, | 
| Willy Tu | 11d6889 | 2022-01-20 10:37:34 -0800 | [diff] [blame] | 1620 | uint3_t /*reserved*/, bool revOnly, | 
|  | 1621 | uint8_t parameter, uint8_t /*set*/, | 
|  | 1622 | uint8_t /*block*/) | 
| Jian Zhang | 23f4465 | 2022-03-17 17:13:10 +0800 | [diff] [blame] | 1623 | { | 
|  | 1624 | message::Payload ret; | 
|  | 1625 | constexpr uint8_t current_revision = 0x11; | 
|  | 1626 | ret.pack(current_revision); | 
|  | 1627 | if (revOnly) | 
|  | 1628 | { | 
|  | 1629 | return responseSuccess(std::move(ret)); | 
|  | 1630 | } | 
|  | 1631 |  | 
|  | 1632 | const uint8_t channel = convertCurrentChannelNum( | 
|  | 1633 | static_cast<uint8_t>(channelBits), ctx->channel); | 
|  | 1634 |  | 
|  | 1635 | if (!isValidChannel(channel)) | 
|  | 1636 | { | 
|  | 1637 | log<level::ERR>("Get Sol Config - Invalid channel in request"); | 
|  | 1638 | return responseInvalidFieldRequest(); | 
|  | 1639 | } | 
|  | 1640 |  | 
|  | 1641 | std::string solService{}; | 
|  | 1642 | std::string solPathWitheEthName = solPath + ipmi::getChannelName(channel); | 
|  | 1643 |  | 
|  | 1644 | if (ipmi::getService(ctx, solInterface, solPathWitheEthName, solService)) | 
|  | 1645 | { | 
|  | 1646 | log<level::ERR>("Set Sol Config - Invalid solInterface", | 
|  | 1647 | entry("SERVICE=%s", solService.c_str()), | 
|  | 1648 | entry("OBJPATH=%s", solPathWitheEthName.c_str()), | 
|  | 1649 | entry("INTERFACE=%s", solInterface)); | 
|  | 1650 | return responseInvalidFieldRequest(); | 
|  | 1651 | } | 
|  | 1652 |  | 
|  | 1653 | switch (static_cast<SolConfParam>(parameter)) | 
|  | 1654 | { | 
|  | 1655 | case SolConfParam::Progress: | 
|  | 1656 | { | 
|  | 1657 | uint8_t progress; | 
|  | 1658 | if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName, | 
|  | 1659 | solInterface, "Progress", progress)) | 
|  | 1660 | { | 
|  | 1661 | return responseUnspecifiedError(); | 
|  | 1662 | } | 
|  | 1663 | ret.pack(progress); | 
|  | 1664 | return responseSuccess(std::move(ret)); | 
|  | 1665 | } | 
|  | 1666 | case SolConfParam::Enable: | 
|  | 1667 | { | 
|  | 1668 | bool enable{}; | 
|  | 1669 | if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName, | 
|  | 1670 | solInterface, "Enable", enable)) | 
|  | 1671 | { | 
|  | 1672 | return responseUnspecifiedError(); | 
|  | 1673 | } | 
|  | 1674 | ret.pack(enable, uint7_t{}); | 
|  | 1675 | return responseSuccess(std::move(ret)); | 
|  | 1676 | } | 
|  | 1677 | case SolConfParam::Authentication: | 
|  | 1678 | { | 
|  | 1679 | // 4bits, cast when pack | 
|  | 1680 | uint8_t privilege; | 
|  | 1681 | bool forceAuth = false; | 
|  | 1682 | bool forceEncrypt = false; | 
|  | 1683 |  | 
|  | 1684 | if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName, | 
|  | 1685 | solInterface, "Privilege", privilege)) | 
|  | 1686 | { | 
|  | 1687 | return responseUnspecifiedError(); | 
|  | 1688 | } | 
|  | 1689 |  | 
|  | 1690 | if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName, | 
|  | 1691 | solInterface, "ForceAuthentication", | 
|  | 1692 | forceAuth)) | 
|  | 1693 | { | 
|  | 1694 | return responseUnspecifiedError(); | 
|  | 1695 | } | 
|  | 1696 |  | 
|  | 1697 | if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName, | 
|  | 1698 | solInterface, "ForceEncryption", | 
|  | 1699 | forceEncrypt)) | 
|  | 1700 | { | 
|  | 1701 | return responseUnspecifiedError(); | 
|  | 1702 | } | 
|  | 1703 | ret.pack(uint4_t{privilege}, uint2_t{}, forceAuth, forceEncrypt); | 
|  | 1704 | return responseSuccess(std::move(ret)); | 
|  | 1705 | } | 
|  | 1706 | case SolConfParam::Accumulate: | 
|  | 1707 | { | 
|  | 1708 | uint8_t interval{}, threshold{}; | 
|  | 1709 |  | 
|  | 1710 | if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName, | 
|  | 1711 | solInterface, "AccumulateIntervalMS", | 
|  | 1712 | interval)) | 
|  | 1713 | { | 
|  | 1714 | return responseUnspecifiedError(); | 
|  | 1715 | } | 
|  | 1716 |  | 
|  | 1717 | if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName, | 
|  | 1718 | solInterface, "Threshold", threshold)) | 
|  | 1719 | { | 
|  | 1720 | return responseUnspecifiedError(); | 
|  | 1721 | } | 
|  | 1722 | ret.pack(interval, threshold); | 
|  | 1723 | return responseSuccess(std::move(ret)); | 
|  | 1724 | } | 
|  | 1725 | case SolConfParam::Retry: | 
|  | 1726 | { | 
|  | 1727 | // 3bits, cast when cast | 
|  | 1728 | uint8_t count{}; | 
|  | 1729 | uint8_t interval{}; | 
|  | 1730 |  | 
|  | 1731 | if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName, | 
|  | 1732 | solInterface, "RetryCount", count)) | 
|  | 1733 | { | 
|  | 1734 | return responseUnspecifiedError(); | 
|  | 1735 | } | 
|  | 1736 |  | 
|  | 1737 | if (ipmi::getDbusProperty(ctx, solService, solPathWitheEthName, | 
|  | 1738 | solInterface, "RetryIntervalMS", | 
|  | 1739 | interval)) | 
|  | 1740 | { | 
|  | 1741 | return responseUnspecifiedError(); | 
|  | 1742 | } | 
|  | 1743 | ret.pack(uint3_t{count}, uint5_t{}, interval); | 
|  | 1744 | return responseSuccess(std::move(ret)); | 
|  | 1745 | } | 
|  | 1746 | case SolConfParam::Port: | 
|  | 1747 | { | 
|  | 1748 | auto port = solDefaultPort; | 
|  | 1749 | ret.pack(static_cast<uint16_t>(port)); | 
|  | 1750 | return responseSuccess(std::move(ret)); | 
|  | 1751 | } | 
|  | 1752 | case SolConfParam::Channel: | 
|  | 1753 | { | 
|  | 1754 | ret.pack(channel); | 
|  | 1755 | return responseSuccess(std::move(ret)); | 
|  | 1756 | } | 
|  | 1757 | case SolConfParam::NonVbitrate: | 
| Jonathan Doman | a48bf77 | 2023-05-26 17:54:57 -0700 | [diff] [blame] | 1758 | { | 
|  | 1759 | uint64_t baudRate; | 
|  | 1760 | uint8_t encodedBitRate = 0; | 
|  | 1761 | if (ipmi::getDbusProperty( | 
|  | 1762 | ctx, "xyz.openbmc_project.Console.default", | 
|  | 1763 | "/xyz/openbmc_project/console/default", | 
|  | 1764 | "xyz.openbmc_project.Console.UART", "Baud", baudRate)) | 
|  | 1765 | { | 
|  | 1766 | return ipmi::responseUnspecifiedError(); | 
|  | 1767 | } | 
|  | 1768 | switch (baudRate) | 
|  | 1769 | { | 
|  | 1770 | case 9600: | 
|  | 1771 | encodedBitRate = 0x06; | 
|  | 1772 | break; | 
|  | 1773 | case 19200: | 
|  | 1774 | encodedBitRate = 0x07; | 
|  | 1775 | break; | 
|  | 1776 | case 38400: | 
|  | 1777 | encodedBitRate = 0x08; | 
|  | 1778 | break; | 
|  | 1779 | case 57600: | 
|  | 1780 | encodedBitRate = 0x09; | 
|  | 1781 | break; | 
|  | 1782 | case 115200: | 
|  | 1783 | encodedBitRate = 0x0a; | 
|  | 1784 | break; | 
|  | 1785 | default: | 
|  | 1786 | break; | 
|  | 1787 | } | 
|  | 1788 | ret.pack(encodedBitRate); | 
|  | 1789 | return responseSuccess(std::move(ret)); | 
|  | 1790 | } | 
| Jian Zhang | 23f4465 | 2022-03-17 17:13:10 +0800 | [diff] [blame] | 1791 | case SolConfParam::Vbitrate: | 
|  | 1792 | default: | 
|  | 1793 | return response(ipmiCCParamNotSupported); | 
|  | 1794 | } | 
|  | 1795 |  | 
|  | 1796 | return response(ccParamNotSupported); | 
|  | 1797 | } | 
|  | 1798 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1799 | } // namespace transport | 
|  | 1800 | } // namespace ipmi | 
| Ratan Gupta | 1247e0b | 2018-03-07 10:47:25 +0530 | [diff] [blame] | 1801 |  | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1802 | void register_netfn_transport_functions() __attribute__((constructor)); | 
| Ratan Gupta | 1247e0b | 2018-03-07 10:47:25 +0530 | [diff] [blame] | 1803 |  | 
| Adriana Kobylak | 5d6481f | 2015-10-29 21:44:55 -0500 | [diff] [blame] | 1804 | void register_netfn_transport_functions() | 
|  | 1805 | { | 
| William A. Kennington III | c514d87 | 2019-04-06 18:19:38 -0700 | [diff] [blame] | 1806 | ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnTransport, | 
|  | 1807 | ipmi::transport::cmdSetLanConfigParameters, | 
|  | 1808 | ipmi::Privilege::Admin, ipmi::transport::setLan); | 
|  | 1809 | ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnTransport, | 
|  | 1810 | ipmi::transport::cmdGetLanConfigParameters, | 
| Johnathan Mantey | 34698d5 | 2019-11-19 14:47:30 -0800 | [diff] [blame] | 1811 | ipmi::Privilege::Operator, ipmi::transport::getLan); | 
| Jian Zhang | 23f4465 | 2022-03-17 17:13:10 +0800 | [diff] [blame] | 1812 | ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnTransport, | 
|  | 1813 | ipmi::transport::cmdSetSolConfigParameters, | 
|  | 1814 | ipmi::Privilege::Admin, | 
|  | 1815 | ipmi::transport::setSolConfParams); | 
|  | 1816 | ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnTransport, | 
|  | 1817 | ipmi::transport::cmdGetSolConfigParameters, | 
|  | 1818 | ipmi::Privilege::User, | 
|  | 1819 | ipmi::transport::getSolConfParams); | 
| Adriana Kobylak | 5d6481f | 2015-10-29 21:44:55 -0500 | [diff] [blame] | 1820 | } |