#include "config.h" #include "msl_verify.hpp" #include "version.hpp" #include #include #include #include #include PHOSPHOR_LOG2_USING; int minimum_ship_level::compare(const Version& versionToCompare, const Version& mslVersion) { if (versionToCompare.major > mslVersion.major) { return (1); } if (versionToCompare.major < mslVersion.major) { return (-1); } if (versionToCompare.minor > mslVersion.minor) { return (1); } if (versionToCompare.minor < mslVersion.minor) { return (-1); } if (versionToCompare.rev > mslVersion.rev) { return (1); } if (versionToCompare.rev < mslVersion.rev) { return (-1); } // Both string are equal and there is no need to make an upgrade return 0. return 0; } // parse Function copy inpVersion onto outVersion in Version format // {major,minor,rev}. void minimum_ship_level::parse(const std::string& inpVersion, Version& outVersion) { std::smatch match; outVersion = {0, 0, 0}; std::regex rx{REGEX_BMC_MSL, std::regex::extended}; if (!std::regex_search(inpVersion, match, rx)) { error("Unable to parse BMC version: {VERSION}", "VERSION", inpVersion); return; } outVersion.major = std::stoi(match[2]); outVersion.minor = std::stoi(match[3]); outVersion.rev = std::stoi(match[4]); } bool minimum_ship_level::verify(const std::string& versionManifest) { // If there is no msl or mslRegex return upgrade is needed. if (!enabled()) { return true; } // Define mslVersion variable and populate in Version format // {major,minor,rev} using parse function. std::string msl = getMinimumVersion(); Version mslVersion = {0, 0, 0}; parse(msl, mslVersion); // Define actualVersion variable and populate in Version format // {major,minor,rev} using parse function. std::string tmpStr{}; tmpStr = versionManifest; Version actualVersion = {0, 0, 0}; parse(versionManifest, actualVersion); // Compare actualVersion vs MSL. auto rc = compare(actualVersion, mslVersion); if (rc < 0) { using namespace phosphor::logging; using IncompatibleErr = sdbusplus::error::xyz::openbmc_project:: software::version::Incompatible; using Incompatible = xyz::openbmc_project::software::version::Incompatible; std::string purpose = "xyz.openbmc_project.Software.Version.VersionPurpose.BMC"; error( "BMC Minimum Ship Level ({MIN_VERSION}) NOT met by {ACTUAL_VERSION}", "MIN_VERSION", msl, "ACTUAL_VERSION", tmpStr, "VERSION_PURPOSE", purpose); report(Incompatible::MIN_VERSION(msl.c_str()), Incompatible::ACTUAL_VERSION(tmpStr.c_str()), Incompatible::VERSION_PURPOSE(purpose.c_str())); return false; } return true; } bool minimum_ship_level::enabled() { std::string msl = getMinimumVersion(); std::string mslRegex{REGEX_BMC_MSL}; if (!msl.empty() && !mslRegex.empty()) { return true; } return false; } std::string minimum_ship_level::getMinimumVersion() { return BMC_MSL; }