summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0004-Fix-for-updating-MAC-address-from-RedFish.patch
blob: 90bbc1d5b74d00171584f5d3a2cedd099361e033 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
From cbd034daf844529eb7f098c990dc8f44c12f6b97 Mon Sep 17 00:00:00 2001
From: sunitakx <sunitax.kumari@linux.intel.com>
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://<bmc_ip>/redfish/v1/Managers/bmc/EthernetInterfaces/eth0
Body:
  {"MACAddress": "xx:xx:xx:xx:xx:xx"}

Response code: {"200 OK"} received.

Signed-off-by: sunitakx <sunitax.kumari@linux.intel.com>
Signed-off-by: Ramya Narayana <ramyax.narayana@intel.com>
---
 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<phosphor::Timer>(
+        [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 <sdbusplus/bus.hpp>
 #include <sdbusplus/bus/match.hpp>
 #include <sdbusplus/server/object.hpp>
+#include <sdbusplus/timer.hpp>
 #include <string>
 #include <xyz/openbmc_project/Collection/DeleteAll/server.hpp>
 #include <xyz/openbmc_project/Network/EthernetInterface/server.hpp>
 #include <xyz/openbmc_project/Network/MACAddress/server.hpp>
 
+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<phosphor::Timer> 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