Skip to content

Commit

Permalink
Ethernet Port: Add LLDP port schema to interfaces
Browse files Browse the repository at this point in the history
Link Layer Discovery Protocol is a Data Link Layer protocol used for
discovering devices on a local network. LLDP advertises information
about themselves to directly connected devices. This information
includes the device's identity, capabilities, and network management
information, which can be used for network monitoring, topology
discovery and network troubleshooting.

This commit will add Bmcweb changes required to enable/disable LLDP
property in ethernet interfaces.

Schema:
https://redfish.dmtf.org/schemas/v1/PortCollection.json
https://redfish.dmtf.org/schemas/v1/Port.v1_14_0.json

Tested by
Get/Patch on
curl https://xxx/redfish/v1/Managers/bmc/DedicatedNetworkPorts/eth1

{
  "@odata.id": "/redfish/v1/Managers/bmc/DedicatedNetworkPorts/eth1",
  "@odata.type": "#Port.v1_14_0.Port",
  "Ethernet": {
    "LLDPEnabled": false
  },
  "Id": "eth1",
  "Links": {
    "EthernetInterfaces": [
      {
        "@odata.id": "/redfish/v1/Managers/bmc/EthernetInterfaces/eth1"
      }
    ]
  },
  "Name": "Manager Dedicated Network Port"
}

Get on
curl https://xxx/redfish/v1/Managers/bmc/EthernetInterfaces
{
...
"Links": {
    "Ports": [
      {
        "@odata.id": "/redfish/v1/Managers/bmc/DedicatedNetworkPorts/eth1"
      }
    ],
    "[email protected]": 1
  }
...
}
Get on
curl https://xxx/redfish/v1/Managers/bmc/DedicatedNetworkPorts

{
  "@odata.id": "/redfish/v1/Managers/bmc/DedicatedNetworkPorts",
  "@odata.type": "#PortCollection.PortCollection",
  "Members": [
    {
      "@odata.id": "/redfish/v1/Managers/bmc/DedicatedNetworkPorts/eth0"
    },
    {
      "@odata.id": "/redfish/v1/Managers/bmc/DedicatedNetworkPorts/eth1"
    }
  ],
  "[email protected]": 2,
  "Name": "Port Collection"
}

Signed-off-by: Abhilash Raju <[email protected]>
  • Loading branch information
abhilashraju committed Jan 14, 2025
1 parent 165289f commit 55cbd5c
Showing 1 changed file with 206 additions and 56 deletions.
262 changes: 206 additions & 56 deletions redfish-core/lib/ethernet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2073,68 +2073,202 @@ inline void afterVlanCreate(
BMCWEB_REDFISH_MANAGER_URI_NAME, vlanInterface);
asyncResp->res.addHeader("Location", vlanInterfaceUri.buffer());
}
inline void handleNetworkPortPatch(
App& app, const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& managerId, const std::string& portId)
{
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
return;
}
if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
{
messages::resourceNotFound(asyncResp->res, "Manager", managerId);
return;
}
std::optional<bool> emitLldp;
if (!json_util::readJsonPatch(req, asyncResp->res, "Ethernet/LLDPEnabled",
emitLldp))
{
return;
}
if (emitLldp)
{
setDbusProperty(
asyncResp, "xyz.openbmc_project.Network",
sdbusplus::message::object_path("/xyz/openbmc_project/network") /
portId,
"xyz.openbmc_project.Network.EthernetInterface", "EmitLLDP",
"LLDPEnabled", *emitLldp);
}
}
inline void handleNetworkPortGet(
App& app, const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& managerId, const std::string& portId)
{
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
return;
}
if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
{
messages::resourceNotFound(asyncResp->res, "Manager", managerId);
return;
}
std::string path = "/xyz/openbmc_project/network/";
path += portId;
asyncResp->res.jsonValue["@odata.id"] =
boost::urls::format("/redfish/v1/Managers/{}/DedicatedNetworkPorts/{}",
BMCWEB_REDFISH_MANAGER_URI_NAME, portId);
asyncResp->res.jsonValue["@odata.type"] = "#Port.v1_14_0.Port";
asyncResp->res.jsonValue["Id"] = portId;
asyncResp->res.jsonValue["Name"] = "Manager Dedicated Network Port";

