From b5a0f16dca8324492a8b2bd69c82f3438e02fa16 Mon Sep 17 00:00:00 2001 From: Saravanan Palanisamy Date: Mon, 4 Mar 2019 18:34:44 +0530 Subject: Add: Get channel payload support command Implemented Get Channel Payload Support command (IPMI Spec sec 24.8) The same is implemented under channel commands, and will be available for both Host & Net ipmid. Uses channel configuration to differentiate between session / session-less channel Tested-by: 1. Verified command executed successfully for session based channel ipmitool raw 6 0x4E 0x1 // Command 03 00 15 00 00 00 00 00 // Response 2. Verified sessionless channel error is returned. Change-Id: I8b294234415b4467aeae6c23c192750471536f4e Signed-off-by: Saravanan Palanisamy Signed-off-by: Richard Marian Thomaiyar --- host-ipmid-whitelist.conf | 1 + user_channel/channel_layer.hpp | 18 +++++++ user_channel/channelcommands.cpp | 109 +++++++++++++++++++++++++++++++++++++++ user_channel/channelcommands.hpp | 1 + 4 files changed, 129 insertions(+) diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf index 7ac432c..961214d 100644 --- a/host-ipmid-whitelist.conf +++ b/host-ipmid-whitelist.conf @@ -26,6 +26,7 @@ 0x06:0x36 //: 0x06:0x37 //: 0x06:0x42 //: +0x06:0x4E //: 0x06:0x54 //: 0x0A:0x10 //: 0x0A:0x11 //: diff --git a/user_channel/channel_layer.hpp b/user_channel/channel_layer.hpp index 94570fb..1a8d64c 100644 --- a/user_channel/channel_layer.hpp +++ b/user_channel/channel_layer.hpp @@ -112,6 +112,24 @@ enum class EAuthType : uint8_t oem = (1 << 0x5), }; +// TODO: Remove duplicate 'PayloadType' definition from netipmid's message.hpp +// to phosphor-ipmi-host/include +/** + * @enum Payload Types (refer spec sec 13.27.3) + */ +enum class PayloadType : uint8_t +{ + IPMI = 0x00, + SOL = 0x01, + OPEN_SESSION_REQUEST = 0x10, + OPEN_SESSION_RESPONSE = 0x11, + RAKP1 = 0x12, + RAKP2 = 0x13, + RAKP3 = 0x14, + RAKP4 = 0x15, + INVALID = 0xFF, +}; + /** * @enum Access mode for channel access set/get (refer spec * sec 22.22 - request byte 2[7:6]) diff --git a/user_channel/channelcommands.cpp b/user_channel/channelcommands.cpp index 546adb0..d1b275e 100644 --- a/user_channel/channelcommands.cpp +++ b/user_channel/channelcommands.cpp @@ -152,6 +152,36 @@ struct GetChannelInfoResp uint8_t auxChInfo[2]; } __attribute__((packed)); +/** @struct GetChannelPayloadSupportReq + * + * Structure for get channel payload support command request (refer spec + * sec 24.8) + */ +struct GetChannelPayloadSupportReq +{ +#if BYTE_ORDER == LITTLE_ENDIAN + uint8_t chNum : 4; + uint8_t reserved : 4; +#endif +#if BYTE_ORDER == BIG_ENDIAN + uint8_t reserved : 4; + uint8_t chNum : 4; +#endif +} __attribute__((packed)); + +/** @struct GetChannelPayloadSupportResp + * + * Structure for get channel payload support command response (refer spec + * sec 24.8) + */ +struct GetChannelPayloadSupportResp +{ + uint8_t stdPayloadType[2]; + uint8_t sessSetupPayloadType[2]; + uint8_t OEMPayloadType[2]; + uint8_t reserved[2]; +} __attribute__((packed)); + ipmi_ret_t ipmiSetChannelAccess(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request, ipmi_response_t response, @@ -390,6 +420,81 @@ ipmi_ret_t ipmiGetChannelInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd, return IPMI_CC_OK; } +ipmi_ret_t ipmiGetChannelPayloadSupport(ipmi_netfn_t netfn, ipmi_cmd_t cmd, + ipmi_request_t request, + ipmi_response_t response, + ipmi_data_len_t data_len, + ipmi_context_t context) +{ + const auto req = static_cast(request); + size_t reqLength = *data_len; + + *data_len = 0; + + if (reqLength != sizeof(*req)) + { + log("Get channel payload - Invalid Length"); + return IPMI_CC_REQ_DATA_LEN_INVALID; + } + + uint8_t chNum = convertCurrentChannelNum(req->chNum); + if (!isValidChannel(chNum) || req->reserved != 0) + { + log("Get channel payload - Invalid field in request"); + return IPMI_CC_INVALID_FIELD_REQUEST; + } + + // Not supported on sessionless channels. + if (EChannelSessSupported::none == getChannelSessionSupport(chNum)) + { + log("Get channel payload - Sessionless Channel"); + return IPMI_CC_INVALID_FIELD_REQUEST; + } + + // Session support is available in active LAN channels. + if ((EChannelSessSupported::none != getChannelSessionSupport(chNum)) && + (!(doesDeviceExist(chNum)))) + { + log("Get channel payload - Device not exist"); + return IPMI_CC_INVALID_FIELD_REQUEST; + } + + auto resp = static_cast(response); + + std::fill(reinterpret_cast(resp), + reinterpret_cast(resp) + sizeof(*resp), 0); + + // TODO: Hard coding for now. + // Mapping PayloadTypes to 'GetChannelPayloadSupportResp' fields: + // -------------------------------------------------------------- + // Mask all except least 3 significant bits to get a value in the range of + // 0-7. This value maps to the bit position of given payload type in 'resp' + // fields. + + static constexpr uint8_t payloadByteMask = 0x07; + static constexpr uint8_t stdPayloadTypeIPMI = + 1 << (static_cast(PayloadType::IPMI) & payloadByteMask); + static constexpr uint8_t stdPayloadTypeSOL = + 1 << (static_cast(PayloadType::SOL) & payloadByteMask); + + static constexpr uint8_t sessPayloadTypeOpenReq = + 1 << (static_cast(PayloadType::OPEN_SESSION_REQUEST) & + payloadByteMask); + static constexpr uint8_t sessPayloadTypeRAKP1 = + 1 << (static_cast(PayloadType::RAKP1) & payloadByteMask); + static constexpr uint8_t sessPayloadTypeRAKP3 = + 1 << (static_cast(PayloadType::RAKP3) & payloadByteMask); + + resp->stdPayloadType[0] = stdPayloadTypeIPMI | stdPayloadTypeSOL; + // RMCP+ Open Session request, RAKP Message1 and RAKP Message3. + resp->sessSetupPayloadType[0] = + sessPayloadTypeOpenReq | sessPayloadTypeRAKP1 | sessPayloadTypeRAKP3; + + *data_len = sizeof(*resp); + + return IPMI_CC_OK; +} + void registerChannelFunctions() __attribute__((constructor)); void registerChannelFunctions() { @@ -403,6 +508,10 @@ void registerChannelFunctions() ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHANNEL_INFO, NULL, ipmiGetChannelInfo, PRIVILEGE_USER); + + ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHANNEL_PAYLOAD_SUPPORT, + NULL, ipmiGetChannelPayloadSupport, PRIVILEGE_USER); + return; } diff --git a/user_channel/channelcommands.hpp b/user_channel/channelcommands.hpp index c612d3f..abcead6 100644 --- a/user_channel/channelcommands.hpp +++ b/user_channel/channelcommands.hpp @@ -28,6 +28,7 @@ enum ipmi_netfn_channel_cmds IPMI_CMD_SET_CHANNEL_ACCESS = 0x40, IPMI_CMD_GET_CHANNEL_ACCESS = 0x41, IPMI_CMD_GET_CHANNEL_INFO = 0x42, + IPMI_CMD_GET_CHANNEL_PAYLOAD_SUPPORT = 0x4E, }; void registerChannelFunctions(); -- cgit v1.2.1