From c9d1813ea31cc9b7bcd33b75a7a6bb66dcb0da22 Mon Sep 17 00:00:00 2001 From: Asmitha Karunanithi <47350623+asmithakarun@users.noreply.github.com> Date: Sat, 4 Mar 2023 00:38:54 +0530 Subject: [PATCH] Add support for IPv6 on hypervisor eth interfaces (#61) This commit adds support for ipv6 addresses on the hypervisor ethernet interfaces. It includes the following changes: [1] https://gerrit.openbmc.org/c/openbmc/phosphor-networkd/+/54393 [2] https://github.com/ibm-openbmc/phosphor-networkd/pull/46 Tested By: [1] PATCH -d '{"DHCPv4": {"DHCPEnabled":false}}' https://${bmc}/redfish/v1/Systems/hypervisor/EthernetInterfaces/eth1 [2] PATCH -d '{"DHCPv4": {"DHCPEnabled":true}}' https://${bmc}/redfish/v1/Systems/hypervisor/EthernetInterfaces/eth1 [3] PATCH -d '{"DHCPv6": {"OperatingMode":"Enabled"}}' https://${bmc}/redfish/v1/Systems/hypervisor/EthernetInterfaces/eth1 [4] PATCH -d '{"DHCPv6": {"OperatingMode":"Disabled"}}' https://${bmc}/redfish/v1/Systems/hypervisor/EthernetInterfaces/eth1 [5] PATCH -d '{"IPv4StaticAddresses": [{"Address": "<>","SubnetMask": "<>","Gateway":"<>"}]}' https://${bmc}/redfish/v1/Systems/hypervisor/EthernetInterfaces/eth1 Signed-off-by: Asmitha Karunanithi --- .../hyp_ethernet_interface.cpp | 646 +++++++++++++----- .../hyp_ip_interface.cpp | 103 ++- .../hyp_ip_interface.hpp | 5 +- .../hyp_network_manager.cpp | 21 +- .../hyp_network_manager.hpp | 5 +- .../test_hyp_ethernet_interface.cpp | 6 +- .../test_hyp_network_manager.cpp | 6 +- 7 files changed, 595 insertions(+), 197 deletions(-) diff --git a/src/ibm/hypervisor-network-mgr-src/hyp_ethernet_interface.cpp b/src/ibm/hypervisor-network-mgr-src/hyp_ethernet_interface.cpp index da8dfa66e..c34a155fa 100644 --- a/src/ibm/hypervisor-network-mgr-src/hyp_ethernet_interface.cpp +++ b/src/ibm/hypervisor-network-mgr-src/hyp_ethernet_interface.cpp @@ -1,4 +1,5 @@ #include "hyp_ethernet_interface.hpp" + #include "util.hpp" class HypEthInterface; @@ -14,16 +15,24 @@ using Argument = xyz::openbmc_project::Common::InvalidArgument; using BIOSConfigManager = sdbusplus::xyz::openbmc_project::BIOSConfig::server::Manager; +constexpr char biosStrType[] = + "xyz.openbmc_project.BIOSConfig.Manager.AttributeType.String"; +constexpr char biosIntType[] = + "xyz.openbmc_project.BIOSConfig.Manager.AttributeType.Integer"; +constexpr char biosEnumType[] = + "xyz.openbmc_project.BIOSConfig.Manager.AttributeType.Enumeration"; + constexpr auto BIOS_SERVICE = "xyz.openbmc_project.BIOSConfigManager"; constexpr auto BIOS_OBJPATH = "/xyz/openbmc_project/bios_config/manager"; constexpr auto BIOS_MGR_INTF = "xyz.openbmc_project.BIOSConfig.Manager"; // The total number of vmi attributes defined in biosTableAttrs -// currently is 9: -// 4 attributes of interface 0 -// 4 attributes of interface 1 -// and 1 vmi_hostname attribute -constexpr auto BIOS_ATTRS_SIZE = 9; +// currently is 17: +// 4 attributes of interface 0 - ipv4 address +// 4 attributes of interface 0 - ipv6 address +// 4 attributes of interface 1 - ipv4 address +// 4 attributes of interface 1 - ipv6 address +constexpr auto BIOS_ATTRS_SIZE = 17; biosTableRetAttrValueType HypEthInterface::getAttrFromBiosTable(const std::string& attrName) @@ -82,151 +91,258 @@ void HypEthInterface::watchBaseBiosTable() { std::string intf = "if" + std::to_string(i); - std::string dhcpEnabled = std::get( - getAttrFromBiosTable("vmi_" + intf + "_ipv4_method")); - - // This method was intended to watch the bios table - // property change signal and update the dbus object - // whenever the dhcp server has provided an - // IP from different range or changed its gateway/subnet mask (or) - // when user updates the bios table ip attributes - - // patch on /redfish/v1/Systems/system/Bios/Settings - // Because, in all other cases, - // user configures ip properties that will be set in the dbus - // object, followed by bios table updation. In this dhcp case, - // the dbus will not be having the updated ip address which - // is in bios table, also in the second case, where one patches - // bios table attributes, the dbus object will not have the updated - // values. This method is to sync the ip addresses - // between the bios table & dbus object. - - // Get corresponding ethernet interface object - std::string ethIntfLabel; - if (intf == "if0") - { - ethIntfLabel = "eth0"; - } - else - { - ethIntfLabel = "eth1"; - } - - // Get the list of all ethernet interfaces from the parent - // data member to get the eth object corresponding to the - // eth interface label above - const auto& ethIntfList = manager.getEthIntfList(); - auto findEthObj = ethIntfList.find(ethIntfLabel); - - if (findEthObj == ethIntfList.end()) + for (std::string protocol : {"ipv4", "ipv6"}) { - log("Cannot find ethernet object"); - return; - } - - const auto& ethObj = std::move(findEthObj->second); - - DHCPConf dhcpState = ethObj->dhcpEnabled(); + std::string dhcpEnabled = + std::get(getAttrFromBiosTable( + "vmi_" + intf + "_" + protocol + "_method")); + + // This method was intended to watch the bios table + // property change signal and update the dbus object + // whenever the dhcp server has provided an + // IP from different range or changed its gateway/subnet mask + // (or) when user updates the bios table ip attributes - patch + // on /redfish/v1/Systems/system/Bios/Settings Because, in all + // other cases, user configures ip properties that will be set + // in the dbus object, followed by bios table updation. In this + // dhcp case, the dbus will not be having the updated ip address + // which is in bios table, also in the second case, where one + // patches bios table attributes, the dbus object will not have + // the updated values. This method is to sync the ip addresses + // between the bios table & dbus object. + + // Get corresponding ethernet interface object + std::string ethIntfLabel; + if (intf == "if0") + { + ethIntfLabel = "eth0"; + } + else + { + ethIntfLabel = "eth1"; + } - if ((dhcpState == HypEthInterface::DHCPConf::none) && - (dhcpEnabled == "IPv4DHCP")) - { - // There is a change in bios table method attribute (changed to - // dhcp) but dbus property contains static Change the dbus - // property to dhcp - log("Setting dhcp on the dbus object"); - ethObj->dhcpEnabled(HypEthInterface::DHCPConf::v4); - } - else if ((dhcpState != HypEthInterface::DHCPConf::none) && - (dhcpEnabled == "IPv4Static")) - { - // There is a change in bios table method attribute (changed to - // static) but dbus property contains dhcp Change the dbus - // property to static - log("Setting static on the dbus object"); - ethObj->dhcpEnabled(HypEthInterface::DHCPConf::none); - } + // Get the list of all ethernet interfaces from the parent + // data member to get the eth object corresponding to the + // eth interface label above + auto& ethIntfList = manager.getEthIntfList(); + auto findEthObj = ethIntfList.find(ethIntfLabel); - const auto& ipAddrs = ethObj->addrs; + if (findEthObj == ethIntfList.end()) + { + log("Cannot find ethernet object"); + return; + } - std::string ipAddr; - std::string currIpAddr; - std::string gateway; - uint8_t prefixLen = 0; + const auto& ethObj = findEthObj->second; - auto biosTableAttrs = manager.getBIOSTableAttrs(); - for (const auto& attr : biosTableAttrs) - { - // Get ip address - if ((attr.first).ends_with(intf + "_ipv4_ipaddr")) + DHCPConf dhcpState = ethObj->dhcpEnabled(); + if ((dhcpState == HypEthInterface::DHCPConf::none) && + ((dhcpEnabled == "IPv4DHCP") || + (dhcpEnabled == "IPv6DHCP") || (dhcpEnabled == "SLAAC"))) + { + // There is a change in bios table method attribute (changed + // to dhcp) but dbus property contains static Change the + // corresponding dbus property to dhcp + log("Setting dhcp on the dbus object"); + if (dhcpEnabled == "IPv4DHCP") + { + ethObj->dhcpEnabled(HypEthInterface::DHCPConf::v4); + ethObj->dhcp4(true); + } + else if (dhcpEnabled == "IPv6DHCP") + { + ethObj->dhcpEnabled(HypEthInterface::DHCPConf::v6); + ethObj->dhcp6(true); + } + else if (dhcpEnabled == "SLAAC") + { + ethObj->dhcpEnabled( + HypEthInterface::DHCPConf::v6stateless); + ethObj->ipv6AcceptRA(true); + } + } + else if ((dhcpState != HypEthInterface::DHCPConf::none) && + ((dhcpEnabled == "IPv4Static") || + (dhcpEnabled == "IPv6Static"))) { - currIpAddr = std::get(attr.second); - if (currIpAddr.empty()) + // There is a change in bios table method attribute (changed + // to static) but dbus property contains dhcp Change the + // corresponding dbus property to static + + if (dhcpEnabled == "IPv4Static") { - log( - "Current IP in biosAttrs copy is empty"); - return; + if ((dhcpState == HypEthInterface::DHCPConf::v6) || + (dhcpState == + HypEthInterface::DHCPConf::v6stateless)) + { + // no change + } + else if (dhcpState == HypEthInterface::DHCPConf::both) + { + ethObj->dhcpEnabled(HypEthInterface::DHCPConf::v6); + ethObj->dhcp4(false); + } + else if (dhcpState == + HypEthInterface::DHCPConf::v4v6stateless) + { + ethObj->dhcpEnabled( + HypEthInterface::DHCPConf::v6stateless); + ethObj->dhcp4(false); + } + else if (dhcpState == HypEthInterface::DHCPConf::v4) + { + ethObj->dhcpEnabled( + HypEthInterface::DHCPConf::none); + ethObj->dhcp4(false); + } } - ipAddr = - std::get(getAttrFromBiosTable(attr.first)); - if (ipAddr != currIpAddr) + else if (dhcpEnabled == "IPv6Static") { - // Ip address has changed - for (auto& addrs : ipAddrs) + if (dhcpState == HypEthInterface::DHCPConf::v4) { - auto& ipObj = addrs.second; - ipObj->HypIP::address(ipAddr); - setIpPropsInMap(attr.first, ipAddr, "String"); - break; + // no change + } + else if (dhcpState == HypEthInterface::DHCPConf::both) + { + ethObj->dhcpEnabled(HypEthInterface::DHCPConf::v4); + ethObj->dhcp6(false); + } + else if (dhcpState == + HypEthInterface::DHCPConf::v4v6stateless) + { + ethObj->dhcpEnabled(HypEthInterface::DHCPConf::v4); + ethObj->ipv6AcceptRA(false); + } + else if (dhcpState == HypEthInterface::DHCPConf::v6) + { + ethObj->dhcpEnabled( + HypEthInterface::DHCPConf::none); + ethObj->dhcp6(false); + } + else if (dhcpState == + HypEthInterface::DHCPConf::v6stateless) + { + ethObj->dhcpEnabled( + HypEthInterface::DHCPConf::none); + ethObj->ipv6AcceptRA(false); } - return; } } - // Get gateway - if ((attr.first).ends_with(intf + "_ipv4_gateway")) + const auto& ipAddrs = ethObj->addrs; + + std::string ipAddr; + std::string currIpAddr; + std::string gateway; + uint8_t prefixLen = 0; + + auto biosTableAttrs = manager.getBIOSTableAttrs(); + for (const auto& attr : biosTableAttrs) { - std::string currGateway = - std::get(attr.second); - if (currGateway.empty()) + // Get ip address + if ((attr.first) + .ends_with(intf + "_" + protocol + "_ipaddr")) { - log( - "Current Gateway in biosAttrs copy is empty"); - return; + currIpAddr = std::get(attr.second); + if (currIpAddr.empty()) + { + log( + "Current IP in biosAttrs copy is empty"); + return; + } + ipAddr = std::get( + getAttrFromBiosTable(attr.first)); + if (ipAddr != currIpAddr) + { + // Ip address has changed + for (auto& addrs : ipAddrs) + { + if ((((protocol == "ipv4") && + ((addrs.first).find('.') != + std::string::npos)) || + ((protocol == "ipv6") && + ((addrs.first).find("::") != + std::string::npos)))) + { + auto& ipObj = addrs.second; + ipObj->HypIP::address(ipAddr); + setIpPropsInMap(attr.first, ipAddr, + "String"); + break; + } + } + return; + } } - gateway = - std::get(getAttrFromBiosTable(attr.first)); - if (gateway != currGateway) + + // Get gateway + if ((attr.first) + .ends_with(intf + "_" + protocol + "_gateway")) { - // Gateway has changed - for (auto& addrs : ipAddrs) + std::string currGateway = + std::get(attr.second); + if (currGateway.empty()) { - auto& ipObj = addrs.second; - ipObj->HypIP::gateway(gateway); - setIpPropsInMap(attr.first, gateway, "String"); - break; + log( + "Current Gateway in biosAttrs copy is empty"); + return; + } + gateway = std::get( + getAttrFromBiosTable(attr.first)); + if (gateway != currGateway) + { + // Gateway has changed + for (auto& addrs : ipAddrs) + { + if ((((protocol == "ipv4") && + ((addrs.first).find('.') != + std::string::npos)) || + ((protocol == "ipv6") && + ((addrs.first).find("::") != + std::string::npos)))) + { + auto& ipObj = addrs.second; + ipObj->HypIP::gateway(gateway); + setIpPropsInMap(attr.first, gateway, + "String"); + break; + } + } + return; } - return; } - } - // Get prefix length - if ((attr.first).ends_with(intf + "_ipv4_prefix_length")) - { - uint8_t currPrefixLen = - static_cast(std::get(attr.second)); - prefixLen = static_cast( - std::get(getAttrFromBiosTable(attr.first))); - if (prefixLen != currPrefixLen) + // Get prefix length + if ((attr.first) + .ends_with(intf + "_" + protocol + + "_prefix_length")) { - // Prefix length has changed" - for (auto& addrs : ipAddrs) + uint8_t currPrefixLen = static_cast( + std::get(attr.second)); + prefixLen = static_cast(std::get( + getAttrFromBiosTable(attr.first))); + if (prefixLen != currPrefixLen) { - auto& ipObj = addrs.second; - ipObj->HypIP::prefixLength(prefixLen); - setIpPropsInMap(attr.first, prefixLen, "Integer"); - break; + // Prefix length has changed" + for (auto& addrs : ipAddrs) + { + if ((((protocol == "ipv4") && + ((addrs.first).find('.') != + std::string::npos)) || + ((protocol == "ipv6") && + ((addrs.first).find("::") != + std::string::npos)))) + { + auto& ipObj = addrs.second; + ipObj->HypIP::prefixLength(prefixLen); + setIpPropsInMap(attr.first, prefixLen, + "Integer"); + break; + } + } + return; } - return; } } } @@ -330,23 +446,41 @@ void HypEthInterface::createIPAddressObjects() { // set the default values for interface 0 in the local // copy of the bios table - biosTableAttrs - manager.setDefaultBIOSTableAttrsOnIntf(intfLabel); - addrs.emplace("eth0", std::make_unique( - bus, (objectPath + "/ipv4/addr0").c_str(), - *this, HypIP::Protocol::IPv4, "0.0.0.0", - HypIP::AddressOrigin::Static, 0, - "0.0.0.0", intfLabel)); + manager.setDefaultBIOSTableAttrsOnIntf(intfLabel, "ipv4"); + addrs.emplace("eth0/v4", + std::make_unique( + bus, (objectPath + "/ipv4/addr0").c_str(), *this, + HypIP::Protocol::IPv4, "0.0.0.0", + HypIP::AddressOrigin::Static, 0, "0.0.0.0", + intfLabel)); + + manager.setDefaultBIOSTableAttrsOnIntf(intfLabel, "ipv6"); + addrs.emplace("eth0/v6", + std::make_unique( + bus, (objectPath + "/ipv6/addr0").c_str(), *this, + HypIP::Protocol::IPv6, + "::", HypIP::AddressOrigin::Static, 128, + "::", intfLabel)); } else if (intfLabel == "if1") { // set the default values for interface 0 in the local // copy of the bios table - biosTableAttrs - manager.setDefaultBIOSTableAttrsOnIntf(intfLabel); - addrs.emplace("eth1", std::make_unique( - bus, (objectPath + "/ipv4/addr0").c_str(), - *this, HypIP::Protocol::IPv4, "0.0.0.0", - HypIP::AddressOrigin::Static, 0, - "0.0.0.0", intfLabel)); + manager.setDefaultBIOSTableAttrsOnIntf(intfLabel, "ipv4"); + addrs.emplace("eth1/v4", + std::make_unique( + bus, (objectPath + "/ipv4/addr0").c_str(), *this, + HypIP::Protocol::IPv4, "0.0.0.0", + HypIP::AddressOrigin::Static, 0, "0.0.0.0", + intfLabel)); + + manager.setDefaultBIOSTableAttrsOnIntf(intfLabel, "ipv6"); + addrs.emplace("eth1/v6", + std::make_unique( + bus, (objectPath + "/ipv6/addr0").c_str(), *this, + HypIP::Protocol::IPv6, + "::", HypIP::AddressOrigin::Static, 128, + "::", intfLabel)); } return; } @@ -385,6 +519,11 @@ void HypEthInterface::createIPAddressObjects() dhcp6(true); } } + else if ((ipType.find("SLAAC") != std::string::npos) && + (protocol == "ipv6")) + { + ipv6AcceptRA(true); + } else { log("Error - Neither Static/DHCP"); @@ -431,6 +570,36 @@ void HypEthInterface::createIPAddressObjects() *this, ipProtocol, ipAddr, ipOrigin, ipPrefixLength, ipGateway, intfLabel)); } + // Set dhcpEnabled property + if (dhcp4()) + { + if (dhcp6()) + { + HypEthernetIntf::dhcpEnabled(HypEthInterface::DHCPConf::both); + } + else if (ipv6AcceptRA()) + { + HypEthernetIntf::dhcpEnabled( + HypEthInterface::DHCPConf::v4v6stateless); + } + else + { + // !v6DhcpEnabled && !slaacEnabled + HypEthernetIntf::dhcpEnabled(HypEthInterface::DHCPConf::v4); + } + } + else + { + if (dhcp6()) + { + HypEthernetIntf::dhcpEnabled(HypEthInterface::DHCPConf::v6); + } + else if (ipv6AcceptRA()) + { + HypEthernetIntf::dhcpEnabled( + HypEthInterface::DHCPConf::v6stateless); + } + } } bool HypEthInterface::ipv6AcceptRA(bool value) @@ -449,6 +618,14 @@ bool HypEthInterface::dhcp4(bool value) if (currValue != value) { HypEthernetIntf::dhcp4(value); + if (value == false) + { + HypEthernetIntf::dhcpEnabled(HypEthInterface::DHCPConf::none); + } + else + { + HypEthernetIntf::dhcpEnabled(HypEthInterface::DHCPConf::v4); + } } return value; } @@ -459,6 +636,14 @@ bool HypEthInterface::dhcp6(bool value) if (currValue != value) { HypEthernetIntf::dhcp6(value); + if (value == false) + { + HypEthernetIntf::dhcpEnabled(HypEthInterface::DHCPConf::none); + } + else + { + HypEthernetIntf::dhcpEnabled(HypEthInterface::DHCPConf::v6); + } } return value; } @@ -535,7 +720,7 @@ ObjectPath HypEthInterface::ip(HypIP::Protocol protType, std::string ipaddress, try { - if (!gateway.empty()) + if (!gateway.empty() && protType == HypIP::Protocol::IPv4) { gateway = std::to_string(ToAddr{}(gateway)); } @@ -557,13 +742,16 @@ ObjectPath HypEthInterface::ip(HypIP::Protocol protType, std::string ipaddress, const std::string ipObjId = "addr0"; std::string protocol; + std::string biosMethod; if (protType == HypIP::Protocol::IPv4) { protocol = "ipv4"; + biosMethod = "IPv4Static"; } else if (protType == HypIP::Protocol::IPv6) { protocol = "ipv6"; + biosMethod = "IPv4DHCP"; } std::string objPath = objectPath + "/" + protocol + "/" + ipObjId; @@ -571,6 +759,12 @@ ObjectPath HypEthInterface::ip(HypIP::Protocol protType, std::string ipaddress, for (auto& addr : addrs) { auto& ipObj = addr.second; + + if (ipObj->type() != protType) + { + continue; + } + std::string ipObjAddr = ipObj->address(); uint8_t ipObjPrefixLen = ipObj->prefixLength(); std::string ipObjGateway = ipObj->gateway(); @@ -599,6 +793,12 @@ ObjectPath HypEthInterface::ip(HypIP::Protocol protType, std::string ipaddress, PendingAttributesType pendingAttributes; auto& ipObj = addrs[ipaddress]; + + pendingAttributes.insert_or_assign( + ipObj->mapDbusToBiosAttr("origin"), + std::make_tuple(BIOSConfigManager::convertAttributeTypeToString( + BIOSConfigManager::AttributeType::Enumeration), + biosMethod)); pendingAttributes.insert_or_assign( ipObj->mapDbusToBiosAttr("address"), std::make_tuple(BIOSConfigManager::convertAttributeTypeToString( @@ -634,63 +834,177 @@ HypEthInterface::DHCPConf HypEthInterface::dhcpEnabled(DHCPConf value) value == DHCPConf::v6stateless || value == DHCPConf::v4v6stateless || value == DHCPConf::v6 || value == DHCPConf::both); - if (old4 == new4 || old6 == new6 || oldra == newra) + if (old4 == new4 && old6 == new6 && oldra == newra) { // if new value is the same as old value return value; } - HypEthernetIntf::dhcpEnabled(value); - - std::unique_ptr ipObj; - std::string method; - if (value != HypEthernetIntf::DHCPConf::none) { - for (auto& itr : addrs) + bool v4Enabled = false; + bool v6Enabled = false; + bool slaacEnabled = false; + HypEthernetIntf::DHCPConf newValue; + + if (value == HypEthernetIntf::DHCPConf::v4) + { + if ((old4 == false && old6 == false && oldra == false) || old4) + { + newValue = value; + v4Enabled = true; + } + else if ((old4 == true && old6 == true) || old6) + { + newValue = HypEthernetIntf::DHCPConf::both; + v4Enabled = true; + v6Enabled = true; + } + else if ((oldra == true && old4 == true) || oldra) + { + newValue = HypEthernetIntf::DHCPConf::v4v6stateless; + v4Enabled = true; + slaacEnabled = true; + } + } + else if (value == HypEthernetIntf::DHCPConf::v6) + { + if ((old4 == false && old6 == false && oldra == false) || + (old4 == true && old6 == true) || oldra || old6) + { + newValue = value; + v6Enabled = true; + } + else + { + newValue = HypEthernetIntf::DHCPConf::both; + v4Enabled = true; + v6Enabled = true; + } + } + else if (value == HypEthernetIntf::DHCPConf::v6stateless) + { + if ((old4 == false && old6 == false && oldra == false) || old6 || + oldra) + { + newValue = value; + slaacEnabled = true; + } + else + { + newValue = HypEthernetIntf::DHCPConf::v4v6stateless; + v4Enabled = true; + slaacEnabled = true; + } + } + else if (value == HypEthernetIntf::DHCPConf::both) { - ipObj = std::move(itr.second); + newValue = HypEthernetIntf::DHCPConf::both; + v4Enabled = true; + v6Enabled = true; + } + else if (value == HypEthernetIntf::DHCPConf::v4v6stateless) + { + newValue = HypEthernetIntf::DHCPConf::v4v6stateless; + v4Enabled = true; + slaacEnabled = true; + } + // Set dhcpEnabled value + HypEthernetIntf::dhcpEnabled(newValue); + + PendingAttributesType pendingAttributes; + ipAddrMapType::iterator itr = addrs.begin(); + while (itr != addrs.end()) + { std::string method; - if (ipObj->type() == HypIP::Protocol::IPv4) + if ((itr->second)->type() == HypIP::Protocol::IPv4) + { + if (v4Enabled) + { + method = "IPv4DHCP"; + v4Enabled = false; + } + else + { + method = "IPv4Static"; + (itr->second)->resetBaseBiosTableAttrs("IPv4"); + } + } + else if ((itr->second)->type() == HypIP::Protocol::IPv6) + { + if (slaacEnabled) + { + method = "SLAAC"; + slaacEnabled = false; + } + else if (v6Enabled) + { + method = "IPv6DHCP"; + v6Enabled = false; + } + else + { + method = "IPv6Static"; + (itr->second)->resetBaseBiosTableAttrs("IPv6"); + } + } + if (!method.empty()) { - method = "IPv4DHCP"; + pendingAttributes.insert_or_assign( + (itr->second)->mapDbusToBiosAttr("origin"), + std::make_tuple(biosEnumType, method)); } - else if (ipObj->type() == HypIP::Protocol::IPv6) + + if (std::next(itr) == addrs.end()) { - method = "IPv6DHCP"; + break; } - break; + itr++; } + log("Updating the ip address properties"); + (itr->second)->updateBiosPendingAttrs(pendingAttributes); } else { - for (auto& itr : addrs) - { - ipObj = std::move(itr.second); + // Set dhcpEnabled value + HypEthernetIntf::dhcpEnabled(HypEthernetIntf::DHCPConf::none); + + PendingAttributesType pendingAttributes; + ipAddrMapType::iterator itr = addrs.begin(); + while (itr != addrs.end()) + { std::string method; - if (ipObj->type() == HypIP::Protocol::IPv4) + if ((itr->second)->type() == HypIP::Protocol::IPv4) { method = "IPv4Static"; + // ipObj->resetBaseBiosTableAttrs("IPv4"); } - else if (ipObj->type() == HypIP::Protocol::IPv6) + else if ((itr->second)->type() == HypIP::Protocol::IPv6) { method = "IPv6Static"; + // ipObj->resetBaseBiosTableAttrs("IPv6"); + } + + pendingAttributes.insert_or_assign( + (itr->second)->mapDbusToBiosAttr("origin"), + std::make_tuple(biosEnumType, method)); + + if (std::next(itr) == addrs.end()) + { + break; } - break; + itr++; + } + (itr->second)->updateBiosPendingAttrs(pendingAttributes); + // Reset values of local copy of bios table to default + for (const auto& itr : addrs) + { + (itr.second)->resetBaseBiosTableAttrs(std::string()); } } - PendingAttributesType pendingAttributes; - pendingAttributes.insert_or_assign( - ipObj->mapDbusToBiosAttr("origin"), - std::make_tuple(BIOSConfigManager::convertAttributeTypeToString( - BIOSConfigManager::AttributeType::Enumeration), - method)); - ipObj->updateBiosPendingAttrs(pendingAttributes); - log("Updating the ip address properties"); - return value; } diff --git a/src/ibm/hypervisor-network-mgr-src/hyp_ip_interface.cpp b/src/ibm/hypervisor-network-mgr-src/hyp_ip_interface.cpp index 3508ddf52..9d646e3cb 100644 --- a/src/ibm/hypervisor-network-mgr-src/hyp_ip_interface.cpp +++ b/src/ibm/hypervisor-network-mgr-src/hyp_ip_interface.cpp @@ -1,4 +1,5 @@ #include "hyp_ip_interface.hpp" + #include "util.hpp" #include @@ -176,34 +177,63 @@ void HypIPAddress::resetIPObjProps() // Reset the ip obj properties log("Resetting the ip addr object properties"); - std::string zeroIp = "0.0.0.0"; - HypIP::address(zeroIp); - HypIP::gateway(zeroIp); - HypIP::prefixLength(0); + std::string defaultIp; + uint8_t defaultPrefixLen = 0; + std::string defaultMethod; + if (HypIP::type() == HypIP::Protocol::IPv4) + { + defaultIp = "0.0.0.0"; + defaultMethod = "IPv4Static"; + } + else if (HypIP::type() == HypIP::Protocol::IPv6) + { + defaultIp = "::"; + defaultPrefixLen = 128; + defaultMethod = "IPv6Static"; + } + HypIP::address(defaultIp); + HypIP::gateway(defaultIp); + HypIP::prefixLength(defaultPrefixLen); HypIP::origin(IP::AddressOrigin::Static); std::string prefix = getHypPrefix(); std::string attrIpaddr = prefix + "ipaddr"; - parent.setIpPropsInMap(attrIpaddr, zeroIp, "String"); - - std::string attrPrefixLen = prefix + "prefix_length"; - parent.setIpPropsInMap(attrPrefixLen, 0, "Integer"); + parent.setIpPropsInMap(attrIpaddr, defaultIp, "String"); std::string attrGateway = prefix + "gateway"; - parent.setIpPropsInMap(attrGateway, zeroIp, "String"); + parent.setIpPropsInMap(attrGateway, defaultIp, "String"); + + std::string attrPrefixLen = prefix + "prefix_length"; + parent.setIpPropsInMap(attrPrefixLen, defaultPrefixLen, "Integer"); std::string attrMethod = prefix + "method"; - parent.setIpPropsInMap(attrMethod, "IPv4Static", "String"); + parent.setIpPropsInMap(attrMethod, defaultMethod, "String"); } -void HypIPAddress::resetBaseBiosTableAttrs() +void HypIPAddress::resetBaseBiosTableAttrs(std::string protocol) { // clear all the entries log("Resetting the bios table attrs of the ip object"); - updateBaseBiosTable(mapDbusToBiosAttr("address"), "0.0.0.0"); - updateBaseBiosTable(mapDbusToBiosAttr("gateway"), "0.0.0.0"); - updateBaseBiosTable(mapDbusToBiosAttr("prefixLength"), 0); + + if (protocol.empty()) + { + protocol = convertProtocolToString(HypIP::type()); + protocol = protocol.substr(protocol.rfind(".") + 1); + } + + if (protocol == "IPv4") + { + updateBaseBiosTable(mapDbusToBiosAttr("address"), "0.0.0.0"); + updateBaseBiosTable(mapDbusToBiosAttr("gateway"), "0.0.0.0"); + updateBaseBiosTable(mapDbusToBiosAttr("prefixLength"), 0); + } + if (protocol == "IPv6") + { + updateBaseBiosTable(mapDbusToBiosAttr("address"), "::"); + updateBaseBiosTable(mapDbusToBiosAttr("gateway"), "::"); + updateBaseBiosTable(mapDbusToBiosAttr("prefixLength"), 128); + } } InAddrAny HypIPAddress::getIpAddress(std::string ip) @@ -373,21 +403,49 @@ HypIP::AddressOrigin HypIPAddress::origin(HypIP::AddressOrigin origin) std::string originBiosAttr; if (originStr.substr(originStr.rfind(".") + 1) == "Static") { - originBiosAttr = "IPv4Static"; + if (HypIP::type() == HypIP::Protocol::IPv4) + { + originBiosAttr = "IPv4Static"; + } + else if (HypIP::type() == HypIP::Protocol::IPv6) + { + originBiosAttr = "IPv6Static"; + } } else if (originStr.substr(originStr.rfind(".") + 1) == "DHCP") { - originBiosAttr = "IPv4DHCP"; + if (HypIP::type() == HypIP::Protocol::IPv4) + { + originBiosAttr = "IPv4DHCP"; + } + else if (HypIP::type() == HypIP::Protocol::IPv6) + { + originBiosAttr = "IPv6DHCP"; + } } std::string currOriginValue; if (addrOrigin == HypIP::AddressOrigin::Static) { - currOriginValue = "IPv4Static"; + if (HypIP::type() == HypIP::Protocol::IPv4) + { + currOriginValue = "IPv4Static"; + } + else if (HypIP::type() == HypIP::Protocol::IPv6) + { + currOriginValue = "IPv6Static"; + } } else if (addrOrigin == HypIP::AddressOrigin::DHCP) { - currOriginValue = "IPv4DHCP"; + if (HypIP::type() == HypIP::Protocol::IPv4) + { + currOriginValue = "IPv4DHCP"; + } + else if (HypIP::type() == HypIP::Protocol::IPv6) + { + currOriginValue = "IPv6DHCP"; + } } origin = HypIP::origin(origin); @@ -422,7 +480,14 @@ void HypIPAddress::delete_() resetIPObjProps(); // update bios table attrs to default - resetBaseBiosTableAttrs(); + if (HypIP::type() == HypIP::Protocol::IPv4) + { + resetBaseBiosTableAttrs("IPv4"); + } + if (HypIP::type() == HypIP::Protocol::IPv6) + { + resetBaseBiosTableAttrs("IPv6"); + } } } // namespace network diff --git a/src/ibm/hypervisor-network-mgr-src/hyp_ip_interface.hpp b/src/ibm/hypervisor-network-mgr-src/hyp_ip_interface.hpp index 12e667a22..9cd9210f6 100644 --- a/src/ibm/hypervisor-network-mgr-src/hyp_ip_interface.hpp +++ b/src/ibm/hypervisor-network-mgr-src/hyp_ip_interface.hpp @@ -81,7 +81,7 @@ class HypIPAddress : public HypIPIfaces /** @brief Method that maps the dbus object's properties * with properties of the bios table. * @param[in] dbusProp - dbus property name - * @result bios table property equivalent to the dbus property. + * @result bios table property equivalent to the dbus property. */ std::string mapDbusToBiosAttr(std::string dbusProp); @@ -105,8 +105,9 @@ class HypIPAddress : public HypIPIfaces void resetIPObjProps(); /** @brief Method to reset the base bios table attributes + * @param[in] protocol - IPv4/IPv6 */ - void resetBaseBiosTableAttrs(); + void resetBaseBiosTableAttrs(std::string protocol); /** @brief Method to set the enabled prop onto dbus from the * persisted file whenever the service starts diff --git a/src/ibm/hypervisor-network-mgr-src/hyp_network_manager.cpp b/src/ibm/hypervisor-network-mgr-src/hyp_network_manager.cpp index 84b9e2f5a..3559519a9 100644 --- a/src/ibm/hypervisor-network-mgr-src/hyp_network_manager.cpp +++ b/src/ibm/hypervisor-network-mgr-src/hyp_network_manager.cpp @@ -77,12 +77,23 @@ void HypNetworkMgr::setBIOSTableAttr( } } -void HypNetworkMgr::setDefaultBIOSTableAttrsOnIntf(const std::string& intf) +void HypNetworkMgr::setDefaultBIOSTableAttrsOnIntf(const std::string& intf, + const std::string& protocol) { - biosTableAttrs.emplace("vmi_" + intf + "_ipv4_ipaddr", "0.0.0.0"); - biosTableAttrs.emplace("vmi_" + intf + "_ipv4_gateway", "0.0.0.0"); - biosTableAttrs.emplace("vmi_" + intf + "_ipv4_prefix_length", 0); - biosTableAttrs.emplace("vmi_" + intf + "_ipv4_method", "IPv4Static"); + if (protocol == "ipv4") + { + biosTableAttrs.emplace("vmi_" + intf + "_ipv4_ipaddr", "0.0.0.0"); + biosTableAttrs.emplace("vmi_" + intf + "_ipv4_gateway", "0.0.0.0"); + biosTableAttrs.emplace("vmi_" + intf + "_ipv4_prefix_length", 0); + biosTableAttrs.emplace("vmi_" + intf + "_ipv4_method", "IPv4Static"); + } + else if (protocol == "ipv6") + { + biosTableAttrs.emplace("vmi_" + intf + "_ipv6_ipaddr", "::"); + biosTableAttrs.emplace("vmi_" + intf + "_ipv6_gateway", "::"); + biosTableAttrs.emplace("vmi_" + intf + "_ipv6_prefix_length", 128); + biosTableAttrs.emplace("vmi_" + intf + "_ipv6_method", "IPv6Static"); + } } void HypNetworkMgr::setDefaultHostnameInBIOSTableAttrs() diff --git a/src/ibm/hypervisor-network-mgr-src/hyp_network_manager.hpp b/src/ibm/hypervisor-network-mgr-src/hyp_network_manager.hpp index e69cb817e..2310dd7c2 100644 --- a/src/ibm/hypervisor-network-mgr-src/hyp_network_manager.hpp +++ b/src/ibm/hypervisor-network-mgr-src/hyp_network_manager.hpp @@ -99,8 +99,11 @@ class HypNetworkMgr /** @brief Method to set all the interface 0 attributes * to its default value in biosTableAttrs data member + * @param[in] intf - interface if0/1 + * @param[in] protocol - ipv4/ipv6 */ - void setDefaultBIOSTableAttrsOnIntf(const std::string& intf); + void setDefaultBIOSTableAttrsOnIntf(const std::string& intf, + const std::string& protocol); /** @brief Method to set the hostname attribute * to its default value in biosTableAttrs diff --git a/test/ibm/hypervisor-network-mgr-test/test_hyp_ethernet_interface.cpp b/test/ibm/hypervisor-network-mgr-test/test_hyp_ethernet_interface.cpp index 837039a3b..526c4d00d 100644 --- a/test/ibm/hypervisor-network-mgr-test/test_hyp_ethernet_interface.cpp +++ b/test/ibm/hypervisor-network-mgr-test/test_hyp_ethernet_interface.cpp @@ -22,8 +22,10 @@ class TestHypEthernetInterface : public testing::Test manager(bus, "/xyz/openbmc_test/network/hypervisor"), interface(makeInterface(bus, manager)) { - manager.setDefaultBIOSTableAttrsOnIntf("if0"); - manager.setDefaultBIOSTableAttrsOnIntf("if1"); + manager.setDefaultBIOSTableAttrsOnIntf("if0", "ipv4"); + manager.setDefaultBIOSTableAttrsOnIntf("if0", "ipv6"); + manager.setDefaultBIOSTableAttrsOnIntf("if1", "ipv4"); + manager.setDefaultBIOSTableAttrsOnIntf("if1", "ipv6"); manager.setDefaultHostnameInBIOSTableAttrs(); interface.createIPAddrObj(); } diff --git a/test/ibm/hypervisor-network-mgr-test/test_hyp_network_manager.cpp b/test/ibm/hypervisor-network-mgr-test/test_hyp_network_manager.cpp index 65914ac2e..72f8c2b85 100644 --- a/test/ibm/hypervisor-network-mgr-test/test_hyp_network_manager.cpp +++ b/test/ibm/hypervisor-network-mgr-test/test_hyp_network_manager.cpp @@ -25,8 +25,10 @@ class TestHypNetworkManager : public testing::Test // method call to set default values in the local copy // of the bios attributes should be called for ipv6 as well - manager.setDefaultBIOSTableAttrsOnIntf("if0"); - manager.setDefaultBIOSTableAttrsOnIntf("if1"); + manager.setDefaultBIOSTableAttrsOnIntf("if0", "ipv4"); + manager.setDefaultBIOSTableAttrsOnIntf("if0", "ipv6"); + manager.setDefaultBIOSTableAttrsOnIntf("if1", "ipv4"); + manager.setDefaultBIOSTableAttrsOnIntf("if1", "ipv6"); manager.setDefaultHostnameInBIOSTableAttrs(); }