sdbusplus::asio::getProperty<bool>(
*crow::connections::systemBus, "xyz.openbmc_project.Network", path,
"xyz.openbmc_project.Network.EthernetInterface", "EmitLLDP",
[asyncResp, portId](const boost::system::error_code& ec, bool enabled) {
if (ec)
{
messages::internalError(asyncResp->res);
}

inline void requestEthernetInterfacesRoutes(App& app)
asyncResp->res.jsonValue["Ethernet"]["LLDPEnabled"] = enabled;
nlohmann::json ifaceArray = nlohmann::json::array();

nlohmann::json::object_t port;
port["@odata.id"] = boost::urls::format(
"/redfish/v1/Managers/{}/EthernetInterfaces/{}",
BMCWEB_REDFISH_MANAGER_URI_NAME, portId);
ifaceArray.push_back(std::move(port));
asyncResp->res.jsonValue["Links"]["EthernetInterfaces"] =
std::move(ifaceArray);
});
}
inline void populateDedicatedPortsRoutes(
App& app, const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& managerId)
{
BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/EthernetInterfaces/")
.privileges(redfish::privileges::getEthernetInterfaceCollection)
.methods(boost::beast::http::verb::get)(
[&app](const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& managerId) {
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
return;
}
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
return;
}

if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
{
messages::resourceNotFound(asyncResp->res, "Manager",
managerId);
return;
}
if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
{
messages::resourceNotFound(asyncResp->res, "Manager", managerId);
return;
}

asyncResp->res.jsonValue["@odata.type"] =
"#EthernetInterfaceCollection.EthernetInterfaceCollection";
asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
"/redfish/v1/Managers/{}/EthernetInterfaces",
BMCWEB_REDFISH_MANAGER_URI_NAME);
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 std::vector<std::string>& ifaceList) {
if (!success)
{
messages::internalError(asyncResp->res);
return;
}
asyncResp->res.jsonValue["@odata.type"] = "#PortCollection.PortCollection";
asyncResp->res.jsonValue["@odata.id"] =
boost::urls::format("/redfish/v1/Managers/{}/DedicatedNetworkPorts",
BMCWEB_REDFISH_MANAGER_URI_NAME);
asyncResp->res.jsonValue["Name"] = "Port Collection";

nlohmann::json& ifaceArray =
asyncResp->res.jsonValue["Members"];
ifaceArray = nlohmann::json::array();
for (const std::string& ifaceItem : ifaceList)
{
nlohmann::json::object_t iface;
iface["@odata.id"] = boost::urls::format(
"/redfish/v1/Managers/{}/EthernetInterfaces/{}",
BMCWEB_REDFISH_MANAGER_URI_NAME, ifaceItem);
ifaceArray.push_back(std::move(iface));
}
getEthernetIfaceList(
[asyncResp](const bool& success,
const std::vector<std::string>& ifaceList) {
if (!success)
{
messages::internalError(asyncResp->res);
return;
}

asyncResp->res.jsonValue["[email protected]"] =
ifaceArray.size();
asyncResp->res.jsonValue["@odata.id"] =
boost::urls::format(
"/redfish/v1/Managers/{}/EthernetInterfaces",
BMCWEB_REDFISH_MANAGER_URI_NAME);
});
});
nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
ifaceArray = nlohmann::json::array();
for (const std::string& ifaceItem : ifaceList)
{
nlohmann::json::object_t iface;
iface["@odata.id"] = boost::urls::format(
"/redfish/v1/Managers/{}/DedicatedNetworkPorts/{}",
BMCWEB_REDFISH_MANAGER_URI_NAME, ifaceItem);
ifaceArray.push_back(std::move(iface));
}

