summaryrefslogtreecommitdiff
path: root/redfish-core/lib
diff options
context:
space:
mode:
Diffstat (limited to 'redfish-core/lib')
-rw-r--r--redfish-core/lib/ethernet.hpp2298
-rw-r--r--redfish-core/lib/hypervisor_system.hpp15
2 files changed, 1085 insertions, 1228 deletions
diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index 99f452d727..d78cb58703 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -1024,1360 +1024,1233 @@ void getEthernetIfaceList(CallbackFunc&& callback)
"org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
}
-/**
- * EthernetCollection derived class for delivering Ethernet Collection Schema
- */
-class EthernetCollection : public Node
+void handleHostnamePatch(const std::string& hostname,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
- public:
- EthernetCollection(App& app) :
- Node(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/")
- {
- entityPrivileges = {
- {boost::beast::http::verb::get, {{"Login"}}},
- {boost::beast::http::verb::head, {{"Login"}}},
- {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
- }
-
- private:
- /**
- * Functions triggers appropriate requests on DBus
- */
- void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request&, const std::vector<std::string>&) override
+ // SHOULD handle host names of up to 255 characters(RFC 1123)
+ if (hostname.length() > 255)
{
- asyncResp->res.jsonValue["@odata.type"] =
- "#EthernetInterfaceCollection.EthernetInterfaceCollection";
- asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/Managers/bmc/EthernetInterfaces";
- asyncResp->res.jsonValue["Name"] =
- "Ethernet Network Interface Collection";
- asyncResp->res.jsonValue["Description"] =
- "Collection of EthernetInterfaces for this Manager";
-
- // Get eth interface list, and call the below callback for JSON
- // preparation
- getEthernetIfaceList(
- [asyncResp](
- const bool& success,
- const boost::container::flat_set<std::string>& ifaceList) {
- if (!success)
- {
- messages::internalError(asyncResp->res);
- return;
- }
-
- nlohmann::json& ifaceArray =
- asyncResp->res.jsonValue["Members"];
- ifaceArray = nlohmann::json::array();
- std::string tag = "_";
- for (const std::string& ifaceItem : ifaceList)
- {
- std::size_t found = ifaceItem.find(tag);
- if (found == std::string::npos)
- {
- ifaceArray.push_back(
- {{"@odata.id",
- "/redfish/v1/Managers/bmc/EthernetInterfaces/" +
- ifaceItem}});
- }
- }
-
- asyncResp->res.jsonValue["Members@odata.count"] =
- ifaceArray.size();
- asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/Managers/bmc/EthernetInterfaces";
- });
+ messages::propertyValueFormatError(asyncResp->res, hostname,
+ "HostName");
+ return;
}
-};
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](const boost::system::error_code ec) {
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
+ }
+ },
+ "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/config",
+ "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
+ std::variant<std::string>(hostname));
+}
-/**
- * EthernetInterface derived class for delivering Ethernet Schema
- */
-class EthernetInterface : public Node
+void handleDomainnamePatch(const std::string& ifaceId,
+ const std::string& domainname,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
- public:
- /*
- * Default Constructor
- */
- EthernetInterface(App& app) :
- Node(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/",
- std::string())
- {
- entityPrivileges = {
- {boost::beast::http::verb::get, {{"Login"}}},
- {boost::beast::http::verb::head, {{"Login"}}},
- {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
- }
-
- private:
- void
- handleHostnamePatch(const std::string& hostname,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
- {
- // SHOULD handle host names of up to 255 characters(RFC 1123)
- if (hostname.length() > 255)
- {
- messages::propertyValueFormatError(asyncResp->res, hostname,
- "HostName");
- return;
- }
- crow::connections::systemBus->async_method_call(
- [asyncResp](const boost::system::error_code ec) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- }
- },
- "xyz.openbmc_project.Network",
- "/xyz/openbmc_project/network/config",
- "org.freedesktop.DBus.Properties", "Set",
- "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
- std::variant<std::string>(hostname));
- }
-
- void handleDomainnamePatch(
- const std::string& ifaceId, const std::string& domainname,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
- {
- std::vector<std::string> vectorDomainname = {domainname};
- crow::connections::systemBus->async_method_call(
- [asyncResp](const boost::system::error_code ec) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- }
- },
- "xyz.openbmc_project.Network",
- "/xyz/openbmc_project/network/" + ifaceId,
- "org.freedesktop.DBus.Properties", "Set",
- "xyz.openbmc_project.Network.EthernetInterface", "DomainName",
- std::variant<std::vector<std::string>>(vectorDomainname));
- }
-
- void handleFqdnPatch(const std::string& ifaceId, const std::string& fqdn,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
- {
- // Total length of FQDN must not exceed 255 characters(RFC 1035)
- if (fqdn.length() > 255)
- {
- messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN");
- return;
- }
-
- size_t pos = fqdn.find('.');
- if (pos == std::string::npos)
- {
- messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN");
- return;
- }
-
- std::string hostname;
- std::string domainname;
- domainname = (fqdn).substr(pos + 1);
- hostname = (fqdn).substr(0, pos);
-
- if (!isHostnameValid(hostname) || !isDomainnameValid(domainname))
- {
- messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN");
- return;
- }
-
- handleHostnamePatch(hostname, asyncResp);
- handleDomainnamePatch(ifaceId, domainname, asyncResp);
- }
+ std::vector<std::string> vectorDomainname = {domainname};
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](const boost::system::error_code ec) {
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
+ }
+ },
+ "xyz.openbmc_project.Network",
+ "/xyz/openbmc_project/network/" + ifaceId,
+ "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.Network.EthernetInterface", "DomainName",
+ std::variant<std::vector<std::string>>(vectorDomainname));
+}
- bool isHostnameValid(const std::string& hostname)
+bool isHostnameValid(const std::string& hostname)
+{
+ // A valid host name can never have the dotted-decimal form (RFC 1123)
+ if (std::all_of(hostname.begin(), hostname.end(), ::isdigit))
{
- // A valid host name can never have the dotted-decimal form (RFC 1123)
- if (std::all_of(hostname.begin(), hostname.end(), ::isdigit))
- {
- return false;
- }
- // Each label(hostname/subdomains) within a valid FQDN
- // MUST handle host names of up to 63 characters (RFC 1123)
- // labels cannot start or end with hyphens (RFC 952)
- // labels can start with numbers (RFC 1123)
- const std::regex pattern(
- "^[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]$");
-
- return std::regex_match(hostname, pattern);
+ return false;
}
+ // Each label(hostname/subdomains) within a valid FQDN
+ // MUST handle host names of up to 63 characters (RFC 1123)
+ // labels cannot start or end with hyphens (RFC 952)
+ // labels can start with numbers (RFC 1123)
+ const std::regex pattern(
+ "^[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]$");
+
+ return std::regex_match(hostname, pattern);
+}
- bool isDomainnameValid(const std::string& domainname)
- {
- // Can have multiple subdomains
- // Top Level Domain's min length is 2 character
- const std::regex pattern("^([A-Za-z0-9][a-zA-Z0-9\\-]{1,61}|[a-zA-Z0-9]"
- "{1,30}\\.)*[a-zA-Z]{2,}$");
+bool isDomainnameValid(const std::string& domainname)
+{
+ // Can have multiple subdomains
+ // Top Level Domain's min length is 2 character
+ const std::regex pattern("^([A-Za-z0-9][a-zA-Z0-9\\-]{1,61}|[a-zA-Z0-9]"
+ "{1,30}\\.)*[a-zA-Z]{2,}$");
- return std::regex_match(domainname, pattern);
- }
+ return std::regex_match(domainname, pattern);
+}
- void handleMACAddressPatch(
- const std::string& ifaceId, const std::string& macAddress,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+void handleFqdnPatch(const std::string& ifaceId, const std::string& fqdn,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ // Total length of FQDN must not exceed 255 characters(RFC 1035)
+ if (fqdn.length() > 255)
{
- crow::connections::systemBus->async_method_call(
- [asyncResp, macAddress](const boost::system::error_code ec) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- },
- "xyz.openbmc_project.Network",
- "/xyz/openbmc_project/network/" + ifaceId,
- "org.freedesktop.DBus.Properties", "Set",
- "xyz.openbmc_project.Network.MACAddress", "MACAddress",
- std::variant<std::string>(macAddress));
+ messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN");
+ return;
}
- void setDHCPEnabled(const std::string& ifaceId,
- const std::string& propertyName, const bool v4Value,
- const bool v6Value,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+ size_t pos = fqdn.find('.');
+ if (pos == std::string::npos)
{
- const std::string dhcp = getDhcpEnabledEnumeration(v4Value, v6Value);
- crow::connections::systemBus->async_method_call(
- [asyncResp](const boost::system::error_code ec) {
- if (ec)
- {
- BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
- messages::internalError(asyncResp->res);
- return;
- }
- messages::success(asyncResp->res);
- },
- "xyz.openbmc_project.Network",
- "/xyz/openbmc_project/network/" + ifaceId,
- "org.freedesktop.DBus.Properties", "Set",
- "xyz.openbmc_project.Network.EthernetInterface", propertyName,
- std::variant<std::string>{dhcp});
+ messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN");
+ return;
}
- void setEthernetInterfaceBoolProperty(
- const std::string& ifaceId, const std::string& propertyName,
- const bool& value, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
- {
- crow::connections::systemBus->async_method_call(
- [asyncResp](const boost::system::error_code ec) {
- if (ec)
- {
- BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
- messages::internalError(asyncResp->res);
- return;
- }
- },
- "xyz.openbmc_project.Network",
- "/xyz/openbmc_project/network/" + ifaceId,
- "org.freedesktop.DBus.Properties", "Set",
- "xyz.openbmc_project.Network.EthernetInterface", propertyName,
- std::variant<bool>{value});
- }
+ std::string hostname;
+ std::string domainname;
+ domainname = (fqdn).substr(pos + 1);
+ hostname = (fqdn).substr(0, pos);
- void setDHCPv4Config(const std::string& propertyName, const bool& value,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+ if (!isHostnameValid(hostname) || !isDomainnameValid(domainname))
{
- BMCWEB_LOG_DEBUG << propertyName << " = " << value;
- crow::connections::systemBus->async_method_call(
- [asyncResp](const boost::system::error_code ec) {
- if (ec)
- {
- BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
- messages::internalError(asyncResp->res);
- return;
- }
- },
- "xyz.openbmc_project.Network",
- "/xyz/openbmc_project/network/config/dhcp",
- "org.freedesktop.DBus.Properties", "Set",
- "xyz.openbmc_project.Network.DHCPConfiguration", propertyName,
- std::variant<bool>{value});
+ messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN");
+ return;
}
- void handleDHCPPatch(const std::string& ifaceId,
- const EthernetInterfaceData& ethData,
- const DHCPParameters& v4dhcpParms,
- const DHCPParameters& v6dhcpParms,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
- {
- bool ipv4Active = translateDHCPEnabledToBool(ethData.DHCPEnabled, true);
- bool ipv6Active =
- translateDHCPEnabledToBool(ethData.DHCPEnabled, false);
-
- bool nextv4DHCPState =
- v4dhcpParms.dhcpv4Enabled ? *v4dhcpParms.dhcpv4Enabled : ipv4Active;
+ handleHostnamePatch(hostname, asyncResp);
+ handleDomainnamePatch(ifaceId, domainname, asyncResp);
+}
- bool nextv6DHCPState{};
- if (v6dhcpParms.dhcpv6OperatingMode)
- {
- if ((*v6dhcpParms.dhcpv6OperatingMode != "Stateful") &&
- (*v6dhcpParms.dhcpv6OperatingMode != "Stateless") &&
- (*v6dhcpParms.dhcpv6OperatingMode != "Disabled"))
+void handleMACAddressPatch(const std::string& ifaceId,
+ const std::string& macAddress,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, macAddress](const boost::system::error_code ec) {
+ if (ec)
{
- messages::propertyValueFormatError(
- asyncResp->res, *v6dhcpParms.dhcpv6OperatingMode,
- "OperatingMode");
+ messages::internalError(asyncResp->res);
return;
}
- nextv6DHCPState = (*v6dhcpParms.dhcpv6OperatingMode == "Stateful");
- }
- else
- {
- nextv6DHCPState = ipv6Active;
- }
+ },
+ "xyz.openbmc_project.Network",
+ "/xyz/openbmc_project/network/" + ifaceId,
+ "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.Network.MACAddress", "MACAddress",
+ std::variant<std::string>(macAddress));
+}
- bool nextDNS{};
- if (v4dhcpParms.useDNSServers && v6dhcpParms.useDNSServers)
- {
- if (*v4dhcpParms.useDNSServers != *v6dhcpParms.useDNSServers)
+void setDHCPEnabled(const std::string& ifaceId, const std::string& propertyName,
+ const bool v4Value, const bool v6Value,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ const std::string dhcp = getDhcpEnabledEnumeration(v4Value, v6Value);
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](const boost::system::error_code ec) {
+ if (ec)
{
- messages::generalError(asyncResp->res);
+ BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
+ messages::internalError(asyncResp->res);
return;
}
- nextDNS = *v4dhcpParms.useDNSServers;
- }
- else if (v4dhcpParms.useDNSServers)
- {
- nextDNS = *v4dhcpParms.useDNSServers;
- }
- else if (v6dhcpParms.useDNSServers)
- {
- nextDNS = *v6dhcpParms.useDNSServers;
- }
- else
- {
- nextDNS = ethData.DNSEnabled;
- }
+ messages::success(asyncResp->res);
+ },
+ "xyz.openbmc_project.Network",
+ "/xyz/openbmc_project/network/" + ifaceId,
+ "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.Network.EthernetInterface", propertyName,
+ std::variant<std::string>{dhcp});
+}
- bool nextNTP{};
- if (v4dhcpParms.useNTPServers && v6dhcpParms.useNTPServers)
- {
- if (*v4dhcpParms.useNTPServers != *v6dhcpParms.useNTPServers)
+void setEthernetInterfaceBoolProperty(
+ const std::string& ifaceId, const std::string& propertyName,
+ const bool& value, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](const boost::system::error_code ec) {
+ if (ec)
{
- messages::generalError(asyncResp->res);
+ BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
+ messages::internalError(asyncResp->res);
return;
}
- nextNTP = *v4dhcpParms.useNTPServers;
- }
- else if (v4dhcpParms.useNTPServers)
- {
- nextNTP = *v4dhcpParms.useNTPServers;
- }
- else if (v6dhcpParms.useNTPServers)
- {
- nextNTP = *v6dhcpParms.useNTPServers;
- }
- else
- {
- nextNTP = ethData.NTPEnabled;
- }
+ },
+ "xyz.openbmc_project.Network",
+ "/xyz/openbmc_project/network/" + ifaceId,
+ "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.Network.EthernetInterface", propertyName,
+ std::variant<bool>{value});
+}
- bool nextUseDomain{};
- if (v4dhcpParms.useUseDomainName && v6dhcpParms.useUseDomainName)
- {
- if (*v4dhcpParms.useUseDomainName != *v6dhcpParms.useUseDomainName)
+void setDHCPv4Config(const std::string& propertyName, const bool& value,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ BMCWEB_LOG_DEBUG << propertyName << " = " << value;
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](const boost::system::error_code ec) {
+ if (ec)
{
- messages::generalError(asyncResp->res);
+ BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
+ messages::internalError(asyncResp->res);
return;
}
- nextUseDomain = *v4dhcpParms.useUseDomainName;
- }
- else if (v4dhcpParms.useUseDomainName)
+ },
+ "xyz.openbmc_project.Network",
+ "/xyz/openbmc_project/network/config/dhcp",
+ "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.Network.DHCPConfiguration", propertyName,
+ std::variant<bool>{value});
+}
+
+void handleDHCPPatch(const std::string& ifaceId,
+ const EthernetInterfaceData& ethData,
+ const DHCPParameters& v4dhcpParms,
+ const DHCPParameters& v6dhcpParms,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ bool ipv4Active = translateDHCPEnabledToBool(ethData.DHCPEnabled, true);
+ bool ipv6Active = translateDHCPEnabledToBool(ethData.DHCPEnabled, false);
+
+ bool nextv4DHCPState =
+ v4dhcpParms.dhcpv4Enabled ? *v4dhcpParms.dhcpv4Enabled : ipv4Active;
+
+ bool nextv6DHCPState{};
+ if (v6dhcpParms.dhcpv6OperatingMode)
+ {
+ if ((*v6dhcpParms.dhcpv6OperatingMode != "Stateful") &&
+ (*v6dhcpParms.dhcpv6OperatingMode != "Stateless") &&
+ (*v6dhcpParms.dhcpv6OperatingMode != "Disabled"))
{
- nextUseDomain = *v4dhcpParms.useUseDomainName;
+ messages::propertyValueFormatError(asyncResp->res,
+ *v6dhcpParms.dhcpv6OperatingMode,
+ "OperatingMode");
+ return;
}
- else if (v6dhcpParms.useUseDomainName)
+ nextv6DHCPState = (*v6dhcpParms.dhcpv6OperatingMode == "Stateful");
+ }
+ else
+ {
+ nextv6DHCPState = ipv6Active;
+ }
+
+ bool nextDNS{};
+ if (v4dhcpParms.useDNSServers && v6dhcpParms.useDNSServers)
+ {
+ if (*v4dhcpParms.useDNSServers != *v6dhcpParms.useDNSServers)
{
- nextUseDomain = *v6dhcpParms.useUseDomainName;
+ messages::generalError(asyncResp->res);
+ return;
}
- else
+ nextDNS = *v4dhcpParms.useDNSServers;
+ }
+ else if (v4dhcpParms.useDNSServers)
+ {
+ nextDNS = *v4dhcpParms.useDNSServers;
+ }
+ else if (v6dhcpParms.useDNSServers)
+ {
+ nextDNS = *v6dhcpParms.useDNSServers;
+ }
+ else
+ {
+ nextDNS = ethData.DNSEnabled;
+ }
+
+ bool nextNTP{};
+ if (v4dhcpParms.useNTPServers && v6dhcpParms.useNTPServers)
+ {
+ if (*v4dhcpParms.useNTPServers != *v6dhcpParms.useNTPServers)
{
- nextUseDomain = ethData.HostNameEnabled;
+ messages::generalError(asyncResp->res);
+ return;
}
-
- BMCWEB_LOG_DEBUG << "set DHCPEnabled...";
- setDHCPEnabled(ifaceId, "DHCPEnabled", nextv4DHCPState, nextv6DHCPState,
- asyncResp);
- BMCWEB_LOG_DEBUG << "set DNSEnabled...";
- setDHCPv4Config("DNSEnabled", nextDNS, asyncResp);
- BMCWEB_LOG_DEBUG << "set NTPEnabled...";
- setDHCPv4Config("NTPEnabled", nextNTP, asyncResp);
- BMCWEB_LOG_DEBUG << "set HostNameEnabled...";
- setDHCPv4Config("HostNameEnabled", nextUseDomain, asyncResp);
+ nextNTP = *v4dhcpParms.useNTPServers;
}
-
- boost::container::flat_set<IPv4AddressData>::const_iterator
- getNextStaticIpEntry(
- const boost::container::flat_set<IPv4AddressData>::const_iterator&
- head,
- const boost::container::flat_set<IPv4AddressData>::const_iterator&
- end)
+ else if (v4dhcpParms.useNTPServers)
{
- return std::find_if(head, end, [](const IPv4AddressData& value) {
- return value.origin == "Static";
- });
+ nextNTP = *v4dhcpParms.useNTPServers;
}
-
- boost::container::flat_set<IPv6AddressData>::const_iterator
- getNextStaticIpEntry(
- const boost::container::flat_set<IPv6AddressData>::const_iterator&
- head,
- const boost::container::flat_set<IPv6AddressData>::const_iterator&
- end)
+ else if (v6dhcpParms.useNTPServers)
{
- return std::find_if(head, end, [](const IPv6AddressData& value) {
- return value.origin == "Static";
- });
+ nextNTP = *v6dhcpParms.useNTPServers;
+ }
+ else
+ {
+ nextNTP = ethData.NTPEnabled;
}
- void handleIPv4StaticPatch(
- const std::string& ifaceId, nlohmann::json& input,
- const boost::container::flat_set<IPv4AddressData>& ipv4Data,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+ bool nextUseDomain{};
+ if (v4dhcpParms.useUseDomainName && v6dhcpParms.useUseDomainName)
{
- if ((!input.is_array()) || input.empty())
+ if (*v4dhcpParms.useUseDomainName != *v6dhcpParms.useUseDomainName)
{
- messages::propertyValueTypeError(
- asyncResp->res,
- input.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace),
- "IPv4StaticAddresses");
+ messages::generalError(asyncResp->res);
return;
}
+ nextUseDomain = *v4dhcpParms.useUseDomainName;
+ }
+ else if (v4dhcpParms.useUseDomainName)
+ {
+ nextUseDomain = *v4dhcpParms.useUseDomainName;
+ }
+ else if (v6dhcpParms.useUseDomainName)
+ {
+ nextUseDomain = *v6dhcpParms.useUseDomainName;
+ }
+ else
+ {
+ nextUseDomain = ethData.HostNameEnabled;
+ }
- unsigned entryIdx = 1;
- // Find the first static IP address currently active on the NIC and
- // match it to the first JSON element in the IPv4StaticAddresses array.
- // Match each subsequent JSON element to the next static IP programmed
- // into the NIC.
- boost::container::flat_set<IPv4AddressData>::const_iterator niciPentry =
- getNextStaticIpEntry(ipv4Data.cbegin(), ipv4Data.cend());
+ BMCWEB_LOG_DEBUG << "set DHCPEnabled...";
+ setDHCPEnabled(ifaceId, "DHCPEnabled", nextv4DHCPState, nextv6DHCPState,
+ asyncResp);
+ BMCWEB_LOG_DEBUG << "set DNSEnabled...";
+ setDHCPv4Config("DNSEnabled", nextDNS, asyncResp);
+ BMCWEB_LOG_DEBUG << "set NTPEnabled...";
+ setDHCPv4Config("NTPEnabled", nextNTP, asyncResp);
+ BMCWEB_LOG_DEBUG << "set HostNameEnabled...";
+ setDHCPv4Config("HostNameEnabled", nextUseDomain, asyncResp);
+}
+
+boost::container::flat_set<IPv4AddressData>::const_iterator
+ getNextStaticIpEntry(
+ const boost::container::flat_set<IPv4AddressData>::const_iterator& head,
+ const boost::container::flat_set<IPv4AddressData>::const_iterator& end)
+{
+ return std::find_if(head, end, [](const IPv4AddressData& value) {
+ return value.origin == "Static";
+ });
+}
+
+boost::container::flat_set<IPv6AddressData>::const_iterator
+ getNextStaticIpEntry(
+ const boost::container::flat_set<IPv6AddressData>::const_iterator& head,
+ const boost::container::flat_set<IPv6AddressData>::const_iterator& end)
+{
+ return std::find_if(head, end, [](const IPv6AddressData& value) {
+ return value.origin == "Static";
+ });
+}
+
+void handleIPv4StaticPatch(
+ const std::string& ifaceId, nlohmann::json& input,
+ const boost::container::flat_set<IPv4AddressData>& ipv4Data,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ if ((!input.is_array()) || input.empty())
+ {
+ messages::propertyValueTypeError(
+ asyncResp->res,
+ input.dump(2, ' ', true, nlohmann::json::error_handler_t::replace),
+ "IPv4StaticAddresses");
+ return;
+ }
- for (nlohmann::json& thisJson : input)
+ unsigned entryIdx = 1;
+ // Find the first static IP address currently active on the NIC and
+ // match it to the first JSON element in the IPv4StaticAddresses array.
+ // Match each subsequent JSON element to the next static IP programmed
+ // into the NIC.
+ boost::container::flat_set<IPv4AddressData>::const_iterator niciPentry =
+ getNextStaticIpEntry(ipv4Data.cbegin(), ipv4Data.cend());
+
+ for (nlohmann::json& thisJson : input)
+ {
+ std::string pathString =
+ "IPv4StaticAddresses/" + std::to_string(entryIdx);
+
+ if (!thisJson.is_null() && !thisJson.empty())
{
- std::string pathString =
- "IPv4StaticAddresses/" + std::to_string(entryIdx);
+ std::optional<std::string> address;
+ std::optional<std::string> subnetMask;
+ std::optional<std::string> gateway;
- if (!thisJson.is_null() && !thisJson.empty())
+ if (!json_util::readJson(thisJson, asyncResp->res, "Address",
+ address, "SubnetMask", subnetMask,
+ "Gateway", gateway))
{
- std::optional<std::string> address;
- std::optional<std::string> subnetMask;
- std::optional<std::string> gateway;
-
- if (!json_util::readJson(thisJson, asyncResp->res, "Address",
- address, "SubnetMask", subnetMask,
- "Gateway", gateway))
- {
- messages::propertyValueFormatError(
- asyncResp->res,
- thisJson.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace),
- pathString);
- return;
- }
+ messages::propertyValueFormatError(
+ asyncResp->res,
+ thisJson.dump(2, ' ', true,
+ nlohmann::json::error_handler_t::replace),
+ pathString);
+ return;
+ }
- // Find the address/subnet/gateway values. Any values that are
- // not explicitly provided are assumed to be unmodified from the
- // current state of the interface. Merge existing state into the
- // current request.
- const std::string* addr = nullptr;
- const std::string* gw = nullptr;
- uint8_t prefixLength = 0;
- bool errorInEntry = false;
- if (address)
- {
- if (ipv4VerifyIpAndGetBitcount(*address))
- {
- addr = &(*address);
- }
- else
- {
- messages::propertyValueFormatError(
- asyncResp->res, *address, pathString + "/Address");
- errorInEntry = true;
- }
- }
- else if (niciPentry != ipv4Data.cend())
+ // Find the address/subnet/gateway values. Any values that are
+ // not explicitly provided are assumed to be unmodified from the
+ // current state of the interface. Merge existing state into the
+ // current request.
+ const std::string* addr = nullptr;
+ const std::string* gw = nullptr;
+ uint8_t prefixLength = 0;
+ bool errorInEntry = false;
+ if (address)
+ {
+ if (ipv4VerifyIpAndGetBitcount(*address))
{
- addr = &(niciPentry->address);
+ addr = &(*address);
}
else
{
- messages::propertyMissing(asyncResp->res,
- pathString + "/Address");
+ messages::propertyValueFormatError(asyncResp->res, *address,
+ pathString + "/Address");
errorInEntry = true;
}
+ }
+ else if (niciPentry != ipv4Data.cend())
+ {
+ addr = &(niciPentry->address);
+ }
+ else
+ {
+ messages::propertyMissing(asyncResp->res,
+ pathString + "/Address");
+ errorInEntry = true;
+ }
- if (subnetMask)
- {
- if (!ipv4VerifyIpAndGetBitcount(*subnetMask, &prefixLength))
- {
- messages::propertyValueFormatError(
- asyncResp->res, *subnetMask,
- pathString + "/SubnetMask");
- errorInEntry = true;
- }
- }
- else if (niciPentry != ipv4Data.cend())
+ if (subnetMask)
+ {
+ if (!ipv4VerifyIpAndGetBitcount(*subnetMask, &prefixLength))
{
- if (!ipv4VerifyIpAndGetBitcount(niciPentry->netmask,
- &prefixLength))
- {
- messages::propertyValueFormatError(
- asyncResp->res, niciPentry->netmask,
- pathString + "/SubnetMask");
- errorInEntry = true;
- }
+ messages::propertyValueFormatError(
+ asyncResp->res, *subnetMask,
+ pathString + "/SubnetMask");
+ errorInEntry = true;
}
- else
+ }
+ else if (niciPentry != ipv4Data.cend())
+ {
+ if (!ipv4VerifyIpAndGetBitcount(niciPentry->netmask,
+ &prefixLength))
{
- messages::propertyMissing(asyncResp->res,
- pathString + "/SubnetMask");
+ messages::propertyValueFormatError(
+ asyncResp->res, niciPentry->netmask,
+ pathString + "/SubnetMask");
errorInEntry = true;
}
+ }
+ else
+ {
+ messages::propertyMissing(asyncResp->res,
+ pathString + "/SubnetMask");
+ errorInEntry = true;
+ }
- if (gateway)
- {
- if (ipv4VerifyIpAndGetBitcount(*gateway))
- {
- gw = &(*gateway);
- }
- else
- {
- messages::propertyValueFormatError(
- asyncResp->res, *gateway, pathString + "/Gateway");
- errorInEntry = true;
- }
- }
- else if (niciPentry != ipv4Data.cend())
+ if (gateway)
+ {
+ if (ipv4VerifyIpAndGetBitcount(*gateway))
{
- gw = &niciPentry->gateway;
+ gw = &(*gateway);
}
else
{
- messages::propertyMissing(asyncResp->res,
- pathString + "/Gateway");
+ messages::propertyValueFormatError(asyncResp->res, *gateway,
+ pathString + "/Gateway");
errorInEntry = true;
}
+ }
+ else if (niciPentry != ipv4Data.cend())
+ {
+ gw = &niciPentry->gateway;
+ }
+ else
+ {
+ messages::propertyMissing(asyncResp->res,
+ pathString + "/Gateway");
+ errorInEntry = true;
+ }
- if (errorInEntry)
- {
- return;
- }
+ if (errorInEntry)
+ {
+ return;
+ }
- if (niciPentry != ipv4Data.cend())
- {
- deleteAndCreateIPv4(ifaceId, niciPentry->id, prefixLength,
- *gw, *addr, asyncResp);
- niciPentry =
- getNextStaticIpEntry(++niciPentry, ipv4Data.cend());
- }
- else
- {
- createIPv4(ifaceId, prefixLength, *gateway, *address,
- asyncResp);
- }
- entryIdx++;
+ if (niciPentry != ipv4Data.cend())
+ {
+ deleteAndCreateIPv4(ifaceId, niciPentry->id, prefixLength, *gw,
+ *addr, asyncResp);
+ niciPentry =
+ getNextStaticIpEntry(++niciPentry, ipv4Data.cend());
}
else
{
- if (niciPentry == ipv4Data.cend())
+ createIPv4(ifaceId, prefixLength, *gateway, *address,
+ asyncResp);
+ }
+ entryIdx++;
+ }
+ else
+ {
+ if (niciPentry == ipv4Data.cend())
+ {
+ // Requesting a DELETE/DO NOT MODIFY action for an item
+ // that isn't present on the eth(n) interface. Input JSON is
+ // in error, so bail out.
+ if (thisJson.is_null())
{
- // Requesting a DELETE/DO NOT MODIFY action for an item
- // that isn't present on the eth(n) interface. Input JSON is
- // in error, so bail out.
- if (thisJson.is_null())
- {
- messages::resourceCannotBeDeleted(asyncResp->res);
- return;
- }
- messages::propertyValueFormatError(
- asyncResp->res,
- thisJson.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace),
- pathString);
+ messages::resourceCannotBeDeleted(asyncResp->res);
return;
}
+ messages::propertyValueFormatError(
+ asyncResp->res,
+ thisJson.dump(2, ' ', true,
+ nlohmann::json::error_handler_t::replace),
+ pathString);
+ return;
+ }
- if (thisJson.is_null())
- {
- deleteIPv4(ifaceId, niciPentry->id, asyncResp);
- }
- if (niciPentry != ipv4Data.cend())
- {
- niciPentry =
- getNextStaticIpEntry(++niciPentry, ipv4Data.cend());
- }
- entryIdx++;
+ if (thisJson.is_null())
+ {
+ deleteIPv4(ifaceId, niciPentry->id, asyncResp);
+ }
+ if (niciPentry != ipv4Data.cend())
+ {
+ niciPentry =
+ getNextStaticIpEntry(++niciPentry, ipv4Data.cend());
}
+ entryIdx++;
}
}
+}
- void handleStaticNameServersPatch(
- const std::string& ifaceId,
- const std::vector<std::string>& updatedStaticNameServers,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+void handleStaticNameServersPatch(
+ const std::string& ifaceId,
+ const std::vector<std::string>& updatedStaticNameServers,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](const boost::system::error_code ec) {
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ },
+ "xyz.openbmc_project.Network",
+ "/xyz/openbmc_project/network/" + ifaceId,
+ "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.Network.EthernetInterface", "StaticNameServers",
+ std::variant<std::vector<std::string>>{updatedStaticNameServers});
+}
+
+void handleIPv6StaticAddressesPatch(
+ const std::string& ifaceId, const nlohmann::json& input,
+ const boost::container::flat_set<IPv6AddressData>& ipv6Data,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+ if (!input.is_array() || input.empty())
{
- crow::connections::systemBus->async_method_call(
- [asyncResp](const boost::system::error_code ec) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- },
- "xyz.openbmc_project.Network",
- "/xyz/openbmc_project/network/" + ifaceId,
- "org.freedesktop.DBus.Properties", "Set",
- "xyz.openbmc_project.Network.EthernetInterface",
- "StaticNameServers",
- std::variant<std::vector<std::string>>{updatedStaticNameServers});
+ messages::propertyValueTypeError(
+ asyncResp->res,
+ input.dump(2, ' ', true, nlohmann::json::error_handler_t::replace),
+ "IPv6StaticAddresses");
+ return;
}
-
- void handleIPv6StaticAddressesPatch(
- const std::string& ifaceId, const nlohmann::json& input,
- const boost::container::flat_set<IPv6AddressData>& ipv6Data,
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+ size_t entryIdx = 1;
+ boost::container::flat_set<IPv6AddressData>::const_iterator niciPentry =
+ getNextStaticIpEntry(ipv6Data.cbegin(), ipv6Data.cend());
+ for (const nlohmann::json& thisJson : input)
{
- if (!input.is_array() || input.empty())
- {
- messages::propertyValueTypeError(
- asyncResp->res,
- input.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace),
- "IPv6StaticAddresses");
- return;
- }
- size_t entryIdx = 1;
- boost::container::flat_set<IPv6AddressData>::const_iterator niciPentry =
- getNextStaticIpEntry(ipv6Data.cbegin(), ipv6Data.cend());
- for (const nlohmann::json& thisJson : input)
- {
- std::string pathString =
- "IPv6StaticAddresses/" + std::to_string(entryIdx);
+ std::string pathString =
+ "IPv6StaticAddresses/" + std::to_string(entryIdx);
- if (!thisJson.is_null() && !thisJson.empty())
+ if (!thisJson.is_null() && !thisJson.empty())
+ {
+ std::optional<std::string> address;
+ std::optional<uint8_t> prefixLength;
+ nlohmann::json thisJsonCopy = thisJson;
+ if (!json_util::readJson(thisJsonCopy, asyncResp->res, "Address",
+ address, "PrefixLength", prefixLength))
{
- std::optional<std::string> address;
- std::optional<uint8_t> prefixLength;
- nlohmann::json thisJsonCopy = thisJson;
- if (!json_util::readJson(thisJsonCopy, asyncResp->res,
- "Address", address, "PrefixLength",
- prefixLength))
- {
- messages::propertyValueFormatError(
- asyncResp->res,
- thisJson.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace),
- pathString);
- return;
- }
-
- const std::string* addr;
- uint8_t prefix;
+ messages::propertyValueFormatError(
+ asyncResp->res,
+ thisJson.dump(2, ' ', true,
+ nlohmann::json::error_handler_t::replace),
+ pathString);
+ return;
+ }
- // Find the address and prefixLength values. Any values that are
- // not explicitly provided are assumed to be unmodified from the
- // current state of the interface. Merge existing state into the
- // current request.
- if (address)
- {
- addr = &(*address);
- }
- else if (niciPentry != ipv6Data.end())
- {
- addr = &(niciPentry->address);
- }
- else
- {
- messages::propertyMissing(asyncResp->res,
- pathString + "/Address");
- return;
- }
+ const std::string* addr;
+ uint8_t prefix;
- if (prefixLength)
- {
- prefix = *prefixLength;
- }
- else if (niciPentry != ipv6Data.end())
- {
- prefix = niciPentry->prefixLength;
- }
- else
- {
- messages::propertyMissing(asyncResp->res,
- pathString + "/PrefixLength");
- return;
- }
+ // Find the address and prefixLength values. Any values that are
+ // not explicitly provided are assumed to be unmodified from the
+ // current state of the interface. Merge existing state into the
+ // current request.
+ if (address)
+ {
+ addr = &(*address);
+ }
+ else if (niciPentry != ipv6Data.end())
+ {
+ addr = &(niciPentry->address);
+ }
+ else
+ {
+ messages::propertyMissing(asyncResp->res,
+ pathString + "/Address");
+ return;
+ }
- if (niciPentry != ipv6Data.end())
- {
- deleteAndCreateIPv6(ifaceId, niciPentry->id, prefix, *addr,
- asyncResp);
- niciPentry =
- getNextStaticIpEntry(++niciPentry, ipv6Data.cend());
- }
- else
- {
- createIPv6(ifaceId, *prefixLength, *addr, asyncResp);
- }
- entryIdx++;
+ if (prefixLength)
+ {
+ prefix = *prefixLength;
+ }
+ else if (niciPentry != ipv6Data.end())
+ {
+ prefix = niciPentry->prefixLength;
}
else
{
- if (niciPentry == ipv6Data.end())
- {
- // Requesting a DELETE/DO NOT MODIFY action for an item
- // that isn't present on the eth(n) interface. Input JSON is
- // in error, so bail out.
- if (thisJson.is_null())
- {
- messages::resourceCannotBeDeleted(asyncResp->res);
- return;
- }
- messages::propertyValueFormatError(
- asyncResp->res,
- thisJson.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace),
- pathString);
- return;
- }
+ messages::propertyMissing(asyncResp->res,
+ pathString + "/PrefixLength");
+ return;
+ }
- if (thisJson.is_null())
- {
- deleteIPv6(ifaceId, niciPentry->id, asyncResp);
- }
- if (niciPentry != ipv6Data.cend())
- {
- niciPentry =
- getNextStaticIpEntry(++niciPentry, ipv6Data.cend());
- }
- entryIdx++;
+ if (niciPentry != ipv6Data.end())
+ {
+ deleteAndCreateIPv6(ifaceId, niciPentry->id, prefix, *addr,
+ asyncResp);
+ niciPentry =
+ getNextStaticIpEntry(++niciPentry, ipv6Data.cend());
+ }
+ else
+ {
+ createIPv6(ifaceId, *prefixLength, *addr, asyncResp);
}
+ entryIdx++;
}
- }
-
- void parseInterfaceData(
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& ifaceId, const EthernetInterfaceData& ethData,
- const boost::container::flat_set<IPv4AddressData>& ipv4Data,
- const boost::container::flat_set<IPv6AddressData>& ipv6Data)
- {
- constexpr const std::array<const char*, 1> inventoryForEthernet = {
- "xyz.openbmc_project.Inventory.Item.Ethernet"};
-
- nlohmann::json& jsonResponse = asyncResp->res.jsonValue;
- jsonResponse["Id"] = ifaceId;
- jsonResponse["@odata.id"] =
- "/redfish/v1/Managers/bmc/EthernetInterfaces/" + ifaceId;
- jsonResponse["InterfaceEnabled"] = ethData.nicEnabled;
-
- auto health = std::make_shared<HealthPopulate>(asyncResp);
-
- crow::connections::systemBus->async_method_call(
- [health](const boost::system::error_code ec,
- std::vector<std::string>& resp) {
- if (ec)
+ else
+ {
+ if (niciPentry == ipv6Data.end())
+ {
+ // Requesting a DELETE/DO NOT MODIFY action for an item
+ // that isn't present on the eth(n) interface. Input JSON is
+ // in error, so bail out.
+ if (thisJson.is_null())
{
+ messages::resourceCannotBeDeleted(asyncResp->res);
return;
}
+ messages::propertyValueFormatError(
+ asyncResp->res,
+ thisJson.dump(2, ' ', true,
+ nlohmann::json::error_handler_t::replace),
+ pathString);
+ return;
+ }
- health->inventory = std::move(resp);
- },
- "xyz.openbmc_project.ObjectMapper",
- "/xyz/openbmc_project/object_mapper",
- "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
- int32_t(0), inventoryForEthernet);
-
- health->populate();
-
- if (ethData.nicEnabled)
- {
- jsonResponse["LinkStatus"] = "LinkUp";
- jsonResponse["Status"]["State"] = "Enabled";
- }
- else
- {
- jsonResponse["LinkStatus"] = "NoLink";
- jsonResponse["Status"]["State"] = "Disabled";
- }
-
- jsonResponse["LinkStatus"] = ethData.linkUp ? "LinkUp" : "LinkDown";
- jsonResponse["SpeedMbps"] = ethData.speed;
- jsonResponse["MACAddress"] = ethData.mac_address;
- jsonResponse["DHCPv4"]["DHCPEnabled"] =
- translateDHCPEnabledToBool(ethData.DHCPEnabled, true);
- jsonResponse["DHCPv4"]["UseNTPServers"] = ethData.NTPEnabled;
- jsonResponse["DHCPv4"]["UseDNSServers"] = ethData.DNSEnabled;
- jsonResponse["DHCPv4"]["UseDomainName"] = ethData.HostNameEnabled;
-
- jsonResponse["DHCPv6"]["OperatingMode"] =
- translateDHCPEnabledToBool(ethData.DHCPEnabled, false) ? "Stateful"
- : "Disabled";
- jsonResponse["DHCPv6"]["UseNTPServers"] = ethData.NTPEnabled;
- jsonResponse["DHCPv6"]["UseDNSServers"] = ethData.DNSEnabled;
- jsonResponse["DHCPv6"]["UseDomainName"] = ethData.HostNameEnabled;
-
- if (!ethData.hostname.empty())
- {
- jsonResponse["HostName"] = ethData.hostname;
-
- // When domain name is empty then it means, that it is a network
- // without domain names, and the host name itself must be treated as
- // FQDN
- std::string fqdn = ethData.hostname;
- if (!ethData.domainnames.empty())
+ if (thisJson.is_null())
+ {
+ deleteIPv6(ifaceId, niciPentry->id, asyncResp);
+ }
+ if (niciPentry != ipv6Data.cend())
{
- fqdn += "." + ethData.domainnames[0];
+ niciPentry =
+ getNextStaticIpEntry(++niciPentry, ipv6Data.cend());
}
- jsonResponse["FQDN"] = fqdn;
+ entryIdx++;
}
+ }
+}
- jsonResponse["VLANs"] = {
- {"@odata.id", "/redfish/v1/Managers/bmc/EthernetInterfaces/" +
- ifaceId + "/VLANs"}};
-
- jsonResponse["NameServers"] = ethData.nameServers;
- jsonResponse["StaticNameServers"] = ethData.staticNameServers;
+void parseInterfaceData(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& ifaceId, const EthernetInterfaceData& ethData,
+ const boost::container::flat_set<IPv4AddressData>& ipv4Data,
+ const boost::container::flat_set<IPv6AddressData>& ipv6Data)
+{
+ constexpr const std::array<const char*, 1> inventoryForEthernet = {
+ "xyz.openbmc_project.Inventory.Item.Ethernet"};
- nlohmann::json& ipv4Array = jsonResponse["IPv4Addresses"];
- nlohmann::json& ipv4StaticArray = jsonResponse["IPv4StaticAddresses"];
- ipv4Array = nlohmann::json::array();
- ipv4StaticArray = nlohmann::json::array();
- for (auto& ipv4Config : ipv4Data)
- {
+ nlohmann::json& jsonResponse = asyncResp->res.jsonValue;
+ jsonResponse["Id"] = ifaceId;
+ jsonResponse["@odata.id"] =
+ "/redfish/v1/Managers/bmc/EthernetInterfaces/" + ifaceId;
+ jsonResponse["InterfaceEnabled"] = ethData.nicEnabled;
- std::string gatewayStr = ipv4Config.gateway;
- if (gatewayStr.empty())
- {
- gatewayStr = "0.0.0.0";
- }
+ auto health = std::make_shared<HealthPopulate>(asyncResp);
- ipv4Array.push_back({{"AddressOrigin", ipv4Config.origin},
- {"SubnetMask", ipv4Config.netmask},
- {"Address", ipv4Config.address},
- {"Gateway", gatewayStr}});
- if (ipv4Config.origin == "Static")
+ crow::connections::systemBus->async_method_call(
+ [health](const boost::system::error_code ec,
+ std::vector<std::string>& resp) {
+ if (ec)
{
- ipv4StaticArray.push_back({{"AddressOrigin", ipv4Config.origin},
- {"SubnetMask", ipv4Config.netmask},
- {"Address", ipv4Config.address},
- {"Gateway", gatewayStr}});
+ return;
}
- }
- std::string ipv6GatewayStr = ethData.ipv6_default_gateway;
- if (ipv6GatewayStr.empty())
- {
- ipv6GatewayStr = "0:0:0:0:0:0:0:0";
- }
+ health->inventory = std::move(resp);
+ },
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/", int32_t(0),
+ inventoryForEthernet);
- jsonResponse["IPv6DefaultGateway"] = ipv6GatewayStr;
+ health->populate();
- nlohmann::json& ipv6Array = jsonResponse["IPv6Addresses"];
- nlohmann::json& ipv6StaticArray = jsonResponse["IPv6StaticAddresses"];
- ipv6Array = nlohmann::json::array();
- ipv6StaticArray = nlohmann::json::array();
- nlohmann::json& ipv6AddrPolicyTable =
- jsonResponse["IPv6AddressPolicyTable"];
- ipv6AddrPolicyTable = nlohmann::json::array();
- for (auto& ipv6Config : ipv6Data)
- {
- ipv6Array.push_back({{"Address", ipv6Config.address},
- {"PrefixLength", ipv6Config.prefixLength},
- {"AddressOrigin", ipv6Config.origin},
- {"AddressState", nullptr}});
- if (ipv6Config.origin == "Static")
- {
- ipv6StaticArray.push_back(
- {{"Address", ipv6Config.address},
- {"PrefixLength", ipv6Config.prefixLength},
- {"AddressOrigin", ipv6Config.origin},
- {"AddressState", nullptr}});
- }
- }
+ if (ethData.nicEnabled)
+ {
+ jsonResponse["LinkStatus"] = "LinkUp";
+ jsonResponse["Status"]["State"] = "Enabled";
+ }
+ else
+ {
+ jsonResponse["LinkStatus"] = "NoLink";
+ jsonResponse["Status"]["State"] = "Disabled";
}
- /**
- * Functions triggers appropriate requests on DBus
- */
- void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request&,
- const std::vector<std::string>& params) override
+ jsonResponse["LinkStatus"] = ethData.linkUp ? "LinkUp" : "LinkDown";
+ jsonResponse["SpeedMbps"] = ethData.speed;
+ jsonResponse["MACAddress"] = ethData.mac_address;
+ jsonResponse["DHCPv4"]["DHCPEnabled"] =
+ translateDHCPEnabledToBool(ethData.DHCPEnabled, true);
+ jsonResponse["DHCPv4"]["UseNTPServers"] = ethData.NTPEnabled;
+ jsonResponse["DHCPv4"]["UseDNSServers"] = ethData.DNSEnabled;
+ jsonResponse["DHCPv4"]["UseDomainName"] = ethData.HostNameEnabled;
+
+ jsonResponse["DHCPv6"]["OperatingMode"] =
+ translateDHCPEnabledToBool(ethData.DHCPEnabled, false) ? "Stateful"
+ : "Disabled";
+ jsonResponse["DHCPv6"]["UseNTPServers"] = ethData.NTPEnabled;
+ jsonResponse["DHCPv6"]["UseDNSServers"] = ethData.DNSEnabled;
+ jsonResponse["DHCPv6"]["UseDomainName"] = ethData.HostNameEnabled;
+
+ if (!ethData.hostname.empty())
{
- if (params.size() != 1)
+ jsonResponse["HostName"] = ethData.hostname;
+
+ // When domain name is empty then it means, that it is a network
+ // without domain names, and the host name itself must be treated as
+ // FQDN
+ std::string fqdn = ethData.hostname;
+ if (!ethData.domainnames.empty())
{
- messages::internalError(asyncResp->res);
- return;
+ fqdn += "." + ethData.domainnames[0];
}
+ jsonResponse["FQDN"] = fqdn;
+ }
- getEthernetIfaceData(
- params[0],
- [this, asyncResp, ifaceId{std::string(params[0])}](
- const bool& success, const EthernetInterfaceData& ethData,
- const boost::container::flat_set<IPv4AddressData>& ipv4Data,
- const boost::container::flat_set<IPv6AddressData>& ipv6Data) {
- if (!success)
- {
- // TODO(Pawel)consider distinguish between non existing
- // object, and other errors
- messages::resourceNotFound(asyncResp->res,
- "EthernetInterface", ifaceId);
- return;
- }
-
- asyncResp->res.jsonValue["@odata.type"] =
- "#EthernetInterface.v1_4_1.EthernetInterface";
- asyncResp->res.jsonValue["Name"] = "Manager Ethernet Interface";
- asyncResp->res.jsonValue["Description"] =
- "Management Network Interface";
+ jsonResponse["VLANs"] = {
+ {"@odata.id",
+ "/redfish/v1/Managers/bmc/EthernetInterfaces/" + ifaceId + "/VLANs"}};
- parseInterfaceData(asyncResp, ifaceId, ethData, ipv4Data,
- ipv6Data);
- });
- }
+ jsonResponse["NameServers"] = ethData.nameServers;
+ jsonResponse["StaticNameServers"] = ethData.staticNameServers;
- void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request& req,
- const std::vector<std::string>& params) override
+ nlohmann::json& ipv4Array = jsonResponse["IPv4Addresses"];
+ nlohmann::json& ipv4StaticArray = jsonResponse["IPv4StaticAddresses"];
+ ipv4Array = nlohmann::json::array();
+ ipv4StaticArray = nlohmann::json::array();
+ for (auto& ipv4Config : ipv4Data)
{
- if (params.size() != 1)
+ std::string gatewayStr = ipv4Config.gateway;
+ if (gatewayStr.empty())
{
- messages::internalError(asyncResp->res);
- return;
+ gatewayStr = "0.0.0.0";
}
- const std::string& ifaceId = params[0];
-
- std::optional<std::string> hostname;
- std::optional<std::string> fqdn;
- std::optional<std::string> macAddress;
- std::optional<std::string> ipv6DefaultGateway;
- std::optional<nlohmann::json> ipv4StaticAddresses;
- std::optional<nlohmann::json> ipv6StaticAddresses;
- std::optional<std::vector<std::string>> staticNameServers;
- std::optional<nlohmann::json> dhcpv4;
- std::optional<nlohmann::json> dhcpv6;
- std::optional<bool> interfaceEnabled;
- DHCPParameters v4dhcpParms;
- DHCPParameters v6dhcpParms;
-
- if (!json_util::readJson(
- req, asyncResp->res, "HostName", hostname, "FQDN", fqdn,
- "IPv4StaticAddresses", ipv4StaticAddresses, "MACAddress",
- macAddress, "StaticNameServers", staticNameServers,
- "IPv6DefaultGateway", ipv6DefaultGateway, "IPv6StaticAddresses",
- ipv6StaticAddresses, "DHCPv4", dhcpv4, "DHCPv6", dhcpv6,
- "InterfaceEnabled", interfaceEnabled))
+ ipv4Array.push_back({{"AddressOrigin", ipv4Config.origin},
+ {"SubnetMask", ipv4Config.netmask},
+ {"Address", ipv4Config.address},
+ {"Gateway", gatewayStr}});
+ if (ipv4Config.origin == "Static")
{
- return;
- }
- if (dhcpv4)
- {
- if (!json_util::readJson(*dhcpv4, asyncResp->res, "DHCPEnabled",
- v4dhcpParms.dhcpv4Enabled, "UseDNSServers",
- v4dhcpParms.useDNSServers, "UseNTPServers",
- v4dhcpParms.useNTPServers, "UseDomainName",
- v4dhcpParms.useUseDomainName))
- {
- return;
- }
+ ipv4StaticArray.push_back({{"AddressOrigin", ipv4Config.origin},
+ {"SubnetMask", ipv4Config.netmask},
+ {"Address", ipv4Config.address},
+ {"Gateway", gatewayStr}});
}
+ }
+
+ std::string ipv6GatewayStr = ethData.ipv6_default_gateway;
+ if (ipv6GatewayStr.empty())
+ {
+ ipv6GatewayStr = "0:0:0:0:0:0:0:0";
+ }
+
+ jsonResponse["IPv6DefaultGateway"] = ipv6GatewayStr;
- if (dhcpv6)
+ nlohmann::json& ipv6Array = jsonResponse["IPv6Addresses"];
+ nlohmann::json& ipv6StaticArray = jsonResponse["IPv6StaticAddresses"];
+ ipv6Array = nlohmann::json::array();
+ ipv6StaticArray = nlohmann::json::array();
+ nlohmann::json& ipv6AddrPolicyTable =
+ jsonResponse["IPv6AddressPolicyTable"];
+ ipv6AddrPolicyTable = nlohmann::json::array();
+ for (auto& ipv6Config : ipv6Data)
+ {
+ ipv6Array.push_back({{"Address", ipv6Config.address},
+ {"PrefixLength", ipv6Config.prefixLength},
+ {"AddressOrigin", ipv6Config.origin},
+ {"AddressState", nullptr}});
+ if (ipv6Config.origin == "Static")
{
- if (!json_util::readJson(*dhcpv6, asyncResp->res, "OperatingMode",
- v6dhcpParms.dhcpv6OperatingMode,
- "UseDNSServers", v6dhcpParms.useDNSServers,
- "UseNTPServers", v6dhcpParms.useNTPServers,
- "UseDomainName",
- v6dhcpParms.useUseDomainName))
- {
- return;
- }
+ ipv6StaticArray.push_back(
+ {{"Address", ipv6Config.address},
+ {"PrefixLength", ipv6Config.prefixLength},
+ {"AddressOrigin", ipv6Config.origin},
+ {"AddressState", nullptr}});
}
+ }
+}
+
+void parseInterfaceData(nlohmann::json& jsonResponse,
+ const std::string& parentIfaceId,
+ const std::string& ifaceId,
+ const EthernetInterfaceData& ethData)
+{
+ // Fill out obvious data...
+ jsonResponse["Id"] = ifaceId;
+ jsonResponse["@odata.id"] = "/redfish/v1/Managers/bmc/EthernetInterfaces/" +
+ parentIfaceId + "/VLANs/" + ifaceId;
+
+ jsonResponse["VLANEnable"] = true;
+ if (!ethData.vlan_id.empty())
+ {
+ jsonResponse["VLANId"] = ethData.vlan_id.back();
+ }
+}
+
+bool verifyNames(const std::string& parent, const std::string& iface)
+{
+ if (!boost::starts_with(iface, parent + "_"))
+ {
+ return false;
+ }
+ return true;
+}
- // Get single eth interface data, and call the below callback for
- // JSON preparation
- getEthernetIfaceData(
- ifaceId,
- [this, asyncResp, ifaceId, hostname = std::move(hostname),
- fqdn = std::move(fqdn), macAddress = std::move(macAddress),
- ipv4StaticAddresses = std::move(ipv4StaticAddresses),
- ipv6DefaultGateway = std::move(ipv6DefaultGateway),
- ipv6StaticAddresses = std::move(ipv6StaticAddresses),
- staticNameServers = std::move(staticNameServers),
- dhcpv4 = std::move(dhcpv4), dhcpv6 = std::move(dhcpv6),
- v4dhcpParms = std::move(v4dhcpParms),
- v6dhcpParms = std::move(v6dhcpParms), interfaceEnabled](
- const bool& success, const EthernetInterfaceData& ethData,
- const boost::container::flat_set<IPv4AddressData>& ipv4Data,
- const boost::container::flat_set<IPv6AddressData>& ipv6Data) {
+inline void requestEthernetInterfacesRoutes(App& app)
+{
+ BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/")
+ .privileges({"Login"})
+ .methods(
+ boost::beast::http::verb::
+ get)([](const crow::Request&,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#EthernetInterfaceCollection.EthernetInterfaceCollection";
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/Managers/bmc/EthernetInterfaces";
+ asyncResp->res.jsonValue["Name"] =
+ "Ethernet Network Interface Collection";
+ asyncResp->res.jsonValue["Description"] =
+ "Collection of EthernetInterfaces for this Manager";
+
+ // Get eth interface list, and call the below callback for JSON
+ // preparation
+ getEthernetIfaceList([asyncResp](const bool& success,
+ const boost::container::flat_set<
+ std::string>& ifaceList) {
if (!success)
{
- // ... otherwise return error
- // TODO(Pawel)consider distinguish between non existing
- // object, and other errors
- messages::resourceNotFound(asyncResp->res,
- "Ethernet Interface", ifaceId);
+ messages::internalError(asyncResp->res);
return;
}
- if (dhcpv4 || dhcpv6)
- {
- handleDHCPPatch(ifaceId, ethData, v4dhcpParms, v6dhcpParms,
- asyncResp);
- }
-
- if (hostname)
+ nlohmann::json& ifaceArray =
+ asyncResp->res.jsonValue["Members"];
+ ifaceArray = nlohmann::json::array();
+ std::string tag = "_";
+ for (const std::string& ifaceItem : ifaceList)
{
- handleHostnamePatch(*hostname, asyncResp);
+ std::size_t found = ifaceItem.find(tag);
+ if (found == std::string::npos)
+ {
+ ifaceArray.push_back(
+ {{"@odata.id",
+ "/redfish/v1/Managers/bmc/EthernetInterfaces/" +
+ ifaceItem}});
+ }
}
- if (fqdn)
- {
- handleFqdnPatch(ifaceId, *fqdn, asyncResp);
- }
+ asyncResp->res.jsonValue["Members@odata.count"] =
+ ifaceArray.size();
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/Managers/bmc/EthernetInterfaces";
+ });
+ });
- if (macAddress)
- {
- handleMACAddressPatch(ifaceId, *macAddress, asyncResp);
- }
+ BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/")
+ .privileges({"Login"})
+ .methods(boost::beast::http::verb::get)(
+ [](const crow::Request&,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& ifaceId) {
+ getEthernetIfaceData(
+ ifaceId,
+ [asyncResp,
+ ifaceId](const bool& success,
+ const EthernetInterfaceData& ethData,
+ const boost::container::flat_set<IPv4AddressData>&
+ ipv4Data,
+ const boost::container::flat_set<IPv6AddressData>&
+ ipv6Data) {
+ if (!success)
+ {
+ // TODO(Pawel)consider distinguish between non
+ // existing object, and other errors
+ messages::resourceNotFound(
+ asyncResp->res, "EthernetInterface", ifaceId);
+ return;
+ }
- if (ipv4StaticAddresses)
- {
- // TODO(ed) for some reason the capture of ipv4Addresses
- // above is returning a const value, not a non-const
- // value. This doesn't really work for us, as we need to
- // be able to efficiently move out the intermedia
- // nlohmann::json objects. This makes a copy of the
- // structure, and operates on that, but could be done
- // more efficiently
- nlohmann::json ipv4Static = *ipv4StaticAddresses;
- handleIPv4StaticPatch(ifaceId, ipv4Static, ipv4Data,
- asyncResp);
- }
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#EthernetInterface.v1_4_1.EthernetInterface";
+ asyncResp->res.jsonValue["Name"] =
+ "Manager Ethernet Interface";
+ asyncResp->res.jsonValue["Description"] =
+ "Management Network Interface";
- if (staticNameServers)
- {
- handleStaticNameServersPatch(ifaceId, *staticNameServers,
- asyncResp);
- }
+ parseInterfaceData(asyncResp, ifaceId, ethData,
+ ipv4Data, ipv6Data);
+ });
+ });
- if (ipv6DefaultGateway)
+ BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/")
+ .privileges({"ConfigureComponents"})
+ .methods(boost::beast::http::verb::patch)(
+ [](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& ifaceId) {
+ std::optional<std::string> hostname;
+ std::optional<std::string> fqdn;
+ std::optional<std::string> macAddress;
+ std::optional<std::string> ipv6DefaultGateway;
+ std::optional<nlohmann::json> ipv4StaticAddresses;
+ std::optional<nlohmann::json> ipv6StaticAddresses;
+ std::optional<std::vector<std::string>> staticNameServers;
+ std::optional<nlohmann::json> dhcpv4;
+ std::optional<nlohmann::json> dhcpv6;
+ std::optional<bool> interfaceEnabled;
+ DHCPParameters v4dhcpParms;
+ DHCPParameters v6dhcpParms;
+
+ if (!json_util::readJson(
+ req, asyncResp->res, "HostName", hostname, "FQDN", fqdn,
+ "IPv4StaticAddresses", ipv4StaticAddresses,
+ "MACAddress", macAddress, "StaticNameServers",
+ staticNameServers, "IPv6DefaultGateway",
+ ipv6DefaultGateway, "IPv6StaticAddresses",
+ ipv6StaticAddresses, "DHCPv4", dhcpv4, "DHCPv6", dhcpv6,
+ "InterfaceEnabled", interfaceEnabled))
{
- messages::propertyNotWritable(asyncResp->res,
- "IPv6DefaultGateway");
+ return;
}
-
- if (ipv6StaticAddresses)
+ if (dhcpv4)
{
- nlohmann::json ipv6Static = *ipv6StaticAddresses;
- handleIPv6StaticAddressesPatch(ifaceId, ipv6Static,
- ipv6Data, asyncResp);
+ if (!json_util::readJson(
+ *dhcpv4, asyncResp->res, "DHCPEnabled",
+ v4dhcpParms.dhcpv4Enabled, "UseDNSServers",
+ v4dhcpParms.useDNSServers, "UseNTPServers",
+ v4dhcpParms.useNTPServers, "UseDomainName",
+ v4dhcpParms.useUseDomainName))
+ {
+ return;
+ }
}
- if (interfaceEnabled)
+ if (dhcpv6)
{
- setEthernetInterfaceBoolProperty(
- ifaceId, "NICEnabled", *interfaceEnabled, asyncResp);
+ if (!json_util::readJson(
+ *dhcpv6, asyncResp->res, "OperatingMode",
+ v6dhcpParms.dhcpv6OperatingMode, "UseDNSServers",
+ v6dhcpParms.useDNSServers, "UseNTPServers",
+ v6dhcpParms.useNTPServers, "UseDomainName",
+ v6dhcpParms.useUseDomainName))
+ {
+ return;
+ }
}
- });
- }
-};
-/**
- * VlanNetworkInterface derived class for delivering VLANNetworkInterface
- * Schema
- */
-class VlanNetworkInterface : public Node
-{
- public:
- /*
- * Default Constructor
- */
- VlanNetworkInterface(App& app) :
- Node(app,
- "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/<str>/",
- std::string(), std::string())
- {
- entityPrivileges = {
- {boost::beast::http::verb::get, {{"Login"}}},
- {boost::beast::http::verb::head, {{"Login"}}},
- {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
- }
-
- private:
- void parseInterfaceData(nlohmann::json& jsonResponse,
- const std::string& parentIfaceId,
- const std::string& ifaceId,
- const EthernetInterfaceData& ethData)
- {
- // Fill out obvious data...
- jsonResponse["Id"] = ifaceId;
- jsonResponse["@odata.id"] =
- "/redfish/v1/Managers/bmc/EthernetInterfaces/" + parentIfaceId +
- "/VLANs/" + ifaceId;
-
- jsonResponse["VLANEnable"] = true;
- if (!ethData.vlan_id.empty())
- {
- jsonResponse["VLANId"] = ethData.vlan_id.back();
- }
- }
-
- bool verifyNames(const std::string& parent, const std::string& iface)
- {
- if (!boost::starts_with(iface, parent + "_"))
- {
- return false;
- }
- return true;
- }
+ // Get single eth interface data, and call the below callback
+ // for JSON preparation
+ getEthernetIfaceData(
+ ifaceId,
+ [asyncResp, ifaceId, hostname = std::move(hostname),
+ fqdn = std::move(fqdn), macAddress = std::move(macAddress),
+ ipv4StaticAddresses = std::move(ipv4StaticAddresses),
+ ipv6DefaultGateway = std::move(ipv6DefaultGateway),
+ ipv6StaticAddresses = std::move(ipv6StaticAddresses),
+ staticNameServers = std::move(staticNameServers),
+ dhcpv4 = std::move(dhcpv4), dhcpv6 = std::move(dhcpv6),
+ v4dhcpParms = std::move(v4dhcpParms),
+ v6dhcpParms = std::move(v6dhcpParms), interfaceEnabled](
+ const bool& success,
+ const EthernetInterfaceData& ethData,
+ const boost::container::flat_set<IPv4AddressData>&
+ ipv4Data,
+ const boost::container::flat_set<IPv6AddressData>&
+ ipv6Data) {
+ if (!success)
+ {
+ // ... otherwise return error
+ // TODO(Pawel)consider distinguish between non
+ // existing object, and other errors
+ messages::resourceNotFound(
+ asyncResp->res, "Ethernet Interface", ifaceId);
+ return;
+ }
- /**
- * Functions triggers appropriate requests on DBus
- */
- void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request&,
- const std::vector<std::string>& params) override
- {
- // TODO(Pawel) this shall be parameterized call (two params) to get
- // EthernetInterfaces for any Manager, not only hardcoded 'openbmc'.
- // Check if there is required param, truly entering this shall be
- // impossible.
- if (params.size() != 2)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (dhcpv4 || dhcpv6)
+ {
+ handleDHCPPatch(ifaceId, ethData, v4dhcpParms,
+ v6dhcpParms, asyncResp);
+ }
- const std::string& parentIfaceId = params[0];
- const std::string& ifaceId = params[1];
- asyncResp->res.jsonValue["@odata.type"] =
- "#VLanNetworkInterface.v1_1_0.VLanNetworkInterface";
- asyncResp->res.jsonValue["Name"] = "VLAN Network Interface";
+ if (hostname)
+ {
+ handleHostnamePatch(*hostname, asyncResp);
+ }
- if (!verifyNames(parentIfaceId, ifaceId))
- {
- return;
- }
+ if (fqdn)
+ {
+ handleFqdnPatch(ifaceId, *fqdn, asyncResp);
+ }
- // Get single eth interface data, and call the below callback for
- // JSON preparation
- getEthernetIfaceData(
- params[1],
- [this, asyncResp, parentIfaceId{std::string(params[0])},
- ifaceId{std::string(params[1])}](
- const bool& success, const EthernetInterfaceData& ethData,
- const boost::container::flat_set<IPv4AddressData>&,
- const boost::container::flat_set<IPv6AddressData>&) {
- if (success && ethData.vlan_id.size() != 0)
- {
- parseInterfaceData(asyncResp->res.jsonValue, parentIfaceId,
- ifaceId, ethData);
- }
- else
- {
- // ... otherwise return error
- // TODO(Pawel)consider distinguish between non existing
- // object, and other errors
- messages::resourceNotFound(
- asyncResp->res, "VLAN Network Interface", ifaceId);
- }
- });
- }
+ if (macAddress)
+ {
+ handleMACAddressPatch(ifaceId, *macAddress,
+ asyncResp);
+ }
- void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request& req,
- const std::vector<std::string>& params) override
- {
+ if (ipv4StaticAddresses)
+ {
+ // TODO(ed) for some reason the capture of
+ // ipv4Addresses above is returning a const value,
+ // not a non-const value. This doesn't really work
+ // for us, as we need to be able to efficiently move
+ // out the intermedia nlohmann::json objects. This
+ // makes a copy of the structure, and operates on
+ // that, but could be done more efficiently
+ nlohmann::json ipv4Static = *ipv4StaticAddresses;
+ handleIPv4StaticPatch(ifaceId, ipv4Static, ipv4Data,
+ asyncResp);
+ }
- if (params.size() != 2)
- {
- messages::internalError(asyncResp->res);
- return;
- }
+ if (staticNameServers)
+ {
+ handleStaticNameServersPatch(
+ ifaceId, *staticNameServers, asyncResp);
+ }
- const std::string& parentIfaceId = params[0];
- const std::string& ifaceId = params[1];
+ if (ipv6DefaultGateway)
+ {
+ messages::propertyNotWritable(asyncResp->res,
+ "IPv6DefaultGateway");
+ }
- if (!verifyNames(parentIfaceId, ifaceId))
- {
- messages::resourceNotFound(asyncResp->res, "VLAN Network Interface",
- ifaceId);
- return;
- }
+ if (ipv6StaticAddresses)
+ {
+ nlohmann::json ipv6Static = *ipv6StaticAddresses;
+ handleIPv6StaticAddressesPatch(ifaceId, ipv6Static,
+ ipv6Data, asyncResp);
+ }
- bool vlanEnable = false;
- uint32_t vlanId = 0;
+ if (interfaceEnabled)
+ {
+ setEthernetInterfaceBoolProperty(
+ ifaceId, "NICEnabled", *interfaceEnabled,
+ asyncResp);
+ }
+ });
+ });
- if (!json_util::readJson(req, asyncResp->res, "VLANEnable", vlanEnable,
- "VLANId", vlanId))
- {
- return;
- }
+ BMCWEB_ROUTE(
+ app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/<str>/")
+ .privileges({"Login"})
+ .methods(boost::beast::http::verb::get)(
+ [](const crow::Request& /* req */,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& parentIfaceId, const std::string& ifaceId) {
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#VLanNetworkInterface.v1_1_0.VLanNetworkInterface";
+ asyncResp->res.jsonValue["Name"] = "VLAN Network Interface";
- // Get single eth interface data, and call the below callback for
- // JSON preparation
- getEthernetIfaceData(
- params[1],
- [asyncResp, parentIfaceId{std::string(params[0])},
- ifaceId{std::string(params[1])}, &vlanEnable,
- &vlanId](const bool& success, const EthernetInterfaceData& ethData,
- const boost::container::flat_set<IPv4AddressData>&,
- const boost::container::flat_set<IPv6AddressData>&) {
- if (success && !ethData.vlan_id.empty())
+ if (!verifyNames(parentIfaceId, ifaceId))
{
- auto callback =
- [asyncResp](const boost::system::error_code ec) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- }
- };
-
- if (vlanEnable == true)
- {
- crow::connections::systemBus->async_method_call(
- std::move(callback), "xyz.openbmc_project.Network",
- "/xyz/openbmc_project/network/" + ifaceId,
- "org.freedesktop.DBus.Properties", "Set",
- "xyz.openbmc_project.Network.VLAN", "Id",
- std::variant<uint32_t>(vlanId));
- }
- else
- {
- BMCWEB_LOG_DEBUG << "vlanEnable is false. Deleting the "
- "vlan interface";
- crow::connections::systemBus->async_method_call(
- std::move(callback), "xyz.openbmc_project.Network",
- std::string("/xyz/openbmc_project/network/") +
- ifaceId,
- "xyz.openbmc_project.Object.Delete", "Delete");
- }
+ return;
}
- else
+
+ // Get single eth interface data, and call the below callback
+ // for JSON preparation
+ getEthernetIfaceData(
+ ifaceId,
+ [asyncResp, parentIfaceId, ifaceId](
+ const bool& success,
+ const EthernetInterfaceData& ethData,
+ const boost::container::flat_set<IPv4AddressData>&,
+ const boost::container::flat_set<IPv6AddressData>&) {
+ if (success && ethData.vlan_id.size() != 0)
+ {
+ parseInterfaceData(asyncResp->res.jsonValue,
+ parentIfaceId, ifaceId, ethData);
+ }
+ else
+ {
+ // ... otherwise return error
+ // TODO(Pawel)consider distinguish between non
+ // existing object, and other errors
+ messages::resourceNotFound(asyncResp->res,
+ "VLAN Network Interface",
+ ifaceId);
+ }
+ });
+ });
+
+ BMCWEB_ROUTE(
+ app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/<str>/")
+ .privileges({"ConfigureComponents"})
+ .methods(boost::beast::http::verb::patch)(
+ [](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& parentIfaceId, const std::string& ifaceId) {
+ if (!verifyNames(parentIfaceId, ifaceId))
{
- // TODO(Pawel)consider distinguish between non existing
- // object, and other errors
messages::resourceNotFound(
asyncResp->res, "VLAN Network Interface", ifaceId);
return;
}
- });
- }
-
- void doDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request&,
- const std::vector<std::string>& params) override
- {
- if (params.size() != 2)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- const std::string& parentIfaceId = params[0];
- const std::string& ifaceId = params[1];
+ bool vlanEnable = false;
+ uint32_t vlanId = 0;
- if (!verifyNames(parentIfaceId, ifaceId))
- {
- messages::resourceNotFound(asyncResp->res, "VLAN Network Interface",
- ifaceId);
- return;
- }
-
- // Get single eth interface data, and call the below callback for
- // JSON preparation
- getEthernetIfaceData(
- params[1],
- [asyncResp, parentIfaceId{std::string(params[0])},
- ifaceId{std::string(params[1])}](
- const bool& success, const EthernetInterfaceData& ethData,
- const boost::container::flat_set<IPv4AddressData>&,
- const boost::container::flat_set<IPv6AddressData>&) {
- if (success && !ethData.vlan_id.empty())
+ if (!json_util::readJson(req, asyncResp->res, "VLANEnable",
+ vlanEnable, "VLANId", vlanId))
{
- auto callback =
- [asyncResp](const boost::system::error_code ec) {
- if (ec)
+ return;
+ }
+
+ // Get single eth interface data, and call the below callback
+ // for JSON preparation
+ getEthernetIfaceData(
+ ifaceId,
+ [asyncResp, parentIfaceId, ifaceId, &vlanEnable, &vlanId](
+ const bool& success,
+ const EthernetInterfaceData& ethData,
+ const boost::container::flat_set<IPv4AddressData>&,
+ const boost::container::flat_set<IPv6AddressData>&) {
+ if (success && !ethData.vlan_id.empty())
+ {
+ auto callback =
+ [asyncResp](
+ const boost::system::error_code ec) {
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
+ }
+ };
+
+ if (vlanEnable == true)
{
- messages::internalError(asyncResp->res);
+ crow::connections::systemBus->async_method_call(
+ std::move(callback),
+ "xyz.openbmc_project.Network",
+ "/xyz/openbmc_project/network/" + ifaceId,
+ "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.Network.VLAN", "Id",
+ std::variant<uint32_t>(vlanId));
}
- };
- crow::connections::systemBus->async_method_call(
- std::move(callback), "xyz.openbmc_project.Network",
- std::string("/xyz/openbmc_project/network/") + ifaceId,
- "xyz.openbmc_project.Object.Delete", "Delete");
- }
- else
+ else
+ {
+ BMCWEB_LOG_DEBUG
+ << "vlanEnable is false. Deleting the "
+ "vlan interface";
+ crow::connections::systemBus->async_method_call(
+ std::move(callback),
+ "xyz.openbmc_project.Network",
+ std::string(
+ "/xyz/openbmc_project/network/") +
+ ifaceId,
+ "xyz.openbmc_project.Object.Delete",
+ "Delete");
+ }
+ }
+ else
+ {
+ // TODO(Pawel)consider distinguish between non
+ // existing object, and other errors
+ messages::resourceNotFound(asyncResp->res,
+ "VLAN Network Interface",
+ ifaceId);
+ return;
+ }
+ });
+ });
+
+ BMCWEB_ROUTE(
+ app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/<str>/")
+ .privileges({"ConfigureComponents"})
+ .methods(boost::beast::http::verb::delete_)(
+ [](const crow::Request& /* req */,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& parentIfaceId, const std::string& ifaceId) {
+ if (!verifyNames(parentIfaceId, ifaceId))
{
- // ... otherwise return error
- // TODO(Pawel)consider distinguish between non existing
- // object, and other errors
messages::resourceNotFound(
asyncResp->res, "VLAN Network Interface", ifaceId);
+ return;
}
- });
- }
-};
-
-/**
- * VlanNetworkInterfaceCollection derived class for delivering
- * VLANNetworkInterface Collection Schema
- */
-class VlanNetworkInterfaceCollection : public Node
-{
- public:
- VlanNetworkInterfaceCollection(App& app) :
- Node(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/",
- std::string())
- {
- entityPrivileges = {
- {boost::beast::http::verb::get, {{"Login"}}},
- {boost::beast::http::verb::head, {{"Login"}}},
- {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
- }
-
- private:
- /**
- * Functions triggers appropriate requests on DBus
- */
- void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request&,
- const std::vector<std::string>& params) override
- {
- if (params.size() != 1)
- {
- // This means there is a problem with the router
- messages::internalError(asyncResp->res);
- return;
- }
- const std::string& rootInterfaceName = params[0];
+ // Get single eth interface data, and call the below callback
+ // for JSON preparation
+ getEthernetIfaceData(
+ ifaceId,
+ [asyncResp, parentIfaceId, ifaceId](
+ const bool& success,
+ const EthernetInterfaceData& ethData,
+ const boost::container::flat_set<IPv4AddressData>&,
+ const boost::container::flat_set<IPv6AddressData>&) {
+ if (success && !ethData.vlan_id.empty())
+ {
+ auto callback =
+ [asyncResp](
+ const boost::system::error_code ec) {
+ if (ec)
+ {
+ messages::internalError(asyncResp->res);
+ }
+ };
+ crow::connections::systemBus->async_method_call(
+ std::move(callback),
+ "xyz.openbmc_project.Network",
+ std::string("/xyz/openbmc_project/network/") +
+ ifaceId,
+ "xyz.openbmc_project.Object.Delete", "Delete");
+ }
+ else
+ {
+ // ... otherwise return error
+ // TODO(Pawel)consider distinguish between non
+ // existing object, and other errors
+ messages::resourceNotFound(asyncResp->res,
+ "VLAN Network Interface",
+ ifaceId);
+ }
+ });
+ });
- // Get eth interface list, and call the below callback for JSON
- // preparation
- getEthernetIfaceList(
- [asyncResp, rootInterfaceName{std::string(rootInterfaceName)}](
- const bool& success,
- const boost::container::flat_set<std::string>& ifaceList) {
+ BMCWEB_ROUTE(app,
+ "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/")
+ .privileges({"Login"})
+ .methods(
+ boost::beast::http::verb::
+ get)([](const crow::Request& /* req */,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& rootInterfaceName) {
+ // Get eth interface list, and call the below callback for JSON
+ // preparation
+ getEthernetIfaceList([asyncResp, rootInterfaceName](
+ const bool& success,
+ const boost::container::flat_set<
+ std::string>& ifaceList) {
if (!success)
{
messages::internalError(asyncResp->res);
@@ -2420,54 +2293,53 @@ class VlanNetworkInterfaceCollection : public Node
"/redfish/v1/Managers/bmc/EthernetInterfaces/" +
rootInterfaceName + "/VLANs";
});
- }
+ });
- void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request& req,
- const std::vector<std::string>& params) override
- {
- if (params.size() != 1)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- bool vlanEnable = false;
- uint32_t vlanId = 0;
- if (!json_util::readJson(req, asyncResp->res, "VLANId", vlanId,
- "VLANEnable", vlanEnable))
- {
- return;
- }
- // Need both vlanId and vlanEnable to service this request
- if (!vlanId)
- {
- messages::propertyMissing(asyncResp->res, "VLANId");
- }
- if (!vlanEnable)
- {
- messages::propertyMissing(asyncResp->res, "VLANEnable");
- }
- if (static_cast<bool>(vlanId) ^ vlanEnable)
- {
- return;
- }
+ BMCWEB_ROUTE(app,
+ "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/VLANs/")
+ .privileges({"ConfigureComponents"})
+ .methods(boost::beast::http::verb::post)(
+ [](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& rootInterfaceName) {
+ bool vlanEnable = false;
+ uint32_t vlanId = 0;
+ if (!json_util::readJson(req, asyncResp->res, "VLANId", vlanId,
+ "VLANEnable", vlanEnable))
+ {
+ return;
+ }
+ // Need both vlanId and vlanEnable to service this request
+ if (!vlanId)
+ {
+ messages::propertyMissing(asyncResp->res, "VLANId");
+ }
+ if (!vlanEnable)
+ {
+ messages::propertyMissing(asyncResp->res, "VLANEnable");
+ }
+ if (static_cast<bool>(vlanId) ^ vlanEnable)
+ {
+ return;
+ }
+
+ auto callback =
+ [asyncResp](const boost::system::error_code ec) {
+ if (ec)
+ {
+ // TODO(ed) make more consistent error messages
+ // based on phosphor-network responses
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ messages::created(asyncResp->res);
+ };
+ crow::connections::systemBus->async_method_call(
+ std::move(callback), "xyz.openbmc_project.Network",
+ "/xyz/openbmc_project/network",
+ "xyz.openbmc_project.Network.VLAN.Create", "VLAN",
+ rootInterfaceName, vlanId);
+ });
+}
- const std::string& rootInterfaceName = params[0];
- auto callback = [asyncResp](const boost::system::error_code ec) {
- if (ec)
- {
- // TODO(ed) make more consistent error messages based on
- // phosphor-network responses
- messages::internalError(asyncResp->res);
- return;
- }
- messages::created(asyncResp->res);
- };
- crow::connections::systemBus->async_method_call(
- std::move(callback), "xyz.openbmc_project.Network",
- "/xyz/openbmc_project/network",
- "xyz.openbmc_project.Network.VLAN.Create", "VLAN",
- rootInterfaceName, vlanId);
- }
-};
} // namespace redfish
diff --git a/redfish-core/lib/hypervisor_system.hpp b/redfish-core/lib/hypervisor_system.hpp
index db6c0c2d7a..0e0629d153 100644
--- a/redfish-core/lib/hypervisor_system.hpp
+++ b/redfish-core/lib/hypervisor_system.hpp
@@ -673,21 +673,6 @@ inline void handleHypervisorIPv4StaticPatch(
}
}
-inline bool isHostnameValid(const std::string& hostName)
-{
- // As per RFC 1123
- // Allow up to 255 characters
- if (hostName.length() > 255)
- {
- return false;
- }
- // Validate the regex
- const std::regex pattern(
- "^[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]$");
-
- return std::regex_match(hostName, pattern);
-}
-
inline void
handleHostnamePatch(const std::string& hostName,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)