From cbd034daf844529eb7f098c990dc8f44c12f6b97 Mon Sep 17 00:00:00 2001 From: sunitakx Date: Tue, 13 Jul 2021 12:54:01 +0000 Subject: [PATCH] Fix for updating MAC address from RedFish Issue: When IP address source for an interface is DHCP and its MAC address is patched using RedFish, response code is not reaching the RedFish request initiator (client). RootCause: After bmcweb patches the MAC address, immediately IP address of that interface also changes to new value (because of DHCP). Due to this, success response from bmcweb is not reaching the client as expected. Fix: Do MAC-ADDR patching after validating the request and responding "200 OK" to RedFish client. i.e Start a timer which will modify the MAC-ADDR at the end of its expiry. Tested: Update the MAC address from RedFish. PATCH: https:///redfish/v1/Managers/bmc/EthernetInterfaces/eth0 Body: {"MACAddress": "xx:xx:xx:xx:xx:xx"} Response code: {"200 OK"} received. Signed-off-by: sunitakx Signed-off-by: Ramya Narayana --- src/ethernet_interface.cpp | 17 ++++++++++++----- src/ethernet_interface.hpp | 5 +++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/ethernet_interface.cpp b/src/ethernet_interface.cpp index 1145773..129905e 100644 --- a/src/ethernet_interface.cpp +++ b/src/ethernet_interface.cpp @@ -143,6 +143,8 @@ EthernetInterface::EthernetInterface(sdbusplus::bus::bus& bus, { this->emit_object_added(); } + macUpdateTimer = std::make_unique( + [this](void) { macAddressTimeoutHandler(); }); } static IP::Protocol convertFamily(int family) @@ -1209,8 +1211,17 @@ void EthernetInterface::writeDHCPSection(std::fstream& stream) } } +void EthernetInterface::macAddressTimeoutHandler() +{ + macUpdateTimer->stop(); + // The MAC and LLADDRs will only update if the NIC is already down + EthernetIntfSocket eifSocket(PF_INET, SOCK_DGRAM, IPPROTO_IP); + setNICAdminState(eifSocket.sock, interfaceName().c_str(), false); + manager.reloadConfigs(); +} std::string EthernetInterface::macAddress(std::string value) { + std::chrono::seconds usec(defaultTimeout); ether_addr newMAC; try { @@ -1244,12 +1255,8 @@ std::string EthernetInterface::macAddress(std::string value) intf->MacAddressIntf::macAddress(validMAC); } MacAddressIntf::macAddress(validMAC); - + macUpdateTimer->start(usec); writeConfigurationFile(); - // The MAC and LLADDRs will only update if the NIC is already down - EthernetIntfSocket eifSocket(PF_INET, SOCK_DGRAM, IPPROTO_IP); - setNICAdminState(eifSocket.sock, interface.c_str(), false); - manager.reloadConfigs(); } #ifdef HAVE_UBOOT_ENV diff --git a/src/ethernet_interface.hpp b/src/ethernet_interface.hpp index fa5c889..70f4756 100644 --- a/src/ethernet_interface.hpp +++ b/src/ethernet_interface.hpp @@ -11,11 +11,14 @@ #include #include #include +#include #include #include #include #include +static constexpr const uint32_t defaultTimeout = 1; + namespace phosphor { namespace network @@ -84,6 +87,8 @@ class EthernetInterface : public Ifaces EthernetInterface& operator=(EthernetInterface&&) = delete; virtual ~EthernetInterface() = default; + std::unique_ptr macUpdateTimer; + void macAddressTimeoutHandler(); /** @brief Constructor to put object onto bus at a dbus path. * @param[in] bus - Bus to attach to. * @param[in] objPath - Path to attach at. -- 2.17.1