From b56e70f39943812287be1668874f9df7bc2e3422 Mon Sep 17 00:00:00 2001
From: "Wang.Bin" <Bin-B.Wang@luxshare-ict.com>
Date: Fri, 21 Mar 2025 09:12:49 +0800
Subject: [PATCH 4/4] Keep the current IP when setting ipsrc to static

---
 transporthandler.cpp | 60 ++++++++++++++++++++++++++++++++++++--------
 transporthandler.hpp |  6 +++++
 2 files changed, 56 insertions(+), 10 deletions(-)

diff --git a/transporthandler.cpp b/transporthandler.cpp
index 38faccc..bab465b 100644
--- a/transporthandler.cpp
+++ b/transporthandler.cpp
@@ -1,5 +1,11 @@
 #include "transporthandler.hpp"
 
+#include <boost/asio/ip/address.hpp>
+#include <boost/asio/ip/address_v4.hpp>
+#include <boost/asio/ip/address_v6.hpp>
+#include <stdplus/net/addr/subnet.hpp>
+#include <stdplus/raw.hpp>
+
 using phosphor::logging::commit;
 using phosphor::logging::elog;
 using phosphor::logging::entry;
@@ -162,6 +168,23 @@ auto logWithChannel(const std::optional<ChannelParams>& params, Args&&... args)
     return log<level>(std::forward<Args>(args)...);
 }
 
+/** @brief Get / Set the Property value from phosphor-networkd EthernetInterface
+ */
+template <typename T>
+static T getEthProp(sdbusplus::bus_t& bus, const ChannelParams& params,
+                    const std::string& prop)
+{
+    return std::get<T>(getDbusProperty(bus, params.service, params.logicalPath,
+                                       INTF_ETHERNET, prop));
+}
+template <typename T>
+static void setEthProp(sdbusplus::bus_t& bus, const ChannelParams& params,
+                       const std::string& prop, const T& t)
+{
+    return setDbusProperty(bus, params.service, params.logicalPath,
+                           INTF_ETHERNET, prop, t);
+}
+
 EthernetInterface::DHCPConf getDHCPProperty(sdbusplus::bus_t& bus,
                                             const ChannelParams& params)
 {
@@ -316,18 +339,25 @@ void deleteObjectIfExists(sdbusplus::bus_t& bus, const std::string& service,
     {
         auto req = bus.new_method_call(service.c_str(), path.c_str(),
                                        ipmi::DELETE_INTERFACE, "Delete");
-        bus.call_noreply(req);
+        
+        bus.call_noreply(req);  
     }
     catch (const sdbusplus::exception_t& e)
     {
         if (strcmp(e.name(),
                    "xyz.openbmc_project.Common.Error.InternalFailure") != 0 &&
-            strcmp(e.name(), "org.freedesktop.DBus.Error.UnknownObject") != 0)
+            strcmp(e.name(), "org.freedesktop.DBus.Error.UnknownObject") != 0 &&
+            strcmp(e.name(), "xyz.openbmc_project.Common.Error.NotAllowed") !=
+                0)
         {
             // We want to rethrow real errors
             throw;
         }
     }
+    catch (...)
+    {
+        throw;
+    }
 }
 
 /** @brief Sets the address info configured for the interface
@@ -383,18 +413,20 @@ void reconfigureIfAddr4(sdbusplus::bus_t& bus, const ChannelParams& params,
         elog<InternalFailure>();
     }
     uint8_t fallbackPrefix = AddrFamily<AF_INET>::defaultPrefix;
+    auto addr = address.value_or(ifaddr->address);
+    // if (!validIntfIP(addr))
+    // {
+    //     log<level::ERR>("IPv4 not unicast");
+    //     elog<InternalFailure>();
+    // }
     if (ifaddr)
     {
         fallbackPrefix = ifaddr->prefix;
         deleteObjectIfExists(bus, params.service, ifaddr->path);
     }
-
-    if (struct in_addr nullIPv4{0};
-        (address == std::nullopt && prefix != std::nullopt) ||
-        (address != std::nullopt &&
-         (address.value().s_addr != nullIPv4.s_addr)))
+    if (addr != stdplus::In4Addr{})
     {
-        createIfAddr<AF_INET>(bus, params, address.value_or(ifaddr->address),
+        createIfAddr<AF_INET>(bus, params, addr,
                               prefix.value_or(fallbackPrefix));
     }
 }
@@ -980,8 +1012,16 @@ RspType<> setLan(Context::ptr ctx, uint4_t channelBits, uint4_t reserved1,
                 case IPSrc::Unspecified:
                 case IPSrc::Static:
                 {
-                    channelCall<setDHCPv4Property>(
-                        channel, EthernetInterface::DHCPConf::none);
+                    auto ifaddr = channelCall<getIfAddr4>(channel);
+
+                    //channelCall<setDHCPv4Property>(channel, EthernetInterface::DHCPConf::none);
+                    channelCall<setEthProp<bool>>(channel, "DHCP4", false);
+
+                    if (ifaddr)
+                    {
+                        channelCall<reconfigureIfAddr4>(channel, ifaddr->address, ifaddr->prefix);
+                    }
+
                     return responseSuccess();
                 }
                 case IPSrc::BIOS:
diff --git a/transporthandler.hpp b/transporthandler.hpp
index 8e1c4fb..a4e862b 100644
--- a/transporthandler.hpp
+++ b/transporthandler.hpp
@@ -17,6 +17,12 @@
 #include <phosphor-logging/log.hpp>
 #include <sdbusplus/bus.hpp>
 #include <sdbusplus/exception.hpp>
+
+#include <stdplus/net/addr/ether.hpp>
+#include <stdplus/net/addr/ip.hpp>
+#include <stdplus/str/conv.hpp>
+#include <stdplus/zstring_view.hpp>
+
 #include <user_channel/channel_layer.hpp>
 #include <xyz/openbmc_project/Common/error.hpp>
 #include <xyz/openbmc_project/Network/EthernetInterface/server.hpp>
-- 
2.25.1