asyncResp->res.jsonValue["[email protected]"] = ifaceArray.size();
asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
"/redfish/v1/Managers/{}/DedicatedNetworkPorts",
BMCWEB_REDFISH_MANAGER_URI_NAME);
});
}
inline void populateConnectedPortLink(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& portId)
{
nlohmann::json ifaceArray = nlohmann::json::array();

nlohmann::json::object_t port;
port["@odata.id"] =
boost::urls::format("/redfish/v1/Managers/{}/DedicatedNetworkPorts/{}",
BMCWEB_REDFISH_MANAGER_URI_NAME, portId);
ifaceArray.push_back(std::move(port));
asyncResp->res.jsonValue["Links"]["[email protected]"] = ifaceArray.size();
asyncResp->res.jsonValue["Links"]["Ports"] = std::move(ifaceArray);
}

inline void handleEthernetInterfacesRoutes(
App& app, const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& managerId)
{
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
return;
}

if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
{
messages::resourceNotFound(asyncResp->res, "Manager", managerId);
return;
}

asyncResp->res.jsonValue["@odata.type"] =
"#EthernetInterfaceCollection.EthernetInterfaceCollection";
asyncResp->res.jsonValue["@odata.id"] =
boost::urls::format("/redfish/v1/Managers/{}/EthernetInterfaces",
BMCWEB_REDFISH_MANAGER_URI_NAME);
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 std::vector<std::string>& ifaceList) {
if (!success)
{
messages::internalError(asyncResp->res);
return;
}

nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
ifaceArray = nlohmann::json::array();
for (const std::string& ifaceItem : ifaceList)
{
nlohmann::json::object_t iface;
iface["@odata.id"] = boost::urls::format(
"/redfish/v1/Managers/{}/EthernetInterfaces/{}",
BMCWEB_REDFISH_MANAGER_URI_NAME, ifaceItem);
ifaceArray.push_back(std::move(iface));
}

asyncResp->res.jsonValue["[email protected]"] = ifaceArray.size();
asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
"/redfish/v1/Managers/{}/EthernetInterfaces",
BMCWEB_REDFISH_MANAGER_URI_NAME);
});
}
inline void requestEthernetInterfacesRoutes(App& app)
{
BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/EthernetInterfaces/")
.privileges(redfish::privileges::getEthernetInterfaceCollection)
.methods(boost::beast::http::verb::get)(
std::bind_front(handleEthernetInterfacesRoutes, std::ref(app)));

BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/EthernetInterfaces/")
.privileges(redfish::privileges::postEthernetInterfaceCollection)
Expand Down Expand Up @@ -2246,6 +2380,7 @@ inline void requestEthernetInterfacesRoutes(App& app)
managerId);
return;
}
populateConnectedPortLink(asyncResp, ifaceId);

getEthernetIfaceData(
ifaceId,
Expand Down Expand Up @@ -2463,6 +2598,21 @@ inline void requestEthernetInterfacesRoutes(App& app)
}
});
});
BMCWEB_ROUTE(app,
"/redfish/v1/Managers/<str>/DedicatedNetworkPorts/<str>/")
.privileges(redfish::privileges::patchEthernetInterface)
.methods(boost::beast::http::verb::patch)(
std::bind_front(handleNetworkPortPatch, std::ref(app)));
BMCWEB_ROUTE(app,
"/redfish/v1/Managers/<str>/DedicatedNetworkPorts/<str>/")
.privileges(redfish::privileges::patchEthernetInterface)
.methods(boost::beast::http::verb::get)(
std::bind_front(handleNetworkPortGet, std::ref(app)));
BMCWEB_ROUTE(app,
"/redfish/v1/Managers/<str>/DedicatedNetworkPorts/")
.privileges(redfish::privileges::getEthernetInterfaceCollection)
.methods(boost::beast::http::verb::get)(
std::bind_front(populateDedicatedPortsRoutes, std::ref(app)));
}

} // namespace redfish

0 comments on commit 55cbd5c

Please sign in to comment.