Add LLDP configuration support
This commit implements EmitLLDP D-bus property to support configuration
of enable/disable LLDP of each ethernet interface.
Tested by:
Set EmitLLDP D-bus property on
xyz.openbmc_project.Network.EthernetInterface
Change-Id: I4ebedff9d3f914219f2f84c861fdee126584a94b
Signed-off-by: Ravi Teja <raviteja28031990@gmail.com>
diff --git a/src/ethernet_interface.cpp b/src/ethernet_interface.cpp
index 46967f5..9cef02f 100644
--- a/src/ethernet_interface.cpp
+++ b/src/ethernet_interface.cpp
@@ -102,7 +102,11 @@
EthernetInterfaceIntf::dhcp6(dhcpVal.v6, true);
EthernetInterfaceIntf::ipv6AcceptRA(getIPv6AcceptRA(config), true);
EthernetInterfaceIntf::nicEnabled(enabled, true);
-
+ auto lldpVal = parseLLDPConf();
+ if (!lldpVal.empty())
+ {
+ EthernetInterfaceIntf::emitLLDP(lldpVal[interfaceName()], true);
+ }
EthernetInterfaceIntf::ntpServers(
config.map.getValueStrings("Network", "NTP"), true);
@@ -1094,6 +1098,16 @@
eth.get().manager.get().reloadConfigs();
}
+bool EthernetInterface::emitLLDP(bool value)
+{
+ if (emitLLDP() != EthernetInterfaceIntf::emitLLDP(value))
+ {
+ manager.get().writeLLDPDConfigurationFile();
+ manager.get().reloadLLDPService();
+ }
+ return value;
+}
+
void EthernetInterface::reloadConfigs()
{
manager.get().reloadConfigs();
diff --git a/src/ethernet_interface.hpp b/src/ethernet_interface.hpp
index 3140528..858779b 100644
--- a/src/ethernet_interface.hpp
+++ b/src/ethernet_interface.hpp
@@ -227,6 +227,11 @@
*/
void reloadConfigs();
+ /** @brief set conf file for LLDP
+ * @param[in] value - lldp value of the interface.
+ */
+ bool emitLLDP(bool value) override;
+
using EthernetInterfaceIntf::interfaceName;
using EthernetInterfaceIntf::linkUp;
using EthernetInterfaceIntf::mtu;
@@ -235,6 +240,7 @@
using EthernetInterfaceIntf::defaultGateway;
using EthernetInterfaceIntf::defaultGateway6;
+ using EthernetInterfaceIntf::emitLLDP;
protected:
/** @brief get the NTP server list from the timsyncd dbus obj
diff --git a/src/network_manager.cpp b/src/network_manager.cpp
index fb3a801..75c759b 100644
--- a/src/network_manager.cpp
+++ b/src/network_manager.cpp
@@ -22,6 +22,7 @@
#include <filesystem>
#include <format>
+#include <fstream>
namespace phosphor
{
@@ -33,6 +34,12 @@
using Argument = xyz::openbmc_project::Common::InvalidArgument;
using std::literals::string_view_literals::operator""sv;
+constexpr auto systemdBusname = "org.freedesktop.systemd1";
+constexpr auto systemdObjPath = "/org/freedesktop/systemd1";
+constexpr auto systemdInterface = "org.freedesktop.systemd1.Manager";
+constexpr auto lldpFilePath = "/etc/lldpd.conf";
+constexpr auto lldpService = "lldpd.service";
+
static constexpr const char enabledMatch[] =
"type='signal',sender='org.freedesktop.network1',path_namespace='/org/"
"freedesktop/network1/"
@@ -515,5 +522,45 @@
}
}
+void Manager::writeLLDPDConfigurationFile()
+{
+ std::ofstream lldpdConfig(lldpFilePath);
+
+ lldpdConfig << "configure system description BMC" << std::endl;
+ lldpdConfig << "configure system ip management pattern eth*" << std::endl;
+ for (const auto& intf : interfaces)
+ {
+ bool emitlldp = intf.second->emitLLDP();
+ if (emitlldp)
+ {
+ lldpdConfig << "configure ports " << intf.second->interfaceName()
+ << " lldp status tx-only" << std::endl;
+ }
+ else
+ {
+ lldpdConfig << "configure ports " << intf.second->interfaceName()
+ << " lldp status disabled" << std::endl;
+ }
+ }
+
+ lldpdConfig.close();
+}
+
+void Manager::reloadLLDPService()
+{
+ try
+ {
+ auto method = bus.get().new_method_call(
+ systemdBusname, systemdObjPath, systemdInterface, "RestartUnit");
+ method.append(lldpService, "replace");
+ bus.get().call_noreply(method);
+ }
+ catch (const sdbusplus::exception_t& ex)
+ {
+ lg2::error("Failed to restart service {SERVICE}: {ERR}", "SERVICE",
+ lldpService, "ERR", ex);
+ }
+}
+
} // namespace network
} // namespace phosphor
diff --git a/src/network_manager.hpp b/src/network_manager.hpp
index b92c528..3bc8ad2 100644
--- a/src/network_manager.hpp
+++ b/src/network_manager.hpp
@@ -55,6 +55,10 @@
*/
void writeToConfigurationFile();
+ /** @brief write the lldp conf file
+ */
+ void writeLLDPDConfigurationFile();
+
/** @brief Adds a single interface to the interface map */
void addInterface(const InterfaceInfo& info);
void removeInterface(const InterfaceInfo& info);
@@ -102,6 +106,10 @@
reload.get().schedule();
}
+ /** Reload LLDP configuration
+ */
+ void reloadLLDPService();
+
/** @brief Persistent map of EthernetInterface dbus objects and their names
*/
stdplus::string_umap<std::unique_ptr<EthernetInterface>> interfaces;
diff --git a/src/util.cpp b/src/util.cpp
index edee79a..ac4d1b4 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -15,6 +15,7 @@
#include <xyz/openbmc_project/Common/error.hpp>
#include <cctype>
+#include <fstream>
#include <string>
#include <string_view>
@@ -26,6 +27,7 @@
using std::literals::string_view_literals::operator""sv;
using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+static constexpr std::string_view lldpdConfigFilePath = "/etc/lldpd.conf";
namespace internal
{
@@ -226,5 +228,42 @@
.value_or(true);
}
+std::map<std::string, bool> parseLLDPConf()
+{
+ std::ifstream lldpdConfig(lldpdConfigFilePath.data());
+ std::map<std::string, bool> portStatus;
+
+ if (!lldpdConfig.is_open())
+ {
+ return portStatus;
+ }
+
+ std::string line;
+ while (std::getline(lldpdConfig, line))
+ {
+ std::string configurePortsStr = "configure ports ";
+ std::string lldpStatusStr = "lldp status ";
+ size_t portStart = line.find(configurePortsStr);
+ if (portStart != std::string::npos)
+ {
+ portStart += configurePortsStr.size();
+ size_t portEnd = line.find(' ', portStart);
+ if (portEnd == std::string::npos)
+ {
+ portEnd = line.length();
+ }
+ std::string portName = line.substr(portStart, portEnd - portStart);
+ size_t pos = line.find(lldpStatusStr);
+ if (pos != std::string::npos)
+ {
+ std::string statusStr = line.substr(pos + lldpStatusStr.size());
+ portStatus[portName] = (statusStr == "disabled") ? false : true;
+ }
+ }
+ }
+ lldpdConfig.close();
+ return portStatus;
+}
+
} // namespace network
} // namespace phosphor
diff --git a/src/util.hpp b/src/util.hpp
index ae34ad6..1c71eab 100644
--- a/src/util.hpp
+++ b/src/util.hpp
@@ -4,6 +4,7 @@
#include <stdplus/raw.hpp>
#include <stdplus/zstring_view.hpp>
+#include <map>
#include <optional>
#include <string>
#include <string_view>
@@ -72,6 +73,10 @@
bool getDHCPProp(const config::Parser& config, DHCPType dhcpType,
std::string_view key);
+/** @brief Read LLDP configuration from lldpd conf file
+ */
+std::map<std::string, bool> parseLLDPConf();
+
namespace internal
{