From 8e9fba263179ccc87be7212c7dbd87cd7a37ac30 Mon Sep 17 00:00:00 2001 From: Johnathan Mantey Date: Thu, 14 Nov 2019 11:24:19 -0800 Subject: [PATCH] Modify Get Lan Configuration IP Address Source to use correct DBus DHCPEnabled type The Get/Set Lan Configuration "IP Address Source" subcommand got broken by phosphor-dbus-interfaces commit 12162be 12162be changed the DBus DHCPEnabled type from boolean to enum type. The Get LAN Configuration IP address Source IPMI command did not get changed to an enum type prior to 12162be being merged. This commit retroactively updates the boolean type to enum type. Tested: ipmitool raw 0xc 2 3 4 0 0 # returns correct state ipmitool raw 0xc 1 3 4 1 # changes DCHP to Static ipmitool raw 0xc 1 3 4 2 # returns Static to DHCP Assigned a static address via Redfish and tested using: ipmitool raw 0xc 2 3 4 0 0 # returns correct state Returned the NIC to use DHCP via Redfish and tested using: ipmitool raw 0xc 2 3 4 0 0 # returns correct state Change-Id: Ia66f7fcf3d5ad0a383b06658b18e8ce2b282e052 Signed-off-by: Johnathan Mantey --- transporthandler.cpp | 97 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 79 insertions(+), 18 deletions(-) diff --git a/transporthandler.cpp b/transporthandler.cpp index 16ce2b2..ccc2a97 100644 --- a/transporthandler.cpp +++ b/transporthandler.cpp @@ -109,6 +109,18 @@ constexpr auto INTF_NEIGHBOR_CREATE_STATIC = constexpr auto INTF_VLAN = "xyz.openbmc_project.Network.VLAN"; constexpr auto INTF_VLAN_CREATE = "xyz.openbmc_project.Network.VLAN.Create"; +static constexpr auto dhcpv4v6 = + "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.both"; +static constexpr auto dhcpv6 = + "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v6"; +static constexpr auto dhcpv4 = + "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v4"; +static constexpr auto dhcpoff = + "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.none"; + +static std::array dhcpEnumerations = {dhcpv4v6, dhcpv4, dhcpv6, + dhcpoff}; + /** @brief Generic paramters for different address families */ template struct AddrFamily @@ -456,25 +468,63 @@ auto channelCall(uint8_t channel, Args&&... args) * * @param[in] bus - The bus object used for lookups * @param[in] params - The parameters for the channel - * @return True if DHCP is enabled, false otherwise + * @return string containing an enumerated value + * constexpr's dhcpv4v6, dhcpv4, dhcpv6, and dhcpoff */ -bool getDHCPProperty(sdbusplus::bus::bus& bus, const ChannelParams& params) +std::string getDHCPProperty(sdbusplus::bus::bus& bus, + const ChannelParams& params) { - return std::get(getDbusProperty( + return std::get(getDbusProperty( bus, params.service, params.logicalPath, INTF_ETHERNET, "DHCPEnabled")); } /** @brief Sets the system value for DHCP on the given interface * - * @param[in] bus - The bus object used for lookups - * @param[in] params - The parameters for the channel - * @param[in] on - Whether or not to enable DHCP + * @param[in] bus - The bus object used for lookups + * @param[in] params - The parameters for the channel + * @param[in] setting - DHCP state to assign (none, v4, v6, both) */ void setDHCPProperty(sdbusplus::bus::bus& bus, const ChannelParams& params, - bool on) + const std::string& setting) { + auto it = dhcpEnumerations.begin(); + while (it != dhcpEnumerations.end()) + { + if (*it == setting) + { + break; + } + it++; + } + if (it == dhcpEnumerations.end()) + { + log("Invalid DHCP setting.", + entry("Requested DHCP mode=%s", setting.c_str())); + elog(); + } + + std::string dhcp = getDHCPProperty(bus, params); + std::string nextDhcp{}; + + if (((dhcp == dhcpv4) && (setting == dhcpv6)) || + ((dhcp == dhcpv6) && (setting == dhcpv4))) + { + // DHCP is enabled independently for IPv4 and IPv6. If IPv4 + // DHCP is enabled, and a request to add IPv6 is received, + // change the DHCPEnabled enum to "both" active. The same + // logic is applied if IPV6 is already enabled, and an IPv4 + // enable request is made. + nextDhcp = dhcpv4v6; + } + else + { + // "both" enabled -> ipv4 only + // "both" enabled -> ipv6 only + // "ip4v", "ipv6", or "both" enabled -> no DHCP + nextDhcp = setting; + } setDbusProperty(bus, params.service, params.logicalPath, INTF_ETHERNET, - "DHCPEnabled", on); + "DHCPEnabled", nextDhcp); } /** @brief Converts a human readable MAC string into MAC bytes @@ -1113,7 +1163,7 @@ void deconfigureChannel(sdbusplus::bus::bus& bus, ChannelParams& params) } // Clear out any settings on the lower physical interface - setDHCPProperty(bus, params, false); + setDHCPProperty(bus, params, dhcpoff); } /** @brief Creates a new VLAN on the specified interface @@ -1401,7 +1451,8 @@ RspType<> setLan(uint4_t channelBits, uint4_t, uint8_t parameter, } case LanParam::IP: { - if (channelCall(channel)) + std::string dhcpSetting = channelCall(channel); + if ((dhcpSetting == dhcpv4) || (dhcpSetting == dhcpv4v6)) { return responseCommandNotAvailable(); } @@ -1431,7 +1482,11 @@ RspType<> setLan(uint4_t channelBits, uint4_t, uint8_t parameter, { case IPSrc::DHCP: { - channelCall(channel, true); + // The IPSrc IPMI command is only for IPv4 + // management. Modifying IPv6 state is done using + // a completely different Set LAN Configuration + // subcommand. + channelCall(channel, dhcpv4); return responseSuccess(); } case IPSrc::Unspecified: @@ -1439,7 +1494,7 @@ RspType<> setLan(uint4_t channelBits, uint4_t, uint8_t parameter, case IPSrc::BIOS: case IPSrc::BMC: { - channelCall(channel, false); + channelCall(channel, dhcpoff); return responseSuccess(); } } @@ -1464,7 +1519,8 @@ RspType<> setLan(uint4_t channelBits, uint4_t, uint8_t parameter, } case LanParam::SubnetMask: { - if (channelCall(channel)) + std::string dhcpSetting = channelCall(channel); + if ((dhcpSetting == dhcpv4) || (dhcpSetting == dhcpv4v6)) { return responseCommandNotAvailable(); } @@ -1481,7 +1537,8 @@ RspType<> setLan(uint4_t channelBits, uint4_t, uint8_t parameter, } case LanParam::Gateway1: { - if (channelCall(channel)) + std::string dhcpSetting = channelCall(channel); + if ((dhcpSetting == dhcpv4) || (dhcpSetting == dhcpv4v6)) { return responseCommandNotAvailable(); } @@ -1606,7 +1663,8 @@ RspType<> setLan(uint4_t channelBits, uint4_t, uint8_t parameter, return responseReqDataLenInvalid(); } std::bitset<8> expected; - if (channelCall(channel)) + std::string dhcp = channelCall(channel); + if ((dhcp == dhcpv4v6) || (dhcp == dhcpv6)) { expected[IPv6RouterControlFlag::Dynamic] = 1; } @@ -1756,7 +1814,8 @@ RspType getLan(uint4_t channelBits, uint3_t, bool revOnly, case LanParam::IPSrc: { auto src = IPSrc::Static; - if (channelCall(channel)) + std::string dhcp = channelCall(channel); + if ((dhcp == dhcpv4) || (dhcp == dhcpv4v6)) { src = IPSrc::DHCP; } @@ -1877,7 +1936,8 @@ RspType getLan(uint4_t channelBits, uint3_t, bool revOnly, case LanParam::IPv6RouterControl: { std::bitset<8> control; - if (channelCall(channel)) + std::string dhcp = channelCall(channel); + if ((dhcp == dhcpv4v6) || (dhcp == dhcpv6)) { control[IPv6RouterControlFlag::Dynamic] = 1; } @@ -1891,7 +1951,8 @@ RspType getLan(uint4_t channelBits, uint3_t, bool revOnly, case LanParam::IPv6StaticRouter1IP: { in6_addr gateway{}; - if (!channelCall(channel)) + std::string dhcp = channelCall(channel); + if ((dhcp == dhcpv4) || (dhcp == dhcpoff)) { gateway = channelCall>(channel).value_or( -- 2.24.1