diff options
author | Jason M. Bills <jason.m.bills@linux.intel.com> | 2020-02-28 02:57:13 +0300 |
---|---|---|
committer | Jason M. Bills <jason.m.bills@linux.intel.com> | 2020-03-02 22:06:57 +0300 |
commit | 6c1caca70063aa707ba809a6b4695d0f0c5646f1 (patch) | |
tree | 84da2f29a60cb571686d3a4fb93f9d1f1189d989 /meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0009-IPv6-Network-changes.patch | |
parent | 9600a7403ba2848c8751280077503a3e0f2f3481 (diff) | |
download | openbmc-6c1caca70063aa707ba809a6b4695d0f0c5646f1.tar.xz |
Update to internal 2020-02-27
Signed-off-by: Jason M. Bills <jason.m.bills@linux.intel.com>
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0009-IPv6-Network-changes.patch')
-rw-r--r-- | meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0009-IPv6-Network-changes.patch | 877 |
1 files changed, 0 insertions, 877 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0009-IPv6-Network-changes.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0009-IPv6-Network-changes.patch deleted file mode 100644 index c862a306a..000000000 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0009-IPv6-Network-changes.patch +++ /dev/null @@ -1,877 +0,0 @@ -From c20bc8eb6a08d177d951012eb91b37398b15d81d Mon Sep 17 00:00:00 2001 -From: Vernon Mauery <vernon.mauery@linux.intel.com> -Date: Tue, 27 Nov 2018 11:01:15 -0800 -Subject: [PATCH] IPv6 Network changes - -Allow IPv6 IPMI set/get commands - -Signed-off-by: David Cobbley <david.j.cobbley@linux.intel.com> -Signed-off-by: Yong Li <yong.b.li@linux.intel.com> -Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com> - -Change-Id: If5528d3b7294c5f8c17db5919439235d0fad0446 ---- - include/ipmid/types.hpp | 9 + - include/ipmid/utils.hpp | 1 + - transporthandler.cpp | 654 +++++++++++++++++++++++++++++++++++++++- - transporthandler.hpp | 50 +++ - 4 files changed, 713 insertions(+), 1 deletion(-) - -Index: phosphor-host-ipmid.clean/include/ipmid/types.hpp -=================================================================== ---- phosphor-host-ipmid.clean.orig/include/ipmid/types.hpp -+++ phosphor-host-ipmid.clean/include/ipmid/types.hpp -@@ -224,6 +224,7 @@ constexpr auto ADDR_TYPE_FORMAT = "%hhx" - - constexpr auto IPV4_ADDRESS_SIZE_BYTE = 4; - constexpr auto IPV6_ADDRESS_SIZE_BYTE = 16; -+constexpr auto IPV6_ADDRESS_STATUS_SIZE = 22; - - constexpr auto DEFAULT_MAC_ADDRESS = "00:00:00:00:00:00"; - constexpr auto DEFAULT_ADDRESS = "0.0.0.0"; -@@ -235,6 +236,7 @@ constexpr auto BITS_32 = 32; - constexpr auto MASK_32_BIT = 0xFFFFFFFF; - constexpr auto VLAN_ID_MASK = 0x00000FFF; - constexpr auto VLAN_ENABLE_MASK = 0x8000; -+constexpr auto IPV6_DUID_SIZE = 18; - - enum class IPOrigin : uint8_t - { -@@ -243,5 +245,12 @@ enum class IPOrigin : uint8_t - DHCP = 2, - }; - -+enum class AddressingEnables : uint8_t -+{ -+ IPv4Only = 0, -+ IPv6Only = 1, -+ IPv4AndIPv6 = 2, -+}; -+ - } // namespace network - } // namespace ipmi -Index: phosphor-host-ipmid.clean/include/ipmid/utils.hpp -=================================================================== ---- phosphor-host-ipmid.clean.orig/include/ipmid/utils.hpp -+++ phosphor-host-ipmid.clean/include/ipmid/utils.hpp -@@ -256,6 +256,7 @@ namespace network - constexpr auto ROOT = "/xyz/openbmc_project/network"; - constexpr auto SERVICE = "xyz.openbmc_project.Network"; - constexpr auto IP_TYPE = "ipv4"; -+constexpr auto IPV6_TYPE = "ipv6"; - constexpr auto IPV4_PREFIX = "169.254"; - constexpr auto IPV6_PREFIX = "fe80"; - constexpr auto IP_INTERFACE = "xyz.openbmc_project.Network.IP"; -Index: phosphor-host-ipmid.clean/transporthandler.cpp -=================================================================== ---- phosphor-host-ipmid.clean.orig/transporthandler.cpp -+++ phosphor-host-ipmid.clean/transporthandler.cpp -@@ -29,6 +29,12 @@ std::unique_ptr<phosphor::Timer> network - - const int SIZE_MAC = 18; // xx:xx:xx:xx:xx:xx - constexpr auto ipv4Protocol = "xyz.openbmc_project.Network.IP.Protocol.IPv4"; -+constexpr auto ipv6Protocol = "xyz.openbmc_project.Network.IP.Protocol.IPv6"; -+ -+static const std::array<std::string, 3> ipAddressEnablesType = { -+ "xyz.openbmc_project.Network.EthernetInterface.IPAllowed.IPv4Only", -+ "xyz.openbmc_project.Network.EthernetInterface.IPAllowed.IPv6Only", -+ "xyz.openbmc_project.Network.EthernetInterface.IPAllowed.IPv4AndIPv6"}; - - std::map<int, std::unique_ptr<struct ChannelConfig_t>> channelConfig; - -@@ -445,6 +451,11 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_n - { - case LanParam::IP: - { -+ if (reqLen != lanParamIPSize) -+ { -+ return IPMI_CC_REQ_DATA_LEN_INVALID; -+ } -+ - std::snprintf(ipaddr, INET_ADDRSTRLEN, - ipmi::network::IP_ADDRESS_FORMAT, reqptr->data[0], - reqptr->data[1], reqptr->data[2], reqptr->data[3]); -@@ -455,6 +466,11 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_n - - case LanParam::IPSRC: - { -+ if (reqLen != lanParamIPSrcSize) -+ { -+ return IPMI_CC_REQ_DATA_LEN_INVALID; -+ } -+ - uint8_t ipsrc{}; - std::memcpy(&ipsrc, reqptr->data, ipmi::network::IPSRC_SIZE_BYTE); - channelConf->ipsrc = static_cast<ipmi::network::IPOrigin>(ipsrc); -@@ -463,6 +479,11 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_n - - case LanParam::MAC: - { -+ if (reqLen != lanParamMACSize) -+ { -+ return IPMI_CC_REQ_DATA_LEN_INVALID; -+ } -+ - char mac[SIZE_MAC]; - - std::snprintf(mac, SIZE_MAC, ipmi::network::MAC_ADDRESS_FORMAT, -@@ -483,6 +504,11 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_n - - case LanParam::SUBNET: - { -+ if (reqLen != lanParamSubnetSize) -+ { -+ return IPMI_CC_REQ_DATA_LEN_INVALID; -+ } -+ - std::snprintf(netmask, INET_ADDRSTRLEN, - ipmi::network::IP_ADDRESS_FORMAT, reqptr->data[0], - reqptr->data[1], reqptr->data[2], reqptr->data[3]); -@@ -492,6 +518,11 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_n - - case LanParam::GATEWAY: - { -+ if (reqLen != lanParamGatewaySize) -+ { -+ return IPMI_CC_REQ_DATA_LEN_INVALID; -+ } -+ - std::snprintf(gateway, INET_ADDRSTRLEN, - ipmi::network::IP_ADDRESS_FORMAT, reqptr->data[0], - reqptr->data[1], reqptr->data[2], reqptr->data[3]); -@@ -522,6 +553,11 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_n - - case LanParam::INPROGRESS: - { -+ if (reqLen != lanParamInProgressSize) -+ { -+ return IPMI_CC_REQ_DATA_LEN_INVALID; -+ } -+ - if (reqptr->data[0] == SET_COMPLETE) - { - channelConf->lan_set_in_progress = SET_COMPLETE; -@@ -540,6 +576,122 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_n - } - break; - -+ case LanParam::IPV6_AND_IPV4_ENABLES: -+ { -+ if (reqLen != lanParamIPv6AndIPv4EnablesSize) -+ { -+ return IPMI_CC_REQ_DATA_LEN_INVALID; -+ } -+ -+ channelConf->ipv6AddressingEnables = reqptr->data[0]; -+ break; -+ } -+ -+ case LanParam::IPV6_STATIC_ADDRESSES: -+ { -+ if (reqLen != lanParamIPv6StaticAddressesSize) -+ { -+ return IPMI_CC_REQ_DATA_LEN_INVALID; -+ } -+ -+ channelConf->ipv6AddressSource = -+ reqptr->data[1] & 0x81; // Looking at bit 0 and bit 7 -+ char tmpIPV6[INET6_ADDRSTRLEN]; -+ inet_ntop(AF_INET6, &reqptr->data[2], tmpIPV6, INET6_ADDRSTRLEN); -+ channelConf->ipv6Addr.assign(tmpIPV6); -+ channelConf->ipv6Prefix = reqptr->data[19]; -+ break; -+ } -+ -+ case LanParam::IPV6_ROUTER_ADDRESS_CONF_CTRL: -+ { -+ if (reqLen != lanParamIPv6RouterAddressConfCtrlSize) -+ { -+ return IPMI_CC_REQ_DATA_LEN_INVALID; -+ } -+ -+ channelConf->ipv6RouterAddressConfigControl = reqptr->data[0]; -+ break; -+ } -+ -+ case LanParam::IPV6_STATIC_ROUTER_1_IP_ADDR: -+ { -+ if (reqLen != lanParamIPv6StaticRouter1IPAddrSize) -+ { -+ return IPMI_CC_REQ_DATA_LEN_INVALID; -+ } -+ -+ char tmpIPV6[INET6_ADDRSTRLEN]; -+ inet_ntop(AF_INET6, reinterpret_cast<const void*>(reqptr->data), -+ tmpIPV6, INET6_ADDRSTRLEN); -+ channelConf->ipv6GatewayAddr.assign(tmpIPV6); -+ break; -+ } -+ -+ case LanParam::IPV6_STATIC_ROUTER_1_PREFIX_LEN: -+ { -+ if (reqLen != lanParamIPv6StaticRouter1PrefixLenSize) -+ { -+ return IPMI_CC_REQ_DATA_LEN_INVALID; -+ } -+ -+ channelConf->ipv6GatewayPrefixLength = reqptr->data[0]; -+ break; -+ } -+ -+ case LanParam::IPV6_STATIC_ROUTER_1_PREFIX_VAL: -+ { -+ if (reqLen != lanParamIPv6StaticRouter1PrefixValSize) -+ { -+ return IPMI_CC_REQ_DATA_LEN_INVALID; -+ } -+ -+ char tmpIPV6[INET6_ADDRSTRLEN]; -+ inet_ntop(AF_INET6, reinterpret_cast<const void*>(reqptr->data), -+ tmpIPV6, INET6_ADDRSTRLEN); -+ channelConf->ipv6GatewayPrefixValue.assign(tmpIPV6); -+ break; -+ } -+ -+ case LanParam::IPV6_STATIC_ROUTER_2_IP_ADDR: -+ { -+ if (reqLen != lanParamIPv6StaticRouter2IPAddrSize) -+ { -+ return IPMI_CC_REQ_DATA_LEN_INVALID; -+ } -+ -+ char tmpIPV6[INET6_ADDRSTRLEN]; -+ inet_ntop(AF_INET6, reinterpret_cast<const void*>(reqptr->data), -+ tmpIPV6, INET6_ADDRSTRLEN); -+ channelConf->ipv6BackupGatewayAddr.assign(tmpIPV6); -+ break; -+ } -+ -+ case LanParam::IPV6_STATIC_ROUTER_2_PREFIX_LEN: -+ { -+ if (reqLen != lanParamIPv6StaticRouter2PrefixLenSize) -+ { -+ return IPMI_CC_REQ_DATA_LEN_INVALID; -+ } -+ -+ channelConf->ipv6BackupGatewayPrefixLength = reqptr->data[0]; -+ break; -+ } -+ -+ case LanParam::IPV6_STATIC_ROUTER_2_PREFIX_VAL: -+ { -+ if (reqLen != lanParamIPv6StaticRouter2PrefixValSize) -+ { -+ return IPMI_CC_REQ_DATA_LEN_INVALID; -+ } -+ -+ char tmpIPV6[INET6_ADDRSTRLEN]; -+ inet_ntop(AF_INET6, reinterpret_cast<const void*>(reqptr->data), -+ tmpIPV6, INET6_ADDRSTRLEN); -+ channelConf->ipv6BackupGatewayPrefixValue.assign(tmpIPV6); -+ break; -+ } -+ - default: - { - rc = IPMI_CC_PARM_NOT_SUPPORTED; -@@ -568,6 +720,7 @@ ipmi_ret_t ipmi_transport_get_lan(ipmi_n - ipmi_ret_t rc = IPMI_CC_OK; - *data_len = 0; - const uint8_t current_revision = 0x11; // Current rev per IPMI Spec 2.0 -+ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()}; - - get_lan_t* reqptr = (get_lan_t*)request; - // channel number is the lower nibble -@@ -713,6 +866,476 @@ ipmi_ret_t ipmi_transport_get_lan(ipmi_n - static_cast<uint8_t>(cipherList.size()); - break; - } -+ case LanParam::IPV6_AND_IPV4_SUPPORTED: -+ { -+ uint8_t addressSupport = -+ 0x1; // Allow both IPv4 & IPv6 simultaneously -+ std::array<uint8_t, 2> buf = {current_revision, addressSupport}; -+ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response)); -+ *data_len = buf.size(); -+ break; -+ } -+ case LanParam::IPV6_AND_IPV4_ENABLES: -+ { -+ // If DHCP, check if you have an ipv6 and ipv4 address. If static -+ // return not supported -+ -+ // 00h check if conf DHCP == ipv4 or off -+ // 01h check if conf DHCP == ipv6 -+ // 02h check if DHCP == true -+ -+ auto ethIP = ethdevice + "/" + ipmi::network::IPV6_TYPE; -+ std::string networkInterfacePath; -+ uint8_t ipVAddressEnables = 0; -+ -+ if (channelConf->lan_set_in_progress == SET_COMPLETE) -+ { -+ try -+ { -+ ipmi::ObjectTree ancestorMap; -+ // if the system has an ip object,then -+ // get the IP object. -+ auto ipObject = -+ ipmi::getDbusObject(bus, ipmi::network::IP_INTERFACE, -+ ipmi::network::ROOT, ethIP); -+ // Get the parent interface of the IP object. -+ try -+ { -+ ipmi::InterfaceList interfaces; -+ interfaces.emplace_back( -+ ipmi::network::ETHERNET_INTERFACE); -+ -+ ancestorMap = ipmi::getAllAncestors( -+ bus, ipObject.first, std::move(interfaces)); -+ } -+ catch (InternalFailure& e) -+ { -+ // if unable to get the parent interface -+ // then commit the error and return. -+ log<level::ERR>( -+ "Unable to get the parent interface", -+ entry("PATH=%s", ipObject.first.c_str()), -+ entry("INTERFACE=%s", -+ ipmi::network::ETHERNET_INTERFACE)); -+ return IPMI_CC_UNSPECIFIED_ERROR; -+ } -+ // for an ip object there would be single parent -+ // interface. -+ networkInterfacePath = ancestorMap.begin()->first; -+ } -+ catch (InternalFailure& e) -+ { -+ // if there is no ip configured on the system,then -+ // get the network interface object. -+ auto networkInterfaceObject = ipmi::getDbusObject( -+ bus, ipmi::network::ETHERNET_INTERFACE, -+ ipmi::network::ROOT, ethdevice); -+ -+ networkInterfacePath = networkInterfaceObject.first; -+ } -+ -+ ipmi::Value ipEnablesProp = ipmi::getDbusProperty( -+ bus, ipmi::network::SERVICE, networkInterfacePath, -+ ipmi::network::ETHERNET_INTERFACE, "IPAddressEnables"); -+ std::string ipEnables = std::get<std::string>(ipEnablesProp); -+ -+ // check if on off ipv4 ipv6, etc. -+ bool found = false; -+ for (uint8_t ii = 0; ii < ipAddressEnablesType.size(); ii++) -+ { -+ if (ipEnables == ipAddressEnablesType[ii]) -+ { -+ ipVAddressEnables = ii; -+ found = true; -+ break; -+ } -+ } -+ if (!found) -+ { -+ return IPMI_CC_PARM_NOT_SUPPORTED; -+ } -+ } -+ else -+ { -+ ipVAddressEnables = channelConf->ipv6AddressingEnables; -+ } -+ -+ std::array<uint8_t, 2> buf = {current_revision, ipVAddressEnables}; -+ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response)); -+ *data_len = buf.size(); -+ break; -+ } -+ case LanParam::IPV6_STATUS: -+ { -+ // Number of IPV6 addresses that are supported -+ constexpr std::array<uint8_t, 3> statusData = {1, 1, 3}; -+ -+ std::array<uint8_t, 4> buf = {current_revision, statusData[0], -+ statusData[1], statusData[2]}; -+ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response)); -+ *data_len = buf.size(); -+ break; -+ } -+ case LanParam::IPV6_STATIC_ADDRESSES: -+ { -+ // Only return set selector 0 -+ uint8_t ipv6SetSelector = 0; -+ std::string ipaddress; -+ auto ethIP = ethdevice + "/" + ipmi::network::IPV6_TYPE; -+ uint8_t ipv6AddressSource = 0; -+ uint8_t prefixLength = 0; -+ uint8_t status = 0; -+ if (channelConf->lan_set_in_progress == SET_COMPLETE) -+ { -+ try -+ { -+ auto ipObjectInfo = -+ ipmi::getIPObject(bus, ipmi::network::IP_INTERFACE, -+ ipmi::network::ROOT, ethIP); -+ -+ auto properties = ipmi::getAllDbusProperties( -+ bus, ipObjectInfo.second, ipObjectInfo.first, -+ ipmi::network::IP_INTERFACE); -+ -+ if (std::get<std::string>(properties["Origin"]) == -+ "xyz.openbmc_project.Network.IP.AddressOrigin.Static") -+ { -+ ipaddress = -+ std::get<std::string>(properties["Address"]); -+ ipv6AddressSource = 0x81; // Looking at bit 0 and bit 7 -+ prefixLength = -+ std::get<uint8_t>(properties["PrefixLength"]); -+ status = 0; -+ } -+ } -+ // ignore the exception, as it is a valid condition that -+ // the system is not configured with any IP. -+ catch (InternalFailure& e) -+ { -+ // nothing to do. -+ } -+ } -+ else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS) -+ { -+ ipv6AddressSource = channelConf->ipv6AddressSource; -+ ipaddress = channelConf->ipv6Addr.c_str(); -+ prefixLength = channelConf->ipv6Prefix; -+ status = 1; -+ } -+ -+ std::array<uint8_t, ipmi::network::IPV6_ADDRESS_STATUS_SIZE> buf = { -+ current_revision, ipv6SetSelector, ipv6AddressSource}; -+ inet_pton(AF_INET6, ipaddress.c_str(), -+ reinterpret_cast<void*>(&buf[3])); -+ buf[20] = prefixLength; -+ buf[21] = status; -+ -+ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response)); -+ *data_len = buf.size(); -+ break; -+ } -+ case LanParam::IPV6_DHCPV6_STATIC_DUID_STORAGE_LENGTH: -+ { -+ // DHCP unique identified -+ // Only 1 read-only 16-byte Block needed -+ uint8_t duidLength = 1; -+ std::array<uint8_t, 2> buf = {current_revision, duidLength}; -+ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response)); -+ *data_len = buf.size(); -+ break; -+ } -+ case LanParam::IPV6_DHCPV6_STATIC_DUIDS: -+ { -+ std::string macAddress; -+ if (channelConf->lan_set_in_progress == SET_COMPLETE) -+ { -+ auto macObjectInfo = -+ ipmi::getDbusObject(bus, ipmi::network::MAC_INTERFACE, -+ ipmi::network::ROOT, ethdevice); -+ -+ auto variant = ipmi::getDbusProperty( -+ bus, macObjectInfo.second, macObjectInfo.first, -+ ipmi::network::MAC_INTERFACE, "MACAddress"); -+ -+ macAddress = std::get<std::string>(variant); -+ } -+ else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS) -+ { -+ macAddress = channelConf->macAddress; -+ } -+ -+ std::array<uint8_t, -+ ipmi::network::IPV6_DUID_SIZE + sizeof(current_revision)> -+ buf; -+ buf = {current_revision, -+ reqptr->parameter_set, -+ reqptr->parameter_block, -+ DUID_LEN, -+ 0, // Filler byte -+ DUID_LL_TYPE, -+ 0, // Filler byte -+ DUIC_ETH_HW_TYPE}; -+ sscanf(macAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT, -+ (&buf[8]), (&buf[9]), (&buf[10]), (&buf[11]), (&buf[12]), -+ (&buf[13])); -+ -+ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response)); -+ *data_len = buf.size(); -+ break; -+ } -+ case LanParam::IPV6_DYNAMIC_ADDRESSES: -+ { -+ std::string ipaddress; -+ uint8_t ipv6AddressSource = 0; -+ uint8_t prefixLength = 0; -+ uint8_t status = 0; -+ auto ethIP = ethdevice + "/" + ipmi::network::IPV6_TYPE; -+ -+ if (channelConf->lan_set_in_progress == SET_COMPLETE) -+ { -+ try -+ { -+ auto ipObjectInfo = -+ ipmi::getIPObject(bus, ipmi::network::IP_INTERFACE, -+ ipmi::network::ROOT, ethIP); -+ -+ auto properties = ipmi::getAllDbusProperties( -+ bus, ipObjectInfo.second, ipObjectInfo.first, -+ ipmi::network::IP_INTERFACE); -+ -+ if (std::get<std::string>(properties["Origin"]) == -+ "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP") -+ { -+ ipaddress = -+ std::get<std::string>(properties["Address"]); -+ ipv6AddressSource = 0x81; // Looking at bit 0 and bit 7 -+ prefixLength = -+ std::get<uint8_t>(properties["PrefixLength"]); -+ status = 0; -+ } -+ else -+ { -+ status = 1; -+ } -+ } -+ // ignore the exception, as it is a valid condition that -+ // the system is not configured with any IP. -+ catch (InternalFailure& e) -+ { -+ // nothing to do. -+ } -+ } -+ else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS) -+ { -+ ipaddress = channelConf->ipv6Addr; -+ ipv6AddressSource = channelConf->ipv6AddressSource; -+ prefixLength = channelConf->ipv6Prefix; -+ status = channelConf->ipv6AddressStatus; -+ } -+ -+ uint8_t ipv6SetSelector = 0; -+ std::array<uint8_t, 22> buf = {current_revision, ipv6SetSelector, -+ ipv6AddressSource}; -+ inet_pton(AF_INET6, ipaddress.c_str(), -+ reinterpret_cast<void*>(&buf[3])); -+ buf[20] = prefixLength; -+ buf[21] = status; -+ -+ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response)); -+ *data_len = buf.size(); -+ break; -+ } -+ case LanParam::IPV6_DHCPV6_DYNAMIC_DUID_STOR_LEN: -+ { -+ uint8_t duidLength = 0; -+ // Only 1 read-only 16-byte Block needed -+ duidLength = 1; -+ -+ std::array<uint8_t, 2> buf = {current_revision, duidLength}; -+ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response)); -+ *data_len = buf.size(); -+ break; -+ } -+ case LanParam::IPV6_DHCPV6_DYNAMIC_DUIDS: -+ { -+ std::string macAddress; -+ if (channelConf->lan_set_in_progress == SET_COMPLETE) -+ { -+ auto macObjectInfo = -+ ipmi::getDbusObject(bus, ipmi::network::MAC_INTERFACE, -+ ipmi::network::ROOT, ethdevice); -+ -+ auto variant = ipmi::getDbusProperty( -+ bus, macObjectInfo.second, macObjectInfo.first, -+ ipmi::network::MAC_INTERFACE, "MACAddress"); -+ -+ macAddress = std::get<std::string>(variant); -+ } -+ else if (channelConf->lan_set_in_progress == SET_IN_PROGRESS) -+ { -+ macAddress = channelConf->macAddress; -+ } -+ -+ std::array<uint8_t, -+ ipmi::network::IPV6_DUID_SIZE + sizeof(current_revision)> -+ buf; -+ buf = {current_revision, -+ reqptr->parameter_set, -+ reqptr->parameter_block, -+ DUID_LEN, -+ 0, // Filler byte -+ DUID_LL_TYPE, -+ 0, // Filler byte -+ DUIC_ETH_HW_TYPE}; -+ -+ sscanf(macAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT, -+ (&buf[8]), (&buf[9]), (&buf[10]), (&buf[11]), (&buf[12]), -+ (&buf[13])); -+ -+ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response)); -+ *data_len = buf.size(); -+ break; -+ } -+ case LanParam::IPV6_ROUTER_ADDRESS_CONF_CTRL: -+ { -+ // Determine if automated router discovery occurs when static -+ // addresses are used for the bmc -+ -+ auto ethIP = ethdevice + "/" + ipmi::network::IPV6_TYPE; -+ std::string networkInterfacePath; -+ uint8_t dynamicRA; -+ if (channelConf->lan_set_in_progress == SET_COMPLETE) -+ { -+ -+ try -+ { -+ ipmi::ObjectTree ancestorMap; -+ // if the system is having ip object,then -+ // get the IP object. -+ auto ipObject = -+ ipmi::getDbusObject(bus, ipmi::network::IP_INTERFACE, -+ ipmi::network::ROOT, ethIP); -+ -+ // Get the parent interface of the IP object. -+ try -+ { -+ ipmi::InterfaceList interfaces; -+ interfaces.emplace_back( -+ ipmi::network::ETHERNET_INTERFACE); -+ -+ ancestorMap = ipmi::getAllAncestors( -+ bus, ipObject.first, std::move(interfaces)); -+ } -+ catch (InternalFailure& e) -+ { -+ // if unable to get the parent interface -+ // then commit the error and return. -+ log<level::ERR>( -+ "Unable to get the parent interface", -+ entry("PATH=%s", ipObject.first.c_str()), -+ entry("INTERFACE=%s", -+ ipmi::network::ETHERNET_INTERFACE)); -+ return IPMI_CC_UNSPECIFIED_ERROR; -+ } -+ // for an ip object there would be single parent -+ // interface. -+ networkInterfacePath = ancestorMap.begin()->first; -+ } -+ catch (InternalFailure& e) -+ { -+ // if there is no ip configured on the system,then -+ // get the network interface object. -+ auto networkInterfaceObject = ipmi::getDbusObject( -+ bus, ipmi::network::ETHERNET_INTERFACE, -+ ipmi::network::ROOT, ethdevice); -+ -+ networkInterfacePath = networkInterfaceObject.first; -+ } -+ -+ auto variant = ipmi::getDbusProperty( -+ bus, ipmi::network::SERVICE, networkInterfacePath, -+ ipmi::network::ETHERNET_INTERFACE, "IPv6AcceptRA"); -+ dynamicRA = std::get<bool>(variant); -+ } -+ else -+ { -+ dynamicRA = channelConf->ipv6RouterAddressConfigControl; -+ } -+ -+ std::array<uint8_t, 2> buf = {current_revision, dynamicRA}; -+ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response)); -+ *data_len = buf.size(); -+ break; -+ } -+ case LanParam::IPV6_STATIC_ROUTER_1_IP_ADDR: -+ { -+ std::array<uint8_t, ipmi::network::IPV6_ADDRESS_SIZE_BYTE + -+ sizeof(current_revision)> -+ buf = {current_revision}; -+ inet_pton(AF_INET6, channelConf->ipv6GatewayAddr.c_str(), -+ reinterpret_cast<void*>(&buf[1])); -+ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response)); -+ *data_len = buf.size(); -+ break; -+ } -+ case LanParam::IPV6_STATIC_ROUTER_1_PREFIX_LEN: -+ { -+ std::array<uint8_t, 2> buf = {current_revision, -+ channelConf->ipv6GatewayPrefixLength}; -+ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response)); -+ *data_len = buf.size(); -+ break; -+ } -+ case LanParam::IPV6_STATIC_ROUTER_1_PREFIX_VAL: -+ { -+ constexpr uint8_t setSelector = 0; -+ std::array<uint8_t, sizeof(setSelector) + -+ ipmi::network::IPV6_ADDRESS_SIZE_BYTE + -+ sizeof(current_revision)> -+ buf = {current_revision, setSelector}; -+ -+ inet_pton(AF_INET6, channelConf->ipv6GatewayPrefixValue.c_str(), -+ reinterpret_cast<void*>(&buf[2])); -+ -+ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response)); -+ *data_len = buf.size(); -+ break; -+ } -+ case LanParam::IPV6_STATIC_ROUTER_2_IP_ADDR: -+ { -+ std::array<uint8_t, ipmi::network::IPV6_ADDRESS_SIZE_BYTE + -+ sizeof(current_revision)> -+ buf = {current_revision}; -+ inet_pton(AF_INET6, channelConf->ipv6BackupGatewayAddr.c_str(), -+ reinterpret_cast<void*>(&buf[1])); -+ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response)); -+ *data_len = buf.size(); -+ break; -+ } -+ case LanParam::IPV6_STATIC_ROUTER_2_PREFIX_LEN: -+ { -+ std::array<uint8_t, 2> buf = { -+ current_revision, channelConf->ipv6BackupGatewayPrefixLength}; -+ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response)); -+ *data_len = buf.size(); -+ break; -+ } -+ case LanParam::IPV6_STATIC_ROUTER_2_PREFIX_VAL: -+ { -+ -+ constexpr uint8_t setSelector = 0; -+ std::array<uint8_t, sizeof(setSelector) + -+ ipmi::network::IPV6_ADDRESS_SIZE_BYTE + -+ sizeof(current_revision)> -+ buf = {current_revision, setSelector}; -+ inet_pton(AF_INET6, -+ channelConf->ipv6BackupGatewayPrefixValue.c_str(), -+ reinterpret_cast<void*>(&buf[2])); -+ -+ std::copy(buf.begin(), buf.end(), static_cast<uint8_t*>(response)); -+ *data_len = buf.size(); -+ break; -+ } - default: - log<level::ERR>("Unsupported parameter", - entry("PARAMETER=0x%x", reqptr->parameter)); -@@ -957,6 +1580,16 @@ void applyChanges(int channel) - ipaddress, prefix); - } - -+ if (!channelConf->ipv6Addr.empty() && -+ channelConf->ipv6AddressSource == -+ 0x80) // Check if IPv6 static addresses are enabled -+ { -+ ipmi::network::createIP(bus, ipmi::network::SERVICE, -+ networkInterfacePath, ipv6Protocol, -+ channelConf->ipv6Addr, -+ channelConf->ipv6Prefix); -+ } -+ - if (!gateway.empty()) - { - ipmi::setDbusProperty(bus, systemObject.second, -@@ -964,7 +1597,24 @@ void applyChanges(int channel) - ipmi::network::SYSTEMCONFIG_INTERFACE, - "DefaultGateway", std::string(gateway)); - } -+ else if (!channelConf->ipv6GatewayAddr.empty()) -+ { -+ ipmi::setDbusProperty( -+ bus, systemObject.second, systemObject.first, -+ ipmi::network::SYSTEMCONFIG_INTERFACE, "DefaultGateway", -+ std::string(channelConf->ipv6GatewayAddr)); -+ } - } -+ // set IPAddress Enables -+ ipmi::setDbusProperty( -+ bus, ipmi::network::SERVICE, networkInterfaceObject.first, -+ ipmi::network::ETHERNET_INTERFACE, "IPAddressEnables", -+ ipAddressEnablesType[channelConf->ipv6AddressingEnables]); -+ -+ ipmi::setDbusProperty( -+ bus, ipmi::network::SERVICE, networkInterfaceObject.first, -+ ipmi::network::ETHERNET_INTERFACE, "IPv6AcceptRA", -+ (bool)channelConf->ipv6RouterAddressConfigControl); - } - catch (sdbusplus::exception::exception& e) - { -Index: phosphor-host-ipmid.clean/transporthandler.hpp -=================================================================== ---- phosphor-host-ipmid.clean.orig/transporthandler.hpp -+++ phosphor-host-ipmid.clean/transporthandler.hpp -@@ -79,8 +79,27 @@ enum class LanParam : uint8_t - IPV6_NEIGHBOR_TIMING_CONFIGURATION = 80, - }; - -+constexpr uint8_t DUID_LEN = 10; -+constexpr uint8_t DUID_LL_TYPE = 3; -+constexpr uint8_t DUIC_ETH_HW_TYPE = 1; -+ - // Data length of parameters - constexpr size_t lanParamVLANSize = 4; -+constexpr size_t lanParamInProgressSize = 3; -+constexpr size_t lanParamIPSize = 6; -+constexpr size_t lanParamIPSrcSize = 3; -+constexpr size_t lanParamMACSize = 8; -+constexpr size_t lanParamSubnetSize = 6; -+constexpr size_t lanParamGatewaySize = 6; -+constexpr size_t lanParamIPv6AndIPv4EnablesSize = 3; -+constexpr size_t lanParamIPv6StaticAddressesSize = 23; -+constexpr size_t lanParamIPv6RouterAddressConfCtrlSize = 3; -+constexpr size_t lanParamIPv6StaticRouter1IPAddrSize = 18; -+constexpr size_t lanParamIPv6StaticRouter1PrefixLenSize = 3; -+constexpr size_t lanParamIPv6StaticRouter1PrefixValSize = 19; -+constexpr size_t lanParamIPv6StaticRouter2IPAddrSize = 18; -+constexpr size_t lanParamIPv6StaticRouter2PrefixLenSize = 3; -+constexpr size_t lanParamIPv6StaticRouter2PrefixValSize = 19; - constexpr uint8_t SET_COMPLETE = 0; - constexpr uint8_t SET_IN_PROGRESS = 1; - constexpr uint8_t SET_COMMIT_WRITE = 2; // Optional -@@ -103,6 +122,20 @@ struct ChannelConfig_t - uint8_t lan_set_in_progress = SET_COMPLETE; - bool flush = false; - -+ // IPV6 parameters -+ uint8_t ipv6AddressSource = 0x0; -+ uint8_t ipv6AddressingEnables = 0x2; -+ std::string ipv6Addr; -+ uint8_t ipv6Prefix = 32; -+ uint8_t ipv6AddressStatus = 0x0; -+ uint8_t ipv6RouterAddressConfigControl = 0x0; -+ std::string ipv6GatewayAddr; -+ std::string ipv6BackupGatewayAddr; -+ uint8_t ipv6GatewayPrefixLength; -+ std::string ipv6GatewayPrefixValue; -+ uint8_t ipv6BackupGatewayPrefixLength = 0x0; -+ std::string ipv6BackupGatewayPrefixValue; -+ - void clear() - { - ipaddr.clear(); -@@ -113,6 +146,20 @@ struct ChannelConfig_t - ipsrc = ipmi::network::IPOrigin::UNSPECIFIED; - lan_set_in_progress = SET_COMPLETE; - flush = false; -+ -+ // IPv6 -+ ipv6Addr.clear(); -+ ipv6GatewayAddr.clear(); -+ ipv6BackupGatewayAddr.clear(); -+ ipv6AddressingEnables = 0x2; -+ ipv6AddressSource = 0x0; -+ ipv6Prefix = 32; -+ ipv6AddressStatus = 0x0; -+ ipv6RouterAddressConfigControl = 0x0; -+ ipv6GatewayPrefixLength = 0x0; -+ ipv6GatewayPrefixValue.clear(); -+ ipv6BackupGatewayPrefixLength = 0x0; -+ ipv6BackupGatewayPrefixValue.clear(); - } - }; - |