summaryrefslogtreecommitdiff
path: root/redfish-core/lib
diff options
context:
space:
mode:
authorJiaqing Zhao <jiaqing.zhao@intel.com>2023-03-08 10:14:58 +0300
committerEd Tanous <ed@tanous.net>2023-06-09 00:52:33 +0300
commitb5ca3fdcf15c029e36b05d619752711871bf0e8d (patch)
tree70d252c388ee96d76002bc74cc59c6f40c2f2e88 /redfish-core/lib
parente7caf25097d911dc290567e2a68ee6c4682e6890 (diff)
downloadbmcweb-b5ca3fdcf15c029e36b05d619752711871bf0e8d.tar.xz
POST EthernetInterfaceCollection for VLAN
With EthernetInterface 1.9.0, creation of VLAN interface is done by POST EthernetInterfaceCollection. This patch implements the POST handler to do so. Tested: * With valid RelatedInterfaces and VLANId provided, new VLAN interface is successfully created. * Creating VLAN over another VLAN or non-existent interface returns error. * Creating an existing VLAN returns ResourceAlreadyExists error. * Invalid RelatedInterfaces links are rejected. Change-Id: I6b1064193eccf7ec487b43139a73d9932b6eea84 Signed-off-by: Jiaqing Zhao <jiaqing.zhao@intel.com> Signed-off-by: Ed Tanous <edtanous@google.com>
Diffstat (limited to 'redfish-core/lib')
-rw-r--r--redfish-core/lib/ethernet.hpp128
1 files changed, 128 insertions, 0 deletions
diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index 74f544c9c8..1d2c988c7c 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -1749,6 +1749,50 @@ inline void afterDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
messages::internalError(asyncResp->res);
}
+inline void afterVlanCreate(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& parentInterfaceUri,
+ const std::string& vlanInterface,
+ const boost::system::error_code& ec,
+ const sdbusplus::message_t& m
+
+)
+{
+ if (ec)
+ {
+ const sd_bus_error* dbusError = m.get_error();
+ if (dbusError == nullptr)
+ {
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ BMCWEB_LOG_DEBUG << "DBus error: " << dbusError->name;
+
+ if (std::string_view(
+ "xyz.openbmc_project.Common.Error.ResourceNotFound") ==
+ dbusError->name)
+ {
+ messages::propertyValueNotInList(
+ asyncResp->res, parentInterfaceUri,
+ "Links/RelatedInterfaces/0/@odata.id");
+ return;
+ }
+ if (std::string_view(
+ "xyz.openbmc_project.Common.Error.InvalidArgument") ==
+ dbusError->name)
+ {
+ messages::resourceAlreadyExists(asyncResp->res, "EthernetInterface",
+ "Id", vlanInterface);
+ return;
+ }
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ const boost::urls::url vlanInterfaceUri = boost::urls::format(
+ "/redfish/v1/Managers/bmc/EthernetInterfaces/{}", vlanInterface);
+ asyncResp->res.addHeader("Location", vlanInterfaceUri.buffer());
+}
+
inline void requestEthernetInterfacesRoutes(App& app)
{
BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/")
@@ -1798,6 +1842,90 @@ inline void requestEthernetInterfacesRoutes(App& app)
});
});
+ BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/")
+ .privileges(redfish::privileges::postEthernetInterfaceCollection)
+ .methods(boost::beast::http::verb::post)(
+ [&app](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+
+ bool vlanEnable = false;
+ uint32_t vlanId = 0;
+ nlohmann::json::array_t relatedInterfaces;
+
+ if (!json_util::readJsonPatch(req, asyncResp->res, "VLAN/VLANEnable",
+ vlanEnable, "VLAN/VLANId", vlanId,
+ "Links/RelatedInterfaces",
+ relatedInterfaces))
+ {
+ return;
+ }
+
+ if (relatedInterfaces.size() != 1)
+ {
+ messages::arraySizeTooLong(asyncResp->res,
+ "Links/RelatedInterfaces",
+ relatedInterfaces.size());
+ return;
+ }
+
+ std::string parentInterfaceUri;
+ if (!json_util::readJson(relatedInterfaces[0], asyncResp->res,
+ "@odata.id", parentInterfaceUri))
+ {
+ messages::propertyMissing(asyncResp->res,
+ "Links/RelatedInterfaces/0/@odata.id");
+ return;
+ }
+ BMCWEB_LOG_INFO << "Parent Interface URI: " << parentInterfaceUri;
+
+ boost::urls::result<boost::urls::url_view> parsedUri =
+ boost::urls::parse_relative_ref(parentInterfaceUri);
+ if (!parsedUri)
+ {
+ messages::propertyValueFormatError(
+ asyncResp->res, parentInterfaceUri,
+ "Links/RelatedInterfaces/0/@odata.id");
+ return;
+ }
+
+ std::string parentInterface;
+ if (!crow::utility::readUrlSegments(
+ *parsedUri, "redfish", "v1", "Managers", "bmc",
+ "EthernetInterfaces", std::ref(parentInterface)))
+ {
+ messages::propertyValueNotInList(
+ asyncResp->res, parentInterfaceUri,
+ "Links/RelatedInterfaces/0/@odata.id");
+ return;
+ }
+
+ if (!vlanEnable)
+ {
+ // In OpenBMC implementation, VLANEnable cannot be false on
+ // create
+ messages::propertyValueIncorrect(asyncResp->res, "VLAN/VLANEnable",
+ "false");
+ return;
+ }
+
+ std::string vlanInterface = parentInterface + "_" +
+ std::to_string(vlanId);
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, parentInterfaceUri,
+ vlanInterface](const boost::system::error_code& ec,
+ const sdbusplus::message_t& m) {
+ afterVlanCreate(asyncResp, parentInterfaceUri, vlanInterface, ec,
+ m);
+ },
+ "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
+ "xyz.openbmc_project.Network.VLAN.Create", "VLAN", parentInterface,
+ vlanId);
+ });
+
BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/")
.privileges(redfish::privileges::getEthernetInterface)
.methods(boost::beast::http::verb::get)(