xref: /openbmc/bmcweb/features/redfish/lib/ethernet.hpp (revision bd79bce8c3f1deb1fb2773868b9ece25233cf27b)
19391bb9cSRapkiewicz, Pawel /*
29391bb9cSRapkiewicz, Pawel // Copyright (c) 2018 Intel Corporation
39391bb9cSRapkiewicz, Pawel //
49391bb9cSRapkiewicz, Pawel // Licensed under the Apache License, Version 2.0 (the "License");
59391bb9cSRapkiewicz, Pawel // you may not use this file except in compliance with the License.
69391bb9cSRapkiewicz, Pawel // You may obtain a copy of the License at
79391bb9cSRapkiewicz, Pawel //
89391bb9cSRapkiewicz, Pawel //      http://www.apache.org/licenses/LICENSE-2.0
99391bb9cSRapkiewicz, Pawel //
109391bb9cSRapkiewicz, Pawel // Unless required by applicable law or agreed to in writing, software
119391bb9cSRapkiewicz, Pawel // distributed under the License is distributed on an "AS IS" BASIS,
129391bb9cSRapkiewicz, Pawel // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139391bb9cSRapkiewicz, Pawel // See the License for the specific language governing permissions and
149391bb9cSRapkiewicz, Pawel // limitations under the License.
159391bb9cSRapkiewicz, Pawel */
169391bb9cSRapkiewicz, Pawel #pragma once
179391bb9cSRapkiewicz, Pawel 
183ccb3adbSEd Tanous #include "app.hpp"
193ccb3adbSEd Tanous #include "dbus_singleton.hpp"
207a1dbc48SGeorge Liu #include "dbus_utility.hpp"
213ccb3adbSEd Tanous #include "error_messages.hpp"
22539d8c6bSEd Tanous #include "generated/enums/ethernet_interface.hpp"
23539d8c6bSEd Tanous #include "generated/enums/resource.hpp"
242c5875a2SEd Tanous #include "human_sort.hpp"
253ccb3adbSEd Tanous #include "query.hpp"
263ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
27033f1e4dSEd Tanous #include "utils/ip_utils.hpp"
283ccb3adbSEd Tanous #include "utils/json_utils.hpp"
29033f1e4dSEd Tanous 
30ce73d5c8SSunitha Harish #include <boost/system/error_code.hpp>
31ef4c65b7SEd Tanous #include <boost/url/format.hpp>
321214b7e7SGunnar Mills 
337a1dbc48SGeorge Liu #include <array>
343dfed536SEd Tanous #include <cstddef>
35ce73d5c8SSunitha Harish #include <memory>
36a24526dcSEd Tanous #include <optional>
373544d2a7SEd Tanous #include <ranges>
38ab6554f1SJoshi-Mansi #include <regex>
397a1dbc48SGeorge Liu #include <string_view>
403dfed536SEd Tanous #include <variant>
4177179532SEd Tanous #include <vector>
429391bb9cSRapkiewicz, Pawel 
431abe55efSEd Tanous namespace redfish
441abe55efSEd Tanous {
459391bb9cSRapkiewicz, Pawel 
464a0cb85cSEd Tanous enum class LinkType
474a0cb85cSEd Tanous {
484a0cb85cSEd Tanous     Local,
494a0cb85cSEd Tanous     Global
504a0cb85cSEd Tanous };
519391bb9cSRapkiewicz, Pawel 
52743eb1c0SJohnathan Mantey enum class IpVersion
53743eb1c0SJohnathan Mantey {
54743eb1c0SJohnathan Mantey     IpV4,
55743eb1c0SJohnathan Mantey     IpV6
56743eb1c0SJohnathan Mantey };
57743eb1c0SJohnathan Mantey 
589391bb9cSRapkiewicz, Pawel /**
599391bb9cSRapkiewicz, Pawel  * Structure for keeping IPv4 data required by Redfish
609391bb9cSRapkiewicz, Pawel  */
611abe55efSEd Tanous struct IPv4AddressData
621abe55efSEd Tanous {
63179db1d7SKowalski, Kamil     std::string id;
644a0cb85cSEd Tanous     std::string address;
654a0cb85cSEd Tanous     std::string domain;
664a0cb85cSEd Tanous     std::string gateway;
679391bb9cSRapkiewicz, Pawel     std::string netmask;
689391bb9cSRapkiewicz, Pawel     std::string origin;
6977179532SEd Tanous     LinkType linktype{};
7077179532SEd Tanous     bool isActive{};
719391bb9cSRapkiewicz, Pawel };
729391bb9cSRapkiewicz, Pawel 
739391bb9cSRapkiewicz, Pawel /**
74e48c0fc5SRavi Teja  * Structure for keeping IPv6 data required by Redfish
75e48c0fc5SRavi Teja  */
76e48c0fc5SRavi Teja struct IPv6AddressData
77e48c0fc5SRavi Teja {
78e48c0fc5SRavi Teja     std::string id;
79e48c0fc5SRavi Teja     std::string address;
80e48c0fc5SRavi Teja     std::string origin;
8177179532SEd Tanous     uint8_t prefixLength = 0;
82e48c0fc5SRavi Teja };
83ce73d5c8SSunitha Harish 
84ce73d5c8SSunitha Harish /**
85ce73d5c8SSunitha Harish  * Structure for keeping static route data required by Redfish
86ce73d5c8SSunitha Harish  */
87ce73d5c8SSunitha Harish struct StaticGatewayData
88ce73d5c8SSunitha Harish {
89ce73d5c8SSunitha Harish     std::string id;
90ce73d5c8SSunitha Harish     std::string gateway;
91ce73d5c8SSunitha Harish     size_t prefixLength = 0;
92ce73d5c8SSunitha Harish     std::string protocol;
93ce73d5c8SSunitha Harish };
94ce73d5c8SSunitha Harish 
95e48c0fc5SRavi Teja /**
969391bb9cSRapkiewicz, Pawel  * Structure for keeping basic single Ethernet Interface information
979391bb9cSRapkiewicz, Pawel  * available from DBus
989391bb9cSRapkiewicz, Pawel  */
991abe55efSEd Tanous struct EthernetInterfaceData
1001abe55efSEd Tanous {
1014a0cb85cSEd Tanous     uint32_t speed;
10235fb5311STejas Patil     size_t mtuSize;
10382695a5bSJiaqing Zhao     bool autoNeg;
104e4588158SJishnu CM     bool dnsv4Enabled;
105e4588158SJishnu CM     bool dnsv6Enabled;
10691c441ecSRavi Teja     bool domainv4Enabled;
10791c441ecSRavi Teja     bool domainv6Enabled;
108e4588158SJishnu CM     bool ntpv4Enabled;
109e4588158SJishnu CM     bool ntpv6Enabled;
110e4588158SJishnu CM     bool hostNamev4Enabled;
111e4588158SJishnu CM     bool hostNamev6Enabled;
112aa05fb27SJohnathan Mantey     bool linkUp;
113eeedda23SJohnathan Mantey     bool nicEnabled;
114b10d8db0SRavi Teja     bool ipv6AcceptRa;
11582695a5bSJiaqing Zhao     std::string dhcpEnabled;
1161f8c7b5dSJohnathan Mantey     std::string operatingMode;
11782695a5bSJiaqing Zhao     std::string hostName;
11882695a5bSJiaqing Zhao     std::string defaultGateway;
11982695a5bSJiaqing Zhao     std::string ipv6DefaultGateway;
120ce73d5c8SSunitha Harish     std::string ipv6StaticDefaultGateway;
12182695a5bSJiaqing Zhao     std::string macAddress;
12217e22024SJiaqing Zhao     std::optional<uint32_t> vlanId;
1230f6efdc1Smanojkiran.eda@gmail.com     std::vector<std::string> nameServers;
1240f6efdc1Smanojkiran.eda@gmail.com     std::vector<std::string> staticNameServers;
125d24bfc7aSJennifer Lee     std::vector<std::string> domainnames;
1269391bb9cSRapkiewicz, Pawel };
1279391bb9cSRapkiewicz, Pawel 
1281f8c7b5dSJohnathan Mantey struct DHCPParameters
1291f8c7b5dSJohnathan Mantey {
1301f8c7b5dSJohnathan Mantey     std::optional<bool> dhcpv4Enabled;
13182695a5bSJiaqing Zhao     std::optional<bool> useDnsServers;
13282695a5bSJiaqing Zhao     std::optional<bool> useNtpServers;
13382695a5bSJiaqing Zhao     std::optional<bool> useDomainName;
1341f8c7b5dSJohnathan Mantey     std::optional<std::string> dhcpv6OperatingMode;
1351f8c7b5dSJohnathan Mantey };
1361f8c7b5dSJohnathan Mantey 
1379391bb9cSRapkiewicz, Pawel // Helper function that changes bits netmask notation (i.e. /24)
1389391bb9cSRapkiewicz, Pawel // into full dot notation
1391abe55efSEd Tanous inline std::string getNetmask(unsigned int bits)
1401abe55efSEd Tanous {
1419391bb9cSRapkiewicz, Pawel     uint32_t value = 0xffffffff << (32 - bits);
1429391bb9cSRapkiewicz, Pawel     std::string netmask = std::to_string((value >> 24) & 0xff) + "." +
1439391bb9cSRapkiewicz, Pawel                           std::to_string((value >> 16) & 0xff) + "." +
1449391bb9cSRapkiewicz, Pawel                           std::to_string((value >> 8) & 0xff) + "." +
1459391bb9cSRapkiewicz, Pawel                           std::to_string(value & 0xff);
1469391bb9cSRapkiewicz, Pawel     return netmask;
1479391bb9cSRapkiewicz, Pawel }
1489391bb9cSRapkiewicz, Pawel 
14982695a5bSJiaqing Zhao inline bool translateDhcpEnabledToBool(const std::string& inputDHCP,
1501f8c7b5dSJohnathan Mantey                                        bool isIPv4)
1511f8c7b5dSJohnathan Mantey {
1521f8c7b5dSJohnathan Mantey     if (isIPv4)
1531f8c7b5dSJohnathan Mantey     {
1541f8c7b5dSJohnathan Mantey         return (
1551f8c7b5dSJohnathan Mantey             (inputDHCP ==
1561f8c7b5dSJohnathan Mantey              "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v4") ||
1571f8c7b5dSJohnathan Mantey             (inputDHCP ==
1581f8c7b5dSJohnathan Mantey              "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.both"));
1591f8c7b5dSJohnathan Mantey     }
1601f8c7b5dSJohnathan Mantey     return ((inputDHCP ==
1611f8c7b5dSJohnathan Mantey              "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v6") ||
1621f8c7b5dSJohnathan Mantey             (inputDHCP ==
1631f8c7b5dSJohnathan Mantey              "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.both"));
1641f8c7b5dSJohnathan Mantey }
1651f8c7b5dSJohnathan Mantey 
1662c70f800SEd Tanous inline std::string getDhcpEnabledEnumeration(bool isIPv4, bool isIPv6)
1671f8c7b5dSJohnathan Mantey {
1681f8c7b5dSJohnathan Mantey     if (isIPv4 && isIPv6)
1691f8c7b5dSJohnathan Mantey     {
1701f8c7b5dSJohnathan Mantey         return "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.both";
1711f8c7b5dSJohnathan Mantey     }
1723174e4dfSEd Tanous     if (isIPv4)
1731f8c7b5dSJohnathan Mantey     {
1741f8c7b5dSJohnathan Mantey         return "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v4";
1751f8c7b5dSJohnathan Mantey     }
1763174e4dfSEd Tanous     if (isIPv6)
1771f8c7b5dSJohnathan Mantey     {
1781f8c7b5dSJohnathan Mantey         return "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v6";
1791f8c7b5dSJohnathan Mantey     }
1801f8c7b5dSJohnathan Mantey     return "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.none";
1811f8c7b5dSJohnathan Mantey }
1821f8c7b5dSJohnathan Mantey 
183*bd79bce8SPatrick Williams inline std::string translateAddressOriginDbusToRedfish(
184*bd79bce8SPatrick Williams     const std::string& inputOrigin, bool isIPv4)
1851abe55efSEd Tanous {
1864a0cb85cSEd Tanous     if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.Static")
1871abe55efSEd Tanous     {
1884a0cb85cSEd Tanous         return "Static";
1899391bb9cSRapkiewicz, Pawel     }
1904a0cb85cSEd Tanous     if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.LinkLocal")
1911abe55efSEd Tanous     {
1924a0cb85cSEd Tanous         if (isIPv4)
1931abe55efSEd Tanous         {
1944a0cb85cSEd Tanous             return "IPv4LinkLocal";
1951abe55efSEd Tanous         }
1964a0cb85cSEd Tanous         return "LinkLocal";
1979391bb9cSRapkiewicz, Pawel     }
1984a0cb85cSEd Tanous     if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP")
1991abe55efSEd Tanous     {
2004a0cb85cSEd Tanous         if (isIPv4)
2014a0cb85cSEd Tanous         {
2024a0cb85cSEd Tanous             return "DHCP";
2034a0cb85cSEd Tanous         }
2044a0cb85cSEd Tanous         return "DHCPv6";
2054a0cb85cSEd Tanous     }
2064a0cb85cSEd Tanous     if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.SLAAC")
2074a0cb85cSEd Tanous     {
2084a0cb85cSEd Tanous         return "SLAAC";
2094a0cb85cSEd Tanous     }
2104a0cb85cSEd Tanous     return "";
2114a0cb85cSEd Tanous }
2124a0cb85cSEd Tanous 
21302cad96eSEd Tanous inline bool extractEthernetInterfaceData(
21402cad96eSEd Tanous     const std::string& ethifaceId,
21502cad96eSEd Tanous     const dbus::utility::ManagedObjectType& dbusData,
2164a0cb85cSEd Tanous     EthernetInterfaceData& ethData)
2174a0cb85cSEd Tanous {
2184c9afe43SEd Tanous     bool idFound = false;
21902cad96eSEd Tanous     for (const auto& objpath : dbusData)
2204a0cb85cSEd Tanous     {
22102cad96eSEd Tanous         for (const auto& ifacePair : objpath.second)
2224a0cb85cSEd Tanous         {
22381ce609eSEd Tanous             if (objpath.first == "/xyz/openbmc_project/network/" + ethifaceId)
224029573d4SEd Tanous             {
2254c9afe43SEd Tanous                 idFound = true;
2264a0cb85cSEd Tanous                 if (ifacePair.first == "xyz.openbmc_project.Network.MACAddress")
2274a0cb85cSEd Tanous                 {
2284a0cb85cSEd Tanous                     for (const auto& propertyPair : ifacePair.second)
2294a0cb85cSEd Tanous                     {
2304a0cb85cSEd Tanous                         if (propertyPair.first == "MACAddress")
2314a0cb85cSEd Tanous                         {
2324a0cb85cSEd Tanous                             const std::string* mac =
233abf2add6SEd Tanous                                 std::get_if<std::string>(&propertyPair.second);
2344a0cb85cSEd Tanous                             if (mac != nullptr)
2354a0cb85cSEd Tanous                             {
23682695a5bSJiaqing Zhao                                 ethData.macAddress = *mac;
2374a0cb85cSEd Tanous                             }
2384a0cb85cSEd Tanous                         }
2394a0cb85cSEd Tanous                     }
2404a0cb85cSEd Tanous                 }
2414a0cb85cSEd Tanous                 else if (ifacePair.first == "xyz.openbmc_project.Network.VLAN")
2424a0cb85cSEd Tanous                 {
2434a0cb85cSEd Tanous                     for (const auto& propertyPair : ifacePair.second)
2444a0cb85cSEd Tanous                     {
2454a0cb85cSEd Tanous                         if (propertyPair.first == "Id")
2464a0cb85cSEd Tanous                         {
2471b6b96c5SEd Tanous                             const uint32_t* id =
248abf2add6SEd Tanous                                 std::get_if<uint32_t>(&propertyPair.second);
2494a0cb85cSEd Tanous                             if (id != nullptr)
2504a0cb85cSEd Tanous                             {
25117e22024SJiaqing Zhao                                 ethData.vlanId = *id;
2524a0cb85cSEd Tanous                             }
2534a0cb85cSEd Tanous                         }
2544a0cb85cSEd Tanous                     }
2554a0cb85cSEd Tanous                 }
2564a0cb85cSEd Tanous                 else if (ifacePair.first ==
2574a0cb85cSEd Tanous                          "xyz.openbmc_project.Network.EthernetInterface")
2584a0cb85cSEd Tanous                 {
2594a0cb85cSEd Tanous                     for (const auto& propertyPair : ifacePair.second)
2604a0cb85cSEd Tanous                     {
2614a0cb85cSEd Tanous                         if (propertyPair.first == "AutoNeg")
2624a0cb85cSEd Tanous                         {
2632c70f800SEd Tanous                             const bool* autoNeg =
264abf2add6SEd Tanous                                 std::get_if<bool>(&propertyPair.second);
2652c70f800SEd Tanous                             if (autoNeg != nullptr)
2664a0cb85cSEd Tanous                             {
26782695a5bSJiaqing Zhao                                 ethData.autoNeg = *autoNeg;
2684a0cb85cSEd Tanous                             }
2694a0cb85cSEd Tanous                         }
2704a0cb85cSEd Tanous                         else if (propertyPair.first == "Speed")
2714a0cb85cSEd Tanous                         {
2724a0cb85cSEd Tanous                             const uint32_t* speed =
273abf2add6SEd Tanous                                 std::get_if<uint32_t>(&propertyPair.second);
2744a0cb85cSEd Tanous                             if (speed != nullptr)
2754a0cb85cSEd Tanous                             {
2764a0cb85cSEd Tanous                                 ethData.speed = *speed;
2774a0cb85cSEd Tanous                             }
2784a0cb85cSEd Tanous                         }
27935fb5311STejas Patil                         else if (propertyPair.first == "MTU")
28035fb5311STejas Patil                         {
2813e7a8da6SAnthony                             const size_t* mtuSize =
2823e7a8da6SAnthony                                 std::get_if<size_t>(&propertyPair.second);
28335fb5311STejas Patil                             if (mtuSize != nullptr)
28435fb5311STejas Patil                             {
28535fb5311STejas Patil                                 ethData.mtuSize = *mtuSize;
28635fb5311STejas Patil                             }
28735fb5311STejas Patil                         }
288aa05fb27SJohnathan Mantey                         else if (propertyPair.first == "LinkUp")
289aa05fb27SJohnathan Mantey                         {
290aa05fb27SJohnathan Mantey                             const bool* linkUp =
291aa05fb27SJohnathan Mantey                                 std::get_if<bool>(&propertyPair.second);
292aa05fb27SJohnathan Mantey                             if (linkUp != nullptr)
293aa05fb27SJohnathan Mantey                             {
294aa05fb27SJohnathan Mantey                                 ethData.linkUp = *linkUp;
295aa05fb27SJohnathan Mantey                             }
296aa05fb27SJohnathan Mantey                         }
297eeedda23SJohnathan Mantey                         else if (propertyPair.first == "NICEnabled")
298eeedda23SJohnathan Mantey                         {
299eeedda23SJohnathan Mantey                             const bool* nicEnabled =
300eeedda23SJohnathan Mantey                                 std::get_if<bool>(&propertyPair.second);
301eeedda23SJohnathan Mantey                             if (nicEnabled != nullptr)
302eeedda23SJohnathan Mantey                             {
303eeedda23SJohnathan Mantey                                 ethData.nicEnabled = *nicEnabled;
304eeedda23SJohnathan Mantey                             }
305eeedda23SJohnathan Mantey                         }
306b10d8db0SRavi Teja                         else if (propertyPair.first == "IPv6AcceptRA")
307b10d8db0SRavi Teja                         {
308b10d8db0SRavi Teja                             const bool* ipv6AcceptRa =
309b10d8db0SRavi Teja                                 std::get_if<bool>(&propertyPair.second);
310b10d8db0SRavi Teja                             if (ipv6AcceptRa != nullptr)
311b10d8db0SRavi Teja                             {
312b10d8db0SRavi Teja                                 ethData.ipv6AcceptRa = *ipv6AcceptRa;
313b10d8db0SRavi Teja                             }
314b10d8db0SRavi Teja                         }
315f85837bfSRAJESWARAN THILLAIGOVINDAN                         else if (propertyPair.first == "Nameservers")
316029573d4SEd Tanous                         {
317029573d4SEd Tanous                             const std::vector<std::string>* nameservers =
3188d78b7a9SPatrick Williams                                 std::get_if<std::vector<std::string>>(
319029573d4SEd Tanous                                     &propertyPair.second);
320029573d4SEd Tanous                             if (nameservers != nullptr)
321029573d4SEd Tanous                             {
322f23b7296SEd Tanous                                 ethData.nameServers = *nameservers;
3230f6efdc1Smanojkiran.eda@gmail.com                             }
3240f6efdc1Smanojkiran.eda@gmail.com                         }
3250f6efdc1Smanojkiran.eda@gmail.com                         else if (propertyPair.first == "StaticNameServers")
3260f6efdc1Smanojkiran.eda@gmail.com                         {
3270f6efdc1Smanojkiran.eda@gmail.com                             const std::vector<std::string>* staticNameServers =
3288d78b7a9SPatrick Williams                                 std::get_if<std::vector<std::string>>(
3290f6efdc1Smanojkiran.eda@gmail.com                                     &propertyPair.second);
3300f6efdc1Smanojkiran.eda@gmail.com                             if (staticNameServers != nullptr)
3310f6efdc1Smanojkiran.eda@gmail.com                             {
332f23b7296SEd Tanous                                 ethData.staticNameServers = *staticNameServers;
3334a0cb85cSEd Tanous                             }
3344a0cb85cSEd Tanous                         }
3352a133282Smanojkiraneda                         else if (propertyPair.first == "DHCPEnabled")
3362a133282Smanojkiraneda                         {
3372c70f800SEd Tanous                             const std::string* dhcpEnabled =
3381f8c7b5dSJohnathan Mantey                                 std::get_if<std::string>(&propertyPair.second);
3392c70f800SEd Tanous                             if (dhcpEnabled != nullptr)
3402a133282Smanojkiraneda                             {
34182695a5bSJiaqing Zhao                                 ethData.dhcpEnabled = *dhcpEnabled;
3422a133282Smanojkiraneda                             }
3432a133282Smanojkiraneda                         }
344d24bfc7aSJennifer Lee                         else if (propertyPair.first == "DomainName")
345d24bfc7aSJennifer Lee                         {
346d24bfc7aSJennifer Lee                             const std::vector<std::string>* domainNames =
3478d78b7a9SPatrick Williams                                 std::get_if<std::vector<std::string>>(
348d24bfc7aSJennifer Lee                                     &propertyPair.second);
349d24bfc7aSJennifer Lee                             if (domainNames != nullptr)
350d24bfc7aSJennifer Lee                             {
351f23b7296SEd Tanous                                 ethData.domainnames = *domainNames;
352d24bfc7aSJennifer Lee                             }
353d24bfc7aSJennifer Lee                         }
3549010ec2eSRavi Teja                         else if (propertyPair.first == "DefaultGateway")
3559010ec2eSRavi Teja                         {
3569010ec2eSRavi Teja                             const std::string* defaultGateway =
3579010ec2eSRavi Teja                                 std::get_if<std::string>(&propertyPair.second);
3589010ec2eSRavi Teja                             if (defaultGateway != nullptr)
3599010ec2eSRavi Teja                             {
3609010ec2eSRavi Teja                                 std::string defaultGatewayStr = *defaultGateway;
3619010ec2eSRavi Teja                                 if (defaultGatewayStr.empty())
3629010ec2eSRavi Teja                                 {
36382695a5bSJiaqing Zhao                                     ethData.defaultGateway = "0.0.0.0";
3649010ec2eSRavi Teja                                 }
3659010ec2eSRavi Teja                                 else
3669010ec2eSRavi Teja                                 {
36782695a5bSJiaqing Zhao                                     ethData.defaultGateway = defaultGatewayStr;
3689010ec2eSRavi Teja                                 }
3699010ec2eSRavi Teja                             }
3709010ec2eSRavi Teja                         }
3719010ec2eSRavi Teja                         else if (propertyPair.first == "DefaultGateway6")
3729010ec2eSRavi Teja                         {
3739010ec2eSRavi Teja                             const std::string* defaultGateway6 =
3749010ec2eSRavi Teja                                 std::get_if<std::string>(&propertyPair.second);
3759010ec2eSRavi Teja                             if (defaultGateway6 != nullptr)
3769010ec2eSRavi Teja                             {
3779010ec2eSRavi Teja                                 std::string defaultGateway6Str =
3789010ec2eSRavi Teja                                     *defaultGateway6;
3799010ec2eSRavi Teja                                 if (defaultGateway6Str.empty())
3809010ec2eSRavi Teja                                 {
38182695a5bSJiaqing Zhao                                     ethData.ipv6DefaultGateway =
3829010ec2eSRavi Teja                                         "0:0:0:0:0:0:0:0";
3839010ec2eSRavi Teja                                 }
3849010ec2eSRavi Teja                                 else
3859010ec2eSRavi Teja                                 {
38682695a5bSJiaqing Zhao                                     ethData.ipv6DefaultGateway =
3879010ec2eSRavi Teja                                         defaultGateway6Str;
3889010ec2eSRavi Teja                                 }
3899010ec2eSRavi Teja                             }
3909010ec2eSRavi Teja                         }
391029573d4SEd Tanous                     }
392029573d4SEd Tanous                 }
393029573d4SEd Tanous             }
3941f8c7b5dSJohnathan Mantey 
395e4588158SJishnu CM             sdbusplus::message::object_path path(
396e4588158SJishnu CM                 "/xyz/openbmc_project/network");
397*bd79bce8SPatrick Williams             sdbusplus::message::object_path dhcp4Path =
398*bd79bce8SPatrick Williams                 path / ethifaceId / "dhcp4";
399e4588158SJishnu CM 
400e4588158SJishnu CM             if (sdbusplus::message::object_path(objpath.first) == dhcp4Path)
4011f8c7b5dSJohnathan Mantey             {
4021f8c7b5dSJohnathan Mantey                 if (ifacePair.first ==
4031f8c7b5dSJohnathan Mantey                     "xyz.openbmc_project.Network.DHCPConfiguration")
4041f8c7b5dSJohnathan Mantey                 {
4051f8c7b5dSJohnathan Mantey                     for (const auto& propertyPair : ifacePair.second)
4061f8c7b5dSJohnathan Mantey                     {
4071f8c7b5dSJohnathan Mantey                         if (propertyPair.first == "DNSEnabled")
4081f8c7b5dSJohnathan Mantey                         {
4092c70f800SEd Tanous                             const bool* dnsEnabled =
4101f8c7b5dSJohnathan Mantey                                 std::get_if<bool>(&propertyPair.second);
4112c70f800SEd Tanous                             if (dnsEnabled != nullptr)
4121f8c7b5dSJohnathan Mantey                             {
413e4588158SJishnu CM                                 ethData.dnsv4Enabled = *dnsEnabled;
4141f8c7b5dSJohnathan Mantey                             }
4151f8c7b5dSJohnathan Mantey                         }
41691c441ecSRavi Teja                         else if (propertyPair.first == "DomainEnabled")
41791c441ecSRavi Teja                         {
41891c441ecSRavi Teja                             const bool* domainEnabled =
41991c441ecSRavi Teja                                 std::get_if<bool>(&propertyPair.second);
42091c441ecSRavi Teja                             if (domainEnabled != nullptr)
42191c441ecSRavi Teja                             {
42291c441ecSRavi Teja                                 ethData.domainv4Enabled = *domainEnabled;
42391c441ecSRavi Teja                             }
42491c441ecSRavi Teja                         }
4251f8c7b5dSJohnathan Mantey                         else if (propertyPair.first == "NTPEnabled")
4261f8c7b5dSJohnathan Mantey                         {
4272c70f800SEd Tanous                             const bool* ntpEnabled =
4281f8c7b5dSJohnathan Mantey                                 std::get_if<bool>(&propertyPair.second);
4292c70f800SEd Tanous                             if (ntpEnabled != nullptr)
4301f8c7b5dSJohnathan Mantey                             {
431e4588158SJishnu CM                                 ethData.ntpv4Enabled = *ntpEnabled;
4321f8c7b5dSJohnathan Mantey                             }
4331f8c7b5dSJohnathan Mantey                         }
4341f8c7b5dSJohnathan Mantey                         else if (propertyPair.first == "HostNameEnabled")
4351f8c7b5dSJohnathan Mantey                         {
4362c70f800SEd Tanous                             const bool* hostNameEnabled =
4371f8c7b5dSJohnathan Mantey                                 std::get_if<bool>(&propertyPair.second);
4382c70f800SEd Tanous                             if (hostNameEnabled != nullptr)
4391f8c7b5dSJohnathan Mantey                             {
440e4588158SJishnu CM                                 ethData.hostNamev4Enabled = *hostNameEnabled;
441e4588158SJishnu CM                             }
442e4588158SJishnu CM                         }
443e4588158SJishnu CM                     }
444e4588158SJishnu CM                 }
445e4588158SJishnu CM             }
446e4588158SJishnu CM 
447*bd79bce8SPatrick Williams             sdbusplus::message::object_path dhcp6Path =
448*bd79bce8SPatrick Williams                 path / ethifaceId / "dhcp6";
449e4588158SJishnu CM 
450e4588158SJishnu CM             if (sdbusplus::message::object_path(objpath.first) == dhcp6Path)
451e4588158SJishnu CM             {
452e4588158SJishnu CM                 if (ifacePair.first ==
453e4588158SJishnu CM                     "xyz.openbmc_project.Network.DHCPConfiguration")
454e4588158SJishnu CM                 {
455e4588158SJishnu CM                     for (const auto& propertyPair : ifacePair.second)
456e4588158SJishnu CM                     {
457e4588158SJishnu CM                         if (propertyPair.first == "DNSEnabled")
458e4588158SJishnu CM                         {
459e4588158SJishnu CM                             const bool* dnsEnabled =
460e4588158SJishnu CM                                 std::get_if<bool>(&propertyPair.second);
461e4588158SJishnu CM                             if (dnsEnabled != nullptr)
462e4588158SJishnu CM                             {
463e4588158SJishnu CM                                 ethData.dnsv6Enabled = *dnsEnabled;
464e4588158SJishnu CM                             }
465e4588158SJishnu CM                         }
46691c441ecSRavi Teja                         if (propertyPair.first == "DomainEnabled")
46791c441ecSRavi Teja                         {
46891c441ecSRavi Teja                             const bool* domainEnabled =
46991c441ecSRavi Teja                                 std::get_if<bool>(&propertyPair.second);
47091c441ecSRavi Teja                             if (domainEnabled != nullptr)
47191c441ecSRavi Teja                             {
47291c441ecSRavi Teja                                 ethData.domainv6Enabled = *domainEnabled;
47391c441ecSRavi Teja                             }
47491c441ecSRavi Teja                         }
475e4588158SJishnu CM                         else if (propertyPair.first == "NTPEnabled")
476e4588158SJishnu CM                         {
477e4588158SJishnu CM                             const bool* ntpEnabled =
478e4588158SJishnu CM                                 std::get_if<bool>(&propertyPair.second);
479e4588158SJishnu CM                             if (ntpEnabled != nullptr)
480e4588158SJishnu CM                             {
481e4588158SJishnu CM                                 ethData.ntpv6Enabled = *ntpEnabled;
482e4588158SJishnu CM                             }
483e4588158SJishnu CM                         }
484e4588158SJishnu CM                         else if (propertyPair.first == "HostNameEnabled")
485e4588158SJishnu CM                         {
486e4588158SJishnu CM                             const bool* hostNameEnabled =
487e4588158SJishnu CM                                 std::get_if<bool>(&propertyPair.second);
488e4588158SJishnu CM                             if (hostNameEnabled != nullptr)
489e4588158SJishnu CM                             {
490e4588158SJishnu CM                                 ethData.hostNamev6Enabled = *hostNameEnabled;
4911f8c7b5dSJohnathan Mantey                             }
4921f8c7b5dSJohnathan Mantey                         }
4931f8c7b5dSJohnathan Mantey                     }
4941f8c7b5dSJohnathan Mantey                 }
4951f8c7b5dSJohnathan Mantey             }
496029573d4SEd Tanous             // System configuration shows up in the global namespace, so no need
497029573d4SEd Tanous             // to check eth number
498029573d4SEd Tanous             if (ifacePair.first ==
4994a0cb85cSEd Tanous                 "xyz.openbmc_project.Network.SystemConfiguration")
5004a0cb85cSEd Tanous             {
5014a0cb85cSEd Tanous                 for (const auto& propertyPair : ifacePair.second)
5024a0cb85cSEd Tanous                 {
5034a0cb85cSEd Tanous                     if (propertyPair.first == "HostName")
5044a0cb85cSEd Tanous                     {
5054a0cb85cSEd Tanous                         const std::string* hostname =
5068d78b7a9SPatrick Williams                             std::get_if<std::string>(&propertyPair.second);
5074a0cb85cSEd Tanous                         if (hostname != nullptr)
5084a0cb85cSEd Tanous                         {
50982695a5bSJiaqing Zhao                             ethData.hostName = *hostname;
5104a0cb85cSEd Tanous                         }
5114a0cb85cSEd Tanous                     }
5124a0cb85cSEd Tanous                 }
5134a0cb85cSEd Tanous             }
5144a0cb85cSEd Tanous         }
5154a0cb85cSEd Tanous     }
5164c9afe43SEd Tanous     return idFound;
5174a0cb85cSEd Tanous }
5184a0cb85cSEd Tanous 
519e48c0fc5SRavi Teja // Helper function that extracts data for single ethernet ipv6 address
52077179532SEd Tanous inline void extractIPV6Data(const std::string& ethifaceId,
521711ac7a9SEd Tanous                             const dbus::utility::ManagedObjectType& dbusData,
52277179532SEd Tanous                             std::vector<IPv6AddressData>& ipv6Config)
523e48c0fc5SRavi Teja {
524*bd79bce8SPatrick Williams     const std::string ipPathStart =
525*bd79bce8SPatrick Williams         "/xyz/openbmc_project/network/" + ethifaceId;
526e48c0fc5SRavi Teja 
527e48c0fc5SRavi Teja     // Since there might be several IPv6 configurations aligned with
528e48c0fc5SRavi Teja     // single ethernet interface, loop over all of them
52981ce609eSEd Tanous     for (const auto& objpath : dbusData)
530e48c0fc5SRavi Teja     {
531e48c0fc5SRavi Teja         // Check if proper pattern for object path appears
532353163e9STony Lee         if (objpath.first.str.starts_with(ipPathStart + "/"))
533e48c0fc5SRavi Teja         {
5349eb808c1SEd Tanous             for (const auto& interface : objpath.second)
535e48c0fc5SRavi Teja             {
536e48c0fc5SRavi Teja                 if (interface.first == "xyz.openbmc_project.Network.IP")
537e48c0fc5SRavi Teja                 {
538*bd79bce8SPatrick Williams                     auto type = std::ranges::find_if(
539*bd79bce8SPatrick Williams                         interface.second, [](const auto& property) {
540353163e9STony Lee                             return property.first == "Type";
541353163e9STony Lee                         });
542353163e9STony Lee                     if (type == interface.second.end())
543353163e9STony Lee                     {
544353163e9STony Lee                         continue;
545353163e9STony Lee                     }
546353163e9STony Lee 
547353163e9STony Lee                     const std::string* typeStr =
548353163e9STony Lee                         std::get_if<std::string>(&type->second);
549353163e9STony Lee 
550353163e9STony Lee                     if (typeStr == nullptr ||
551353163e9STony Lee                         (*typeStr !=
552353163e9STony Lee                          "xyz.openbmc_project.Network.IP.Protocol.IPv6"))
553353163e9STony Lee                     {
554353163e9STony Lee                         continue;
555353163e9STony Lee                     }
556353163e9STony Lee 
557e48c0fc5SRavi Teja                     // Instance IPv6AddressData structure, and set as
558e48c0fc5SRavi Teja                     // appropriate
55977179532SEd Tanous                     IPv6AddressData& ipv6Address = ipv6Config.emplace_back();
5602c70f800SEd Tanous                     ipv6Address.id =
561353163e9STony Lee                         objpath.first.str.substr(ipPathStart.size());
5629eb808c1SEd Tanous                     for (const auto& property : interface.second)
563e48c0fc5SRavi Teja                     {
564e48c0fc5SRavi Teja                         if (property.first == "Address")
565e48c0fc5SRavi Teja                         {
566e48c0fc5SRavi Teja                             const std::string* address =
567e48c0fc5SRavi Teja                                 std::get_if<std::string>(&property.second);
568e48c0fc5SRavi Teja                             if (address != nullptr)
569e48c0fc5SRavi Teja                             {
5702c70f800SEd Tanous                                 ipv6Address.address = *address;
571e48c0fc5SRavi Teja                             }
572e48c0fc5SRavi Teja                         }
573e48c0fc5SRavi Teja                         else if (property.first == "Origin")
574e48c0fc5SRavi Teja                         {
575e48c0fc5SRavi Teja                             const std::string* origin =
576e48c0fc5SRavi Teja                                 std::get_if<std::string>(&property.second);
577e48c0fc5SRavi Teja                             if (origin != nullptr)
578e48c0fc5SRavi Teja                             {
5792c70f800SEd Tanous                                 ipv6Address.origin =
580e48c0fc5SRavi Teja                                     translateAddressOriginDbusToRedfish(*origin,
581e48c0fc5SRavi Teja                                                                         false);
582e48c0fc5SRavi Teja                             }
583e48c0fc5SRavi Teja                         }
584e48c0fc5SRavi Teja                         else if (property.first == "PrefixLength")
585e48c0fc5SRavi Teja                         {
586e48c0fc5SRavi Teja                             const uint8_t* prefix =
587e48c0fc5SRavi Teja                                 std::get_if<uint8_t>(&property.second);
588e48c0fc5SRavi Teja                             if (prefix != nullptr)
589e48c0fc5SRavi Teja                             {
5902c70f800SEd Tanous                                 ipv6Address.prefixLength = *prefix;
591e48c0fc5SRavi Teja                             }
592e48c0fc5SRavi Teja                         }
593889ff694SAsmitha Karunanithi                         else if (property.first == "Type" ||
594889ff694SAsmitha Karunanithi                                  property.first == "Gateway")
595889ff694SAsmitha Karunanithi                         {
596889ff694SAsmitha Karunanithi                             // Type & Gateway is not used
597889ff694SAsmitha Karunanithi                         }
598e48c0fc5SRavi Teja                         else
599e48c0fc5SRavi Teja                         {
60062598e31SEd Tanous                             BMCWEB_LOG_ERROR(
60162598e31SEd Tanous                                 "Got extra property: {} on the {} object",
60262598e31SEd Tanous                                 property.first, objpath.first.str);
603e48c0fc5SRavi Teja                         }
604e48c0fc5SRavi Teja                     }
605e48c0fc5SRavi Teja                 }
606e48c0fc5SRavi Teja             }
607e48c0fc5SRavi Teja         }
608e48c0fc5SRavi Teja     }
609e48c0fc5SRavi Teja }
610e48c0fc5SRavi Teja 
6114a0cb85cSEd Tanous // Helper function that extracts data for single ethernet ipv4 address
61277179532SEd Tanous inline void extractIPData(const std::string& ethifaceId,
613711ac7a9SEd Tanous                           const dbus::utility::ManagedObjectType& dbusData,
61477179532SEd Tanous                           std::vector<IPv4AddressData>& ipv4Config)
6154a0cb85cSEd Tanous {
616*bd79bce8SPatrick Williams     const std::string ipPathStart =
617*bd79bce8SPatrick Williams         "/xyz/openbmc_project/network/" + ethifaceId;
6184a0cb85cSEd Tanous 
6194a0cb85cSEd Tanous     // Since there might be several IPv4 configurations aligned with
6204a0cb85cSEd Tanous     // single ethernet interface, loop over all of them
62181ce609eSEd Tanous     for (const auto& objpath : dbusData)
6224a0cb85cSEd Tanous     {
6234a0cb85cSEd Tanous         // Check if proper pattern for object path appears
624353163e9STony Lee         if (objpath.first.str.starts_with(ipPathStart + "/"))
6254a0cb85cSEd Tanous         {
6269eb808c1SEd Tanous             for (const auto& interface : objpath.second)
6274a0cb85cSEd Tanous             {
6284a0cb85cSEd Tanous                 if (interface.first == "xyz.openbmc_project.Network.IP")
6294a0cb85cSEd Tanous                 {
630*bd79bce8SPatrick Williams                     auto type = std::ranges::find_if(
631*bd79bce8SPatrick Williams                         interface.second, [](const auto& property) {
632353163e9STony Lee                             return property.first == "Type";
633353163e9STony Lee                         });
634353163e9STony Lee                     if (type == interface.second.end())
635353163e9STony Lee                     {
636353163e9STony Lee                         continue;
637353163e9STony Lee                     }
638353163e9STony Lee 
639353163e9STony Lee                     const std::string* typeStr =
640353163e9STony Lee                         std::get_if<std::string>(&type->second);
641353163e9STony Lee 
642353163e9STony Lee                     if (typeStr == nullptr ||
643353163e9STony Lee                         (*typeStr !=
644353163e9STony Lee                          "xyz.openbmc_project.Network.IP.Protocol.IPv4"))
645353163e9STony Lee                     {
646353163e9STony Lee                         continue;
647353163e9STony Lee                     }
648353163e9STony Lee 
6494a0cb85cSEd Tanous                     // Instance IPv4AddressData structure, and set as
6504a0cb85cSEd Tanous                     // appropriate
65177179532SEd Tanous                     IPv4AddressData& ipv4Address = ipv4Config.emplace_back();
6522c70f800SEd Tanous                     ipv4Address.id =
653353163e9STony Lee                         objpath.first.str.substr(ipPathStart.size());
6549eb808c1SEd Tanous                     for (const auto& property : interface.second)
6554a0cb85cSEd Tanous                     {
6564a0cb85cSEd Tanous                         if (property.first == "Address")
6574a0cb85cSEd Tanous                         {
6584a0cb85cSEd Tanous                             const std::string* address =
659abf2add6SEd Tanous                                 std::get_if<std::string>(&property.second);
6604a0cb85cSEd Tanous                             if (address != nullptr)
6614a0cb85cSEd Tanous                             {
6622c70f800SEd Tanous                                 ipv4Address.address = *address;
6634a0cb85cSEd Tanous                             }
6644a0cb85cSEd Tanous                         }
6654a0cb85cSEd Tanous                         else if (property.first == "Origin")
6664a0cb85cSEd Tanous                         {
6674a0cb85cSEd Tanous                             const std::string* origin =
668abf2add6SEd Tanous                                 std::get_if<std::string>(&property.second);
6694a0cb85cSEd Tanous                             if (origin != nullptr)
6704a0cb85cSEd Tanous                             {
6712c70f800SEd Tanous                                 ipv4Address.origin =
6724a0cb85cSEd Tanous                                     translateAddressOriginDbusToRedfish(*origin,
6734a0cb85cSEd Tanous                                                                         true);
6744a0cb85cSEd Tanous                             }
6754a0cb85cSEd Tanous                         }
6764a0cb85cSEd Tanous                         else if (property.first == "PrefixLength")
6774a0cb85cSEd Tanous                         {
6784a0cb85cSEd Tanous                             const uint8_t* mask =
679abf2add6SEd Tanous                                 std::get_if<uint8_t>(&property.second);
6804a0cb85cSEd Tanous                             if (mask != nullptr)
6814a0cb85cSEd Tanous                             {
6824a0cb85cSEd Tanous                                 // convert it to the string
6832c70f800SEd Tanous                                 ipv4Address.netmask = getNetmask(*mask);
6844a0cb85cSEd Tanous                             }
6854a0cb85cSEd Tanous                         }
686889ff694SAsmitha Karunanithi                         else if (property.first == "Type" ||
687889ff694SAsmitha Karunanithi                                  property.first == "Gateway")
688889ff694SAsmitha Karunanithi                         {
689889ff694SAsmitha Karunanithi                             // Type & Gateway is not used
690889ff694SAsmitha Karunanithi                         }
6914a0cb85cSEd Tanous                         else
6924a0cb85cSEd Tanous                         {
69362598e31SEd Tanous                             BMCWEB_LOG_ERROR(
69462598e31SEd Tanous                                 "Got extra property: {} on the {} object",
69562598e31SEd Tanous                                 property.first, objpath.first.str);
6964a0cb85cSEd Tanous                         }
6974a0cb85cSEd Tanous                     }
6984a0cb85cSEd Tanous                     // Check if given address is local, or global
6992c70f800SEd Tanous                     ipv4Address.linktype =
70011ba3979SEd Tanous                         ipv4Address.address.starts_with("169.254.")
70118659d10SJohnathan Mantey                             ? LinkType::Local
70218659d10SJohnathan Mantey                             : LinkType::Global;
7034a0cb85cSEd Tanous                 }
7044a0cb85cSEd Tanous             }
7054a0cb85cSEd Tanous         }
7064a0cb85cSEd Tanous     }
7074a0cb85cSEd Tanous }
708588c3f0dSKowalski, Kamil 
709588c3f0dSKowalski, Kamil /**
710743eb1c0SJohnathan Mantey  * @brief Modifies the default gateway assigned to the NIC
711743eb1c0SJohnathan Mantey  *
712743eb1c0SJohnathan Mantey  * @param[in] ifaceId     Id of network interface whose default gateway is to be
713743eb1c0SJohnathan Mantey  *                        changed
714743eb1c0SJohnathan Mantey  * @param[in] gateway     The new gateway value. Assigning an empty string
715743eb1c0SJohnathan Mantey  *                        causes the gateway to be deleted
716743eb1c0SJohnathan Mantey  * @param[io] asyncResp   Response object that will be returned to client
717743eb1c0SJohnathan Mantey  *
718743eb1c0SJohnathan Mantey  * @return None
719743eb1c0SJohnathan Mantey  */
720743eb1c0SJohnathan Mantey inline void updateIPv4DefaultGateway(
721743eb1c0SJohnathan Mantey     const std::string& ifaceId, const std::string& gateway,
722743eb1c0SJohnathan Mantey     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
723743eb1c0SJohnathan Mantey {
724743eb1c0SJohnathan Mantey     setDbusProperty(
725e93abac6SGinu George         asyncResp, "Gateway", "xyz.openbmc_project.Network",
726743eb1c0SJohnathan Mantey         sdbusplus::message::object_path("/xyz/openbmc_project/network") /
727743eb1c0SJohnathan Mantey             ifaceId,
728743eb1c0SJohnathan Mantey         "xyz.openbmc_project.Network.EthernetInterface", "DefaultGateway",
729e93abac6SGinu George         gateway);
730743eb1c0SJohnathan Mantey }
731743eb1c0SJohnathan Mantey 
732743eb1c0SJohnathan Mantey /**
733743eb1c0SJohnathan Mantey  * @brief Deletes given static IP address for the interface
734179db1d7SKowalski, Kamil  *
735179db1d7SKowalski, Kamil  * @param[in] ifaceId     Id of interface whose IP should be deleted
736179db1d7SKowalski, Kamil  * @param[in] ipHash      DBus Hash id of IP that should be deleted
737179db1d7SKowalski, Kamil  * @param[io] asyncResp   Response object that will be returned to client
738179db1d7SKowalski, Kamil  *
739179db1d7SKowalski, Kamil  * @return None
740179db1d7SKowalski, Kamil  */
7419c5e585cSRavi Teja inline void deleteIPAddress(const std::string& ifaceId,
7429c5e585cSRavi Teja                             const std::string& ipHash,
7438d1b46d7Szhanghch05                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
7441abe55efSEd Tanous {
74555c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
7465e7e2dc5SEd Tanous         [asyncResp](const boost::system::error_code& ec) {
7471abe55efSEd Tanous             if (ec)
7481abe55efSEd Tanous             {
749a08b46ccSJason M. Bills                 messages::internalError(asyncResp->res);
7501abe55efSEd Tanous             }
751179db1d7SKowalski, Kamil         },
752179db1d7SKowalski, Kamil         "xyz.openbmc_project.Network",
7539c5e585cSRavi Teja         "/xyz/openbmc_project/network/" + ifaceId + ipHash,
754179db1d7SKowalski, Kamil         "xyz.openbmc_project.Object.Delete", "Delete");
755179db1d7SKowalski, Kamil }
756179db1d7SKowalski, Kamil 
757179db1d7SKowalski, Kamil /**
75801784826SJohnathan Mantey  * @brief Creates a static IPv4 entry
759179db1d7SKowalski, Kamil  *
76001784826SJohnathan Mantey  * @param[in] ifaceId      Id of interface upon which to create the IPv4 entry
76101784826SJohnathan Mantey  * @param[in] prefixLength IPv4 prefix syntax for the subnet mask
76201784826SJohnathan Mantey  * @param[in] gateway      IPv4 address of this interfaces gateway
76301784826SJohnathan Mantey  * @param[in] address      IPv4 address to assign to this interface
764179db1d7SKowalski, Kamil  * @param[io] asyncResp    Response object that will be returned to client
765179db1d7SKowalski, Kamil  *
766179db1d7SKowalski, Kamil  * @return None
767179db1d7SKowalski, Kamil  */
768cb13a392SEd Tanous inline void createIPv4(const std::string& ifaceId, uint8_t prefixLength,
769cb13a392SEd Tanous                        const std::string& gateway, const std::string& address,
7708d1b46d7Szhanghch05                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
7711abe55efSEd Tanous {
772*bd79bce8SPatrick Williams     auto createIpHandler =
773*bd79bce8SPatrick Williams         [asyncResp, ifaceId, gateway](const boost::system::error_code& ec) {
7741abe55efSEd Tanous             if (ec)
7751abe55efSEd Tanous             {
776a08b46ccSJason M. Bills                 messages::internalError(asyncResp->res);
7779010ec2eSRavi Teja                 return;
778179db1d7SKowalski, Kamil             }
7799010ec2eSRavi Teja         };
7809010ec2eSRavi Teja 
7819010ec2eSRavi Teja     crow::connections::systemBus->async_method_call(
7829010ec2eSRavi Teja         std::move(createIpHandler), "xyz.openbmc_project.Network",
783179db1d7SKowalski, Kamil         "/xyz/openbmc_project/network/" + ifaceId,
784179db1d7SKowalski, Kamil         "xyz.openbmc_project.Network.IP.Create", "IP",
78501784826SJohnathan Mantey         "xyz.openbmc_project.Network.IP.Protocol.IPv4", address, prefixLength,
786179db1d7SKowalski, Kamil         gateway);
787179db1d7SKowalski, Kamil }
788e48c0fc5SRavi Teja 
789e48c0fc5SRavi Teja /**
790743eb1c0SJohnathan Mantey  * @brief Deletes the IP entry for this interface and creates a replacement
791743eb1c0SJohnathan Mantey  * static entry
79201784826SJohnathan Mantey  *
79301784826SJohnathan Mantey  * @param[in] ifaceId        Id of interface upon which to create the IPv6 entry
79401784826SJohnathan Mantey  * @param[in] id             The unique hash entry identifying the DBus entry
795743eb1c0SJohnathan Mantey  * @param[in] prefixLength   Prefix syntax for the subnet mask
796743eb1c0SJohnathan Mantey  * @param[in] address        Address to assign to this interface
797743eb1c0SJohnathan Mantey  * @param[in] numStaticAddrs Count of IPv4 static addresses
79801784826SJohnathan Mantey  * @param[io] asyncResp      Response object that will be returned to client
79901784826SJohnathan Mantey  *
80001784826SJohnathan Mantey  * @return None
80101784826SJohnathan Mantey  */
8029c5e585cSRavi Teja 
8039c5e585cSRavi Teja inline void deleteAndCreateIPAddress(
8049c5e585cSRavi Teja     IpVersion version, const std::string& ifaceId, const std::string& id,
8058d1b46d7Szhanghch05     uint8_t prefixLength, const std::string& address,
8069c5e585cSRavi Teja     const std::string& gateway,
8078d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
80801784826SJohnathan Mantey {
80901784826SJohnathan Mantey     crow::connections::systemBus->async_method_call(
8109c5e585cSRavi Teja         [asyncResp, version, ifaceId, address, prefixLength,
8119c5e585cSRavi Teja          gateway](const boost::system::error_code& ec) {
81201784826SJohnathan Mantey             if (ec)
81301784826SJohnathan Mantey             {
81401784826SJohnathan Mantey                 messages::internalError(asyncResp->res);
81501784826SJohnathan Mantey             }
8169c5e585cSRavi Teja             std::string protocol = "xyz.openbmc_project.Network.IP.Protocol.";
8179c5e585cSRavi Teja             protocol += version == IpVersion::IpV4 ? "IPv4" : "IPv6";
81801784826SJohnathan Mantey             crow::connections::systemBus->async_method_call(
8195e7e2dc5SEd Tanous                 [asyncResp](const boost::system::error_code& ec2) {
82023a21a1cSEd Tanous                     if (ec2)
82101784826SJohnathan Mantey                     {
82201784826SJohnathan Mantey                         messages::internalError(asyncResp->res);
82301784826SJohnathan Mantey                     }
82401784826SJohnathan Mantey                 },
82501784826SJohnathan Mantey                 "xyz.openbmc_project.Network",
82601784826SJohnathan Mantey                 "/xyz/openbmc_project/network/" + ifaceId,
827*bd79bce8SPatrick Williams                 "xyz.openbmc_project.Network.IP.Create", "IP", protocol,
828*bd79bce8SPatrick Williams                 address, prefixLength, gateway);
82901784826SJohnathan Mantey         },
83001784826SJohnathan Mantey         "xyz.openbmc_project.Network",
8319c5e585cSRavi Teja         "/xyz/openbmc_project/network/" + ifaceId + id,
83201784826SJohnathan Mantey         "xyz.openbmc_project.Object.Delete", "Delete");
83301784826SJohnathan Mantey }
83401784826SJohnathan Mantey 
835ce73d5c8SSunitha Harish inline bool extractIPv6DefaultGatewayData(
836ce73d5c8SSunitha Harish     const std::string& ethifaceId,
837ce73d5c8SSunitha Harish     const dbus::utility::ManagedObjectType& dbusData,
838ce73d5c8SSunitha Harish     std::vector<StaticGatewayData>& staticGatewayConfig)
839ce73d5c8SSunitha Harish {
840ce73d5c8SSunitha Harish     std::string staticGatewayPathStart("/xyz/openbmc_project/network/");
841ce73d5c8SSunitha Harish     staticGatewayPathStart += ethifaceId;
842ce73d5c8SSunitha Harish 
843ce73d5c8SSunitha Harish     for (const auto& objpath : dbusData)
844ce73d5c8SSunitha Harish     {
845ce73d5c8SSunitha Harish         if (!std::string_view(objpath.first.str)
846ce73d5c8SSunitha Harish                  .starts_with(staticGatewayPathStart))
847ce73d5c8SSunitha Harish         {
848ce73d5c8SSunitha Harish             continue;
849ce73d5c8SSunitha Harish         }
850ce73d5c8SSunitha Harish         for (const auto& interface : objpath.second)
851ce73d5c8SSunitha Harish         {
852ce73d5c8SSunitha Harish             if (interface.first != "xyz.openbmc_project.Network.StaticGateway")
853ce73d5c8SSunitha Harish             {
854ce73d5c8SSunitha Harish                 continue;
855ce73d5c8SSunitha Harish             }
856ce73d5c8SSunitha Harish             StaticGatewayData& staticGateway =
857ce73d5c8SSunitha Harish                 staticGatewayConfig.emplace_back();
858ce73d5c8SSunitha Harish             staticGateway.id = objpath.first.filename();
859ce73d5c8SSunitha Harish 
860ce73d5c8SSunitha Harish             bool success = sdbusplus::unpackPropertiesNoThrow(
861ce73d5c8SSunitha Harish                 redfish::dbus_utils::UnpackErrorPrinter(), interface.second,
862ce73d5c8SSunitha Harish                 "Gateway", staticGateway.gateway, "PrefixLength",
863ce73d5c8SSunitha Harish                 staticGateway.prefixLength, "ProtocolType",
864ce73d5c8SSunitha Harish                 staticGateway.protocol);
865ce73d5c8SSunitha Harish             if (!success)
866ce73d5c8SSunitha Harish             {
867ce73d5c8SSunitha Harish                 return false;
868ce73d5c8SSunitha Harish             }
869ce73d5c8SSunitha Harish         }
870ce73d5c8SSunitha Harish     }
871ce73d5c8SSunitha Harish     return true;
872ce73d5c8SSunitha Harish }
873ce73d5c8SSunitha Harish 
87401784826SJohnathan Mantey /**
875e48c0fc5SRavi Teja  * @brief Creates IPv6 with given data
876e48c0fc5SRavi Teja  *
877e48c0fc5SRavi Teja  * @param[in] ifaceId      Id of interface whose IP should be added
878e48c0fc5SRavi Teja  * @param[in] prefixLength Prefix length that needs to be added
879e48c0fc5SRavi Teja  * @param[in] address      IP address that needs to be added
880e48c0fc5SRavi Teja  * @param[io] asyncResp    Response object that will be returned to client
881e48c0fc5SRavi Teja  *
882e48c0fc5SRavi Teja  * @return None
883e48c0fc5SRavi Teja  */
88401784826SJohnathan Mantey inline void createIPv6(const std::string& ifaceId, uint8_t prefixLength,
88501784826SJohnathan Mantey                        const std::string& address,
8868d1b46d7Szhanghch05                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
887e48c0fc5SRavi Teja {
888ce73d5c8SSunitha Harish     sdbusplus::message::object_path path("/xyz/openbmc_project/network");
889ce73d5c8SSunitha Harish     path /= ifaceId;
890ce73d5c8SSunitha Harish 
891*bd79bce8SPatrick Williams     auto createIpHandler =
892*bd79bce8SPatrick Williams         [asyncResp, address](const boost::system::error_code& ec) {
893e48c0fc5SRavi Teja             if (ec)
894e48c0fc5SRavi Teja             {
895fc23ef8aSNitin Kumar Kotania                 if (ec == boost::system::errc::io_error)
896fc23ef8aSNitin Kumar Kotania                 {
897fc23ef8aSNitin Kumar Kotania                     messages::propertyValueFormatError(asyncResp->res, address,
898fc23ef8aSNitin Kumar Kotania                                                        "Address");
899fc23ef8aSNitin Kumar Kotania                 }
900fc23ef8aSNitin Kumar Kotania                 else
901fc23ef8aSNitin Kumar Kotania                 {
902e48c0fc5SRavi Teja                     messages::internalError(asyncResp->res);
903e48c0fc5SRavi Teja                 }
904fc23ef8aSNitin Kumar Kotania             }
905e48c0fc5SRavi Teja         };
906ce73d5c8SSunitha Harish     // Passing null for gateway, as per redfish spec IPv6StaticAddresses
907ce73d5c8SSunitha Harish     // object does not have associated gateway property
908e48c0fc5SRavi Teja     crow::connections::systemBus->async_method_call(
909ce73d5c8SSunitha Harish         std::move(createIpHandler), "xyz.openbmc_project.Network", path,
910e48c0fc5SRavi Teja         "xyz.openbmc_project.Network.IP.Create", "IP",
911e48c0fc5SRavi Teja         "xyz.openbmc_project.Network.IP.Protocol.IPv6", address, prefixLength,
912e48c0fc5SRavi Teja         "");
913e48c0fc5SRavi Teja }
914e48c0fc5SRavi Teja 
915179db1d7SKowalski, Kamil /**
916ce73d5c8SSunitha Harish  * @brief Deletes given IPv6 Static Gateway
917ce73d5c8SSunitha Harish  *
918ce73d5c8SSunitha Harish  * @param[in] ifaceId     Id of interface whose IP should be deleted
919ce73d5c8SSunitha Harish  * @param[in] ipHash      DBus Hash id of IP that should be deleted
920ce73d5c8SSunitha Harish  * @param[io] asyncResp   Response object that will be returned to client
921ce73d5c8SSunitha Harish  *
922ce73d5c8SSunitha Harish  * @return None
923ce73d5c8SSunitha Harish  */
924ce73d5c8SSunitha Harish inline void
925ce73d5c8SSunitha Harish     deleteIPv6Gateway(std::string_view gatewayId,
926ce73d5c8SSunitha Harish                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
927ce73d5c8SSunitha Harish {
928ce73d5c8SSunitha Harish     sdbusplus::message::object_path path("/xyz/openbmc_project/network");
929ce73d5c8SSunitha Harish     path /= gatewayId;
930ce73d5c8SSunitha Harish     crow::connections::systemBus->async_method_call(
931ce73d5c8SSunitha Harish         [asyncResp](const boost::system::error_code& ec) {
932ce73d5c8SSunitha Harish             if (ec)
933ce73d5c8SSunitha Harish             {
934ce73d5c8SSunitha Harish                 messages::internalError(asyncResp->res);
935ce73d5c8SSunitha Harish             }
936ce73d5c8SSunitha Harish         },
937ce73d5c8SSunitha Harish         "xyz.openbmc_project.Network", path,
938ce73d5c8SSunitha Harish         "xyz.openbmc_project.Object.Delete", "Delete");
939ce73d5c8SSunitha Harish }
940ce73d5c8SSunitha Harish 
941ce73d5c8SSunitha Harish /**
942ce73d5c8SSunitha Harish  * @brief Creates IPv6 static default gateway with given data
943ce73d5c8SSunitha Harish  *
944ce73d5c8SSunitha Harish  * @param[in] ifaceId      Id of interface whose IP should be added
945ce73d5c8SSunitha Harish  * @param[in] prefixLength Prefix length that needs to be added
946ce73d5c8SSunitha Harish  * @param[in] gateway      Gateway address that needs to be added
947ce73d5c8SSunitha Harish  * @param[io] asyncResp    Response object that will be returned to client
948ce73d5c8SSunitha Harish  *
949ce73d5c8SSunitha Harish  * @return None
950ce73d5c8SSunitha Harish  */
951ce73d5c8SSunitha Harish inline void createIPv6DefaultGateway(
952ce73d5c8SSunitha Harish     std::string_view ifaceId, size_t prefixLength, std::string_view gateway,
953ce73d5c8SSunitha Harish     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
954ce73d5c8SSunitha Harish {
955ce73d5c8SSunitha Harish     sdbusplus::message::object_path path("/xyz/openbmc_project/network");
956ce73d5c8SSunitha Harish     path /= ifaceId;
957ce73d5c8SSunitha Harish     auto createIpHandler = [asyncResp](const boost::system::error_code& ec) {
958ce73d5c8SSunitha Harish         if (ec)
959ce73d5c8SSunitha Harish         {
960ce73d5c8SSunitha Harish             messages::internalError(asyncResp->res);
961ce73d5c8SSunitha Harish         }
962ce73d5c8SSunitha Harish     };
963ce73d5c8SSunitha Harish     crow::connections::systemBus->async_method_call(
964ce73d5c8SSunitha Harish         std::move(createIpHandler), "xyz.openbmc_project.Network", path,
965ce73d5c8SSunitha Harish         "xyz.openbmc_project.Network.StaticGateway.Create", "StaticGateway",
966ce73d5c8SSunitha Harish         gateway, prefixLength, "xyz.openbmc_project.Network.IP.Protocol.IPv6");
967ce73d5c8SSunitha Harish }
968ce73d5c8SSunitha Harish 
969ce73d5c8SSunitha Harish /**
970ce73d5c8SSunitha Harish  * @brief Deletes the IPv6 default gateway entry for this interface and
971ce73d5c8SSunitha Harish  * creates a replacement IPv6 default gateway entry
972ce73d5c8SSunitha Harish  *
973ce73d5c8SSunitha Harish  * @param[in] ifaceId      Id of interface upon which to create the IPv6
974ce73d5c8SSunitha Harish  * entry
975ce73d5c8SSunitha Harish  * @param[in] gateway      IPv6 gateway to assign to this interface
976ce73d5c8SSunitha Harish  * @param[in] prefixLength IPv6 prefix syntax for the subnet mask
977ce73d5c8SSunitha Harish  * @param[io] asyncResp    Response object that will be returned to client
978ce73d5c8SSunitha Harish  *
979ce73d5c8SSunitha Harish  * @return None
980ce73d5c8SSunitha Harish  */
981ce73d5c8SSunitha Harish inline void deleteAndCreateIPv6DefaultGateway(
982ce73d5c8SSunitha Harish     std::string_view ifaceId, std::string_view gatewayId,
983ce73d5c8SSunitha Harish     std::string_view gateway, size_t prefixLength,
984ce73d5c8SSunitha Harish     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
985ce73d5c8SSunitha Harish {
986ce73d5c8SSunitha Harish     sdbusplus::message::object_path path("/xyz/openbmc_project/network");
987ce73d5c8SSunitha Harish     path /= gatewayId;
988ce73d5c8SSunitha Harish     crow::connections::systemBus->async_method_call(
989ce73d5c8SSunitha Harish         [asyncResp, ifaceId, gateway,
990ce73d5c8SSunitha Harish          prefixLength](const boost::system::error_code& ec) {
991ce73d5c8SSunitha Harish             if (ec)
992ce73d5c8SSunitha Harish             {
993ce73d5c8SSunitha Harish                 messages::internalError(asyncResp->res);
994ce73d5c8SSunitha Harish                 return;
995ce73d5c8SSunitha Harish             }
996ce73d5c8SSunitha Harish             createIPv6DefaultGateway(ifaceId, prefixLength, gateway, asyncResp);
997ce73d5c8SSunitha Harish         },
998ce73d5c8SSunitha Harish         "xyz.openbmc_project.Network", path,
999ce73d5c8SSunitha Harish         "xyz.openbmc_project.Object.Delete", "Delete");
1000ce73d5c8SSunitha Harish }
1001ce73d5c8SSunitha Harish 
1002ce73d5c8SSunitha Harish /**
1003ce73d5c8SSunitha Harish  * @brief Sets IPv6 default gateway with given data
1004ce73d5c8SSunitha Harish  *
1005ce73d5c8SSunitha Harish  * @param[in] ifaceId      Id of interface whose gateway should be added
1006ce73d5c8SSunitha Harish  * @param[in] input        Contains address that needs to be added
1007ce73d5c8SSunitha Harish  * @param[in] staticGatewayData  Current static gateways in the system
1008ce73d5c8SSunitha Harish  * @param[io] asyncResp    Response object that will be returned to client
1009ce73d5c8SSunitha Harish  *
1010ce73d5c8SSunitha Harish  * @return None
1011ce73d5c8SSunitha Harish  */
1012ce73d5c8SSunitha Harish 
1013ce73d5c8SSunitha Harish inline void handleIPv6DefaultGateway(
10143dfed536SEd Tanous     const std::string& ifaceId,
10153dfed536SEd Tanous     std::vector<std::variant<nlohmann::json::object_t, std::nullptr_t>>& input,
1016ce73d5c8SSunitha Harish     const std::vector<StaticGatewayData>& staticGatewayData,
1017ce73d5c8SSunitha Harish     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1018ce73d5c8SSunitha Harish {
1019ce73d5c8SSunitha Harish     size_t entryIdx = 1;
1020ce73d5c8SSunitha Harish     std::vector<StaticGatewayData>::const_iterator staticGatewayEntry =
1021ce73d5c8SSunitha Harish         staticGatewayData.begin();
1022ce73d5c8SSunitha Harish 
10233dfed536SEd Tanous     for (std::variant<nlohmann::json::object_t, std::nullptr_t>& thisJson :
10243dfed536SEd Tanous          input)
1025ce73d5c8SSunitha Harish     {
1026ce73d5c8SSunitha Harish         // find the next gateway entry
1027ce73d5c8SSunitha Harish         while (staticGatewayEntry != staticGatewayData.end())
1028ce73d5c8SSunitha Harish         {
1029ce73d5c8SSunitha Harish             if (staticGatewayEntry->protocol ==
1030ce73d5c8SSunitha Harish                 "xyz.openbmc_project.Network.IP.Protocol.IPv6")
1031ce73d5c8SSunitha Harish             {
1032ce73d5c8SSunitha Harish                 break;
1033ce73d5c8SSunitha Harish             }
1034ce73d5c8SSunitha Harish             staticGatewayEntry++;
1035ce73d5c8SSunitha Harish         }
1036*bd79bce8SPatrick Williams         std::string pathString =
1037*bd79bce8SPatrick Williams             "IPv6StaticDefaultGateways/" + std::to_string(entryIdx);
10383dfed536SEd Tanous         nlohmann::json::object_t* obj =
10393dfed536SEd Tanous             std::get_if<nlohmann::json::object_t>(&thisJson);
10403dfed536SEd Tanous         if (obj == nullptr)
1041ce73d5c8SSunitha Harish         {
1042ce73d5c8SSunitha Harish             if (staticGatewayEntry == staticGatewayData.end())
1043ce73d5c8SSunitha Harish             {
1044ce73d5c8SSunitha Harish                 messages::resourceCannotBeDeleted(asyncResp->res);
1045ce73d5c8SSunitha Harish                 return;
1046ce73d5c8SSunitha Harish             }
1047ce73d5c8SSunitha Harish             deleteIPv6Gateway(staticGatewayEntry->id, asyncResp);
1048ce73d5c8SSunitha Harish             return;
1049ce73d5c8SSunitha Harish         }
10503dfed536SEd Tanous         if (obj->empty())
1051ce73d5c8SSunitha Harish         {
1052ce73d5c8SSunitha Harish             // Do nothing, but make sure the entry exists.
1053ce73d5c8SSunitha Harish             if (staticGatewayEntry == staticGatewayData.end())
1054ce73d5c8SSunitha Harish             {
10553dfed536SEd Tanous                 messages::propertyValueFormatError(asyncResp->res, *obj,
1056ce73d5c8SSunitha Harish                                                    pathString);
1057ce73d5c8SSunitha Harish                 return;
1058ce73d5c8SSunitha Harish             }
1059ce73d5c8SSunitha Harish         }
1060ce73d5c8SSunitha Harish         std::optional<std::string> address;
1061ce73d5c8SSunitha Harish         std::optional<size_t> prefixLength;
1062ce73d5c8SSunitha Harish 
10633dfed536SEd Tanous         if (!json_util::readJsonObject(*obj, asyncResp->res, "Address", address,
10643dfed536SEd Tanous                                        "PrefixLength", prefixLength))
1065ce73d5c8SSunitha Harish         {
1066ce73d5c8SSunitha Harish             return;
1067ce73d5c8SSunitha Harish         }
1068ce73d5c8SSunitha Harish         const std::string* addr = nullptr;
1069ce73d5c8SSunitha Harish         size_t prefix = 0;
1070ce73d5c8SSunitha Harish         if (address)
1071ce73d5c8SSunitha Harish         {
1072ce73d5c8SSunitha Harish             addr = &(*address);
1073ce73d5c8SSunitha Harish         }
1074ce73d5c8SSunitha Harish         else if (staticGatewayEntry != staticGatewayData.end())
1075ce73d5c8SSunitha Harish         {
1076ce73d5c8SSunitha Harish             addr = &(staticGatewayEntry->gateway);
1077ce73d5c8SSunitha Harish         }
1078ce73d5c8SSunitha Harish         else
1079ce73d5c8SSunitha Harish         {
1080ce73d5c8SSunitha Harish             messages::propertyMissing(asyncResp->res, pathString + "/Address");
1081ce73d5c8SSunitha Harish             return;
1082ce73d5c8SSunitha Harish         }
1083ce73d5c8SSunitha Harish         if (prefixLength)
1084ce73d5c8SSunitha Harish         {
1085ce73d5c8SSunitha Harish             prefix = *prefixLength;
1086ce73d5c8SSunitha Harish         }
1087ce73d5c8SSunitha Harish         else if (staticGatewayEntry != staticGatewayData.end())
1088ce73d5c8SSunitha Harish         {
1089ce73d5c8SSunitha Harish             prefix = staticGatewayEntry->prefixLength;
1090ce73d5c8SSunitha Harish         }
1091ce73d5c8SSunitha Harish         else
1092ce73d5c8SSunitha Harish         {
1093ce73d5c8SSunitha Harish             messages::propertyMissing(asyncResp->res,
1094ce73d5c8SSunitha Harish                                       pathString + "/PrefixLength");
1095ce73d5c8SSunitha Harish             return;
1096ce73d5c8SSunitha Harish         }
1097ce73d5c8SSunitha Harish         if (staticGatewayEntry != staticGatewayData.end())
1098ce73d5c8SSunitha Harish         {
1099ce73d5c8SSunitha Harish             deleteAndCreateIPv6DefaultGateway(ifaceId, staticGatewayEntry->id,
1100ce73d5c8SSunitha Harish                                               *addr, prefix, asyncResp);
1101ce73d5c8SSunitha Harish             staticGatewayEntry++;
1102ce73d5c8SSunitha Harish         }
1103ce73d5c8SSunitha Harish         else
1104ce73d5c8SSunitha Harish         {
1105ce73d5c8SSunitha Harish             createIPv6DefaultGateway(ifaceId, prefix, *addr, asyncResp);
1106ce73d5c8SSunitha Harish         }
1107ce73d5c8SSunitha Harish         entryIdx++;
1108ce73d5c8SSunitha Harish     }
1109ce73d5c8SSunitha Harish }
1110ce73d5c8SSunitha Harish 
1111ce73d5c8SSunitha Harish /**
1112179db1d7SKowalski, Kamil  * Function that retrieves all properties for given Ethernet Interface
1113179db1d7SKowalski, Kamil  * Object
1114179db1d7SKowalski, Kamil  * from EntityManager Network Manager
11154a0cb85cSEd Tanous  * @param ethiface_id a eth interface id to query on DBus
1116179db1d7SKowalski, Kamil  * @param callback a function that shall be called to convert Dbus output
1117179db1d7SKowalski, Kamil  * into JSON
1118179db1d7SKowalski, Kamil  */
1119179db1d7SKowalski, Kamil template <typename CallbackFunc>
112081ce609eSEd Tanous void getEthernetIfaceData(const std::string& ethifaceId,
11211abe55efSEd Tanous                           CallbackFunc&& callback)
11221abe55efSEd Tanous {
1123f5892d0dSGeorge Liu     sdbusplus::message::object_path path("/xyz/openbmc_project/network");
1124f5892d0dSGeorge Liu     dbus::utility::getManagedObjects(
1125f5892d0dSGeorge Liu         "xyz.openbmc_project.Network", path,
1126f94c4ecfSEd Tanous         [ethifaceId{std::string{ethifaceId}},
11278cb2c024SEd Tanous          callback = std::forward<CallbackFunc>(callback)](
11288b24275dSEd Tanous             const boost::system::error_code& ec,
11293dfed536SEd Tanous             const dbus::utility::ManagedObjectType& resp) mutable {
113055c7b7a2SEd Tanous             EthernetInterfaceData ethData{};
113177179532SEd Tanous             std::vector<IPv4AddressData> ipv4Data;
113277179532SEd Tanous             std::vector<IPv6AddressData> ipv6Data;
1133ce73d5c8SSunitha Harish             std::vector<StaticGatewayData> ipv6GatewayData;
1134179db1d7SKowalski, Kamil 
11358b24275dSEd Tanous             if (ec)
11361abe55efSEd Tanous             {
1137ce73d5c8SSunitha Harish                 callback(false, ethData, ipv4Data, ipv6Data, ipv6GatewayData);
1138179db1d7SKowalski, Kamil                 return;
1139179db1d7SKowalski, Kamil             }
1140179db1d7SKowalski, Kamil 
1141*bd79bce8SPatrick Williams             bool found =
1142*bd79bce8SPatrick Williams                 extractEthernetInterfaceData(ethifaceId, resp, ethData);
11434c9afe43SEd Tanous             if (!found)
11444c9afe43SEd Tanous             {
1145ce73d5c8SSunitha Harish                 callback(false, ethData, ipv4Data, ipv6Data, ipv6GatewayData);
11464c9afe43SEd Tanous                 return;
11474c9afe43SEd Tanous             }
11484c9afe43SEd Tanous 
11492c70f800SEd Tanous             extractIPData(ethifaceId, resp, ipv4Data);
1150179db1d7SKowalski, Kamil             // Fix global GW
11511abe55efSEd Tanous             for (IPv4AddressData& ipv4 : ipv4Data)
11521abe55efSEd Tanous             {
1153c619141bSRavi Teja                 if (((ipv4.linktype == LinkType::Global) &&
1154c619141bSRavi Teja                      (ipv4.gateway == "0.0.0.0")) ||
11559010ec2eSRavi Teja                     (ipv4.origin == "DHCP") || (ipv4.origin == "Static"))
11561abe55efSEd Tanous                 {
115782695a5bSJiaqing Zhao                     ipv4.gateway = ethData.defaultGateway;
1158179db1d7SKowalski, Kamil                 }
1159179db1d7SKowalski, Kamil             }
1160179db1d7SKowalski, Kamil 
11612c70f800SEd Tanous             extractIPV6Data(ethifaceId, resp, ipv6Data);
1162*bd79bce8SPatrick Williams             if (!extractIPv6DefaultGatewayData(ethifaceId, resp,
1163*bd79bce8SPatrick Williams                                                ipv6GatewayData))
1164ce73d5c8SSunitha Harish             {
1165ce73d5c8SSunitha Harish                 callback(false, ethData, ipv4Data, ipv6Data, ipv6GatewayData);
1166ce73d5c8SSunitha Harish             }
11674e0453b1SGunnar Mills             // Finally make a callback with useful data
1168ce73d5c8SSunitha Harish             callback(true, ethData, ipv4Data, ipv6Data, ipv6GatewayData);
1169f5892d0dSGeorge Liu         });
1170271584abSEd Tanous }
1171179db1d7SKowalski, Kamil 
1172179db1d7SKowalski, Kamil /**
11739391bb9cSRapkiewicz, Pawel  * Function that retrieves all Ethernet Interfaces available through Network
11749391bb9cSRapkiewicz, Pawel  * Manager
11751abe55efSEd Tanous  * @param callback a function that shall be called to convert Dbus output
11761abe55efSEd Tanous  * into JSON.
11779391bb9cSRapkiewicz, Pawel  */
11789391bb9cSRapkiewicz, Pawel template <typename CallbackFunc>
11791abe55efSEd Tanous void getEthernetIfaceList(CallbackFunc&& callback)
11801abe55efSEd Tanous {
1181f5892d0dSGeorge Liu     sdbusplus::message::object_path path("/xyz/openbmc_project/network");
1182f5892d0dSGeorge Liu     dbus::utility::getManagedObjects(
1183f5892d0dSGeorge Liu         "xyz.openbmc_project.Network", path,
11848cb2c024SEd Tanous         [callback = std::forward<CallbackFunc>(callback)](
11858b24275dSEd Tanous             const boost::system::error_code& ec,
1186f5892d0dSGeorge Liu             const dbus::utility::ManagedObjectType& resp) {
11871abe55efSEd Tanous             // Callback requires vector<string> to retrieve all available
11881abe55efSEd Tanous             // ethernet interfaces
118977179532SEd Tanous             std::vector<std::string> ifaceList;
11902c70f800SEd Tanous             ifaceList.reserve(resp.size());
11918b24275dSEd Tanous             if (ec)
11921abe55efSEd Tanous             {
11932c70f800SEd Tanous                 callback(false, ifaceList);
11949391bb9cSRapkiewicz, Pawel                 return;
11959391bb9cSRapkiewicz, Pawel             }
11969391bb9cSRapkiewicz, Pawel 
11979391bb9cSRapkiewicz, Pawel             // Iterate over all retrieved ObjectPaths.
11984a0cb85cSEd Tanous             for (const auto& objpath : resp)
11991abe55efSEd Tanous             {
12009391bb9cSRapkiewicz, Pawel                 // And all interfaces available for certain ObjectPath.
12014a0cb85cSEd Tanous                 for (const auto& interface : objpath.second)
12021abe55efSEd Tanous                 {
12031abe55efSEd Tanous                     // If interface is
12044a0cb85cSEd Tanous                     // xyz.openbmc_project.Network.EthernetInterface, this is
12054a0cb85cSEd Tanous                     // what we're looking for.
12069391bb9cSRapkiewicz, Pawel                     if (interface.first ==
12071abe55efSEd Tanous                         "xyz.openbmc_project.Network.EthernetInterface")
12081abe55efSEd Tanous                     {
12092dfd18efSEd Tanous                         std::string ifaceId = objpath.first.filename();
12102dfd18efSEd Tanous                         if (ifaceId.empty())
12111abe55efSEd Tanous                         {
12122dfd18efSEd Tanous                             continue;
12139391bb9cSRapkiewicz, Pawel                         }
12142dfd18efSEd Tanous                         // and put it into output vector.
121577179532SEd Tanous                         ifaceList.emplace_back(ifaceId);
12169391bb9cSRapkiewicz, Pawel                     }
12179391bb9cSRapkiewicz, Pawel                 }
12189391bb9cSRapkiewicz, Pawel             }
12192c5875a2SEd Tanous 
12203544d2a7SEd Tanous             std::ranges::sort(ifaceList, AlphanumLess<std::string>());
12212c5875a2SEd Tanous 
1222a434f2bdSEd Tanous             // Finally make a callback with useful data
12232c70f800SEd Tanous             callback(true, ifaceList);
1224f5892d0dSGeorge Liu         });
1225271584abSEd Tanous }
12269391bb9cSRapkiewicz, Pawel 
12274f48d5f6SEd Tanous inline void
12284f48d5f6SEd Tanous     handleHostnamePatch(const std::string& hostname,
12298d1b46d7Szhanghch05                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
12301abe55efSEd Tanous {
1231ab6554f1SJoshi-Mansi     // SHOULD handle host names of up to 255 characters(RFC 1123)
1232ab6554f1SJoshi-Mansi     if (hostname.length() > 255)
1233ab6554f1SJoshi-Mansi     {
1234ab6554f1SJoshi-Mansi         messages::propertyValueFormatError(asyncResp->res, hostname,
1235ab6554f1SJoshi-Mansi                                            "HostName");
1236ab6554f1SJoshi-Mansi         return;
1237ab6554f1SJoshi-Mansi     }
1238d02aad39SEd Tanous     setDbusProperty(
1239e93abac6SGinu George         asyncResp, "HostName", "xyz.openbmc_project.Network",
1240d02aad39SEd Tanous         sdbusplus::message::object_path("/xyz/openbmc_project/network/config"),
1241d02aad39SEd Tanous         "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
1242e93abac6SGinu George         hostname);
1243588c3f0dSKowalski, Kamil }
1244588c3f0dSKowalski, Kamil 
12454f48d5f6SEd Tanous inline void
124635fb5311STejas Patil     handleMTUSizePatch(const std::string& ifaceId, const size_t mtuSize,
124735fb5311STejas Patil                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
124835fb5311STejas Patil {
1249d02aad39SEd Tanous     sdbusplus::message::object_path objPath("/xyz/openbmc_project/network");
1250d02aad39SEd Tanous     objPath /= ifaceId;
1251e93abac6SGinu George     setDbusProperty(asyncResp, "MTUSize", "xyz.openbmc_project.Network",
1252e93abac6SGinu George                     objPath, "xyz.openbmc_project.Network.EthernetInterface",
1253e93abac6SGinu George                     "MTU", mtuSize);
125435fb5311STejas Patil }
125535fb5311STejas Patil 
1256*bd79bce8SPatrick Williams inline void handleDomainnamePatch(
1257*bd79bce8SPatrick Williams     const std::string& ifaceId, const std::string& domainname,
12588d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1259ab6554f1SJoshi-Mansi {
1260ab6554f1SJoshi-Mansi     std::vector<std::string> vectorDomainname = {domainname};
1261d02aad39SEd Tanous     setDbusProperty(
1262e93abac6SGinu George         asyncResp, "FQDN", "xyz.openbmc_project.Network",
1263d02aad39SEd Tanous         sdbusplus::message::object_path("/xyz/openbmc_project/network") /
1264d02aad39SEd Tanous             ifaceId,
1265e93abac6SGinu George         "xyz.openbmc_project.Network.EthernetInterface", "DomainName",
1266d02aad39SEd Tanous         vectorDomainname);
1267ab6554f1SJoshi-Mansi }
1268ab6554f1SJoshi-Mansi 
12694f48d5f6SEd Tanous inline bool isHostnameValid(const std::string& hostname)
1270bf648f77SEd Tanous {
1271bf648f77SEd Tanous     // A valid host name can never have the dotted-decimal form (RFC 1123)
12723544d2a7SEd Tanous     if (std::ranges::all_of(hostname, ::isdigit))
1273bf648f77SEd Tanous     {
1274bf648f77SEd Tanous         return false;
1275bf648f77SEd Tanous     }
1276bf648f77SEd Tanous     // Each label(hostname/subdomains) within a valid FQDN
1277bf648f77SEd Tanous     // MUST handle host names of up to 63 characters (RFC 1123)
1278bf648f77SEd Tanous     // labels cannot start or end with hyphens (RFC 952)
1279bf648f77SEd Tanous     // labels can start with numbers (RFC 1123)
12804b242749SEd Tanous     const static std::regex pattern(
1281bf648f77SEd Tanous         "^[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]$");
1282bf648f77SEd Tanous 
1283bf648f77SEd Tanous     return std::regex_match(hostname, pattern);
1284bf648f77SEd Tanous }
1285bf648f77SEd Tanous 
12864f48d5f6SEd Tanous inline bool isDomainnameValid(const std::string& domainname)
1287bf648f77SEd Tanous {
1288bf648f77SEd Tanous     // Can have multiple subdomains
1289bf648f77SEd Tanous     // Top Level Domain's min length is 2 character
12904b242749SEd Tanous     const static std::regex pattern(
12910fda0f12SGeorge Liu         "^([A-Za-z0-9][a-zA-Z0-9\\-]{1,61}|[a-zA-Z0-9]{1,30}\\.)*[a-zA-Z]{2,}$");
1292bf648f77SEd Tanous 
1293bf648f77SEd Tanous     return std::regex_match(domainname, pattern);
1294bf648f77SEd Tanous }
1295bf648f77SEd Tanous 
12964f48d5f6SEd Tanous inline void handleFqdnPatch(const std::string& ifaceId, const std::string& fqdn,
12978d1b46d7Szhanghch05                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1298ab6554f1SJoshi-Mansi {
1299ab6554f1SJoshi-Mansi     // Total length of FQDN must not exceed 255 characters(RFC 1035)
1300ab6554f1SJoshi-Mansi     if (fqdn.length() > 255)
1301ab6554f1SJoshi-Mansi     {
1302ab6554f1SJoshi-Mansi         messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN");
1303ab6554f1SJoshi-Mansi         return;
1304ab6554f1SJoshi-Mansi     }
1305ab6554f1SJoshi-Mansi 
1306ab6554f1SJoshi-Mansi     size_t pos = fqdn.find('.');
1307ab6554f1SJoshi-Mansi     if (pos == std::string::npos)
1308ab6554f1SJoshi-Mansi     {
1309ab6554f1SJoshi-Mansi         messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN");
1310ab6554f1SJoshi-Mansi         return;
1311ab6554f1SJoshi-Mansi     }
1312ab6554f1SJoshi-Mansi 
1313ab6554f1SJoshi-Mansi     std::string hostname;
1314ab6554f1SJoshi-Mansi     std::string domainname;
1315ab6554f1SJoshi-Mansi     domainname = (fqdn).substr(pos + 1);
1316ab6554f1SJoshi-Mansi     hostname = (fqdn).substr(0, pos);
1317ab6554f1SJoshi-Mansi 
1318ab6554f1SJoshi-Mansi     if (!isHostnameValid(hostname) || !isDomainnameValid(domainname))
1319ab6554f1SJoshi-Mansi     {
1320ab6554f1SJoshi-Mansi         messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN");
1321ab6554f1SJoshi-Mansi         return;
1322ab6554f1SJoshi-Mansi     }
1323ab6554f1SJoshi-Mansi 
1324ab6554f1SJoshi-Mansi     handleHostnamePatch(hostname, asyncResp);
1325ab6554f1SJoshi-Mansi     handleDomainnamePatch(ifaceId, domainname, asyncResp);
1326ab6554f1SJoshi-Mansi }
1327ab6554f1SJoshi-Mansi 
1328*bd79bce8SPatrick Williams inline void handleMACAddressPatch(
1329*bd79bce8SPatrick Williams     const std::string& ifaceId, const std::string& macAddress,
13308d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1331d577665bSRatan Gupta {
1332d02aad39SEd Tanous     setDbusProperty(
1333e93abac6SGinu George         asyncResp, "MACAddress", "xyz.openbmc_project.Network",
1334d02aad39SEd Tanous         sdbusplus::message::object_path("/xyz/openbmc_project/network") /
1335d02aad39SEd Tanous             ifaceId,
1336e93abac6SGinu George         "xyz.openbmc_project.Network.MACAddress", "MACAddress", macAddress);
1337d577665bSRatan Gupta }
1338286b9118SJohnathan Mantey 
13394f48d5f6SEd Tanous inline void setDHCPEnabled(const std::string& ifaceId,
13404f48d5f6SEd Tanous                            const std::string& propertyName, const bool v4Value,
13414f48d5f6SEd Tanous                            const bool v6Value,
13428d1b46d7Szhanghch05                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1343da131a9aSJennifer Lee {
13442c70f800SEd Tanous     const std::string dhcp = getDhcpEnabledEnumeration(v4Value, v6Value);
1345d02aad39SEd Tanous     setDbusProperty(
1346e93abac6SGinu George         asyncResp, "DHCPv4", "xyz.openbmc_project.Network",
1347d02aad39SEd Tanous         sdbusplus::message::object_path("/xyz/openbmc_project/network") /
1348d02aad39SEd Tanous             ifaceId,
1349e93abac6SGinu George         "xyz.openbmc_project.Network.EthernetInterface", propertyName, dhcp);
1350eeedda23SJohnathan Mantey }
1351eeedda23SJohnathan Mantey 
1352e4588158SJishnu CM enum class NetworkType
1353e4588158SJishnu CM {
1354e4588158SJishnu CM     dhcp4,
1355e4588158SJishnu CM     dhcp6
1356e4588158SJishnu CM };
1357e4588158SJishnu CM 
1358e4588158SJishnu CM inline void setDHCPConfig(const std::string& propertyName, const bool& value,
1359e4588158SJishnu CM                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1360e4588158SJishnu CM                           const std::string& ethifaceId, NetworkType type)
1361da131a9aSJennifer Lee {
136262598e31SEd Tanous     BMCWEB_LOG_DEBUG("{} = {}", propertyName, value);
13631847f2a0SAsmitha Karunanithi     std::string redfishPropertyName;
1364e4588158SJishnu CM     sdbusplus::message::object_path path("/xyz/openbmc_project/network/");
1365e4588158SJishnu CM     path /= ethifaceId;
1366e4588158SJishnu CM 
1367e4588158SJishnu CM     if (type == NetworkType::dhcp4)
1368e4588158SJishnu CM     {
1369e4588158SJishnu CM         path /= "dhcp4";
13701847f2a0SAsmitha Karunanithi         redfishPropertyName = "DHCPv4";
1371e4588158SJishnu CM     }
1372e4588158SJishnu CM     else
1373e4588158SJishnu CM     {
1374e4588158SJishnu CM         path /= "dhcp6";
13751847f2a0SAsmitha Karunanithi         redfishPropertyName = "DHCPv6";
1376e4588158SJishnu CM     }
1377e4588158SJishnu CM 
1378e93abac6SGinu George     setDbusProperty(
1379e93abac6SGinu George         asyncResp, redfishPropertyName, "xyz.openbmc_project.Network", path,
1380e93abac6SGinu George         "xyz.openbmc_project.Network.DHCPConfiguration", propertyName, value);
1381da131a9aSJennifer Lee }
1382d577665bSRatan Gupta 
1383b10d8db0SRavi Teja inline void handleSLAACAutoConfigPatch(
1384b10d8db0SRavi Teja     const std::string& ifaceId, bool ipv6AutoConfigEnabled,
1385b10d8db0SRavi Teja     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1386b10d8db0SRavi Teja {
1387b10d8db0SRavi Teja     sdbusplus::message::object_path path("/xyz/openbmc_project/network");
1388b10d8db0SRavi Teja     path /= ifaceId;
1389e93abac6SGinu George     setDbusProperty(asyncResp,
13901847f2a0SAsmitha Karunanithi                     "StatelessAddressAutoConfig/IPv6AutoConfigEnabled",
1391e93abac6SGinu George                     "xyz.openbmc_project.Network", path,
1392e93abac6SGinu George                     "xyz.openbmc_project.Network.EthernetInterface",
1393e93abac6SGinu George                     "IPv6AcceptRA", ipv6AutoConfigEnabled);
1394b10d8db0SRavi Teja }
1395b10d8db0SRavi Teja 
1396*bd79bce8SPatrick Williams inline void handleDHCPPatch(
1397*bd79bce8SPatrick Williams     const std::string& ifaceId, const EthernetInterfaceData& ethData,
1398*bd79bce8SPatrick Williams     const DHCPParameters& v4dhcpParms, const DHCPParameters& v6dhcpParms,
13998d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1400da131a9aSJennifer Lee {
140182695a5bSJiaqing Zhao     bool ipv4Active = translateDhcpEnabledToBool(ethData.dhcpEnabled, true);
140282695a5bSJiaqing Zhao     bool ipv6Active = translateDhcpEnabledToBool(ethData.dhcpEnabled, false);
1403da131a9aSJennifer Lee 
1404743eb1c0SJohnathan Mantey     if (ipv4Active)
1405743eb1c0SJohnathan Mantey     {
1406743eb1c0SJohnathan Mantey         updateIPv4DefaultGateway(ifaceId, "", asyncResp);
1407743eb1c0SJohnathan Mantey     }
14081f8c7b5dSJohnathan Mantey     bool nextv4DHCPState =
14091f8c7b5dSJohnathan Mantey         v4dhcpParms.dhcpv4Enabled ? *v4dhcpParms.dhcpv4Enabled : ipv4Active;
14101f8c7b5dSJohnathan Mantey 
14111f8c7b5dSJohnathan Mantey     bool nextv6DHCPState{};
14121f8c7b5dSJohnathan Mantey     if (v6dhcpParms.dhcpv6OperatingMode)
1413da131a9aSJennifer Lee     {
1414b10d8db0SRavi Teja         if ((*v6dhcpParms.dhcpv6OperatingMode != "Enabled") &&
14151f8c7b5dSJohnathan Mantey             (*v6dhcpParms.dhcpv6OperatingMode != "Disabled"))
14161f8c7b5dSJohnathan Mantey         {
1417bf648f77SEd Tanous             messages::propertyValueFormatError(asyncResp->res,
1418bf648f77SEd Tanous                                                *v6dhcpParms.dhcpv6OperatingMode,
14191f8c7b5dSJohnathan Mantey                                                "OperatingMode");
1420da131a9aSJennifer Lee             return;
1421da131a9aSJennifer Lee         }
1422b10d8db0SRavi Teja         nextv6DHCPState = (*v6dhcpParms.dhcpv6OperatingMode == "Enabled");
14231f8c7b5dSJohnathan Mantey     }
14241f8c7b5dSJohnathan Mantey     else
1425da131a9aSJennifer Lee     {
14261f8c7b5dSJohnathan Mantey         nextv6DHCPState = ipv6Active;
14271f8c7b5dSJohnathan Mantey     }
14281f8c7b5dSJohnathan Mantey 
1429e4588158SJishnu CM     bool nextDNSv4 = ethData.dnsv4Enabled;
1430e4588158SJishnu CM     bool nextDNSv6 = ethData.dnsv6Enabled;
1431e4588158SJishnu CM     if (v4dhcpParms.useDnsServers)
14321f8c7b5dSJohnathan Mantey     {
1433e4588158SJishnu CM         nextDNSv4 = *v4dhcpParms.useDnsServers;
14341f8c7b5dSJohnathan Mantey     }
1435e4588158SJishnu CM     if (v6dhcpParms.useDnsServers)
14361f8c7b5dSJohnathan Mantey     {
1437e4588158SJishnu CM         nextDNSv6 = *v6dhcpParms.useDnsServers;
14381f8c7b5dSJohnathan Mantey     }
14391f8c7b5dSJohnathan Mantey 
1440e4588158SJishnu CM     bool nextNTPv4 = ethData.ntpv4Enabled;
1441e4588158SJishnu CM     bool nextNTPv6 = ethData.ntpv6Enabled;
1442e4588158SJishnu CM     if (v4dhcpParms.useNtpServers)
14431f8c7b5dSJohnathan Mantey     {
1444e4588158SJishnu CM         nextNTPv4 = *v4dhcpParms.useNtpServers;
14451f8c7b5dSJohnathan Mantey     }
1446e4588158SJishnu CM     if (v6dhcpParms.useNtpServers)
14471f8c7b5dSJohnathan Mantey     {
1448e4588158SJishnu CM         nextNTPv6 = *v6dhcpParms.useNtpServers;
14491f8c7b5dSJohnathan Mantey     }
14501f8c7b5dSJohnathan Mantey 
145191c441ecSRavi Teja     bool nextUsev4Domain = ethData.domainv4Enabled;
145291c441ecSRavi Teja     bool nextUsev6Domain = ethData.domainv6Enabled;
1453e4588158SJishnu CM     if (v4dhcpParms.useDomainName)
14541f8c7b5dSJohnathan Mantey     {
1455e4588158SJishnu CM         nextUsev4Domain = *v4dhcpParms.useDomainName;
14561f8c7b5dSJohnathan Mantey     }
1457e4588158SJishnu CM     if (v6dhcpParms.useDomainName)
14581f8c7b5dSJohnathan Mantey     {
1459e4588158SJishnu CM         nextUsev6Domain = *v6dhcpParms.useDomainName;
14601f8c7b5dSJohnathan Mantey     }
14611f8c7b5dSJohnathan Mantey 
146262598e31SEd Tanous     BMCWEB_LOG_DEBUG("set DHCPEnabled...");
14631f8c7b5dSJohnathan Mantey     setDHCPEnabled(ifaceId, "DHCPEnabled", nextv4DHCPState, nextv6DHCPState,
14641f8c7b5dSJohnathan Mantey                    asyncResp);
146562598e31SEd Tanous     BMCWEB_LOG_DEBUG("set DNSEnabled...");
1466e4588158SJishnu CM     setDHCPConfig("DNSEnabled", nextDNSv4, asyncResp, ifaceId,
1467e4588158SJishnu CM                   NetworkType::dhcp4);
146862598e31SEd Tanous     BMCWEB_LOG_DEBUG("set NTPEnabled...");
1469e4588158SJishnu CM     setDHCPConfig("NTPEnabled", nextNTPv4, asyncResp, ifaceId,
1470e4588158SJishnu CM                   NetworkType::dhcp4);
147191c441ecSRavi Teja     BMCWEB_LOG_DEBUG("set DomainEnabled...");
147291c441ecSRavi Teja     setDHCPConfig("DomainEnabled", nextUsev4Domain, asyncResp, ifaceId,
1473e4588158SJishnu CM                   NetworkType::dhcp4);
1474e4588158SJishnu CM     BMCWEB_LOG_DEBUG("set DNSEnabled for dhcp6...");
1475e4588158SJishnu CM     setDHCPConfig("DNSEnabled", nextDNSv6, asyncResp, ifaceId,
1476e4588158SJishnu CM                   NetworkType::dhcp6);
1477e4588158SJishnu CM     BMCWEB_LOG_DEBUG("set NTPEnabled for dhcp6...");
1478e4588158SJishnu CM     setDHCPConfig("NTPEnabled", nextNTPv6, asyncResp, ifaceId,
1479e4588158SJishnu CM                   NetworkType::dhcp6);
148091c441ecSRavi Teja     BMCWEB_LOG_DEBUG("set DomainEnabled for dhcp6...");
148191c441ecSRavi Teja     setDHCPConfig("DomainEnabled", nextUsev6Domain, asyncResp, ifaceId,
1482e4588158SJishnu CM                   NetworkType::dhcp6);
1483da131a9aSJennifer Lee }
148401784826SJohnathan Mantey 
148577179532SEd Tanous inline std::vector<IPv4AddressData>::const_iterator getNextStaticIpEntry(
148677179532SEd Tanous     const std::vector<IPv4AddressData>::const_iterator& head,
148777179532SEd Tanous     const std::vector<IPv4AddressData>::const_iterator& end)
148801784826SJohnathan Mantey {
148917a897dfSManojkiran Eda     return std::find_if(head, end, [](const IPv4AddressData& value) {
149017a897dfSManojkiran Eda         return value.origin == "Static";
149117a897dfSManojkiran Eda     });
149201784826SJohnathan Mantey }
149301784826SJohnathan Mantey 
149477179532SEd Tanous inline std::vector<IPv6AddressData>::const_iterator getNextStaticIpEntry(
149577179532SEd Tanous     const std::vector<IPv6AddressData>::const_iterator& head,
149677179532SEd Tanous     const std::vector<IPv6AddressData>::const_iterator& end)
149701784826SJohnathan Mantey {
149817a897dfSManojkiran Eda     return std::find_if(head, end, [](const IPv6AddressData& value) {
149917a897dfSManojkiran Eda         return value.origin == "Static";
150017a897dfSManojkiran Eda     });
150101784826SJohnathan Mantey }
150201784826SJohnathan Mantey 
15033dfed536SEd Tanous inline void handleIPv4StaticPatch(
15043dfed536SEd Tanous     const std::string& ifaceId,
15053dfed536SEd Tanous     std::vector<std::variant<nlohmann::json::object_t, std::nullptr_t>>& input,
1506743eb1c0SJohnathan Mantey     const EthernetInterfaceData& ethData,
150777179532SEd Tanous     const std::vector<IPv4AddressData>& ipv4Data,
15088d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
15091abe55efSEd Tanous {
1510271584abSEd Tanous     unsigned entryIdx = 1;
151101784826SJohnathan Mantey     // Find the first static IP address currently active on the NIC and
151201784826SJohnathan Mantey     // match it to the first JSON element in the IPv4StaticAddresses array.
151301784826SJohnathan Mantey     // Match each subsequent JSON element to the next static IP programmed
151401784826SJohnathan Mantey     // into the NIC.
151577179532SEd Tanous     std::vector<IPv4AddressData>::const_iterator nicIpEntry =
15162c70f800SEd Tanous         getNextStaticIpEntry(ipv4Data.cbegin(), ipv4Data.cend());
151701784826SJohnathan Mantey 
1518743eb1c0SJohnathan Mantey     bool gatewayValueAssigned{};
15194a8f5d43SJohnathan Mantey     bool preserveGateway{};
1520743eb1c0SJohnathan Mantey     std::string activePath{};
1521743eb1c0SJohnathan Mantey     std::string activeGateway{};
1522743eb1c0SJohnathan Mantey     if (!ethData.defaultGateway.empty() && ethData.defaultGateway != "0.0.0.0")
1523743eb1c0SJohnathan Mantey     {
1524743eb1c0SJohnathan Mantey         // The NIC is already configured with a default gateway. Use this if
1525743eb1c0SJohnathan Mantey         // the leading entry in the PATCH is '{}', which is preserving an active
1526743eb1c0SJohnathan Mantey         // static address.
1527743eb1c0SJohnathan Mantey         activeGateway = ethData.defaultGateway;
1528743eb1c0SJohnathan Mantey         activePath = "IPv4StaticAddresses/1";
1529743eb1c0SJohnathan Mantey         gatewayValueAssigned = true;
1530743eb1c0SJohnathan Mantey     }
1531743eb1c0SJohnathan Mantey 
15323dfed536SEd Tanous     for (std::variant<nlohmann::json::object_t, std::nullptr_t>& thisJson :
15333dfed536SEd Tanous          input)
15341abe55efSEd Tanous     {
1535*bd79bce8SPatrick Williams         std::string pathString =
1536*bd79bce8SPatrick Williams             "IPv4StaticAddresses/" + std::to_string(entryIdx);
15373dfed536SEd Tanous         nlohmann::json::object_t* obj =
15383dfed536SEd Tanous             std::get_if<nlohmann::json::object_t>(&thisJson);
1539743eb1c0SJohnathan Mantey         if (obj == nullptr)
1540743eb1c0SJohnathan Mantey         {
1541743eb1c0SJohnathan Mantey             if (nicIpEntry != ipv4Data.cend())
1542743eb1c0SJohnathan Mantey             {
1543743eb1c0SJohnathan Mantey                 deleteIPAddress(ifaceId, nicIpEntry->id, asyncResp);
1544*bd79bce8SPatrick Williams                 nicIpEntry =
1545*bd79bce8SPatrick Williams                     getNextStaticIpEntry(++nicIpEntry, ipv4Data.cend());
15464a8f5d43SJohnathan Mantey                 if (!preserveGateway && (nicIpEntry == ipv4Data.cend()))
1547743eb1c0SJohnathan Mantey                 {
1548743eb1c0SJohnathan Mantey                     // All entries have been processed, and this last has
1549743eb1c0SJohnathan Mantey                     // requested the IP address be deleted. No prior entry
1550743eb1c0SJohnathan Mantey                     // performed an action that created or modified a
1551743eb1c0SJohnathan Mantey                     // gateway. Deleting this IP address means the default
1552743eb1c0SJohnathan Mantey                     // gateway entry has to be removed as well.
1553743eb1c0SJohnathan Mantey                     updateIPv4DefaultGateway(ifaceId, "", asyncResp);
1554743eb1c0SJohnathan Mantey                 }
1555743eb1c0SJohnathan Mantey                 entryIdx++;
1556743eb1c0SJohnathan Mantey                 continue;
1557743eb1c0SJohnathan Mantey             }
1558743eb1c0SJohnathan Mantey             // Received a DELETE action on an entry not assigned to the NIC
1559743eb1c0SJohnathan Mantey             messages::resourceCannotBeDeleted(asyncResp->res);
1560743eb1c0SJohnathan Mantey             return;
1561743eb1c0SJohnathan Mantey         }
1562743eb1c0SJohnathan Mantey 
1563743eb1c0SJohnathan Mantey         // An Add/Modify action is requested
1564743eb1c0SJohnathan Mantey         if (!obj->empty())
1565f476acbfSRatan Gupta         {
1566537174c4SEd Tanous             std::optional<std::string> address;
1567537174c4SEd Tanous             std::optional<std::string> subnetMask;
1568537174c4SEd Tanous             std::optional<std::string> gateway;
1569537174c4SEd Tanous 
15703dfed536SEd Tanous             if (!json_util::readJsonObject(*obj, asyncResp->res, "Address",
15717e27d832SJohnathan Mantey                                            address, "SubnetMask", subnetMask,
15727e27d832SJohnathan Mantey                                            "Gateway", gateway))
1573537174c4SEd Tanous             {
15743dfed536SEd Tanous                 messages::propertyValueFormatError(asyncResp->res, *obj,
157571f52d96SEd Tanous                                                    pathString);
1576537174c4SEd Tanous                 return;
1577179db1d7SKowalski, Kamil             }
1578179db1d7SKowalski, Kamil 
157901784826SJohnathan Mantey             // Find the address/subnet/gateway values. Any values that are
158001784826SJohnathan Mantey             // not explicitly provided are assumed to be unmodified from the
158101784826SJohnathan Mantey             // current state of the interface. Merge existing state into the
158201784826SJohnathan Mantey             // current request.
1583537174c4SEd Tanous             if (address)
15841abe55efSEd Tanous             {
1585e01d0c36SEd Tanous                 if (!ip_util::ipv4VerifyIpAndGetBitcount(*address))
158601784826SJohnathan Mantey                 {
1587bf648f77SEd Tanous                     messages::propertyValueFormatError(asyncResp->res, *address,
1588bf648f77SEd Tanous                                                        pathString + "/Address");
1589e01d0c36SEd Tanous                     return;
159001784826SJohnathan Mantey                 }
159101784826SJohnathan Mantey             }
159285ffe86aSJiaqing Zhao             else if (nicIpEntry != ipv4Data.cend())
159301784826SJohnathan Mantey             {
1594e01d0c36SEd Tanous                 address = (nicIpEntry->address);
159501784826SJohnathan Mantey             }
159601784826SJohnathan Mantey             else
159701784826SJohnathan Mantey             {
159801784826SJohnathan Mantey                 messages::propertyMissing(asyncResp->res,
159901784826SJohnathan Mantey                                           pathString + "/Address");
1600e01d0c36SEd Tanous                 return;
16014a0cb85cSEd Tanous             }
16024a0cb85cSEd Tanous 
1603e01d0c36SEd Tanous             uint8_t prefixLength = 0;
1604537174c4SEd Tanous             if (subnetMask)
16054a0cb85cSEd Tanous             {
1606033f1e4dSEd Tanous                 if (!ip_util::ipv4VerifyIpAndGetBitcount(*subnetMask,
1607033f1e4dSEd Tanous                                                          &prefixLength))
16084a0cb85cSEd Tanous                 {
1609f12894f8SJason M. Bills                     messages::propertyValueFormatError(
1610537174c4SEd Tanous                         asyncResp->res, *subnetMask,
16114a0cb85cSEd Tanous                         pathString + "/SubnetMask");
1612e01d0c36SEd Tanous                     return;
16134a0cb85cSEd Tanous                 }
16144a0cb85cSEd Tanous             }
161585ffe86aSJiaqing Zhao             else if (nicIpEntry != ipv4Data.cend())
16164a0cb85cSEd Tanous             {
1617033f1e4dSEd Tanous                 if (!ip_util::ipv4VerifyIpAndGetBitcount(nicIpEntry->netmask,
161801784826SJohnathan Mantey                                                          &prefixLength))
16194a0cb85cSEd Tanous                 {
162001784826SJohnathan Mantey                     messages::propertyValueFormatError(
162185ffe86aSJiaqing Zhao                         asyncResp->res, nicIpEntry->netmask,
162201784826SJohnathan Mantey                         pathString + "/SubnetMask");
1623e01d0c36SEd Tanous                     return;
16244a0cb85cSEd Tanous                 }
16254a0cb85cSEd Tanous             }
16261abe55efSEd Tanous             else
16271abe55efSEd Tanous             {
162801784826SJohnathan Mantey                 messages::propertyMissing(asyncResp->res,
162901784826SJohnathan Mantey                                           pathString + "/SubnetMask");
1630e01d0c36SEd Tanous                 return;
163101784826SJohnathan Mantey             }
163201784826SJohnathan Mantey 
163301784826SJohnathan Mantey             if (gateway)
163401784826SJohnathan Mantey             {
1635e01d0c36SEd Tanous                 if (!ip_util::ipv4VerifyIpAndGetBitcount(*gateway))
163601784826SJohnathan Mantey                 {
1637bf648f77SEd Tanous                     messages::propertyValueFormatError(asyncResp->res, *gateway,
1638bf648f77SEd Tanous                                                        pathString + "/Gateway");
1639e01d0c36SEd Tanous                     return;
164001784826SJohnathan Mantey                 }
164101784826SJohnathan Mantey             }
164285ffe86aSJiaqing Zhao             else if (nicIpEntry != ipv4Data.cend())
164301784826SJohnathan Mantey             {
1644e01d0c36SEd Tanous                 gateway = nicIpEntry->gateway;
164501784826SJohnathan Mantey             }
164601784826SJohnathan Mantey             else
16471abe55efSEd Tanous             {
1648a08b46ccSJason M. Bills                 messages::propertyMissing(asyncResp->res,
16494a0cb85cSEd Tanous                                           pathString + "/Gateway");
165001784826SJohnathan Mantey                 return;
16514a0cb85cSEd Tanous             }
16524a0cb85cSEd Tanous 
1653743eb1c0SJohnathan Mantey             if (gatewayValueAssigned)
1654743eb1c0SJohnathan Mantey             {
1655743eb1c0SJohnathan Mantey                 if (activeGateway != gateway)
1656743eb1c0SJohnathan Mantey                 {
1657743eb1c0SJohnathan Mantey                     // A NIC can only have a single active gateway value.
1658743eb1c0SJohnathan Mantey                     // If any gateway in the array of static addresses
1659743eb1c0SJohnathan Mantey                     // mismatch the PATCH is in error.
1660743eb1c0SJohnathan Mantey                     std::string arg1 = pathString + "/Gateway";
1661743eb1c0SJohnathan Mantey                     std::string arg2 = activePath + "/Gateway";
1662743eb1c0SJohnathan Mantey                     messages::propertyValueConflict(asyncResp->res, arg1, arg2);
1663743eb1c0SJohnathan Mantey                     return;
1664743eb1c0SJohnathan Mantey                 }
1665743eb1c0SJohnathan Mantey             }
1666743eb1c0SJohnathan Mantey             else
1667743eb1c0SJohnathan Mantey             {
1668743eb1c0SJohnathan Mantey                 // Capture the very first gateway value from the incoming
1669743eb1c0SJohnathan Mantey                 // JSON record and use it at the default gateway.
1670743eb1c0SJohnathan Mantey                 updateIPv4DefaultGateway(ifaceId, *gateway, asyncResp);
1671743eb1c0SJohnathan Mantey                 activeGateway = *gateway;
1672743eb1c0SJohnathan Mantey                 activePath = pathString;
1673743eb1c0SJohnathan Mantey                 gatewayValueAssigned = true;
1674743eb1c0SJohnathan Mantey             }
1675743eb1c0SJohnathan Mantey 
167685ffe86aSJiaqing Zhao             if (nicIpEntry != ipv4Data.cend())
16771abe55efSEd Tanous             {
16789c5e585cSRavi Teja                 deleteAndCreateIPAddress(IpVersion::IpV4, ifaceId,
167977eb0153SEd Tanous                                          nicIpEntry->id, prefixLength, *address,
168077eb0153SEd Tanous                                          *gateway, asyncResp);
1681*bd79bce8SPatrick Williams                 nicIpEntry =
1682*bd79bce8SPatrick Williams                     getNextStaticIpEntry(++nicIpEntry, ipv4Data.cend());
16834a8f5d43SJohnathan Mantey                 preserveGateway = true;
1684588c3f0dSKowalski, Kamil             }
168501784826SJohnathan Mantey             else
168601784826SJohnathan Mantey             {
1687cb13a392SEd Tanous                 createIPv4(ifaceId, prefixLength, *gateway, *address,
1688cb13a392SEd Tanous                            asyncResp);
16894a8f5d43SJohnathan Mantey                 preserveGateway = true;
16904a0cb85cSEd Tanous             }
16914a0cb85cSEd Tanous             entryIdx++;
16924a0cb85cSEd Tanous         }
169301784826SJohnathan Mantey         else
169401784826SJohnathan Mantey         {
1695743eb1c0SJohnathan Mantey             // Received {}, do not modify this address
169685ffe86aSJiaqing Zhao             if (nicIpEntry != ipv4Data.cend())
169701784826SJohnathan Mantey             {
1698*bd79bce8SPatrick Williams                 nicIpEntry =
1699*bd79bce8SPatrick Williams                     getNextStaticIpEntry(++nicIpEntry, ipv4Data.cend());
17004a8f5d43SJohnathan Mantey                 preserveGateway = true;
170101784826SJohnathan Mantey                 entryIdx++;
170201784826SJohnathan Mantey             }
1703743eb1c0SJohnathan Mantey             else
1704743eb1c0SJohnathan Mantey             {
1705743eb1c0SJohnathan Mantey                 // Requested a DO NOT MODIFY action on an entry not assigned
1706743eb1c0SJohnathan Mantey                 // to the NIC
1707743eb1c0SJohnathan Mantey                 messages::propertyValueFormatError(asyncResp->res, *obj,
1708743eb1c0SJohnathan Mantey                                                    pathString);
1709743eb1c0SJohnathan Mantey                 return;
1710743eb1c0SJohnathan Mantey             }
1711743eb1c0SJohnathan Mantey         }
171201784826SJohnathan Mantey     }
17134a0cb85cSEd Tanous }
17144a0cb85cSEd Tanous 
17154f48d5f6SEd Tanous inline void handleStaticNameServersPatch(
1716f85837bfSRAJESWARAN THILLAIGOVINDAN     const std::string& ifaceId,
1717f85837bfSRAJESWARAN THILLAIGOVINDAN     const std::vector<std::string>& updatedStaticNameServers,
17188d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1719f85837bfSRAJESWARAN THILLAIGOVINDAN {
17201847f2a0SAsmitha Karunanithi     setDbusProperty(
1721e93abac6SGinu George         asyncResp, "StaticNameServers", "xyz.openbmc_project.Network",
17221847f2a0SAsmitha Karunanithi         sdbusplus::message::object_path("/xyz/openbmc_project/network") /
17231847f2a0SAsmitha Karunanithi             ifaceId,
17249ae226faSGeorge Liu         "xyz.openbmc_project.Network.EthernetInterface", "StaticNameServers",
1725e93abac6SGinu George         updatedStaticNameServers);
1726f85837bfSRAJESWARAN THILLAIGOVINDAN }
1727f85837bfSRAJESWARAN THILLAIGOVINDAN 
17284f48d5f6SEd Tanous inline void handleIPv6StaticAddressesPatch(
17293dfed536SEd Tanous     const std::string& ifaceId,
17303dfed536SEd Tanous     std::vector<std::variant<nlohmann::json::object_t, std::nullptr_t>>& input,
173177179532SEd Tanous     const std::vector<IPv6AddressData>& ipv6Data,
17328d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1733e48c0fc5SRavi Teja {
1734271584abSEd Tanous     size_t entryIdx = 1;
173577179532SEd Tanous     std::vector<IPv6AddressData>::const_iterator nicIpEntry =
17362c70f800SEd Tanous         getNextStaticIpEntry(ipv6Data.cbegin(), ipv6Data.cend());
17373dfed536SEd Tanous     for (std::variant<nlohmann::json::object_t, std::nullptr_t>& thisJson :
17383dfed536SEd Tanous          input)
1739e48c0fc5SRavi Teja     {
1740*bd79bce8SPatrick Williams         std::string pathString =
1741*bd79bce8SPatrick Williams             "IPv6StaticAddresses/" + std::to_string(entryIdx);
17423dfed536SEd Tanous         nlohmann::json::object_t* obj =
17433dfed536SEd Tanous             std::get_if<nlohmann::json::object_t>(&thisJson);
17443dfed536SEd Tanous         if (obj != nullptr && !obj->empty())
1745e48c0fc5SRavi Teja         {
1746e48c0fc5SRavi Teja             std::optional<std::string> address;
1747e48c0fc5SRavi Teja             std::optional<uint8_t> prefixLength;
17483dfed536SEd Tanous             nlohmann::json::object_t thisJsonCopy = *obj;
17493dfed536SEd Tanous             if (!json_util::readJsonObject(thisJsonCopy, asyncResp->res,
17503dfed536SEd Tanous                                            "Address", address, "PrefixLength",
17513dfed536SEd Tanous                                            prefixLength))
1752e48c0fc5SRavi Teja             {
17533dfed536SEd Tanous                 messages::propertyValueFormatError(asyncResp->res, thisJsonCopy,
175471f52d96SEd Tanous                                                    pathString);
1755e48c0fc5SRavi Teja                 return;
1756e48c0fc5SRavi Teja             }
1757e48c0fc5SRavi Teja 
175801784826SJohnathan Mantey             // Find the address and prefixLength values. Any values that are
175901784826SJohnathan Mantey             // not explicitly provided are assumed to be unmodified from the
176001784826SJohnathan Mantey             // current state of the interface. Merge existing state into the
176101784826SJohnathan Mantey             // current request.
1762d547d8d2SEd Tanous             if (!address)
1763e48c0fc5SRavi Teja             {
1764d547d8d2SEd Tanous                 if (nicIpEntry == ipv6Data.end())
176501784826SJohnathan Mantey                 {
176601784826SJohnathan Mantey                     messages::propertyMissing(asyncResp->res,
176701784826SJohnathan Mantey                                               pathString + "/Address");
176801784826SJohnathan Mantey                     return;
1769e48c0fc5SRavi Teja                 }
1770d547d8d2SEd Tanous                 address = nicIpEntry->address;
1771d547d8d2SEd Tanous             }
1772e48c0fc5SRavi Teja 
1773d547d8d2SEd Tanous             if (!prefixLength)
1774e48c0fc5SRavi Teja             {
1775d547d8d2SEd Tanous                 if (nicIpEntry == ipv6Data.end())
1776e48c0fc5SRavi Teja                 {
1777e48c0fc5SRavi Teja                     messages::propertyMissing(asyncResp->res,
1778e48c0fc5SRavi Teja                                               pathString + "/PrefixLength");
177901784826SJohnathan Mantey                     return;
1780e48c0fc5SRavi Teja                 }
1781d547d8d2SEd Tanous                 prefixLength = nicIpEntry->prefixLength;
1782d547d8d2SEd Tanous             }
1783e48c0fc5SRavi Teja 
178485ffe86aSJiaqing Zhao             if (nicIpEntry != ipv6Data.end())
1785e48c0fc5SRavi Teja             {
17869c5e585cSRavi Teja                 deleteAndCreateIPAddress(IpVersion::IpV6, ifaceId,
1787d547d8d2SEd Tanous                                          nicIpEntry->id, *prefixLength,
1788d547d8d2SEd Tanous                                          *address, "", asyncResp);
1789*bd79bce8SPatrick Williams                 nicIpEntry =
1790*bd79bce8SPatrick Williams                     getNextStaticIpEntry(++nicIpEntry, ipv6Data.cend());
179101784826SJohnathan Mantey             }
179201784826SJohnathan Mantey             else
179301784826SJohnathan Mantey             {
1794d547d8d2SEd Tanous                 createIPv6(ifaceId, *prefixLength, *address, asyncResp);
1795e48c0fc5SRavi Teja             }
1796e48c0fc5SRavi Teja             entryIdx++;
1797e48c0fc5SRavi Teja         }
179801784826SJohnathan Mantey         else
179901784826SJohnathan Mantey         {
180085ffe86aSJiaqing Zhao             if (nicIpEntry == ipv6Data.end())
180101784826SJohnathan Mantey             {
180201784826SJohnathan Mantey                 // Requesting a DELETE/DO NOT MODIFY action for an item
180301784826SJohnathan Mantey                 // that isn't present on the eth(n) interface. Input JSON is
180401784826SJohnathan Mantey                 // in error, so bail out.
18053dfed536SEd Tanous                 if (obj == nullptr)
180601784826SJohnathan Mantey                 {
180701784826SJohnathan Mantey                     messages::resourceCannotBeDeleted(asyncResp->res);
180801784826SJohnathan Mantey                     return;
180901784826SJohnathan Mantey                 }
18103dfed536SEd Tanous                 messages::propertyValueFormatError(asyncResp->res, *obj,
181171f52d96SEd Tanous                                                    pathString);
181201784826SJohnathan Mantey                 return;
181301784826SJohnathan Mantey             }
181401784826SJohnathan Mantey 
18153dfed536SEd Tanous             if (obj == nullptr)
181601784826SJohnathan Mantey             {
18179c5e585cSRavi Teja                 deleteIPAddress(ifaceId, nicIpEntry->id, asyncResp);
181801784826SJohnathan Mantey             }
181985ffe86aSJiaqing Zhao             if (nicIpEntry != ipv6Data.cend())
182001784826SJohnathan Mantey             {
1821*bd79bce8SPatrick Williams                 nicIpEntry =
1822*bd79bce8SPatrick Williams                     getNextStaticIpEntry(++nicIpEntry, ipv6Data.cend());
182301784826SJohnathan Mantey             }
182401784826SJohnathan Mantey             entryIdx++;
182501784826SJohnathan Mantey         }
182601784826SJohnathan Mantey     }
1827e48c0fc5SRavi Teja }
1828e48c0fc5SRavi Teja 
18297857cb8dSJiaqing Zhao inline std::string extractParentInterfaceName(const std::string& ifaceId)
18307857cb8dSJiaqing Zhao {
18317857cb8dSJiaqing Zhao     std::size_t pos = ifaceId.find('_');
18327857cb8dSJiaqing Zhao     return ifaceId.substr(0, pos);
18337857cb8dSJiaqing Zhao }
18347857cb8dSJiaqing Zhao 
1835*bd79bce8SPatrick Williams inline void parseInterfaceData(
1836*bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1837*bd79bce8SPatrick Williams     const std::string& ifaceId, const EthernetInterfaceData& ethData,
183877179532SEd Tanous     const std::vector<IPv4AddressData>& ipv4Data,
1839ce73d5c8SSunitha Harish     const std::vector<IPv6AddressData>& ipv6Data,
1840ce73d5c8SSunitha Harish     const std::vector<StaticGatewayData>& ipv6GatewayData)
18414a0cb85cSEd Tanous {
18422c70f800SEd Tanous     nlohmann::json& jsonResponse = asyncResp->res.jsonValue;
184381ce609eSEd Tanous     jsonResponse["Id"] = ifaceId;
1844253f11b8SEd Tanous     jsonResponse["@odata.id"] =
1845253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Managers/{}/EthernetInterfaces/{}",
1846253f11b8SEd Tanous                             BMCWEB_REDFISH_MANAGER_URI_NAME, ifaceId);
18472c70f800SEd Tanous     jsonResponse["InterfaceEnabled"] = ethData.nicEnabled;
1848eeedda23SJohnathan Mantey 
1849eeedda23SJohnathan Mantey     if (ethData.nicEnabled)
1850eeedda23SJohnathan Mantey     {
1851539d8c6bSEd Tanous         jsonResponse["LinkStatus"] =
1852539d8c6bSEd Tanous             ethData.linkUp ? ethernet_interface::LinkStatus::LinkUp
1853539d8c6bSEd Tanous                            : ethernet_interface::LinkStatus::LinkDown;
1854539d8c6bSEd Tanous         jsonResponse["Status"]["State"] = resource::State::Enabled;
1855029573d4SEd Tanous     }
1856029573d4SEd Tanous     else
1857029573d4SEd Tanous     {
1858539d8c6bSEd Tanous         jsonResponse["LinkStatus"] = ethernet_interface::LinkStatus::NoLink;
1859539d8c6bSEd Tanous         jsonResponse["Status"]["State"] = resource::State::Disabled;
1860029573d4SEd Tanous     }
1861aa05fb27SJohnathan Mantey 
18622c70f800SEd Tanous     jsonResponse["SpeedMbps"] = ethData.speed;
186335fb5311STejas Patil     jsonResponse["MTUSize"] = ethData.mtuSize;
186482695a5bSJiaqing Zhao     jsonResponse["MACAddress"] = ethData.macAddress;
18652c70f800SEd Tanous     jsonResponse["DHCPv4"]["DHCPEnabled"] =
186682695a5bSJiaqing Zhao         translateDhcpEnabledToBool(ethData.dhcpEnabled, true);
1867e4588158SJishnu CM     jsonResponse["DHCPv4"]["UseNTPServers"] = ethData.ntpv4Enabled;
1868e4588158SJishnu CM     jsonResponse["DHCPv4"]["UseDNSServers"] = ethData.dnsv4Enabled;
1869de9ad764SRavi Teja     jsonResponse["DHCPv4"]["UseDomainName"] = ethData.domainv4Enabled;
18702c70f800SEd Tanous     jsonResponse["DHCPv6"]["OperatingMode"] =
1871*bd79bce8SPatrick Williams         translateDhcpEnabledToBool(ethData.dhcpEnabled, false)
1872*bd79bce8SPatrick Williams             ? "Enabled"
18731f8c7b5dSJohnathan Mantey             : "Disabled";
1874e4588158SJishnu CM     jsonResponse["DHCPv6"]["UseNTPServers"] = ethData.ntpv6Enabled;
1875e4588158SJishnu CM     jsonResponse["DHCPv6"]["UseDNSServers"] = ethData.dnsv6Enabled;
1876de9ad764SRavi Teja     jsonResponse["DHCPv6"]["UseDomainName"] = ethData.domainv6Enabled;
1877b10d8db0SRavi Teja     jsonResponse["StatelessAddressAutoConfig"]["IPv6AutoConfigEnabled"] =
1878b10d8db0SRavi Teja         ethData.ipv6AcceptRa;
18792a133282Smanojkiraneda 
188082695a5bSJiaqing Zhao     if (!ethData.hostName.empty())
18814a0cb85cSEd Tanous     {
188282695a5bSJiaqing Zhao         jsonResponse["HostName"] = ethData.hostName;
1883ab6554f1SJoshi-Mansi 
1884ab6554f1SJoshi-Mansi         // When domain name is empty then it means, that it is a network
1885ab6554f1SJoshi-Mansi         // without domain names, and the host name itself must be treated as
1886ab6554f1SJoshi-Mansi         // FQDN
188782695a5bSJiaqing Zhao         std::string fqdn = ethData.hostName;
1888d24bfc7aSJennifer Lee         if (!ethData.domainnames.empty())
1889d24bfc7aSJennifer Lee         {
18902c70f800SEd Tanous             fqdn += "." + ethData.domainnames[0];
1891d24bfc7aSJennifer Lee         }
18922c70f800SEd Tanous         jsonResponse["FQDN"] = fqdn;
18934a0cb85cSEd Tanous     }
18944a0cb85cSEd Tanous 
18957857cb8dSJiaqing Zhao     if (ethData.vlanId)
18967857cb8dSJiaqing Zhao     {
1897539d8c6bSEd Tanous         jsonResponse["EthernetInterfaceType"] =
1898539d8c6bSEd Tanous             ethernet_interface::EthernetDeviceType::Virtual;
18997857cb8dSJiaqing Zhao         jsonResponse["VLAN"]["VLANEnable"] = true;
19007857cb8dSJiaqing Zhao         jsonResponse["VLAN"]["VLANId"] = *ethData.vlanId;
19017857cb8dSJiaqing Zhao         jsonResponse["VLAN"]["Tagged"] = true;
19027857cb8dSJiaqing Zhao 
19037857cb8dSJiaqing Zhao         nlohmann::json::array_t relatedInterfaces;
19047857cb8dSJiaqing Zhao         nlohmann::json& parentInterface = relatedInterfaces.emplace_back();
19057857cb8dSJiaqing Zhao         parentInterface["@odata.id"] =
1906253f11b8SEd Tanous             boost::urls::format("/redfish/v1/Managers/{}/EthernetInterfaces",
1907253f11b8SEd Tanous                                 BMCWEB_REDFISH_MANAGER_URI_NAME,
19087857cb8dSJiaqing Zhao                                 extractParentInterfaceName(ifaceId));
19097857cb8dSJiaqing Zhao         jsonResponse["Links"]["RelatedInterfaces"] =
19107857cb8dSJiaqing Zhao             std::move(relatedInterfaces);
19117857cb8dSJiaqing Zhao     }
19127857cb8dSJiaqing Zhao     else
19137857cb8dSJiaqing Zhao     {
1914539d8c6bSEd Tanous         jsonResponse["EthernetInterfaceType"] =
1915539d8c6bSEd Tanous             ethernet_interface::EthernetDeviceType::Physical;
19167857cb8dSJiaqing Zhao     }
19177857cb8dSJiaqing Zhao 
19182c70f800SEd Tanous     jsonResponse["NameServers"] = ethData.nameServers;
19192c70f800SEd Tanous     jsonResponse["StaticNameServers"] = ethData.staticNameServers;
19204a0cb85cSEd Tanous 
19212c70f800SEd Tanous     nlohmann::json& ipv4Array = jsonResponse["IPv4Addresses"];
19222c70f800SEd Tanous     nlohmann::json& ipv4StaticArray = jsonResponse["IPv4StaticAddresses"];
19232c70f800SEd Tanous     ipv4Array = nlohmann::json::array();
19242c70f800SEd Tanous     ipv4StaticArray = nlohmann::json::array();
19259eb808c1SEd Tanous     for (const auto& ipv4Config : ipv4Data)
19264a0cb85cSEd Tanous     {
19272c70f800SEd Tanous         std::string gatewayStr = ipv4Config.gateway;
1928fa5053a6SGunnar Mills         if (gatewayStr.empty())
1929fa5053a6SGunnar Mills         {
1930fa5053a6SGunnar Mills             gatewayStr = "0.0.0.0";
1931fa5053a6SGunnar Mills         }
19321476687dSEd Tanous         nlohmann::json::object_t ipv4;
19331476687dSEd Tanous         ipv4["AddressOrigin"] = ipv4Config.origin;
19341476687dSEd Tanous         ipv4["SubnetMask"] = ipv4Config.netmask;
19351476687dSEd Tanous         ipv4["Address"] = ipv4Config.address;
19361476687dSEd Tanous         ipv4["Gateway"] = gatewayStr;
1937fa5053a6SGunnar Mills 
19382c70f800SEd Tanous         if (ipv4Config.origin == "Static")
1939d1d50814SRavi Teja         {
19401476687dSEd Tanous             ipv4StaticArray.push_back(ipv4);
1941d1d50814SRavi Teja         }
19421476687dSEd Tanous 
1943b2ba3072SPatrick Williams         ipv4Array.emplace_back(std::move(ipv4));
194401784826SJohnathan Mantey     }
1945d1d50814SRavi Teja 
194682695a5bSJiaqing Zhao     std::string ipv6GatewayStr = ethData.ipv6DefaultGateway;
19477ea79e5eSRavi Teja     if (ipv6GatewayStr.empty())
19487ea79e5eSRavi Teja     {
19497ea79e5eSRavi Teja         ipv6GatewayStr = "0:0:0:0:0:0:0:0";
19507ea79e5eSRavi Teja     }
19517ea79e5eSRavi Teja 
19527ea79e5eSRavi Teja     jsonResponse["IPv6DefaultGateway"] = ipv6GatewayStr;
1953e48c0fc5SRavi Teja 
1954ce73d5c8SSunitha Harish     nlohmann::json::array_t ipv6StaticGatewayArray;
1955ce73d5c8SSunitha Harish     for (const auto& ipv6GatewayConfig : ipv6GatewayData)
1956ce73d5c8SSunitha Harish     {
1957ce73d5c8SSunitha Harish         nlohmann::json::object_t ipv6Gateway;
1958ce73d5c8SSunitha Harish         ipv6Gateway["Address"] = ipv6GatewayConfig.gateway;
1959ce73d5c8SSunitha Harish         ipv6Gateway["PrefixLength"] = ipv6GatewayConfig.prefixLength;
1960ce73d5c8SSunitha Harish         ipv6StaticGatewayArray.emplace_back(std::move(ipv6Gateway));
1961ce73d5c8SSunitha Harish     }
1962ce73d5c8SSunitha Harish     jsonResponse["IPv6StaticDefaultGateways"] =
1963ce73d5c8SSunitha Harish         std::move(ipv6StaticGatewayArray);
1964ce73d5c8SSunitha Harish 
19652c70f800SEd Tanous     nlohmann::json& ipv6Array = jsonResponse["IPv6Addresses"];
19662c70f800SEd Tanous     nlohmann::json& ipv6StaticArray = jsonResponse["IPv6StaticAddresses"];
19672c70f800SEd Tanous     ipv6Array = nlohmann::json::array();
19682c70f800SEd Tanous     ipv6StaticArray = nlohmann::json::array();
19697f2e23e9SJohnathan Mantey     nlohmann::json& ipv6AddrPolicyTable =
19702c70f800SEd Tanous         jsonResponse["IPv6AddressPolicyTable"];
19717f2e23e9SJohnathan Mantey     ipv6AddrPolicyTable = nlohmann::json::array();
19729eb808c1SEd Tanous     for (const auto& ipv6Config : ipv6Data)
1973e48c0fc5SRavi Teja     {
19741476687dSEd Tanous         nlohmann::json::object_t ipv6;
19751476687dSEd Tanous         ipv6["Address"] = ipv6Config.address;
19761476687dSEd Tanous         ipv6["PrefixLength"] = ipv6Config.prefixLength;
19771476687dSEd Tanous         ipv6["AddressOrigin"] = ipv6Config.origin;
1978f8361275SSunitha Harish 
1979b2ba3072SPatrick Williams         ipv6Array.emplace_back(std::move(ipv6));
19802c70f800SEd Tanous         if (ipv6Config.origin == "Static")
1981e48c0fc5SRavi Teja         {
19821476687dSEd Tanous             nlohmann::json::object_t ipv6Static;
19831476687dSEd Tanous             ipv6Static["Address"] = ipv6Config.address;
19841476687dSEd Tanous             ipv6Static["PrefixLength"] = ipv6Config.prefixLength;
1985b2ba3072SPatrick Williams             ipv6StaticArray.emplace_back(std::move(ipv6Static));
198601784826SJohnathan Mantey         }
1987e48c0fc5SRavi Teja     }
1988588c3f0dSKowalski, Kamil }
1989588c3f0dSKowalski, Kamil 
1990e7caf250SJiaqing Zhao inline void afterDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1991e7caf250SJiaqing Zhao                         const std::string& ifaceId,
1992e7caf250SJiaqing Zhao                         const boost::system::error_code& ec,
1993e7caf250SJiaqing Zhao                         const sdbusplus::message_t& m)
1994e7caf250SJiaqing Zhao {
1995e7caf250SJiaqing Zhao     if (!ec)
1996e7caf250SJiaqing Zhao     {
1997e7caf250SJiaqing Zhao         return;
1998e7caf250SJiaqing Zhao     }
1999e7caf250SJiaqing Zhao     const sd_bus_error* dbusError = m.get_error();
2000e7caf250SJiaqing Zhao     if (dbusError == nullptr)
2001e7caf250SJiaqing Zhao     {
2002e7caf250SJiaqing Zhao         messages::internalError(asyncResp->res);
2003e7caf250SJiaqing Zhao         return;
2004e7caf250SJiaqing Zhao     }
200562598e31SEd Tanous     BMCWEB_LOG_DEBUG("DBus error: {}", dbusError->name);
2006e7caf250SJiaqing Zhao 
2007e7caf250SJiaqing Zhao     if (std::string_view("org.freedesktop.DBus.Error.UnknownObject") ==
2008e7caf250SJiaqing Zhao         dbusError->name)
2009e7caf250SJiaqing Zhao     {
2010e7caf250SJiaqing Zhao         messages::resourceNotFound(asyncResp->res, "EthernetInterface",
2011e7caf250SJiaqing Zhao                                    ifaceId);
2012e7caf250SJiaqing Zhao         return;
2013e7caf250SJiaqing Zhao     }
2014e7caf250SJiaqing Zhao     if (std::string_view("org.freedesktop.DBus.Error.UnknownMethod") ==
2015e7caf250SJiaqing Zhao         dbusError->name)
2016e7caf250SJiaqing Zhao     {
2017e7caf250SJiaqing Zhao         messages::resourceCannotBeDeleted(asyncResp->res);
2018e7caf250SJiaqing Zhao         return;
2019e7caf250SJiaqing Zhao     }
2020e7caf250SJiaqing Zhao     messages::internalError(asyncResp->res);
2021e7caf250SJiaqing Zhao }
2022e7caf250SJiaqing Zhao 
2023*bd79bce8SPatrick Williams inline void afterVlanCreate(
2024*bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2025*bd79bce8SPatrick Williams     const std::string& parentInterfaceUri, const std::string& vlanInterface,
2026*bd79bce8SPatrick Williams     const boost::system::error_code& ec, const sdbusplus::message_t& m
2027b5ca3fdcSJiaqing Zhao 
2028b5ca3fdcSJiaqing Zhao )
2029b5ca3fdcSJiaqing Zhao {
2030b5ca3fdcSJiaqing Zhao     if (ec)
2031b5ca3fdcSJiaqing Zhao     {
2032b5ca3fdcSJiaqing Zhao         const sd_bus_error* dbusError = m.get_error();
2033b5ca3fdcSJiaqing Zhao         if (dbusError == nullptr)
2034b5ca3fdcSJiaqing Zhao         {
2035b5ca3fdcSJiaqing Zhao             messages::internalError(asyncResp->res);
2036b5ca3fdcSJiaqing Zhao             return;
2037b5ca3fdcSJiaqing Zhao         }
203862598e31SEd Tanous         BMCWEB_LOG_DEBUG("DBus error: {}", dbusError->name);
2039b5ca3fdcSJiaqing Zhao 
2040b5ca3fdcSJiaqing Zhao         if (std::string_view(
2041b5ca3fdcSJiaqing Zhao                 "xyz.openbmc_project.Common.Error.ResourceNotFound") ==
2042b5ca3fdcSJiaqing Zhao             dbusError->name)
2043b5ca3fdcSJiaqing Zhao         {
2044b5ca3fdcSJiaqing Zhao             messages::propertyValueNotInList(
2045b5ca3fdcSJiaqing Zhao                 asyncResp->res, parentInterfaceUri,
2046b5ca3fdcSJiaqing Zhao                 "Links/RelatedInterfaces/0/@odata.id");
2047b5ca3fdcSJiaqing Zhao             return;
2048b5ca3fdcSJiaqing Zhao         }
2049b5ca3fdcSJiaqing Zhao         if (std::string_view(
2050b5ca3fdcSJiaqing Zhao                 "xyz.openbmc_project.Common.Error.InvalidArgument") ==
2051b5ca3fdcSJiaqing Zhao             dbusError->name)
2052b5ca3fdcSJiaqing Zhao         {
2053b5ca3fdcSJiaqing Zhao             messages::resourceAlreadyExists(asyncResp->res, "EthernetInterface",
2054b5ca3fdcSJiaqing Zhao                                             "Id", vlanInterface);
2055b5ca3fdcSJiaqing Zhao             return;
2056b5ca3fdcSJiaqing Zhao         }
2057b5ca3fdcSJiaqing Zhao         messages::internalError(asyncResp->res);
2058b5ca3fdcSJiaqing Zhao         return;
2059b5ca3fdcSJiaqing Zhao     }
2060b5ca3fdcSJiaqing Zhao 
2061253f11b8SEd Tanous     const boost::urls::url vlanInterfaceUri =
2062253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Managers/{}/EthernetInterfaces/{}",
2063253f11b8SEd Tanous                             BMCWEB_REDFISH_MANAGER_URI_NAME, vlanInterface);
2064b5ca3fdcSJiaqing Zhao     asyncResp->res.addHeader("Location", vlanInterfaceUri.buffer());
2065b5ca3fdcSJiaqing Zhao }
2066b5ca3fdcSJiaqing Zhao 
2067bf648f77SEd Tanous inline void requestEthernetInterfacesRoutes(App& app)
2068bf648f77SEd Tanous {
2069253f11b8SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/EthernetInterfaces/")
2070ed398213SEd Tanous         .privileges(redfish::privileges::getEthernetInterfaceCollection)
20711476687dSEd Tanous         .methods(boost::beast::http::verb::get)(
20721476687dSEd Tanous             [&app](const crow::Request& req,
2073253f11b8SEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2074253f11b8SEd Tanous                    const std::string& managerId) {
20753ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
207645ca1b86SEd Tanous                 {
207745ca1b86SEd Tanous                     return;
207845ca1b86SEd Tanous                 }
207945ca1b86SEd Tanous 
2080253f11b8SEd Tanous                 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
2081253f11b8SEd Tanous                 {
2082*bd79bce8SPatrick Williams                     messages::resourceNotFound(asyncResp->res, "Manager",
2083*bd79bce8SPatrick Williams                                                managerId);
2084253f11b8SEd Tanous                     return;
2085253f11b8SEd Tanous                 }
2086253f11b8SEd Tanous 
2087bf648f77SEd Tanous                 asyncResp->res.jsonValue["@odata.type"] =
2088bf648f77SEd Tanous                     "#EthernetInterfaceCollection.EthernetInterfaceCollection";
2089*bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
2090*bd79bce8SPatrick Williams                     "/redfish/v1/Managers/{}/EthernetInterfaces",
2091253f11b8SEd Tanous                     BMCWEB_REDFISH_MANAGER_URI_NAME);
2092bf648f77SEd Tanous                 asyncResp->res.jsonValue["Name"] =
2093bf648f77SEd Tanous                     "Ethernet Network Interface Collection";
2094bf648f77SEd Tanous                 asyncResp->res.jsonValue["Description"] =
2095bf648f77SEd Tanous                     "Collection of EthernetInterfaces for this Manager";
2096bf648f77SEd Tanous 
2097bf648f77SEd Tanous                 // Get eth interface list, and call the below callback for JSON
2098bf648f77SEd Tanous                 // preparation
2099002d39b4SEd Tanous                 getEthernetIfaceList(
210077179532SEd Tanous                     [asyncResp](const bool& success,
210177179532SEd Tanous                                 const std::vector<std::string>& ifaceList) {
2102bf648f77SEd Tanous                         if (!success)
21031abe55efSEd Tanous                         {
2104f12894f8SJason M. Bills                             messages::internalError(asyncResp->res);
21059391bb9cSRapkiewicz, Pawel                             return;
21069391bb9cSRapkiewicz, Pawel                         }
21079391bb9cSRapkiewicz, Pawel 
2108*bd79bce8SPatrick Williams                         nlohmann::json& ifaceArray =
2109*bd79bce8SPatrick Williams                             asyncResp->res.jsonValue["Members"];
2110bf648f77SEd Tanous                         ifaceArray = nlohmann::json::array();
2111bf648f77SEd Tanous                         for (const std::string& ifaceItem : ifaceList)
2112bf648f77SEd Tanous                         {
21131476687dSEd Tanous                             nlohmann::json::object_t iface;
2114ef4c65b7SEd Tanous                             iface["@odata.id"] = boost::urls::format(
2115253f11b8SEd Tanous                                 "/redfish/v1/Managers/{}/EthernetInterfaces/{}",
2116253f11b8SEd Tanous                                 BMCWEB_REDFISH_MANAGER_URI_NAME, ifaceItem);
21177857cb8dSJiaqing Zhao                             ifaceArray.push_back(std::move(iface));
2118bf648f77SEd Tanous                         }
2119bf648f77SEd Tanous 
2120*bd79bce8SPatrick Williams                         asyncResp->res.jsonValue["Members@odata.count"] =
2121*bd79bce8SPatrick Williams                             ifaceArray.size();
2122*bd79bce8SPatrick Williams                         asyncResp->res.jsonValue["@odata.id"] =
2123*bd79bce8SPatrick Williams                             boost::urls::format(
2124253f11b8SEd Tanous                                 "/redfish/v1/Managers/{}/EthernetInterfaces",
2125253f11b8SEd Tanous                                 BMCWEB_REDFISH_MANAGER_URI_NAME);
2126bf648f77SEd Tanous                     });
2127bf648f77SEd Tanous             });
2128bf648f77SEd Tanous 
2129253f11b8SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/EthernetInterfaces/")
2130b5ca3fdcSJiaqing Zhao         .privileges(redfish::privileges::postEthernetInterfaceCollection)
2131b5ca3fdcSJiaqing Zhao         .methods(boost::beast::http::verb::post)(
2132b5ca3fdcSJiaqing Zhao             [&app](const crow::Request& req,
2133253f11b8SEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2134253f11b8SEd Tanous                    const std::string& managerId) {
2135b5ca3fdcSJiaqing Zhao                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2136b5ca3fdcSJiaqing Zhao                 {
2137b5ca3fdcSJiaqing Zhao                     return;
2138b5ca3fdcSJiaqing Zhao                 }
2139b5ca3fdcSJiaqing Zhao 
2140253f11b8SEd Tanous                 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
2141253f11b8SEd Tanous                 {
2142*bd79bce8SPatrick Williams                     messages::resourceNotFound(asyncResp->res, "Manager",
2143*bd79bce8SPatrick Williams                                                managerId);
2144253f11b8SEd Tanous                     return;
2145253f11b8SEd Tanous                 }
2146253f11b8SEd Tanous 
2147b5ca3fdcSJiaqing Zhao                 bool vlanEnable = false;
2148b5ca3fdcSJiaqing Zhao                 uint32_t vlanId = 0;
21493dfed536SEd Tanous                 std::vector<nlohmann::json::object_t> relatedInterfaces;
2150b5ca3fdcSJiaqing Zhao 
2151*bd79bce8SPatrick Williams                 if (!json_util::readJsonPatch(
2152*bd79bce8SPatrick Williams                         req, asyncResp->res, "VLAN/VLANEnable", vlanEnable,
2153*bd79bce8SPatrick Williams                         "VLAN/VLANId", vlanId, "Links/RelatedInterfaces",
2154b5ca3fdcSJiaqing Zhao                         relatedInterfaces))
2155b5ca3fdcSJiaqing Zhao                 {
2156b5ca3fdcSJiaqing Zhao                     return;
2157b5ca3fdcSJiaqing Zhao                 }
2158b5ca3fdcSJiaqing Zhao 
2159b5ca3fdcSJiaqing Zhao                 if (relatedInterfaces.size() != 1)
2160b5ca3fdcSJiaqing Zhao                 {
2161b5ca3fdcSJiaqing Zhao                     messages::arraySizeTooLong(asyncResp->res,
2162b5ca3fdcSJiaqing Zhao                                                "Links/RelatedInterfaces",
2163b5ca3fdcSJiaqing Zhao                                                relatedInterfaces.size());
2164b5ca3fdcSJiaqing Zhao                     return;
2165b5ca3fdcSJiaqing Zhao                 }
2166b5ca3fdcSJiaqing Zhao 
2167b5ca3fdcSJiaqing Zhao                 std::string parentInterfaceUri;
2168*bd79bce8SPatrick Williams                 if (!json_util::readJsonObject(relatedInterfaces[0],
2169*bd79bce8SPatrick Williams                                                asyncResp->res, "@odata.id",
2170*bd79bce8SPatrick Williams                                                parentInterfaceUri))
2171b5ca3fdcSJiaqing Zhao                 {
2172*bd79bce8SPatrick Williams                     messages::propertyMissing(
2173*bd79bce8SPatrick Williams                         asyncResp->res, "Links/RelatedInterfaces/0/@odata.id");
2174b5ca3fdcSJiaqing Zhao                     return;
2175b5ca3fdcSJiaqing Zhao                 }
217662598e31SEd Tanous                 BMCWEB_LOG_INFO("Parent Interface URI: {}", parentInterfaceUri);
2177b5ca3fdcSJiaqing Zhao 
21786fd29553SEd Tanous                 boost::system::result<boost::urls::url_view> parsedUri =
2179b5ca3fdcSJiaqing Zhao                     boost::urls::parse_relative_ref(parentInterfaceUri);
2180b5ca3fdcSJiaqing Zhao                 if (!parsedUri)
2181b5ca3fdcSJiaqing Zhao                 {
2182b5ca3fdcSJiaqing Zhao                     messages::propertyValueFormatError(
2183b5ca3fdcSJiaqing Zhao                         asyncResp->res, parentInterfaceUri,
2184b5ca3fdcSJiaqing Zhao                         "Links/RelatedInterfaces/0/@odata.id");
2185b5ca3fdcSJiaqing Zhao                     return;
2186b5ca3fdcSJiaqing Zhao                 }
2187b5ca3fdcSJiaqing Zhao 
2188b5ca3fdcSJiaqing Zhao                 std::string parentInterface;
2189b5ca3fdcSJiaqing Zhao                 if (!crow::utility::readUrlSegments(
2190b5ca3fdcSJiaqing Zhao                         *parsedUri, "redfish", "v1", "Managers", "bmc",
2191b5ca3fdcSJiaqing Zhao                         "EthernetInterfaces", std::ref(parentInterface)))
2192b5ca3fdcSJiaqing Zhao                 {
2193b5ca3fdcSJiaqing Zhao                     messages::propertyValueNotInList(
2194b5ca3fdcSJiaqing Zhao                         asyncResp->res, parentInterfaceUri,
2195b5ca3fdcSJiaqing Zhao                         "Links/RelatedInterfaces/0/@odata.id");
2196b5ca3fdcSJiaqing Zhao                     return;
2197b5ca3fdcSJiaqing Zhao                 }
2198b5ca3fdcSJiaqing Zhao 
2199b5ca3fdcSJiaqing Zhao                 if (!vlanEnable)
2200b5ca3fdcSJiaqing Zhao                 {
2201b5ca3fdcSJiaqing Zhao                     // In OpenBMC implementation, VLANEnable cannot be false on
2202b5ca3fdcSJiaqing Zhao                     // create
2203*bd79bce8SPatrick Williams                     messages::propertyValueIncorrect(
2204*bd79bce8SPatrick Williams                         asyncResp->res, "VLAN/VLANEnable", "false");
2205b5ca3fdcSJiaqing Zhao                     return;
2206b5ca3fdcSJiaqing Zhao                 }
2207b5ca3fdcSJiaqing Zhao 
2208*bd79bce8SPatrick Williams                 std::string vlanInterface =
2209*bd79bce8SPatrick Williams                     parentInterface + "_" + std::to_string(vlanId);
2210b5ca3fdcSJiaqing Zhao                 crow::connections::systemBus->async_method_call(
2211b5ca3fdcSJiaqing Zhao                     [asyncResp, parentInterfaceUri,
2212b5ca3fdcSJiaqing Zhao                      vlanInterface](const boost::system::error_code& ec,
2213b5ca3fdcSJiaqing Zhao                                     const sdbusplus::message_t& m) {
2214*bd79bce8SPatrick Williams                         afterVlanCreate(asyncResp, parentInterfaceUri,
2215*bd79bce8SPatrick Williams                                         vlanInterface, ec, m);
2216b5ca3fdcSJiaqing Zhao                     },
2217*bd79bce8SPatrick Williams                     "xyz.openbmc_project.Network",
2218*bd79bce8SPatrick Williams                     "/xyz/openbmc_project/network",
2219*bd79bce8SPatrick Williams                     "xyz.openbmc_project.Network.VLAN.Create", "VLAN",
2220*bd79bce8SPatrick Williams                     parentInterface, vlanId);
2221b5ca3fdcSJiaqing Zhao             });
2222b5ca3fdcSJiaqing Zhao 
2223253f11b8SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/EthernetInterfaces/<str>/")
2224ed398213SEd Tanous         .privileges(redfish::privileges::getEthernetInterface)
2225bf648f77SEd Tanous         .methods(boost::beast::http::verb::get)(
222645ca1b86SEd Tanous             [&app](const crow::Request& req,
2227bf648f77SEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2228253f11b8SEd Tanous                    const std::string& managerId, const std::string& ifaceId) {
22293ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
223045ca1b86SEd Tanous                 {
223145ca1b86SEd Tanous                     return;
223245ca1b86SEd Tanous                 }
2233253f11b8SEd Tanous 
2234253f11b8SEd Tanous                 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
2235253f11b8SEd Tanous                 {
2236*bd79bce8SPatrick Williams                     messages::resourceNotFound(asyncResp->res, "Manager",
2237*bd79bce8SPatrick Williams                                                managerId);
2238253f11b8SEd Tanous                     return;
2239253f11b8SEd Tanous                 }
2240253f11b8SEd Tanous 
22414a0cb85cSEd Tanous                 getEthernetIfaceData(
2242bf648f77SEd Tanous                     ifaceId,
2243*bd79bce8SPatrick Williams                     [asyncResp, ifaceId](
2244*bd79bce8SPatrick Williams                         const bool& success,
2245*bd79bce8SPatrick Williams                         const EthernetInterfaceData& ethData,
224677179532SEd Tanous                         const std::vector<IPv4AddressData>& ipv4Data,
2247ce73d5c8SSunitha Harish                         const std::vector<IPv6AddressData>& ipv6Data,
2248ce73d5c8SSunitha Harish                         const std::vector<StaticGatewayData>& ipv6GatewayData) {
22494a0cb85cSEd Tanous                         if (!success)
22501abe55efSEd Tanous                         {
2251bf648f77SEd Tanous                             // TODO(Pawel)consider distinguish between non
2252bf648f77SEd Tanous                             // existing object, and other errors
2253*bd79bce8SPatrick Williams                             messages::resourceNotFound(
2254*bd79bce8SPatrick Williams                                 asyncResp->res, "EthernetInterface", ifaceId);
22554a0cb85cSEd Tanous                             return;
22569391bb9cSRapkiewicz, Pawel                         }
22574c9afe43SEd Tanous 
22580f74e643SEd Tanous                         asyncResp->res.jsonValue["@odata.type"] =
225993bbc953SJiaqing Zhao                             "#EthernetInterface.v1_9_0.EthernetInterface";
2260*bd79bce8SPatrick Williams                         asyncResp->res.jsonValue["Name"] =
2261*bd79bce8SPatrick Williams                             "Manager Ethernet Interface";
22620f74e643SEd Tanous                         asyncResp->res.jsonValue["Description"] =
22630f74e643SEd Tanous                             "Management Network Interface";
22640f74e643SEd Tanous 
2265*bd79bce8SPatrick Williams                         parseInterfaceData(asyncResp, ifaceId, ethData,
2266*bd79bce8SPatrick Williams                                            ipv4Data, ipv6Data, ipv6GatewayData);
22679391bb9cSRapkiewicz, Pawel                     });
2268bf648f77SEd Tanous             });
22699391bb9cSRapkiewicz, Pawel 
2270253f11b8SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/EthernetInterfaces/<str>/")
2271ed398213SEd Tanous         .privileges(redfish::privileges::patchEthernetInterface)
2272bf648f77SEd Tanous         .methods(boost::beast::http::verb::patch)(
227345ca1b86SEd Tanous             [&app](const crow::Request& req,
2274bf648f77SEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2275253f11b8SEd Tanous                    const std::string& managerId, const std::string& ifaceId) {
22763ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
227745ca1b86SEd Tanous                 {
227845ca1b86SEd Tanous                     return;
227945ca1b86SEd Tanous                 }
2280253f11b8SEd Tanous 
2281253f11b8SEd Tanous                 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
2282253f11b8SEd Tanous                 {
2283*bd79bce8SPatrick Williams                     messages::resourceNotFound(asyncResp->res, "Manager",
2284*bd79bce8SPatrick Williams                                                managerId);
2285253f11b8SEd Tanous                     return;
2286253f11b8SEd Tanous                 }
2287253f11b8SEd Tanous 
2288bc0bd6e0SEd Tanous                 std::optional<std::string> hostname;
2289ab6554f1SJoshi-Mansi                 std::optional<std::string> fqdn;
2290d577665bSRatan Gupta                 std::optional<std::string> macAddress;
22919a6fc6feSRavi Teja                 std::optional<std::string> ipv6DefaultGateway;
2292*bd79bce8SPatrick Williams                 std::optional<std::vector<
2293*bd79bce8SPatrick Williams                     std::variant<nlohmann::json::object_t, std::nullptr_t>>>
22943dfed536SEd Tanous                     ipv4StaticAddresses;
2295*bd79bce8SPatrick Williams                 std::optional<std::vector<
2296*bd79bce8SPatrick Williams                     std::variant<nlohmann::json::object_t, std::nullptr_t>>>
22973dfed536SEd Tanous                     ipv6StaticAddresses;
2298*bd79bce8SPatrick Williams                 std::optional<std::vector<
2299*bd79bce8SPatrick Williams                     std::variant<nlohmann::json::object_t, std::nullptr_t>>>
23003dfed536SEd Tanous                     ipv6StaticDefaultGateways;
2301f85837bfSRAJESWARAN THILLAIGOVINDAN                 std::optional<std::vector<std::string>> staticNameServers;
2302b10d8db0SRavi Teja                 std::optional<bool> ipv6AutoConfigEnabled;
2303eeedda23SJohnathan Mantey                 std::optional<bool> interfaceEnabled;
230435fb5311STejas Patil                 std::optional<size_t> mtuSize;
23051f8c7b5dSJohnathan Mantey                 DHCPParameters v4dhcpParms;
23061f8c7b5dSJohnathan Mantey                 DHCPParameters v6dhcpParms;
2307b10d8db0SRavi Teja                 // clang-format off
23083dfed536SEd Tanous         if (!json_util::readJsonPatch(req, asyncResp->res,
23093dfed536SEd Tanous                 "DHCPv4/DHCPEnabled",   v4dhcpParms.dhcpv4Enabled,
23103dfed536SEd Tanous                 "DHCPv4/UseDNSServers", v4dhcpParms.useDnsServers,
23113dfed536SEd Tanous                 "DHCPv4/UseDomainName", v4dhcpParms.useDomainName,
23123dfed536SEd Tanous                 "DHCPv4/UseNTPServers", v4dhcpParms.useNtpServers,
23133dfed536SEd Tanous                 "DHCPv6/OperatingMode", v6dhcpParms.dhcpv6OperatingMode,
23143dfed536SEd Tanous                 "DHCPv6/UseDNSServers", v6dhcpParms.useDnsServers,
23153dfed536SEd Tanous                 "DHCPv6/UseDomainName", v6dhcpParms.useDomainName,
23163dfed536SEd Tanous                 "DHCPv6/UseNTPServers", v6dhcpParms.useNtpServers,
2317b10d8db0SRavi Teja                 "FQDN", fqdn,
2318b10d8db0SRavi Teja                 "HostName", hostname,
2319b10d8db0SRavi Teja                 "IPv4StaticAddresses", ipv4StaticAddresses,
2320b10d8db0SRavi Teja                 "IPv6DefaultGateway", ipv6DefaultGateway,
2321b10d8db0SRavi Teja                 "IPv6StaticAddresses", ipv6StaticAddresses,
2322ce73d5c8SSunitha Harish                 "IPv6StaticDefaultGateways", ipv6StaticDefaultGateways,
2323b10d8db0SRavi Teja                 "InterfaceEnabled", interfaceEnabled,
2324b10d8db0SRavi Teja                 "MACAddress", macAddress,
2325b10d8db0SRavi Teja                 "MTUSize", mtuSize,
2326b10d8db0SRavi Teja                 "StatelessAddressAutoConfig/IPv6AutoConfigEnabled", ipv6AutoConfigEnabled,
2327b10d8db0SRavi Teja                 "StaticNameServers", staticNameServers
2328b10d8db0SRavi Teja                 )
2329b10d8db0SRavi Teja             )
23301abe55efSEd Tanous         {
2331588c3f0dSKowalski, Kamil             return;
2332588c3f0dSKowalski, Kamil         }
2333b10d8db0SRavi Teja                 // clang-format on
2334da131a9aSJennifer Lee 
2335bf648f77SEd Tanous                 // Get single eth interface data, and call the below callback
2336bf648f77SEd Tanous                 // for JSON preparation
23374a0cb85cSEd Tanous                 getEthernetIfaceData(
23382c70f800SEd Tanous                     ifaceId,
2339bf648f77SEd Tanous                     [asyncResp, ifaceId, hostname = std::move(hostname),
2340ab6554f1SJoshi-Mansi                      fqdn = std::move(fqdn), macAddress = std::move(macAddress),
2341d1d50814SRavi Teja                      ipv4StaticAddresses = std::move(ipv4StaticAddresses),
23429a6fc6feSRavi Teja                      ipv6DefaultGateway = std::move(ipv6DefaultGateway),
2343e48c0fc5SRavi Teja                      ipv6StaticAddresses = std::move(ipv6StaticAddresses),
2344*bd79bce8SPatrick Williams                      ipv6StaticDefaultGateway =
2345*bd79bce8SPatrick Williams                          std::move(ipv6StaticDefaultGateways),
23463dfed536SEd Tanous                      staticNameServers = std::move(staticNameServers), mtuSize,
2347*bd79bce8SPatrick Williams                      ipv6AutoConfigEnabled,
2348*bd79bce8SPatrick Williams                      v4dhcpParms = std::move(v4dhcpParms),
2349f23b7296SEd Tanous                      v6dhcpParms = std::move(v6dhcpParms), interfaceEnabled](
2350*bd79bce8SPatrick Williams                         const bool success,
2351*bd79bce8SPatrick Williams                         const EthernetInterfaceData& ethData,
235277179532SEd Tanous                         const std::vector<IPv4AddressData>& ipv4Data,
2353ce73d5c8SSunitha Harish                         const std::vector<IPv6AddressData>& ipv6Data,
2354*bd79bce8SPatrick Williams                         const std::vector<StaticGatewayData>&
2355*bd79bce8SPatrick Williams                             ipv6GatewayData) mutable {
23561abe55efSEd Tanous                         if (!success)
23571abe55efSEd Tanous                         {
2358588c3f0dSKowalski, Kamil                             // ... otherwise return error
2359bf648f77SEd Tanous                             // TODO(Pawel)consider distinguish between non
2360bf648f77SEd Tanous                             // existing object, and other errors
2361*bd79bce8SPatrick Williams                             messages::resourceNotFound(
2362*bd79bce8SPatrick Williams                                 asyncResp->res, "EthernetInterface", ifaceId);
2363588c3f0dSKowalski, Kamil                             return;
2364588c3f0dSKowalski, Kamil                         }
2365588c3f0dSKowalski, Kamil 
2366*bd79bce8SPatrick Williams                         handleDHCPPatch(ifaceId, ethData, v4dhcpParms,
2367*bd79bce8SPatrick Williams                                         v6dhcpParms, asyncResp);
23681f8c7b5dSJohnathan Mantey 
23690627a2c7SEd Tanous                         if (hostname)
23701abe55efSEd Tanous                         {
23710627a2c7SEd Tanous                             handleHostnamePatch(*hostname, asyncResp);
23721abe55efSEd Tanous                         }
23730627a2c7SEd Tanous 
2374b10d8db0SRavi Teja                         if (ipv6AutoConfigEnabled)
2375b10d8db0SRavi Teja                         {
2376*bd79bce8SPatrick Williams                             handleSLAACAutoConfigPatch(
2377*bd79bce8SPatrick Williams                                 ifaceId, *ipv6AutoConfigEnabled, asyncResp);
2378b10d8db0SRavi Teja                         }
2379b10d8db0SRavi Teja 
2380ab6554f1SJoshi-Mansi                         if (fqdn)
2381ab6554f1SJoshi-Mansi                         {
23822c70f800SEd Tanous                             handleFqdnPatch(ifaceId, *fqdn, asyncResp);
2383ab6554f1SJoshi-Mansi                         }
2384ab6554f1SJoshi-Mansi 
2385d577665bSRatan Gupta                         if (macAddress)
2386d577665bSRatan Gupta                         {
2387*bd79bce8SPatrick Williams                             handleMACAddressPatch(ifaceId, *macAddress,
2388*bd79bce8SPatrick Williams                                                   asyncResp);
2389d577665bSRatan Gupta                         }
2390d577665bSRatan Gupta 
2391d1d50814SRavi Teja                         if (ipv4StaticAddresses)
2392d1d50814SRavi Teja                         {
2393*bd79bce8SPatrick Williams                             handleIPv4StaticPatch(ifaceId, *ipv4StaticAddresses,
2394*bd79bce8SPatrick Williams                                                   ethData, ipv4Data, asyncResp);
23951abe55efSEd Tanous                         }
23960627a2c7SEd Tanous 
2397f85837bfSRAJESWARAN THILLAIGOVINDAN                         if (staticNameServers)
2398f85837bfSRAJESWARAN THILLAIGOVINDAN                         {
2399*bd79bce8SPatrick Williams                             handleStaticNameServersPatch(
2400*bd79bce8SPatrick Williams                                 ifaceId, *staticNameServers, asyncResp);
2401f85837bfSRAJESWARAN THILLAIGOVINDAN                         }
24029a6fc6feSRavi Teja 
24039a6fc6feSRavi Teja                         if (ipv6DefaultGateway)
24049a6fc6feSRavi Teja                         {
24059a6fc6feSRavi Teja                             messages::propertyNotWritable(asyncResp->res,
24069a6fc6feSRavi Teja                                                           "IPv6DefaultGateway");
24079a6fc6feSRavi Teja                         }
2408e48c0fc5SRavi Teja 
2409e48c0fc5SRavi Teja                         if (ipv6StaticAddresses)
2410e48c0fc5SRavi Teja                         {
2411*bd79bce8SPatrick Williams                             handleIPv6StaticAddressesPatch(ifaceId,
2412*bd79bce8SPatrick Williams                                                            *ipv6StaticAddresses,
2413ddd70dcaSEd Tanous                                                            ipv6Data, asyncResp);
2414e48c0fc5SRavi Teja                         }
2415eeedda23SJohnathan Mantey 
2416ce73d5c8SSunitha Harish                         if (ipv6StaticDefaultGateway)
2417ce73d5c8SSunitha Harish                         {
2418*bd79bce8SPatrick Williams                             handleIPv6DefaultGateway(
2419*bd79bce8SPatrick Williams                                 ifaceId, *ipv6StaticDefaultGateway,
2420ce73d5c8SSunitha Harish                                 ipv6GatewayData, asyncResp);
2421ce73d5c8SSunitha Harish                         }
2422ce73d5c8SSunitha Harish 
2423eeedda23SJohnathan Mantey                         if (interfaceEnabled)
2424eeedda23SJohnathan Mantey                         {
2425*bd79bce8SPatrick Williams                             setDbusProperty(
2426*bd79bce8SPatrick Williams                                 asyncResp, "InterfaceEnabled",
2427e93abac6SGinu George                                 "xyz.openbmc_project.Network",
2428d02aad39SEd Tanous                                 sdbusplus::message::object_path(
2429d02aad39SEd Tanous                                     "/xyz/openbmc_project/network") /
2430d02aad39SEd Tanous                                     ifaceId,
2431d02aad39SEd Tanous                                 "xyz.openbmc_project.Network.EthernetInterface",
2432e93abac6SGinu George                                 "NICEnabled", *interfaceEnabled);
2433eeedda23SJohnathan Mantey                         }
243435fb5311STejas Patil 
243535fb5311STejas Patil                         if (mtuSize)
243635fb5311STejas Patil                         {
243735fb5311STejas Patil                             handleMTUSizePatch(ifaceId, *mtuSize, asyncResp);
243835fb5311STejas Patil                         }
2439588c3f0dSKowalski, Kamil                     });
2440bf648f77SEd Tanous             });
2441e7caf250SJiaqing Zhao 
2442253f11b8SEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/EthernetInterfaces/<str>/")
2443e7caf250SJiaqing Zhao         .privileges(redfish::privileges::deleteEthernetInterface)
2444e7caf250SJiaqing Zhao         .methods(boost::beast::http::verb::delete_)(
2445e7caf250SJiaqing Zhao             [&app](const crow::Request& req,
2446e7caf250SJiaqing Zhao                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2447253f11b8SEd Tanous                    const std::string& managerId, const std::string& ifaceId) {
2448e7caf250SJiaqing Zhao                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2449e7caf250SJiaqing Zhao                 {
2450e7caf250SJiaqing Zhao                     return;
2451e7caf250SJiaqing Zhao                 }
2452e7caf250SJiaqing Zhao 
2453253f11b8SEd Tanous                 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
2454253f11b8SEd Tanous                 {
2455*bd79bce8SPatrick Williams                     messages::resourceNotFound(asyncResp->res, "Manager",
2456*bd79bce8SPatrick Williams                                                managerId);
2457253f11b8SEd Tanous                     return;
2458253f11b8SEd Tanous                 }
2459253f11b8SEd Tanous 
2460e7caf250SJiaqing Zhao                 crow::connections::systemBus->async_method_call(
2461e7caf250SJiaqing Zhao                     [asyncResp, ifaceId](const boost::system::error_code& ec,
2462e7caf250SJiaqing Zhao                                          const sdbusplus::message_t& m) {
2463e7caf250SJiaqing Zhao                         afterDelete(asyncResp, ifaceId, ec, m);
2464e7caf250SJiaqing Zhao                     },
2465e7caf250SJiaqing Zhao                     "xyz.openbmc_project.Network",
2466e7caf250SJiaqing Zhao                     std::string("/xyz/openbmc_project/network/") + ifaceId,
2467e7caf250SJiaqing Zhao                     "xyz.openbmc_project.Object.Delete", "Delete");
2468e7caf250SJiaqing Zhao             });
24694a0cb85cSEd Tanous }
2470bf648f77SEd Tanous 
24719391bb9cSRapkiewicz, Pawel } // namespace redfish
2472