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" 222c5875a2SEd Tanous #include "human_sort.hpp" 233ccb3adbSEd Tanous #include "query.hpp" 243ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 25033f1e4dSEd Tanous #include "utils/ip_utils.hpp" 263ccb3adbSEd Tanous #include "utils/json_utils.hpp" 27033f1e4dSEd Tanous 28ce73d5c8SSunitha Harish #include <boost/system/error_code.hpp> 29ef4c65b7SEd Tanous #include <boost/url/format.hpp> 301214b7e7SGunnar Mills 317a1dbc48SGeorge Liu #include <array> 323dfed536SEd Tanous #include <cstddef> 33ce73d5c8SSunitha Harish #include <memory> 34a24526dcSEd Tanous #include <optional> 353544d2a7SEd Tanous #include <ranges> 36ab6554f1SJoshi-Mansi #include <regex> 377a1dbc48SGeorge Liu #include <string_view> 383dfed536SEd Tanous #include <variant> 3977179532SEd Tanous #include <vector> 409391bb9cSRapkiewicz, Pawel 411abe55efSEd Tanous namespace redfish 421abe55efSEd Tanous { 439391bb9cSRapkiewicz, Pawel 444a0cb85cSEd Tanous enum class LinkType 454a0cb85cSEd Tanous { 464a0cb85cSEd Tanous Local, 474a0cb85cSEd Tanous Global 484a0cb85cSEd Tanous }; 499391bb9cSRapkiewicz, Pawel 509391bb9cSRapkiewicz, Pawel /** 519391bb9cSRapkiewicz, Pawel * Structure for keeping IPv4 data required by Redfish 529391bb9cSRapkiewicz, Pawel */ 531abe55efSEd Tanous struct IPv4AddressData 541abe55efSEd Tanous { 55179db1d7SKowalski, Kamil std::string id; 564a0cb85cSEd Tanous std::string address; 574a0cb85cSEd Tanous std::string domain; 584a0cb85cSEd Tanous std::string gateway; 599391bb9cSRapkiewicz, Pawel std::string netmask; 609391bb9cSRapkiewicz, Pawel std::string origin; 6177179532SEd Tanous LinkType linktype{}; 6277179532SEd Tanous bool isActive{}; 639391bb9cSRapkiewicz, Pawel }; 649391bb9cSRapkiewicz, Pawel 659391bb9cSRapkiewicz, Pawel /** 66e48c0fc5SRavi Teja * Structure for keeping IPv6 data required by Redfish 67e48c0fc5SRavi Teja */ 68e48c0fc5SRavi Teja struct IPv6AddressData 69e48c0fc5SRavi Teja { 70e48c0fc5SRavi Teja std::string id; 71e48c0fc5SRavi Teja std::string address; 72e48c0fc5SRavi Teja std::string origin; 7377179532SEd Tanous uint8_t prefixLength = 0; 74e48c0fc5SRavi Teja }; 75ce73d5c8SSunitha Harish 76ce73d5c8SSunitha Harish /** 77ce73d5c8SSunitha Harish * Structure for keeping static route data required by Redfish 78ce73d5c8SSunitha Harish */ 79ce73d5c8SSunitha Harish struct StaticGatewayData 80ce73d5c8SSunitha Harish { 81ce73d5c8SSunitha Harish std::string id; 82ce73d5c8SSunitha Harish std::string gateway; 83ce73d5c8SSunitha Harish size_t prefixLength = 0; 84ce73d5c8SSunitha Harish std::string protocol; 85ce73d5c8SSunitha Harish }; 86ce73d5c8SSunitha Harish 87e48c0fc5SRavi Teja /** 889391bb9cSRapkiewicz, Pawel * Structure for keeping basic single Ethernet Interface information 899391bb9cSRapkiewicz, Pawel * available from DBus 909391bb9cSRapkiewicz, Pawel */ 911abe55efSEd Tanous struct EthernetInterfaceData 921abe55efSEd Tanous { 934a0cb85cSEd Tanous uint32_t speed; 9435fb5311STejas Patil size_t mtuSize; 9582695a5bSJiaqing Zhao bool autoNeg; 96e4588158SJishnu CM bool dnsv4Enabled; 97e4588158SJishnu CM bool dnsv6Enabled; 9891c441ecSRavi Teja bool domainv4Enabled; 9991c441ecSRavi Teja bool domainv6Enabled; 100e4588158SJishnu CM bool ntpv4Enabled; 101e4588158SJishnu CM bool ntpv6Enabled; 102e4588158SJishnu CM bool hostNamev4Enabled; 103e4588158SJishnu CM bool hostNamev6Enabled; 104aa05fb27SJohnathan Mantey bool linkUp; 105eeedda23SJohnathan Mantey bool nicEnabled; 106b10d8db0SRavi Teja bool ipv6AcceptRa; 10782695a5bSJiaqing Zhao std::string dhcpEnabled; 1081f8c7b5dSJohnathan Mantey std::string operatingMode; 10982695a5bSJiaqing Zhao std::string hostName; 11082695a5bSJiaqing Zhao std::string defaultGateway; 11182695a5bSJiaqing Zhao std::string ipv6DefaultGateway; 112ce73d5c8SSunitha Harish std::string ipv6StaticDefaultGateway; 11382695a5bSJiaqing Zhao std::string macAddress; 11417e22024SJiaqing Zhao std::optional<uint32_t> vlanId; 1150f6efdc1Smanojkiran.eda@gmail.com std::vector<std::string> nameServers; 1160f6efdc1Smanojkiran.eda@gmail.com std::vector<std::string> staticNameServers; 117d24bfc7aSJennifer Lee std::vector<std::string> domainnames; 1189391bb9cSRapkiewicz, Pawel }; 1199391bb9cSRapkiewicz, Pawel 1201f8c7b5dSJohnathan Mantey struct DHCPParameters 1211f8c7b5dSJohnathan Mantey { 1221f8c7b5dSJohnathan Mantey std::optional<bool> dhcpv4Enabled; 12382695a5bSJiaqing Zhao std::optional<bool> useDnsServers; 12482695a5bSJiaqing Zhao std::optional<bool> useNtpServers; 12582695a5bSJiaqing Zhao std::optional<bool> useDomainName; 1261f8c7b5dSJohnathan Mantey std::optional<std::string> dhcpv6OperatingMode; 1271f8c7b5dSJohnathan Mantey }; 1281f8c7b5dSJohnathan Mantey 1299391bb9cSRapkiewicz, Pawel // Helper function that changes bits netmask notation (i.e. /24) 1309391bb9cSRapkiewicz, Pawel // into full dot notation 1311abe55efSEd Tanous inline std::string getNetmask(unsigned int bits) 1321abe55efSEd Tanous { 1339391bb9cSRapkiewicz, Pawel uint32_t value = 0xffffffff << (32 - bits); 1349391bb9cSRapkiewicz, Pawel std::string netmask = std::to_string((value >> 24) & 0xff) + "." + 1359391bb9cSRapkiewicz, Pawel std::to_string((value >> 16) & 0xff) + "." + 1369391bb9cSRapkiewicz, Pawel std::to_string((value >> 8) & 0xff) + "." + 1379391bb9cSRapkiewicz, Pawel std::to_string(value & 0xff); 1389391bb9cSRapkiewicz, Pawel return netmask; 1399391bb9cSRapkiewicz, Pawel } 1409391bb9cSRapkiewicz, Pawel 14182695a5bSJiaqing Zhao inline bool translateDhcpEnabledToBool(const std::string& inputDHCP, 1421f8c7b5dSJohnathan Mantey bool isIPv4) 1431f8c7b5dSJohnathan Mantey { 1441f8c7b5dSJohnathan Mantey if (isIPv4) 1451f8c7b5dSJohnathan Mantey { 1461f8c7b5dSJohnathan Mantey return ( 1471f8c7b5dSJohnathan Mantey (inputDHCP == 1481f8c7b5dSJohnathan Mantey "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v4") || 1491f8c7b5dSJohnathan Mantey (inputDHCP == 1501f8c7b5dSJohnathan Mantey "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.both")); 1511f8c7b5dSJohnathan Mantey } 1521f8c7b5dSJohnathan Mantey return ((inputDHCP == 1531f8c7b5dSJohnathan Mantey "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v6") || 1541f8c7b5dSJohnathan Mantey (inputDHCP == 1551f8c7b5dSJohnathan Mantey "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.both")); 1561f8c7b5dSJohnathan Mantey } 1571f8c7b5dSJohnathan Mantey 1582c70f800SEd Tanous inline std::string getDhcpEnabledEnumeration(bool isIPv4, bool isIPv6) 1591f8c7b5dSJohnathan Mantey { 1601f8c7b5dSJohnathan Mantey if (isIPv4 && isIPv6) 1611f8c7b5dSJohnathan Mantey { 1621f8c7b5dSJohnathan Mantey return "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.both"; 1631f8c7b5dSJohnathan Mantey } 1643174e4dfSEd Tanous if (isIPv4) 1651f8c7b5dSJohnathan Mantey { 1661f8c7b5dSJohnathan Mantey return "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v4"; 1671f8c7b5dSJohnathan Mantey } 1683174e4dfSEd Tanous if (isIPv6) 1691f8c7b5dSJohnathan Mantey { 1701f8c7b5dSJohnathan Mantey return "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v6"; 1711f8c7b5dSJohnathan Mantey } 1721f8c7b5dSJohnathan Mantey return "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.none"; 1731f8c7b5dSJohnathan Mantey } 1741f8c7b5dSJohnathan Mantey 1754a0cb85cSEd Tanous inline std::string 1764a0cb85cSEd Tanous translateAddressOriginDbusToRedfish(const std::string& inputOrigin, 1774a0cb85cSEd Tanous bool isIPv4) 1781abe55efSEd Tanous { 1794a0cb85cSEd Tanous if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.Static") 1801abe55efSEd Tanous { 1814a0cb85cSEd Tanous return "Static"; 1829391bb9cSRapkiewicz, Pawel } 1834a0cb85cSEd Tanous if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.LinkLocal") 1841abe55efSEd Tanous { 1854a0cb85cSEd Tanous if (isIPv4) 1861abe55efSEd Tanous { 1874a0cb85cSEd Tanous return "IPv4LinkLocal"; 1881abe55efSEd Tanous } 1894a0cb85cSEd Tanous return "LinkLocal"; 1909391bb9cSRapkiewicz, Pawel } 1914a0cb85cSEd Tanous if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP") 1921abe55efSEd Tanous { 1934a0cb85cSEd Tanous if (isIPv4) 1944a0cb85cSEd Tanous { 1954a0cb85cSEd Tanous return "DHCP"; 1964a0cb85cSEd Tanous } 1974a0cb85cSEd Tanous return "DHCPv6"; 1984a0cb85cSEd Tanous } 1994a0cb85cSEd Tanous if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.SLAAC") 2004a0cb85cSEd Tanous { 2014a0cb85cSEd Tanous return "SLAAC"; 2024a0cb85cSEd Tanous } 2034a0cb85cSEd Tanous return ""; 2044a0cb85cSEd Tanous } 2054a0cb85cSEd Tanous 20602cad96eSEd Tanous inline bool extractEthernetInterfaceData( 20702cad96eSEd Tanous const std::string& ethifaceId, 20802cad96eSEd Tanous const dbus::utility::ManagedObjectType& dbusData, 2094a0cb85cSEd Tanous EthernetInterfaceData& ethData) 2104a0cb85cSEd Tanous { 2114c9afe43SEd Tanous bool idFound = false; 21202cad96eSEd Tanous for (const auto& objpath : dbusData) 2134a0cb85cSEd Tanous { 21402cad96eSEd Tanous for (const auto& ifacePair : objpath.second) 2154a0cb85cSEd Tanous { 21681ce609eSEd Tanous if (objpath.first == "/xyz/openbmc_project/network/" + ethifaceId) 217029573d4SEd Tanous { 2184c9afe43SEd Tanous idFound = true; 2194a0cb85cSEd Tanous if (ifacePair.first == "xyz.openbmc_project.Network.MACAddress") 2204a0cb85cSEd Tanous { 2214a0cb85cSEd Tanous for (const auto& propertyPair : ifacePair.second) 2224a0cb85cSEd Tanous { 2234a0cb85cSEd Tanous if (propertyPair.first == "MACAddress") 2244a0cb85cSEd Tanous { 2254a0cb85cSEd Tanous const std::string* mac = 226abf2add6SEd Tanous std::get_if<std::string>(&propertyPair.second); 2274a0cb85cSEd Tanous if (mac != nullptr) 2284a0cb85cSEd Tanous { 22982695a5bSJiaqing Zhao ethData.macAddress = *mac; 2304a0cb85cSEd Tanous } 2314a0cb85cSEd Tanous } 2324a0cb85cSEd Tanous } 2334a0cb85cSEd Tanous } 2344a0cb85cSEd Tanous else if (ifacePair.first == "xyz.openbmc_project.Network.VLAN") 2354a0cb85cSEd Tanous { 2364a0cb85cSEd Tanous for (const auto& propertyPair : ifacePair.second) 2374a0cb85cSEd Tanous { 2384a0cb85cSEd Tanous if (propertyPair.first == "Id") 2394a0cb85cSEd Tanous { 2401b6b96c5SEd Tanous const uint32_t* id = 241abf2add6SEd Tanous std::get_if<uint32_t>(&propertyPair.second); 2424a0cb85cSEd Tanous if (id != nullptr) 2434a0cb85cSEd Tanous { 24417e22024SJiaqing Zhao ethData.vlanId = *id; 2454a0cb85cSEd Tanous } 2464a0cb85cSEd Tanous } 2474a0cb85cSEd Tanous } 2484a0cb85cSEd Tanous } 2494a0cb85cSEd Tanous else if (ifacePair.first == 2504a0cb85cSEd Tanous "xyz.openbmc_project.Network.EthernetInterface") 2514a0cb85cSEd Tanous { 2524a0cb85cSEd Tanous for (const auto& propertyPair : ifacePair.second) 2534a0cb85cSEd Tanous { 2544a0cb85cSEd Tanous if (propertyPair.first == "AutoNeg") 2554a0cb85cSEd Tanous { 2562c70f800SEd Tanous const bool* autoNeg = 257abf2add6SEd Tanous std::get_if<bool>(&propertyPair.second); 2582c70f800SEd Tanous if (autoNeg != nullptr) 2594a0cb85cSEd Tanous { 26082695a5bSJiaqing Zhao ethData.autoNeg = *autoNeg; 2614a0cb85cSEd Tanous } 2624a0cb85cSEd Tanous } 2634a0cb85cSEd Tanous else if (propertyPair.first == "Speed") 2644a0cb85cSEd Tanous { 2654a0cb85cSEd Tanous const uint32_t* speed = 266abf2add6SEd Tanous std::get_if<uint32_t>(&propertyPair.second); 2674a0cb85cSEd Tanous if (speed != nullptr) 2684a0cb85cSEd Tanous { 2694a0cb85cSEd Tanous ethData.speed = *speed; 2704a0cb85cSEd Tanous } 2714a0cb85cSEd Tanous } 27235fb5311STejas Patil else if (propertyPair.first == "MTU") 27335fb5311STejas Patil { 2743e7a8da6SAnthony const size_t* mtuSize = 2753e7a8da6SAnthony std::get_if<size_t>(&propertyPair.second); 27635fb5311STejas Patil if (mtuSize != nullptr) 27735fb5311STejas Patil { 27835fb5311STejas Patil ethData.mtuSize = *mtuSize; 27935fb5311STejas Patil } 28035fb5311STejas Patil } 281aa05fb27SJohnathan Mantey else if (propertyPair.first == "LinkUp") 282aa05fb27SJohnathan Mantey { 283aa05fb27SJohnathan Mantey const bool* linkUp = 284aa05fb27SJohnathan Mantey std::get_if<bool>(&propertyPair.second); 285aa05fb27SJohnathan Mantey if (linkUp != nullptr) 286aa05fb27SJohnathan Mantey { 287aa05fb27SJohnathan Mantey ethData.linkUp = *linkUp; 288aa05fb27SJohnathan Mantey } 289aa05fb27SJohnathan Mantey } 290eeedda23SJohnathan Mantey else if (propertyPair.first == "NICEnabled") 291eeedda23SJohnathan Mantey { 292eeedda23SJohnathan Mantey const bool* nicEnabled = 293eeedda23SJohnathan Mantey std::get_if<bool>(&propertyPair.second); 294eeedda23SJohnathan Mantey if (nicEnabled != nullptr) 295eeedda23SJohnathan Mantey { 296eeedda23SJohnathan Mantey ethData.nicEnabled = *nicEnabled; 297eeedda23SJohnathan Mantey } 298eeedda23SJohnathan Mantey } 299b10d8db0SRavi Teja else if (propertyPair.first == "IPv6AcceptRA") 300b10d8db0SRavi Teja { 301b10d8db0SRavi Teja const bool* ipv6AcceptRa = 302b10d8db0SRavi Teja std::get_if<bool>(&propertyPair.second); 303b10d8db0SRavi Teja if (ipv6AcceptRa != nullptr) 304b10d8db0SRavi Teja { 305b10d8db0SRavi Teja ethData.ipv6AcceptRa = *ipv6AcceptRa; 306b10d8db0SRavi Teja } 307b10d8db0SRavi Teja } 308f85837bfSRAJESWARAN THILLAIGOVINDAN else if (propertyPair.first == "Nameservers") 309029573d4SEd Tanous { 310029573d4SEd Tanous const std::vector<std::string>* nameservers = 3118d78b7a9SPatrick Williams std::get_if<std::vector<std::string>>( 312029573d4SEd Tanous &propertyPair.second); 313029573d4SEd Tanous if (nameservers != nullptr) 314029573d4SEd Tanous { 315f23b7296SEd Tanous ethData.nameServers = *nameservers; 3160f6efdc1Smanojkiran.eda@gmail.com } 3170f6efdc1Smanojkiran.eda@gmail.com } 3180f6efdc1Smanojkiran.eda@gmail.com else if (propertyPair.first == "StaticNameServers") 3190f6efdc1Smanojkiran.eda@gmail.com { 3200f6efdc1Smanojkiran.eda@gmail.com const std::vector<std::string>* staticNameServers = 3218d78b7a9SPatrick Williams std::get_if<std::vector<std::string>>( 3220f6efdc1Smanojkiran.eda@gmail.com &propertyPair.second); 3230f6efdc1Smanojkiran.eda@gmail.com if (staticNameServers != nullptr) 3240f6efdc1Smanojkiran.eda@gmail.com { 325f23b7296SEd Tanous ethData.staticNameServers = *staticNameServers; 3264a0cb85cSEd Tanous } 3274a0cb85cSEd Tanous } 3282a133282Smanojkiraneda else if (propertyPair.first == "DHCPEnabled") 3292a133282Smanojkiraneda { 3302c70f800SEd Tanous const std::string* dhcpEnabled = 3311f8c7b5dSJohnathan Mantey std::get_if<std::string>(&propertyPair.second); 3322c70f800SEd Tanous if (dhcpEnabled != nullptr) 3332a133282Smanojkiraneda { 33482695a5bSJiaqing Zhao ethData.dhcpEnabled = *dhcpEnabled; 3352a133282Smanojkiraneda } 3362a133282Smanojkiraneda } 337d24bfc7aSJennifer Lee else if (propertyPair.first == "DomainName") 338d24bfc7aSJennifer Lee { 339d24bfc7aSJennifer Lee const std::vector<std::string>* domainNames = 3408d78b7a9SPatrick Williams std::get_if<std::vector<std::string>>( 341d24bfc7aSJennifer Lee &propertyPair.second); 342d24bfc7aSJennifer Lee if (domainNames != nullptr) 343d24bfc7aSJennifer Lee { 344f23b7296SEd Tanous ethData.domainnames = *domainNames; 345d24bfc7aSJennifer Lee } 346d24bfc7aSJennifer Lee } 3479010ec2eSRavi Teja else if (propertyPair.first == "DefaultGateway") 3489010ec2eSRavi Teja { 3499010ec2eSRavi Teja const std::string* defaultGateway = 3509010ec2eSRavi Teja std::get_if<std::string>(&propertyPair.second); 3519010ec2eSRavi Teja if (defaultGateway != nullptr) 3529010ec2eSRavi Teja { 3539010ec2eSRavi Teja std::string defaultGatewayStr = *defaultGateway; 3549010ec2eSRavi Teja if (defaultGatewayStr.empty()) 3559010ec2eSRavi Teja { 35682695a5bSJiaqing Zhao ethData.defaultGateway = "0.0.0.0"; 3579010ec2eSRavi Teja } 3589010ec2eSRavi Teja else 3599010ec2eSRavi Teja { 36082695a5bSJiaqing Zhao ethData.defaultGateway = defaultGatewayStr; 3619010ec2eSRavi Teja } 3629010ec2eSRavi Teja } 3639010ec2eSRavi Teja } 3649010ec2eSRavi Teja else if (propertyPair.first == "DefaultGateway6") 3659010ec2eSRavi Teja { 3669010ec2eSRavi Teja const std::string* defaultGateway6 = 3679010ec2eSRavi Teja std::get_if<std::string>(&propertyPair.second); 3689010ec2eSRavi Teja if (defaultGateway6 != nullptr) 3699010ec2eSRavi Teja { 3709010ec2eSRavi Teja std::string defaultGateway6Str = 3719010ec2eSRavi Teja *defaultGateway6; 3729010ec2eSRavi Teja if (defaultGateway6Str.empty()) 3739010ec2eSRavi Teja { 37482695a5bSJiaqing Zhao ethData.ipv6DefaultGateway = 3759010ec2eSRavi Teja "0:0:0:0:0:0:0:0"; 3769010ec2eSRavi Teja } 3779010ec2eSRavi Teja else 3789010ec2eSRavi Teja { 37982695a5bSJiaqing Zhao ethData.ipv6DefaultGateway = 3809010ec2eSRavi Teja defaultGateway6Str; 3819010ec2eSRavi Teja } 3829010ec2eSRavi Teja } 3839010ec2eSRavi Teja } 384029573d4SEd Tanous } 385029573d4SEd Tanous } 386029573d4SEd Tanous } 3871f8c7b5dSJohnathan Mantey 388e4588158SJishnu CM sdbusplus::message::object_path path( 389e4588158SJishnu CM "/xyz/openbmc_project/network"); 390e4588158SJishnu CM sdbusplus::message::object_path dhcp4Path = path / ethifaceId / 391e4588158SJishnu CM "dhcp4"; 392e4588158SJishnu CM 393e4588158SJishnu CM if (sdbusplus::message::object_path(objpath.first) == dhcp4Path) 3941f8c7b5dSJohnathan Mantey { 3951f8c7b5dSJohnathan Mantey if (ifacePair.first == 3961f8c7b5dSJohnathan Mantey "xyz.openbmc_project.Network.DHCPConfiguration") 3971f8c7b5dSJohnathan Mantey { 3981f8c7b5dSJohnathan Mantey for (const auto& propertyPair : ifacePair.second) 3991f8c7b5dSJohnathan Mantey { 4001f8c7b5dSJohnathan Mantey if (propertyPair.first == "DNSEnabled") 4011f8c7b5dSJohnathan Mantey { 4022c70f800SEd Tanous const bool* dnsEnabled = 4031f8c7b5dSJohnathan Mantey std::get_if<bool>(&propertyPair.second); 4042c70f800SEd Tanous if (dnsEnabled != nullptr) 4051f8c7b5dSJohnathan Mantey { 406e4588158SJishnu CM ethData.dnsv4Enabled = *dnsEnabled; 4071f8c7b5dSJohnathan Mantey } 4081f8c7b5dSJohnathan Mantey } 40991c441ecSRavi Teja else if (propertyPair.first == "DomainEnabled") 41091c441ecSRavi Teja { 41191c441ecSRavi Teja const bool* domainEnabled = 41291c441ecSRavi Teja std::get_if<bool>(&propertyPair.second); 41391c441ecSRavi Teja if (domainEnabled != nullptr) 41491c441ecSRavi Teja { 41591c441ecSRavi Teja ethData.domainv4Enabled = *domainEnabled; 41691c441ecSRavi Teja } 41791c441ecSRavi Teja } 4181f8c7b5dSJohnathan Mantey else if (propertyPair.first == "NTPEnabled") 4191f8c7b5dSJohnathan Mantey { 4202c70f800SEd Tanous const bool* ntpEnabled = 4211f8c7b5dSJohnathan Mantey std::get_if<bool>(&propertyPair.second); 4222c70f800SEd Tanous if (ntpEnabled != nullptr) 4231f8c7b5dSJohnathan Mantey { 424e4588158SJishnu CM ethData.ntpv4Enabled = *ntpEnabled; 4251f8c7b5dSJohnathan Mantey } 4261f8c7b5dSJohnathan Mantey } 4271f8c7b5dSJohnathan Mantey else if (propertyPair.first == "HostNameEnabled") 4281f8c7b5dSJohnathan Mantey { 4292c70f800SEd Tanous const bool* hostNameEnabled = 4301f8c7b5dSJohnathan Mantey std::get_if<bool>(&propertyPair.second); 4312c70f800SEd Tanous if (hostNameEnabled != nullptr) 4321f8c7b5dSJohnathan Mantey { 433e4588158SJishnu CM ethData.hostNamev4Enabled = *hostNameEnabled; 434e4588158SJishnu CM } 435e4588158SJishnu CM } 436e4588158SJishnu CM } 437e4588158SJishnu CM } 438e4588158SJishnu CM } 439e4588158SJishnu CM 440e4588158SJishnu CM sdbusplus::message::object_path dhcp6Path = path / ethifaceId / 441e4588158SJishnu CM "dhcp6"; 442e4588158SJishnu CM 443e4588158SJishnu CM if (sdbusplus::message::object_path(objpath.first) == dhcp6Path) 444e4588158SJishnu CM { 445e4588158SJishnu CM if (ifacePair.first == 446e4588158SJishnu CM "xyz.openbmc_project.Network.DHCPConfiguration") 447e4588158SJishnu CM { 448e4588158SJishnu CM for (const auto& propertyPair : ifacePair.second) 449e4588158SJishnu CM { 450e4588158SJishnu CM if (propertyPair.first == "DNSEnabled") 451e4588158SJishnu CM { 452e4588158SJishnu CM const bool* dnsEnabled = 453e4588158SJishnu CM std::get_if<bool>(&propertyPair.second); 454e4588158SJishnu CM if (dnsEnabled != nullptr) 455e4588158SJishnu CM { 456e4588158SJishnu CM ethData.dnsv6Enabled = *dnsEnabled; 457e4588158SJishnu CM } 458e4588158SJishnu CM } 45991c441ecSRavi Teja if (propertyPair.first == "DomainEnabled") 46091c441ecSRavi Teja { 46191c441ecSRavi Teja const bool* domainEnabled = 46291c441ecSRavi Teja std::get_if<bool>(&propertyPair.second); 46391c441ecSRavi Teja if (domainEnabled != nullptr) 46491c441ecSRavi Teja { 46591c441ecSRavi Teja ethData.domainv6Enabled = *domainEnabled; 46691c441ecSRavi Teja } 46791c441ecSRavi Teja } 468e4588158SJishnu CM else if (propertyPair.first == "NTPEnabled") 469e4588158SJishnu CM { 470e4588158SJishnu CM const bool* ntpEnabled = 471e4588158SJishnu CM std::get_if<bool>(&propertyPair.second); 472e4588158SJishnu CM if (ntpEnabled != nullptr) 473e4588158SJishnu CM { 474e4588158SJishnu CM ethData.ntpv6Enabled = *ntpEnabled; 475e4588158SJishnu CM } 476e4588158SJishnu CM } 477e4588158SJishnu CM else if (propertyPair.first == "HostNameEnabled") 478e4588158SJishnu CM { 479e4588158SJishnu CM const bool* hostNameEnabled = 480e4588158SJishnu CM std::get_if<bool>(&propertyPair.second); 481e4588158SJishnu CM if (hostNameEnabled != nullptr) 482e4588158SJishnu CM { 483e4588158SJishnu CM ethData.hostNamev6Enabled = *hostNameEnabled; 4841f8c7b5dSJohnathan Mantey } 4851f8c7b5dSJohnathan Mantey } 4861f8c7b5dSJohnathan Mantey } 4871f8c7b5dSJohnathan Mantey } 4881f8c7b5dSJohnathan Mantey } 489029573d4SEd Tanous // System configuration shows up in the global namespace, so no need 490029573d4SEd Tanous // to check eth number 491029573d4SEd Tanous if (ifacePair.first == 4924a0cb85cSEd Tanous "xyz.openbmc_project.Network.SystemConfiguration") 4934a0cb85cSEd Tanous { 4944a0cb85cSEd Tanous for (const auto& propertyPair : ifacePair.second) 4954a0cb85cSEd Tanous { 4964a0cb85cSEd Tanous if (propertyPair.first == "HostName") 4974a0cb85cSEd Tanous { 4984a0cb85cSEd Tanous const std::string* hostname = 4998d78b7a9SPatrick Williams std::get_if<std::string>(&propertyPair.second); 5004a0cb85cSEd Tanous if (hostname != nullptr) 5014a0cb85cSEd Tanous { 50282695a5bSJiaqing Zhao ethData.hostName = *hostname; 5034a0cb85cSEd Tanous } 5044a0cb85cSEd Tanous } 5054a0cb85cSEd Tanous } 5064a0cb85cSEd Tanous } 5074a0cb85cSEd Tanous } 5084a0cb85cSEd Tanous } 5094c9afe43SEd Tanous return idFound; 5104a0cb85cSEd Tanous } 5114a0cb85cSEd Tanous 512e48c0fc5SRavi Teja // Helper function that extracts data for single ethernet ipv6 address 51377179532SEd Tanous inline void extractIPV6Data(const std::string& ethifaceId, 514711ac7a9SEd Tanous const dbus::utility::ManagedObjectType& dbusData, 51577179532SEd Tanous std::vector<IPv6AddressData>& ipv6Config) 516e48c0fc5SRavi Teja { 51789492a15SPatrick Williams const std::string ipPathStart = "/xyz/openbmc_project/network/" + 51889492a15SPatrick Williams ethifaceId; 519e48c0fc5SRavi Teja 520e48c0fc5SRavi Teja // Since there might be several IPv6 configurations aligned with 521e48c0fc5SRavi Teja // single ethernet interface, loop over all of them 52281ce609eSEd Tanous for (const auto& objpath : dbusData) 523e48c0fc5SRavi Teja { 524e48c0fc5SRavi Teja // Check if proper pattern for object path appears 525353163e9STony Lee if (objpath.first.str.starts_with(ipPathStart + "/")) 526e48c0fc5SRavi Teja { 5279eb808c1SEd Tanous for (const auto& interface : objpath.second) 528e48c0fc5SRavi Teja { 529e48c0fc5SRavi Teja if (interface.first == "xyz.openbmc_project.Network.IP") 530e48c0fc5SRavi Teja { 5313544d2a7SEd Tanous auto type = std::ranges::find_if(interface.second, 532353163e9STony Lee [](const auto& property) { 533353163e9STony Lee return property.first == "Type"; 534353163e9STony Lee }); 535353163e9STony Lee if (type == interface.second.end()) 536353163e9STony Lee { 537353163e9STony Lee continue; 538353163e9STony Lee } 539353163e9STony Lee 540353163e9STony Lee const std::string* typeStr = 541353163e9STony Lee std::get_if<std::string>(&type->second); 542353163e9STony Lee 543353163e9STony Lee if (typeStr == nullptr || 544353163e9STony Lee (*typeStr != 545353163e9STony Lee "xyz.openbmc_project.Network.IP.Protocol.IPv6")) 546353163e9STony Lee { 547353163e9STony Lee continue; 548353163e9STony Lee } 549353163e9STony Lee 550e48c0fc5SRavi Teja // Instance IPv6AddressData structure, and set as 551e48c0fc5SRavi Teja // appropriate 55277179532SEd Tanous IPv6AddressData& ipv6Address = ipv6Config.emplace_back(); 5532c70f800SEd Tanous ipv6Address.id = 554353163e9STony Lee objpath.first.str.substr(ipPathStart.size()); 5559eb808c1SEd Tanous for (const auto& property : interface.second) 556e48c0fc5SRavi Teja { 557e48c0fc5SRavi Teja if (property.first == "Address") 558e48c0fc5SRavi Teja { 559e48c0fc5SRavi Teja const std::string* address = 560e48c0fc5SRavi Teja std::get_if<std::string>(&property.second); 561e48c0fc5SRavi Teja if (address != nullptr) 562e48c0fc5SRavi Teja { 5632c70f800SEd Tanous ipv6Address.address = *address; 564e48c0fc5SRavi Teja } 565e48c0fc5SRavi Teja } 566e48c0fc5SRavi Teja else if (property.first == "Origin") 567e48c0fc5SRavi Teja { 568e48c0fc5SRavi Teja const std::string* origin = 569e48c0fc5SRavi Teja std::get_if<std::string>(&property.second); 570e48c0fc5SRavi Teja if (origin != nullptr) 571e48c0fc5SRavi Teja { 5722c70f800SEd Tanous ipv6Address.origin = 573e48c0fc5SRavi Teja translateAddressOriginDbusToRedfish(*origin, 574e48c0fc5SRavi Teja false); 575e48c0fc5SRavi Teja } 576e48c0fc5SRavi Teja } 577e48c0fc5SRavi Teja else if (property.first == "PrefixLength") 578e48c0fc5SRavi Teja { 579e48c0fc5SRavi Teja const uint8_t* prefix = 580e48c0fc5SRavi Teja std::get_if<uint8_t>(&property.second); 581e48c0fc5SRavi Teja if (prefix != nullptr) 582e48c0fc5SRavi Teja { 5832c70f800SEd Tanous ipv6Address.prefixLength = *prefix; 584e48c0fc5SRavi Teja } 585e48c0fc5SRavi Teja } 586889ff694SAsmitha Karunanithi else if (property.first == "Type" || 587889ff694SAsmitha Karunanithi property.first == "Gateway") 588889ff694SAsmitha Karunanithi { 589889ff694SAsmitha Karunanithi // Type & Gateway is not used 590889ff694SAsmitha Karunanithi } 591e48c0fc5SRavi Teja else 592e48c0fc5SRavi Teja { 59362598e31SEd Tanous BMCWEB_LOG_ERROR( 59462598e31SEd Tanous "Got extra property: {} on the {} object", 59562598e31SEd Tanous property.first, objpath.first.str); 596e48c0fc5SRavi Teja } 597e48c0fc5SRavi Teja } 598e48c0fc5SRavi Teja } 599e48c0fc5SRavi Teja } 600e48c0fc5SRavi Teja } 601e48c0fc5SRavi Teja } 602e48c0fc5SRavi Teja } 603e48c0fc5SRavi Teja 6044a0cb85cSEd Tanous // Helper function that extracts data for single ethernet ipv4 address 60577179532SEd Tanous inline void extractIPData(const std::string& ethifaceId, 606711ac7a9SEd Tanous const dbus::utility::ManagedObjectType& dbusData, 60777179532SEd Tanous std::vector<IPv4AddressData>& ipv4Config) 6084a0cb85cSEd Tanous { 60989492a15SPatrick Williams const std::string ipPathStart = "/xyz/openbmc_project/network/" + 61089492a15SPatrick Williams ethifaceId; 6114a0cb85cSEd Tanous 6124a0cb85cSEd Tanous // Since there might be several IPv4 configurations aligned with 6134a0cb85cSEd Tanous // single ethernet interface, loop over all of them 61481ce609eSEd Tanous for (const auto& objpath : dbusData) 6154a0cb85cSEd Tanous { 6164a0cb85cSEd Tanous // Check if proper pattern for object path appears 617353163e9STony Lee if (objpath.first.str.starts_with(ipPathStart + "/")) 6184a0cb85cSEd Tanous { 6199eb808c1SEd Tanous for (const auto& interface : objpath.second) 6204a0cb85cSEd Tanous { 6214a0cb85cSEd Tanous if (interface.first == "xyz.openbmc_project.Network.IP") 6224a0cb85cSEd Tanous { 6233544d2a7SEd Tanous auto type = std::ranges::find_if(interface.second, 624353163e9STony Lee [](const auto& property) { 625353163e9STony Lee return property.first == "Type"; 626353163e9STony Lee }); 627353163e9STony Lee if (type == interface.second.end()) 628353163e9STony Lee { 629353163e9STony Lee continue; 630353163e9STony Lee } 631353163e9STony Lee 632353163e9STony Lee const std::string* typeStr = 633353163e9STony Lee std::get_if<std::string>(&type->second); 634353163e9STony Lee 635353163e9STony Lee if (typeStr == nullptr || 636353163e9STony Lee (*typeStr != 637353163e9STony Lee "xyz.openbmc_project.Network.IP.Protocol.IPv4")) 638353163e9STony Lee { 639353163e9STony Lee continue; 640353163e9STony Lee } 641353163e9STony Lee 6424a0cb85cSEd Tanous // Instance IPv4AddressData structure, and set as 6434a0cb85cSEd Tanous // appropriate 64477179532SEd Tanous IPv4AddressData& ipv4Address = ipv4Config.emplace_back(); 6452c70f800SEd Tanous ipv4Address.id = 646353163e9STony Lee objpath.first.str.substr(ipPathStart.size()); 6479eb808c1SEd Tanous for (const auto& property : interface.second) 6484a0cb85cSEd Tanous { 6494a0cb85cSEd Tanous if (property.first == "Address") 6504a0cb85cSEd Tanous { 6514a0cb85cSEd Tanous const std::string* address = 652abf2add6SEd Tanous std::get_if<std::string>(&property.second); 6534a0cb85cSEd Tanous if (address != nullptr) 6544a0cb85cSEd Tanous { 6552c70f800SEd Tanous ipv4Address.address = *address; 6564a0cb85cSEd Tanous } 6574a0cb85cSEd Tanous } 6584a0cb85cSEd Tanous else if (property.first == "Origin") 6594a0cb85cSEd Tanous { 6604a0cb85cSEd Tanous const std::string* origin = 661abf2add6SEd Tanous std::get_if<std::string>(&property.second); 6624a0cb85cSEd Tanous if (origin != nullptr) 6634a0cb85cSEd Tanous { 6642c70f800SEd Tanous ipv4Address.origin = 6654a0cb85cSEd Tanous translateAddressOriginDbusToRedfish(*origin, 6664a0cb85cSEd Tanous true); 6674a0cb85cSEd Tanous } 6684a0cb85cSEd Tanous } 6694a0cb85cSEd Tanous else if (property.first == "PrefixLength") 6704a0cb85cSEd Tanous { 6714a0cb85cSEd Tanous const uint8_t* mask = 672abf2add6SEd Tanous std::get_if<uint8_t>(&property.second); 6734a0cb85cSEd Tanous if (mask != nullptr) 6744a0cb85cSEd Tanous { 6754a0cb85cSEd Tanous // convert it to the string 6762c70f800SEd Tanous ipv4Address.netmask = getNetmask(*mask); 6774a0cb85cSEd Tanous } 6784a0cb85cSEd Tanous } 679889ff694SAsmitha Karunanithi else if (property.first == "Type" || 680889ff694SAsmitha Karunanithi property.first == "Gateway") 681889ff694SAsmitha Karunanithi { 682889ff694SAsmitha Karunanithi // Type & Gateway is not used 683889ff694SAsmitha Karunanithi } 6844a0cb85cSEd Tanous else 6854a0cb85cSEd Tanous { 68662598e31SEd Tanous BMCWEB_LOG_ERROR( 68762598e31SEd Tanous "Got extra property: {} on the {} object", 68862598e31SEd Tanous property.first, objpath.first.str); 6894a0cb85cSEd Tanous } 6904a0cb85cSEd Tanous } 6914a0cb85cSEd Tanous // Check if given address is local, or global 6922c70f800SEd Tanous ipv4Address.linktype = 69311ba3979SEd Tanous ipv4Address.address.starts_with("169.254.") 69418659d10SJohnathan Mantey ? LinkType::Local 69518659d10SJohnathan Mantey : LinkType::Global; 6964a0cb85cSEd Tanous } 6974a0cb85cSEd Tanous } 6984a0cb85cSEd Tanous } 6994a0cb85cSEd Tanous } 7004a0cb85cSEd Tanous } 701588c3f0dSKowalski, Kamil 702588c3f0dSKowalski, Kamil /** 70301784826SJohnathan Mantey * @brief Deletes given IPv4 interface 704179db1d7SKowalski, Kamil * 705179db1d7SKowalski, Kamil * @param[in] ifaceId Id of interface whose IP should be deleted 706179db1d7SKowalski, Kamil * @param[in] ipHash DBus Hash id of IP that should be deleted 707179db1d7SKowalski, Kamil * @param[io] asyncResp Response object that will be returned to client 708179db1d7SKowalski, Kamil * 709179db1d7SKowalski, Kamil * @return None 710179db1d7SKowalski, Kamil */ 7119c5e585cSRavi Teja inline void deleteIPAddress(const std::string& ifaceId, 7129c5e585cSRavi Teja const std::string& ipHash, 7138d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 7141abe55efSEd Tanous { 71555c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 7165e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 7171abe55efSEd Tanous if (ec) 7181abe55efSEd Tanous { 719a08b46ccSJason M. Bills messages::internalError(asyncResp->res); 7201abe55efSEd Tanous } 721179db1d7SKowalski, Kamil }, 722179db1d7SKowalski, Kamil "xyz.openbmc_project.Network", 7239c5e585cSRavi Teja "/xyz/openbmc_project/network/" + ifaceId + ipHash, 724179db1d7SKowalski, Kamil "xyz.openbmc_project.Object.Delete", "Delete"); 725179db1d7SKowalski, Kamil } 726179db1d7SKowalski, Kamil 727244b6d5bSGunnar Mills inline void updateIPv4DefaultGateway( 728244b6d5bSGunnar Mills const std::string& ifaceId, const std::string& gateway, 729244b6d5bSGunnar Mills const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 7309010ec2eSRavi Teja { 731d02aad39SEd Tanous setDbusProperty( 732d02aad39SEd Tanous asyncResp, "xyz.openbmc_project.Network", 733d02aad39SEd Tanous sdbusplus::message::object_path("/xyz/openbmc_project/network") / 734d02aad39SEd Tanous ifaceId, 7359ae226faSGeorge Liu "xyz.openbmc_project.Network.EthernetInterface", "DefaultGateway", 736d02aad39SEd Tanous "Gateway", gateway); 7379010ec2eSRavi Teja } 738179db1d7SKowalski, Kamil /** 73901784826SJohnathan Mantey * @brief Creates a static IPv4 entry 740179db1d7SKowalski, Kamil * 74101784826SJohnathan Mantey * @param[in] ifaceId Id of interface upon which to create the IPv4 entry 74201784826SJohnathan Mantey * @param[in] prefixLength IPv4 prefix syntax for the subnet mask 74301784826SJohnathan Mantey * @param[in] gateway IPv4 address of this interfaces gateway 74401784826SJohnathan Mantey * @param[in] address IPv4 address to assign to this interface 745179db1d7SKowalski, Kamil * @param[io] asyncResp Response object that will be returned to client 746179db1d7SKowalski, Kamil * 747179db1d7SKowalski, Kamil * @return None 748179db1d7SKowalski, Kamil */ 749cb13a392SEd Tanous inline void createIPv4(const std::string& ifaceId, uint8_t prefixLength, 750cb13a392SEd Tanous const std::string& gateway, const std::string& address, 7518d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 7521abe55efSEd Tanous { 7535a39f77aSPatrick Williams auto createIpHandler = [asyncResp, ifaceId, 7545a39f77aSPatrick Williams gateway](const boost::system::error_code& ec) { 7551abe55efSEd Tanous if (ec) 7561abe55efSEd Tanous { 757a08b46ccSJason M. Bills messages::internalError(asyncResp->res); 7589010ec2eSRavi Teja return; 759179db1d7SKowalski, Kamil } 7609010ec2eSRavi Teja updateIPv4DefaultGateway(ifaceId, gateway, asyncResp); 7619010ec2eSRavi Teja }; 7629010ec2eSRavi Teja 7639010ec2eSRavi Teja crow::connections::systemBus->async_method_call( 7649010ec2eSRavi Teja std::move(createIpHandler), "xyz.openbmc_project.Network", 765179db1d7SKowalski, Kamil "/xyz/openbmc_project/network/" + ifaceId, 766179db1d7SKowalski, Kamil "xyz.openbmc_project.Network.IP.Create", "IP", 76701784826SJohnathan Mantey "xyz.openbmc_project.Network.IP.Protocol.IPv4", address, prefixLength, 768179db1d7SKowalski, Kamil gateway); 769179db1d7SKowalski, Kamil } 770e48c0fc5SRavi Teja 771e48c0fc5SRavi Teja /** 77201784826SJohnathan Mantey * @brief Deletes the IPv6 entry for this interface and creates a replacement 77301784826SJohnathan Mantey * static IPv6 entry 77401784826SJohnathan Mantey * 77501784826SJohnathan Mantey * @param[in] ifaceId Id of interface upon which to create the IPv6 entry 77601784826SJohnathan Mantey * @param[in] id The unique hash entry identifying the DBus entry 77701784826SJohnathan Mantey * @param[in] prefixLength IPv6 prefix syntax for the subnet mask 77801784826SJohnathan Mantey * @param[in] address IPv6 address to assign to this interface 77901784826SJohnathan Mantey * @param[io] asyncResp Response object that will be returned to client 78001784826SJohnathan Mantey * 78101784826SJohnathan Mantey * @return None 78201784826SJohnathan Mantey */ 7839c5e585cSRavi Teja 7849c5e585cSRavi Teja enum class IpVersion 7859c5e585cSRavi Teja { 7869c5e585cSRavi Teja IpV4, 7879c5e585cSRavi Teja IpV6 7889c5e585cSRavi Teja }; 7899c5e585cSRavi Teja 7909c5e585cSRavi Teja inline void deleteAndCreateIPAddress( 7919c5e585cSRavi Teja IpVersion version, const std::string& ifaceId, const std::string& id, 7928d1b46d7Szhanghch05 uint8_t prefixLength, const std::string& address, 7939c5e585cSRavi Teja const std::string& gateway, 7948d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 79501784826SJohnathan Mantey { 79601784826SJohnathan Mantey crow::connections::systemBus->async_method_call( 7979c5e585cSRavi Teja [asyncResp, version, ifaceId, address, prefixLength, 7989c5e585cSRavi Teja gateway](const boost::system::error_code& ec) { 79901784826SJohnathan Mantey if (ec) 80001784826SJohnathan Mantey { 80101784826SJohnathan Mantey messages::internalError(asyncResp->res); 80201784826SJohnathan Mantey } 8039c5e585cSRavi Teja std::string protocol = "xyz.openbmc_project.Network.IP.Protocol."; 8049c5e585cSRavi Teja protocol += version == IpVersion::IpV4 ? "IPv4" : "IPv6"; 80501784826SJohnathan Mantey crow::connections::systemBus->async_method_call( 8065e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 80723a21a1cSEd Tanous if (ec2) 80801784826SJohnathan Mantey { 80901784826SJohnathan Mantey messages::internalError(asyncResp->res); 81001784826SJohnathan Mantey } 81101784826SJohnathan Mantey }, 81201784826SJohnathan Mantey "xyz.openbmc_project.Network", 81301784826SJohnathan Mantey "/xyz/openbmc_project/network/" + ifaceId, 8149c5e585cSRavi Teja "xyz.openbmc_project.Network.IP.Create", "IP", protocol, address, 8159c5e585cSRavi Teja prefixLength, gateway); 81601784826SJohnathan Mantey }, 81701784826SJohnathan Mantey "xyz.openbmc_project.Network", 8189c5e585cSRavi Teja "/xyz/openbmc_project/network/" + ifaceId + id, 81901784826SJohnathan Mantey "xyz.openbmc_project.Object.Delete", "Delete"); 82001784826SJohnathan Mantey } 82101784826SJohnathan Mantey 822ce73d5c8SSunitha Harish inline bool extractIPv6DefaultGatewayData( 823ce73d5c8SSunitha Harish const std::string& ethifaceId, 824ce73d5c8SSunitha Harish const dbus::utility::ManagedObjectType& dbusData, 825ce73d5c8SSunitha Harish std::vector<StaticGatewayData>& staticGatewayConfig) 826ce73d5c8SSunitha Harish { 827ce73d5c8SSunitha Harish std::string staticGatewayPathStart("/xyz/openbmc_project/network/"); 828ce73d5c8SSunitha Harish staticGatewayPathStart += ethifaceId; 829ce73d5c8SSunitha Harish 830ce73d5c8SSunitha Harish for (const auto& objpath : dbusData) 831ce73d5c8SSunitha Harish { 832ce73d5c8SSunitha Harish if (!std::string_view(objpath.first.str) 833ce73d5c8SSunitha Harish .starts_with(staticGatewayPathStart)) 834ce73d5c8SSunitha Harish { 835ce73d5c8SSunitha Harish continue; 836ce73d5c8SSunitha Harish } 837ce73d5c8SSunitha Harish for (const auto& interface : objpath.second) 838ce73d5c8SSunitha Harish { 839ce73d5c8SSunitha Harish if (interface.first != "xyz.openbmc_project.Network.StaticGateway") 840ce73d5c8SSunitha Harish { 841ce73d5c8SSunitha Harish continue; 842ce73d5c8SSunitha Harish } 843ce73d5c8SSunitha Harish StaticGatewayData& staticGateway = 844ce73d5c8SSunitha Harish staticGatewayConfig.emplace_back(); 845ce73d5c8SSunitha Harish staticGateway.id = objpath.first.filename(); 846ce73d5c8SSunitha Harish 847ce73d5c8SSunitha Harish bool success = sdbusplus::unpackPropertiesNoThrow( 848ce73d5c8SSunitha Harish redfish::dbus_utils::UnpackErrorPrinter(), interface.second, 849ce73d5c8SSunitha Harish "Gateway", staticGateway.gateway, "PrefixLength", 850ce73d5c8SSunitha Harish staticGateway.prefixLength, "ProtocolType", 851ce73d5c8SSunitha Harish staticGateway.protocol); 852ce73d5c8SSunitha Harish if (!success) 853ce73d5c8SSunitha Harish { 854ce73d5c8SSunitha Harish return false; 855ce73d5c8SSunitha Harish } 856ce73d5c8SSunitha Harish } 857ce73d5c8SSunitha Harish } 858ce73d5c8SSunitha Harish return true; 859ce73d5c8SSunitha Harish } 860ce73d5c8SSunitha Harish 86101784826SJohnathan Mantey /** 862e48c0fc5SRavi Teja * @brief Creates IPv6 with given data 863e48c0fc5SRavi Teja * 864e48c0fc5SRavi Teja * @param[in] ifaceId Id of interface whose IP should be added 865e48c0fc5SRavi Teja * @param[in] prefixLength Prefix length that needs to be added 866e48c0fc5SRavi Teja * @param[in] address IP address that needs to be added 867e48c0fc5SRavi Teja * @param[io] asyncResp Response object that will be returned to client 868e48c0fc5SRavi Teja * 869e48c0fc5SRavi Teja * @return None 870e48c0fc5SRavi Teja */ 87101784826SJohnathan Mantey inline void createIPv6(const std::string& ifaceId, uint8_t prefixLength, 87201784826SJohnathan Mantey const std::string& address, 8738d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 874e48c0fc5SRavi Teja { 875ce73d5c8SSunitha Harish sdbusplus::message::object_path path("/xyz/openbmc_project/network"); 876ce73d5c8SSunitha Harish path /= ifaceId; 877ce73d5c8SSunitha Harish 8785a39f77aSPatrick Williams auto createIpHandler = [asyncResp, 8795a39f77aSPatrick Williams address](const boost::system::error_code& ec) { 880e48c0fc5SRavi Teja if (ec) 881e48c0fc5SRavi Teja { 882fc23ef8aSNitin Kumar Kotania if (ec == boost::system::errc::io_error) 883fc23ef8aSNitin Kumar Kotania { 884fc23ef8aSNitin Kumar Kotania messages::propertyValueFormatError(asyncResp->res, address, 885fc23ef8aSNitin Kumar Kotania "Address"); 886fc23ef8aSNitin Kumar Kotania } 887fc23ef8aSNitin Kumar Kotania else 888fc23ef8aSNitin Kumar Kotania { 889e48c0fc5SRavi Teja messages::internalError(asyncResp->res); 890e48c0fc5SRavi Teja } 891fc23ef8aSNitin Kumar Kotania } 892e48c0fc5SRavi Teja }; 893ce73d5c8SSunitha Harish // Passing null for gateway, as per redfish spec IPv6StaticAddresses 894ce73d5c8SSunitha Harish // object does not have associated gateway property 895e48c0fc5SRavi Teja crow::connections::systemBus->async_method_call( 896ce73d5c8SSunitha Harish std::move(createIpHandler), "xyz.openbmc_project.Network", path, 897e48c0fc5SRavi Teja "xyz.openbmc_project.Network.IP.Create", "IP", 898e48c0fc5SRavi Teja "xyz.openbmc_project.Network.IP.Protocol.IPv6", address, prefixLength, 899e48c0fc5SRavi Teja ""); 900e48c0fc5SRavi Teja } 901e48c0fc5SRavi Teja 902179db1d7SKowalski, Kamil /** 903ce73d5c8SSunitha Harish * @brief Deletes given IPv6 Static Gateway 904ce73d5c8SSunitha Harish * 905ce73d5c8SSunitha Harish * @param[in] ifaceId Id of interface whose IP should be deleted 906ce73d5c8SSunitha Harish * @param[in] ipHash DBus Hash id of IP that should be deleted 907ce73d5c8SSunitha Harish * @param[io] asyncResp Response object that will be returned to client 908ce73d5c8SSunitha Harish * 909ce73d5c8SSunitha Harish * @return None 910ce73d5c8SSunitha Harish */ 911ce73d5c8SSunitha Harish inline void 912ce73d5c8SSunitha Harish deleteIPv6Gateway(std::string_view gatewayId, 913ce73d5c8SSunitha Harish const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 914ce73d5c8SSunitha Harish { 915ce73d5c8SSunitha Harish sdbusplus::message::object_path path("/xyz/openbmc_project/network"); 916ce73d5c8SSunitha Harish path /= gatewayId; 917ce73d5c8SSunitha Harish crow::connections::systemBus->async_method_call( 918ce73d5c8SSunitha Harish [asyncResp](const boost::system::error_code& ec) { 919ce73d5c8SSunitha Harish if (ec) 920ce73d5c8SSunitha Harish { 921ce73d5c8SSunitha Harish messages::internalError(asyncResp->res); 922ce73d5c8SSunitha Harish } 923ce73d5c8SSunitha Harish }, 924ce73d5c8SSunitha Harish "xyz.openbmc_project.Network", path, 925ce73d5c8SSunitha Harish "xyz.openbmc_project.Object.Delete", "Delete"); 926ce73d5c8SSunitha Harish } 927ce73d5c8SSunitha Harish 928ce73d5c8SSunitha Harish /** 929ce73d5c8SSunitha Harish * @brief Creates IPv6 static default gateway with given data 930ce73d5c8SSunitha Harish * 931ce73d5c8SSunitha Harish * @param[in] ifaceId Id of interface whose IP should be added 932ce73d5c8SSunitha Harish * @param[in] prefixLength Prefix length that needs to be added 933ce73d5c8SSunitha Harish * @param[in] gateway Gateway address that needs to be added 934ce73d5c8SSunitha Harish * @param[io] asyncResp Response object that will be returned to client 935ce73d5c8SSunitha Harish * 936ce73d5c8SSunitha Harish * @return None 937ce73d5c8SSunitha Harish */ 938ce73d5c8SSunitha Harish inline void createIPv6DefaultGateway( 939ce73d5c8SSunitha Harish std::string_view ifaceId, size_t prefixLength, std::string_view gateway, 940ce73d5c8SSunitha Harish const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 941ce73d5c8SSunitha Harish { 942ce73d5c8SSunitha Harish sdbusplus::message::object_path path("/xyz/openbmc_project/network"); 943ce73d5c8SSunitha Harish path /= ifaceId; 944ce73d5c8SSunitha Harish auto createIpHandler = [asyncResp](const boost::system::error_code& ec) { 945ce73d5c8SSunitha Harish if (ec) 946ce73d5c8SSunitha Harish { 947ce73d5c8SSunitha Harish messages::internalError(asyncResp->res); 948ce73d5c8SSunitha Harish } 949ce73d5c8SSunitha Harish }; 950ce73d5c8SSunitha Harish crow::connections::systemBus->async_method_call( 951ce73d5c8SSunitha Harish std::move(createIpHandler), "xyz.openbmc_project.Network", path, 952ce73d5c8SSunitha Harish "xyz.openbmc_project.Network.StaticGateway.Create", "StaticGateway", 953ce73d5c8SSunitha Harish gateway, prefixLength, "xyz.openbmc_project.Network.IP.Protocol.IPv6"); 954ce73d5c8SSunitha Harish } 955ce73d5c8SSunitha Harish 956ce73d5c8SSunitha Harish /** 957ce73d5c8SSunitha Harish * @brief Deletes the IPv6 default gateway entry for this interface and 958ce73d5c8SSunitha Harish * creates a replacement IPv6 default gateway entry 959ce73d5c8SSunitha Harish * 960ce73d5c8SSunitha Harish * @param[in] ifaceId Id of interface upon which to create the IPv6 961ce73d5c8SSunitha Harish * entry 962ce73d5c8SSunitha Harish * @param[in] gateway IPv6 gateway to assign to this interface 963ce73d5c8SSunitha Harish * @param[in] prefixLength IPv6 prefix syntax for the subnet mask 964ce73d5c8SSunitha Harish * @param[io] asyncResp Response object that will be returned to client 965ce73d5c8SSunitha Harish * 966ce73d5c8SSunitha Harish * @return None 967ce73d5c8SSunitha Harish */ 968ce73d5c8SSunitha Harish inline void deleteAndCreateIPv6DefaultGateway( 969ce73d5c8SSunitha Harish std::string_view ifaceId, std::string_view gatewayId, 970ce73d5c8SSunitha Harish std::string_view gateway, size_t prefixLength, 971ce73d5c8SSunitha Harish const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 972ce73d5c8SSunitha Harish { 973ce73d5c8SSunitha Harish sdbusplus::message::object_path path("/xyz/openbmc_project/network"); 974ce73d5c8SSunitha Harish path /= gatewayId; 975ce73d5c8SSunitha Harish crow::connections::systemBus->async_method_call( 976ce73d5c8SSunitha Harish [asyncResp, ifaceId, gateway, 977ce73d5c8SSunitha Harish prefixLength](const boost::system::error_code& ec) { 978ce73d5c8SSunitha Harish if (ec) 979ce73d5c8SSunitha Harish { 980ce73d5c8SSunitha Harish messages::internalError(asyncResp->res); 981ce73d5c8SSunitha Harish return; 982ce73d5c8SSunitha Harish } 983ce73d5c8SSunitha Harish createIPv6DefaultGateway(ifaceId, prefixLength, gateway, asyncResp); 984ce73d5c8SSunitha Harish }, 985ce73d5c8SSunitha Harish "xyz.openbmc_project.Network", path, 986ce73d5c8SSunitha Harish "xyz.openbmc_project.Object.Delete", "Delete"); 987ce73d5c8SSunitha Harish } 988ce73d5c8SSunitha Harish 989ce73d5c8SSunitha Harish /** 990ce73d5c8SSunitha Harish * @brief Sets IPv6 default gateway with given data 991ce73d5c8SSunitha Harish * 992ce73d5c8SSunitha Harish * @param[in] ifaceId Id of interface whose gateway should be added 993ce73d5c8SSunitha Harish * @param[in] input Contains address that needs to be added 994ce73d5c8SSunitha Harish * @param[in] staticGatewayData Current static gateways in the system 995ce73d5c8SSunitha Harish * @param[io] asyncResp Response object that will be returned to client 996ce73d5c8SSunitha Harish * 997ce73d5c8SSunitha Harish * @return None 998ce73d5c8SSunitha Harish */ 999ce73d5c8SSunitha Harish 1000ce73d5c8SSunitha Harish inline void handleIPv6DefaultGateway( 10013dfed536SEd Tanous const std::string& ifaceId, 10023dfed536SEd Tanous std::vector<std::variant<nlohmann::json::object_t, std::nullptr_t>>& input, 1003ce73d5c8SSunitha Harish const std::vector<StaticGatewayData>& staticGatewayData, 1004ce73d5c8SSunitha Harish const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1005ce73d5c8SSunitha Harish { 1006ce73d5c8SSunitha Harish size_t entryIdx = 1; 1007ce73d5c8SSunitha Harish std::vector<StaticGatewayData>::const_iterator staticGatewayEntry = 1008ce73d5c8SSunitha Harish staticGatewayData.begin(); 1009ce73d5c8SSunitha Harish 10103dfed536SEd Tanous for (std::variant<nlohmann::json::object_t, std::nullptr_t>& thisJson : 10113dfed536SEd Tanous input) 1012ce73d5c8SSunitha Harish { 1013ce73d5c8SSunitha Harish // find the next gateway entry 1014ce73d5c8SSunitha Harish while (staticGatewayEntry != staticGatewayData.end()) 1015ce73d5c8SSunitha Harish { 1016ce73d5c8SSunitha Harish if (staticGatewayEntry->protocol == 1017ce73d5c8SSunitha Harish "xyz.openbmc_project.Network.IP.Protocol.IPv6") 1018ce73d5c8SSunitha Harish { 1019ce73d5c8SSunitha Harish break; 1020ce73d5c8SSunitha Harish } 1021ce73d5c8SSunitha Harish staticGatewayEntry++; 1022ce73d5c8SSunitha Harish } 1023ce73d5c8SSunitha Harish std::string pathString = "IPv6StaticDefaultGateways/" + 1024ce73d5c8SSunitha Harish std::to_string(entryIdx); 10253dfed536SEd Tanous nlohmann::json::object_t* obj = 10263dfed536SEd Tanous std::get_if<nlohmann::json::object_t>(&thisJson); 10273dfed536SEd Tanous if (obj == nullptr) 1028ce73d5c8SSunitha Harish { 1029ce73d5c8SSunitha Harish if (staticGatewayEntry == staticGatewayData.end()) 1030ce73d5c8SSunitha Harish { 1031ce73d5c8SSunitha Harish messages::resourceCannotBeDeleted(asyncResp->res); 1032ce73d5c8SSunitha Harish return; 1033ce73d5c8SSunitha Harish } 1034ce73d5c8SSunitha Harish deleteIPv6Gateway(staticGatewayEntry->id, asyncResp); 1035ce73d5c8SSunitha Harish return; 1036ce73d5c8SSunitha Harish } 10373dfed536SEd Tanous if (obj->empty()) 1038ce73d5c8SSunitha Harish { 1039ce73d5c8SSunitha Harish // Do nothing, but make sure the entry exists. 1040ce73d5c8SSunitha Harish if (staticGatewayEntry == staticGatewayData.end()) 1041ce73d5c8SSunitha Harish { 10423dfed536SEd Tanous messages::propertyValueFormatError(asyncResp->res, *obj, 1043ce73d5c8SSunitha Harish pathString); 1044ce73d5c8SSunitha Harish return; 1045ce73d5c8SSunitha Harish } 1046ce73d5c8SSunitha Harish } 1047ce73d5c8SSunitha Harish std::optional<std::string> address; 1048ce73d5c8SSunitha Harish std::optional<size_t> prefixLength; 1049ce73d5c8SSunitha Harish 10503dfed536SEd Tanous if (!json_util::readJsonObject(*obj, asyncResp->res, "Address", address, 10513dfed536SEd Tanous "PrefixLength", prefixLength)) 1052ce73d5c8SSunitha Harish { 1053ce73d5c8SSunitha Harish return; 1054ce73d5c8SSunitha Harish } 1055ce73d5c8SSunitha Harish const std::string* addr = nullptr; 1056ce73d5c8SSunitha Harish size_t prefix = 0; 1057ce73d5c8SSunitha Harish if (address) 1058ce73d5c8SSunitha Harish { 1059ce73d5c8SSunitha Harish addr = &(*address); 1060ce73d5c8SSunitha Harish } 1061ce73d5c8SSunitha Harish else if (staticGatewayEntry != staticGatewayData.end()) 1062ce73d5c8SSunitha Harish { 1063ce73d5c8SSunitha Harish addr = &(staticGatewayEntry->gateway); 1064ce73d5c8SSunitha Harish } 1065ce73d5c8SSunitha Harish else 1066ce73d5c8SSunitha Harish { 1067ce73d5c8SSunitha Harish messages::propertyMissing(asyncResp->res, pathString + "/Address"); 1068ce73d5c8SSunitha Harish return; 1069ce73d5c8SSunitha Harish } 1070ce73d5c8SSunitha Harish if (prefixLength) 1071ce73d5c8SSunitha Harish { 1072ce73d5c8SSunitha Harish prefix = *prefixLength; 1073ce73d5c8SSunitha Harish } 1074ce73d5c8SSunitha Harish else if (staticGatewayEntry != staticGatewayData.end()) 1075ce73d5c8SSunitha Harish { 1076ce73d5c8SSunitha Harish prefix = staticGatewayEntry->prefixLength; 1077ce73d5c8SSunitha Harish } 1078ce73d5c8SSunitha Harish else 1079ce73d5c8SSunitha Harish { 1080ce73d5c8SSunitha Harish messages::propertyMissing(asyncResp->res, 1081ce73d5c8SSunitha Harish pathString + "/PrefixLength"); 1082ce73d5c8SSunitha Harish return; 1083ce73d5c8SSunitha Harish } 1084ce73d5c8SSunitha Harish if (staticGatewayEntry != staticGatewayData.end()) 1085ce73d5c8SSunitha Harish { 1086ce73d5c8SSunitha Harish deleteAndCreateIPv6DefaultGateway(ifaceId, staticGatewayEntry->id, 1087ce73d5c8SSunitha Harish *addr, prefix, asyncResp); 1088ce73d5c8SSunitha Harish staticGatewayEntry++; 1089ce73d5c8SSunitha Harish } 1090ce73d5c8SSunitha Harish else 1091ce73d5c8SSunitha Harish { 1092ce73d5c8SSunitha Harish createIPv6DefaultGateway(ifaceId, prefix, *addr, asyncResp); 1093ce73d5c8SSunitha Harish } 1094ce73d5c8SSunitha Harish entryIdx++; 1095ce73d5c8SSunitha Harish } 1096ce73d5c8SSunitha Harish } 1097ce73d5c8SSunitha Harish 1098ce73d5c8SSunitha Harish /** 1099179db1d7SKowalski, Kamil * Function that retrieves all properties for given Ethernet Interface 1100179db1d7SKowalski, Kamil * Object 1101179db1d7SKowalski, Kamil * from EntityManager Network Manager 11024a0cb85cSEd Tanous * @param ethiface_id a eth interface id to query on DBus 1103179db1d7SKowalski, Kamil * @param callback a function that shall be called to convert Dbus output 1104179db1d7SKowalski, Kamil * into JSON 1105179db1d7SKowalski, Kamil */ 1106179db1d7SKowalski, Kamil template <typename CallbackFunc> 110781ce609eSEd Tanous void getEthernetIfaceData(const std::string& ethifaceId, 11081abe55efSEd Tanous CallbackFunc&& callback) 11091abe55efSEd Tanous { 1110f5892d0dSGeorge Liu sdbusplus::message::object_path path("/xyz/openbmc_project/network"); 1111f5892d0dSGeorge Liu dbus::utility::getManagedObjects( 1112f5892d0dSGeorge Liu "xyz.openbmc_project.Network", path, 1113f94c4ecfSEd Tanous [ethifaceId{std::string{ethifaceId}}, 1114*8cb2c024SEd Tanous callback = std::forward<CallbackFunc>(callback)]( 11158b24275dSEd Tanous const boost::system::error_code& ec, 11163dfed536SEd Tanous const dbus::utility::ManagedObjectType& resp) mutable { 111755c7b7a2SEd Tanous EthernetInterfaceData ethData{}; 111877179532SEd Tanous std::vector<IPv4AddressData> ipv4Data; 111977179532SEd Tanous std::vector<IPv6AddressData> ipv6Data; 1120ce73d5c8SSunitha Harish std::vector<StaticGatewayData> ipv6GatewayData; 1121179db1d7SKowalski, Kamil 11228b24275dSEd Tanous if (ec) 11231abe55efSEd Tanous { 1124ce73d5c8SSunitha Harish callback(false, ethData, ipv4Data, ipv6Data, ipv6GatewayData); 1125179db1d7SKowalski, Kamil return; 1126179db1d7SKowalski, Kamil } 1127179db1d7SKowalski, Kamil 1128002d39b4SEd Tanous bool found = extractEthernetInterfaceData(ethifaceId, resp, ethData); 11294c9afe43SEd Tanous if (!found) 11304c9afe43SEd Tanous { 1131ce73d5c8SSunitha Harish callback(false, ethData, ipv4Data, ipv6Data, ipv6GatewayData); 11324c9afe43SEd Tanous return; 11334c9afe43SEd Tanous } 11344c9afe43SEd Tanous 11352c70f800SEd Tanous extractIPData(ethifaceId, resp, ipv4Data); 1136179db1d7SKowalski, Kamil // Fix global GW 11371abe55efSEd Tanous for (IPv4AddressData& ipv4 : ipv4Data) 11381abe55efSEd Tanous { 1139c619141bSRavi Teja if (((ipv4.linktype == LinkType::Global) && 1140c619141bSRavi Teja (ipv4.gateway == "0.0.0.0")) || 11419010ec2eSRavi Teja (ipv4.origin == "DHCP") || (ipv4.origin == "Static")) 11421abe55efSEd Tanous { 114382695a5bSJiaqing Zhao ipv4.gateway = ethData.defaultGateway; 1144179db1d7SKowalski, Kamil } 1145179db1d7SKowalski, Kamil } 1146179db1d7SKowalski, Kamil 11472c70f800SEd Tanous extractIPV6Data(ethifaceId, resp, ipv6Data); 1148ce73d5c8SSunitha Harish if (!extractIPv6DefaultGatewayData(ethifaceId, resp, ipv6GatewayData)) 1149ce73d5c8SSunitha Harish { 1150ce73d5c8SSunitha Harish callback(false, ethData, ipv4Data, ipv6Data, ipv6GatewayData); 1151ce73d5c8SSunitha Harish } 11524e0453b1SGunnar Mills // Finally make a callback with useful data 1153ce73d5c8SSunitha Harish callback(true, ethData, ipv4Data, ipv6Data, ipv6GatewayData); 1154f5892d0dSGeorge Liu }); 1155271584abSEd Tanous } 1156179db1d7SKowalski, Kamil 1157179db1d7SKowalski, Kamil /** 11589391bb9cSRapkiewicz, Pawel * Function that retrieves all Ethernet Interfaces available through Network 11599391bb9cSRapkiewicz, Pawel * Manager 11601abe55efSEd Tanous * @param callback a function that shall be called to convert Dbus output 11611abe55efSEd Tanous * into JSON. 11629391bb9cSRapkiewicz, Pawel */ 11639391bb9cSRapkiewicz, Pawel template <typename CallbackFunc> 11641abe55efSEd Tanous void getEthernetIfaceList(CallbackFunc&& callback) 11651abe55efSEd Tanous { 1166f5892d0dSGeorge Liu sdbusplus::message::object_path path("/xyz/openbmc_project/network"); 1167f5892d0dSGeorge Liu dbus::utility::getManagedObjects( 1168f5892d0dSGeorge Liu "xyz.openbmc_project.Network", path, 1169*8cb2c024SEd Tanous [callback = std::forward<CallbackFunc>(callback)]( 11708b24275dSEd Tanous const boost::system::error_code& ec, 1171f5892d0dSGeorge Liu const dbus::utility::ManagedObjectType& resp) { 11721abe55efSEd Tanous // Callback requires vector<string> to retrieve all available 11731abe55efSEd Tanous // ethernet interfaces 117477179532SEd Tanous std::vector<std::string> ifaceList; 11752c70f800SEd Tanous ifaceList.reserve(resp.size()); 11768b24275dSEd Tanous if (ec) 11771abe55efSEd Tanous { 11782c70f800SEd Tanous callback(false, ifaceList); 11799391bb9cSRapkiewicz, Pawel return; 11809391bb9cSRapkiewicz, Pawel } 11819391bb9cSRapkiewicz, Pawel 11829391bb9cSRapkiewicz, Pawel // Iterate over all retrieved ObjectPaths. 11834a0cb85cSEd Tanous for (const auto& objpath : resp) 11841abe55efSEd Tanous { 11859391bb9cSRapkiewicz, Pawel // And all interfaces available for certain ObjectPath. 11864a0cb85cSEd Tanous for (const auto& interface : objpath.second) 11871abe55efSEd Tanous { 11881abe55efSEd Tanous // If interface is 11894a0cb85cSEd Tanous // xyz.openbmc_project.Network.EthernetInterface, this is 11904a0cb85cSEd Tanous // what we're looking for. 11919391bb9cSRapkiewicz, Pawel if (interface.first == 11921abe55efSEd Tanous "xyz.openbmc_project.Network.EthernetInterface") 11931abe55efSEd Tanous { 11942dfd18efSEd Tanous std::string ifaceId = objpath.first.filename(); 11952dfd18efSEd Tanous if (ifaceId.empty()) 11961abe55efSEd Tanous { 11972dfd18efSEd Tanous continue; 11989391bb9cSRapkiewicz, Pawel } 11992dfd18efSEd Tanous // and put it into output vector. 120077179532SEd Tanous ifaceList.emplace_back(ifaceId); 12019391bb9cSRapkiewicz, Pawel } 12029391bb9cSRapkiewicz, Pawel } 12039391bb9cSRapkiewicz, Pawel } 12042c5875a2SEd Tanous 12053544d2a7SEd Tanous std::ranges::sort(ifaceList, AlphanumLess<std::string>()); 12062c5875a2SEd Tanous 1207a434f2bdSEd Tanous // Finally make a callback with useful data 12082c70f800SEd Tanous callback(true, ifaceList); 1209f5892d0dSGeorge Liu }); 1210271584abSEd Tanous } 12119391bb9cSRapkiewicz, Pawel 12124f48d5f6SEd Tanous inline void 12134f48d5f6SEd Tanous handleHostnamePatch(const std::string& hostname, 12148d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 12151abe55efSEd Tanous { 1216ab6554f1SJoshi-Mansi // SHOULD handle host names of up to 255 characters(RFC 1123) 1217ab6554f1SJoshi-Mansi if (hostname.length() > 255) 1218ab6554f1SJoshi-Mansi { 1219ab6554f1SJoshi-Mansi messages::propertyValueFormatError(asyncResp->res, hostname, 1220ab6554f1SJoshi-Mansi "HostName"); 1221ab6554f1SJoshi-Mansi return; 1222ab6554f1SJoshi-Mansi } 1223d02aad39SEd Tanous setDbusProperty( 1224d02aad39SEd Tanous asyncResp, "xyz.openbmc_project.Network", 1225d02aad39SEd Tanous sdbusplus::message::object_path("/xyz/openbmc_project/network/config"), 1226d02aad39SEd Tanous "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 1227d02aad39SEd Tanous "HostName", hostname); 1228588c3f0dSKowalski, Kamil } 1229588c3f0dSKowalski, Kamil 12304f48d5f6SEd Tanous inline void 123135fb5311STejas Patil handleMTUSizePatch(const std::string& ifaceId, const size_t mtuSize, 123235fb5311STejas Patil const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 123335fb5311STejas Patil { 1234d02aad39SEd Tanous sdbusplus::message::object_path objPath("/xyz/openbmc_project/network"); 1235d02aad39SEd Tanous objPath /= ifaceId; 1236d02aad39SEd Tanous setDbusProperty(asyncResp, "xyz.openbmc_project.Network", objPath, 1237d02aad39SEd Tanous "xyz.openbmc_project.Network.EthernetInterface", "MTU", 1238d02aad39SEd Tanous "MTUSize", mtuSize); 123935fb5311STejas Patil } 124035fb5311STejas Patil 124135fb5311STejas Patil inline void 12424f48d5f6SEd Tanous handleDomainnamePatch(const std::string& ifaceId, 1243bf648f77SEd Tanous const std::string& domainname, 12448d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1245ab6554f1SJoshi-Mansi { 1246ab6554f1SJoshi-Mansi std::vector<std::string> vectorDomainname = {domainname}; 1247d02aad39SEd Tanous setDbusProperty( 1248d02aad39SEd Tanous asyncResp, "xyz.openbmc_project.Network", 1249d02aad39SEd Tanous sdbusplus::message::object_path("/xyz/openbmc_project/network") / 1250d02aad39SEd Tanous ifaceId, 1251d02aad39SEd Tanous "xyz.openbmc_project.Network.EthernetInterface", "DomainName", "FQDN", 1252d02aad39SEd Tanous vectorDomainname); 1253ab6554f1SJoshi-Mansi } 1254ab6554f1SJoshi-Mansi 12554f48d5f6SEd Tanous inline bool isHostnameValid(const std::string& hostname) 1256bf648f77SEd Tanous { 1257bf648f77SEd Tanous // A valid host name can never have the dotted-decimal form (RFC 1123) 12583544d2a7SEd Tanous if (std::ranges::all_of(hostname, ::isdigit)) 1259bf648f77SEd Tanous { 1260bf648f77SEd Tanous return false; 1261bf648f77SEd Tanous } 1262bf648f77SEd Tanous // Each label(hostname/subdomains) within a valid FQDN 1263bf648f77SEd Tanous // MUST handle host names of up to 63 characters (RFC 1123) 1264bf648f77SEd Tanous // labels cannot start or end with hyphens (RFC 952) 1265bf648f77SEd Tanous // labels can start with numbers (RFC 1123) 12664b242749SEd Tanous const static std::regex pattern( 1267bf648f77SEd Tanous "^[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]$"); 1268bf648f77SEd Tanous 1269bf648f77SEd Tanous return std::regex_match(hostname, pattern); 1270bf648f77SEd Tanous } 1271bf648f77SEd Tanous 12724f48d5f6SEd Tanous inline bool isDomainnameValid(const std::string& domainname) 1273bf648f77SEd Tanous { 1274bf648f77SEd Tanous // Can have multiple subdomains 1275bf648f77SEd Tanous // Top Level Domain's min length is 2 character 12764b242749SEd Tanous const static std::regex pattern( 12770fda0f12SGeorge Liu "^([A-Za-z0-9][a-zA-Z0-9\\-]{1,61}|[a-zA-Z0-9]{1,30}\\.)*[a-zA-Z]{2,}$"); 1278bf648f77SEd Tanous 1279bf648f77SEd Tanous return std::regex_match(domainname, pattern); 1280bf648f77SEd Tanous } 1281bf648f77SEd Tanous 12824f48d5f6SEd Tanous inline void handleFqdnPatch(const std::string& ifaceId, const std::string& fqdn, 12838d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1284ab6554f1SJoshi-Mansi { 1285ab6554f1SJoshi-Mansi // Total length of FQDN must not exceed 255 characters(RFC 1035) 1286ab6554f1SJoshi-Mansi if (fqdn.length() > 255) 1287ab6554f1SJoshi-Mansi { 1288ab6554f1SJoshi-Mansi messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN"); 1289ab6554f1SJoshi-Mansi return; 1290ab6554f1SJoshi-Mansi } 1291ab6554f1SJoshi-Mansi 1292ab6554f1SJoshi-Mansi size_t pos = fqdn.find('.'); 1293ab6554f1SJoshi-Mansi if (pos == std::string::npos) 1294ab6554f1SJoshi-Mansi { 1295ab6554f1SJoshi-Mansi messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN"); 1296ab6554f1SJoshi-Mansi return; 1297ab6554f1SJoshi-Mansi } 1298ab6554f1SJoshi-Mansi 1299ab6554f1SJoshi-Mansi std::string hostname; 1300ab6554f1SJoshi-Mansi std::string domainname; 1301ab6554f1SJoshi-Mansi domainname = (fqdn).substr(pos + 1); 1302ab6554f1SJoshi-Mansi hostname = (fqdn).substr(0, pos); 1303ab6554f1SJoshi-Mansi 1304ab6554f1SJoshi-Mansi if (!isHostnameValid(hostname) || !isDomainnameValid(domainname)) 1305ab6554f1SJoshi-Mansi { 1306ab6554f1SJoshi-Mansi messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN"); 1307ab6554f1SJoshi-Mansi return; 1308ab6554f1SJoshi-Mansi } 1309ab6554f1SJoshi-Mansi 1310ab6554f1SJoshi-Mansi handleHostnamePatch(hostname, asyncResp); 1311ab6554f1SJoshi-Mansi handleDomainnamePatch(ifaceId, domainname, asyncResp); 1312ab6554f1SJoshi-Mansi } 1313ab6554f1SJoshi-Mansi 13144f48d5f6SEd Tanous inline void 13154f48d5f6SEd Tanous handleMACAddressPatch(const std::string& ifaceId, 1316bf648f77SEd Tanous const std::string& macAddress, 13178d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1318d577665bSRatan Gupta { 1319d02aad39SEd Tanous setDbusProperty( 1320d02aad39SEd Tanous asyncResp, "xyz.openbmc_project.Network", 1321d02aad39SEd Tanous sdbusplus::message::object_path("/xyz/openbmc_project/network") / 1322d02aad39SEd Tanous ifaceId, 1323d02aad39SEd Tanous "xyz.openbmc_project.Network.MACAddress", "MACAddress", "MACAddress", 1324d02aad39SEd Tanous macAddress); 1325d577665bSRatan Gupta } 1326286b9118SJohnathan Mantey 13274f48d5f6SEd Tanous inline void setDHCPEnabled(const std::string& ifaceId, 13284f48d5f6SEd Tanous const std::string& propertyName, const bool v4Value, 13294f48d5f6SEd Tanous const bool v6Value, 13308d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1331da131a9aSJennifer Lee { 13322c70f800SEd Tanous const std::string dhcp = getDhcpEnabledEnumeration(v4Value, v6Value); 1333d02aad39SEd Tanous setDbusProperty( 1334d02aad39SEd Tanous asyncResp, "xyz.openbmc_project.Network", 1335d02aad39SEd Tanous sdbusplus::message::object_path("/xyz/openbmc_project/network") / 1336d02aad39SEd Tanous ifaceId, 1337d02aad39SEd Tanous "xyz.openbmc_project.Network.EthernetInterface", propertyName, "DHCPv4", 1338d02aad39SEd Tanous dhcp); 1339eeedda23SJohnathan Mantey } 1340eeedda23SJohnathan Mantey 1341e4588158SJishnu CM enum class NetworkType 1342e4588158SJishnu CM { 1343e4588158SJishnu CM dhcp4, 1344e4588158SJishnu CM dhcp6 1345e4588158SJishnu CM }; 1346e4588158SJishnu CM 1347e4588158SJishnu CM inline void setDHCPConfig(const std::string& propertyName, const bool& value, 1348e4588158SJishnu CM const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1349e4588158SJishnu CM const std::string& ethifaceId, NetworkType type) 1350da131a9aSJennifer Lee { 135162598e31SEd Tanous BMCWEB_LOG_DEBUG("{} = {}", propertyName, value); 13521847f2a0SAsmitha Karunanithi std::string redfishPropertyName; 1353e4588158SJishnu CM sdbusplus::message::object_path path("/xyz/openbmc_project/network/"); 1354e4588158SJishnu CM path /= ethifaceId; 1355e4588158SJishnu CM 1356e4588158SJishnu CM if (type == NetworkType::dhcp4) 1357e4588158SJishnu CM { 1358e4588158SJishnu CM path /= "dhcp4"; 13591847f2a0SAsmitha Karunanithi redfishPropertyName = "DHCPv4"; 1360e4588158SJishnu CM } 1361e4588158SJishnu CM else 1362e4588158SJishnu CM { 1363e4588158SJishnu CM path /= "dhcp6"; 13641847f2a0SAsmitha Karunanithi redfishPropertyName = "DHCPv6"; 1365e4588158SJishnu CM } 1366e4588158SJishnu CM 13671847f2a0SAsmitha Karunanithi setDbusProperty(asyncResp, "xyz.openbmc_project.Network", path, 13681847f2a0SAsmitha Karunanithi "xyz.openbmc_project.Network.DHCPConfiguration", 13691847f2a0SAsmitha Karunanithi propertyName, redfishPropertyName, value); 1370da131a9aSJennifer Lee } 1371d577665bSRatan Gupta 1372b10d8db0SRavi Teja inline void handleSLAACAutoConfigPatch( 1373b10d8db0SRavi Teja const std::string& ifaceId, bool ipv6AutoConfigEnabled, 1374b10d8db0SRavi Teja const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1375b10d8db0SRavi Teja { 1376b10d8db0SRavi Teja sdbusplus::message::object_path path("/xyz/openbmc_project/network"); 1377b10d8db0SRavi Teja path /= ifaceId; 13781847f2a0SAsmitha Karunanithi setDbusProperty(asyncResp, "xyz.openbmc_project.Network", path, 13791847f2a0SAsmitha Karunanithi "xyz.openbmc_project.Network.EthernetInterface", 13801847f2a0SAsmitha Karunanithi "IPv6AcceptRA", 13811847f2a0SAsmitha Karunanithi "StatelessAddressAutoConfig/IPv6AutoConfigEnabled", 13821847f2a0SAsmitha Karunanithi ipv6AutoConfigEnabled); 1383b10d8db0SRavi Teja } 1384b10d8db0SRavi Teja 13854f48d5f6SEd Tanous inline void handleDHCPPatch(const std::string& ifaceId, 13861f8c7b5dSJohnathan Mantey const EthernetInterfaceData& ethData, 1387f23b7296SEd Tanous const DHCPParameters& v4dhcpParms, 1388f23b7296SEd Tanous const DHCPParameters& v6dhcpParms, 13898d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1390da131a9aSJennifer Lee { 139182695a5bSJiaqing Zhao bool ipv4Active = translateDhcpEnabledToBool(ethData.dhcpEnabled, true); 139282695a5bSJiaqing Zhao bool ipv6Active = translateDhcpEnabledToBool(ethData.dhcpEnabled, false); 1393da131a9aSJennifer Lee 13941f8c7b5dSJohnathan Mantey bool nextv4DHCPState = 13951f8c7b5dSJohnathan Mantey v4dhcpParms.dhcpv4Enabled ? *v4dhcpParms.dhcpv4Enabled : ipv4Active; 13961f8c7b5dSJohnathan Mantey 13971f8c7b5dSJohnathan Mantey bool nextv6DHCPState{}; 13981f8c7b5dSJohnathan Mantey if (v6dhcpParms.dhcpv6OperatingMode) 1399da131a9aSJennifer Lee { 1400b10d8db0SRavi Teja if ((*v6dhcpParms.dhcpv6OperatingMode != "Enabled") && 14011f8c7b5dSJohnathan Mantey (*v6dhcpParms.dhcpv6OperatingMode != "Disabled")) 14021f8c7b5dSJohnathan Mantey { 1403bf648f77SEd Tanous messages::propertyValueFormatError(asyncResp->res, 1404bf648f77SEd Tanous *v6dhcpParms.dhcpv6OperatingMode, 14051f8c7b5dSJohnathan Mantey "OperatingMode"); 1406da131a9aSJennifer Lee return; 1407da131a9aSJennifer Lee } 1408b10d8db0SRavi Teja nextv6DHCPState = (*v6dhcpParms.dhcpv6OperatingMode == "Enabled"); 14091f8c7b5dSJohnathan Mantey } 14101f8c7b5dSJohnathan Mantey else 1411da131a9aSJennifer Lee { 14121f8c7b5dSJohnathan Mantey nextv6DHCPState = ipv6Active; 14131f8c7b5dSJohnathan Mantey } 14141f8c7b5dSJohnathan Mantey 1415e4588158SJishnu CM bool nextDNSv4 = ethData.dnsv4Enabled; 1416e4588158SJishnu CM bool nextDNSv6 = ethData.dnsv6Enabled; 1417e4588158SJishnu CM if (v4dhcpParms.useDnsServers) 14181f8c7b5dSJohnathan Mantey { 1419e4588158SJishnu CM nextDNSv4 = *v4dhcpParms.useDnsServers; 14201f8c7b5dSJohnathan Mantey } 1421e4588158SJishnu CM if (v6dhcpParms.useDnsServers) 14221f8c7b5dSJohnathan Mantey { 1423e4588158SJishnu CM nextDNSv6 = *v6dhcpParms.useDnsServers; 14241f8c7b5dSJohnathan Mantey } 14251f8c7b5dSJohnathan Mantey 1426e4588158SJishnu CM bool nextNTPv4 = ethData.ntpv4Enabled; 1427e4588158SJishnu CM bool nextNTPv6 = ethData.ntpv6Enabled; 1428e4588158SJishnu CM if (v4dhcpParms.useNtpServers) 14291f8c7b5dSJohnathan Mantey { 1430e4588158SJishnu CM nextNTPv4 = *v4dhcpParms.useNtpServers; 14311f8c7b5dSJohnathan Mantey } 1432e4588158SJishnu CM if (v6dhcpParms.useNtpServers) 14331f8c7b5dSJohnathan Mantey { 1434e4588158SJishnu CM nextNTPv6 = *v6dhcpParms.useNtpServers; 14351f8c7b5dSJohnathan Mantey } 14361f8c7b5dSJohnathan Mantey 143791c441ecSRavi Teja bool nextUsev4Domain = ethData.domainv4Enabled; 143891c441ecSRavi Teja bool nextUsev6Domain = ethData.domainv6Enabled; 1439e4588158SJishnu CM if (v4dhcpParms.useDomainName) 14401f8c7b5dSJohnathan Mantey { 1441e4588158SJishnu CM nextUsev4Domain = *v4dhcpParms.useDomainName; 14421f8c7b5dSJohnathan Mantey } 1443e4588158SJishnu CM if (v6dhcpParms.useDomainName) 14441f8c7b5dSJohnathan Mantey { 1445e4588158SJishnu CM nextUsev6Domain = *v6dhcpParms.useDomainName; 14461f8c7b5dSJohnathan Mantey } 14471f8c7b5dSJohnathan Mantey 144862598e31SEd Tanous BMCWEB_LOG_DEBUG("set DHCPEnabled..."); 14491f8c7b5dSJohnathan Mantey setDHCPEnabled(ifaceId, "DHCPEnabled", nextv4DHCPState, nextv6DHCPState, 14501f8c7b5dSJohnathan Mantey asyncResp); 145162598e31SEd Tanous BMCWEB_LOG_DEBUG("set DNSEnabled..."); 1452e4588158SJishnu CM setDHCPConfig("DNSEnabled", nextDNSv4, asyncResp, ifaceId, 1453e4588158SJishnu CM NetworkType::dhcp4); 145462598e31SEd Tanous BMCWEB_LOG_DEBUG("set NTPEnabled..."); 1455e4588158SJishnu CM setDHCPConfig("NTPEnabled", nextNTPv4, asyncResp, ifaceId, 1456e4588158SJishnu CM NetworkType::dhcp4); 145791c441ecSRavi Teja BMCWEB_LOG_DEBUG("set DomainEnabled..."); 145891c441ecSRavi Teja setDHCPConfig("DomainEnabled", nextUsev4Domain, asyncResp, ifaceId, 1459e4588158SJishnu CM NetworkType::dhcp4); 1460e4588158SJishnu CM BMCWEB_LOG_DEBUG("set DNSEnabled for dhcp6..."); 1461e4588158SJishnu CM setDHCPConfig("DNSEnabled", nextDNSv6, asyncResp, ifaceId, 1462e4588158SJishnu CM NetworkType::dhcp6); 1463e4588158SJishnu CM BMCWEB_LOG_DEBUG("set NTPEnabled for dhcp6..."); 1464e4588158SJishnu CM setDHCPConfig("NTPEnabled", nextNTPv6, asyncResp, ifaceId, 1465e4588158SJishnu CM NetworkType::dhcp6); 146691c441ecSRavi Teja BMCWEB_LOG_DEBUG("set DomainEnabled for dhcp6..."); 146791c441ecSRavi Teja setDHCPConfig("DomainEnabled", nextUsev6Domain, asyncResp, ifaceId, 1468e4588158SJishnu CM NetworkType::dhcp6); 1469da131a9aSJennifer Lee } 147001784826SJohnathan Mantey 147177179532SEd Tanous inline std::vector<IPv4AddressData>::const_iterator getNextStaticIpEntry( 147277179532SEd Tanous const std::vector<IPv4AddressData>::const_iterator& head, 147377179532SEd Tanous const std::vector<IPv4AddressData>::const_iterator& end) 147401784826SJohnathan Mantey { 147517a897dfSManojkiran Eda return std::find_if(head, end, [](const IPv4AddressData& value) { 147617a897dfSManojkiran Eda return value.origin == "Static"; 147717a897dfSManojkiran Eda }); 147801784826SJohnathan Mantey } 147901784826SJohnathan Mantey 148077179532SEd Tanous inline std::vector<IPv6AddressData>::const_iterator getNextStaticIpEntry( 148177179532SEd Tanous const std::vector<IPv6AddressData>::const_iterator& head, 148277179532SEd Tanous const std::vector<IPv6AddressData>::const_iterator& end) 148301784826SJohnathan Mantey { 148417a897dfSManojkiran Eda return std::find_if(head, end, [](const IPv6AddressData& value) { 148517a897dfSManojkiran Eda return value.origin == "Static"; 148617a897dfSManojkiran Eda }); 148701784826SJohnathan Mantey } 148801784826SJohnathan Mantey 14893dfed536SEd Tanous inline void handleIPv4StaticPatch( 14903dfed536SEd Tanous const std::string& ifaceId, 14913dfed536SEd Tanous std::vector<std::variant<nlohmann::json::object_t, std::nullptr_t>>& input, 149277179532SEd Tanous const std::vector<IPv4AddressData>& ipv4Data, 14938d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 14941abe55efSEd Tanous { 1495271584abSEd Tanous unsigned entryIdx = 1; 149601784826SJohnathan Mantey // Find the first static IP address currently active on the NIC and 149701784826SJohnathan Mantey // match it to the first JSON element in the IPv4StaticAddresses array. 149801784826SJohnathan Mantey // Match each subsequent JSON element to the next static IP programmed 149901784826SJohnathan Mantey // into the NIC. 150077179532SEd Tanous std::vector<IPv4AddressData>::const_iterator nicIpEntry = 15012c70f800SEd Tanous getNextStaticIpEntry(ipv4Data.cbegin(), ipv4Data.cend()); 150201784826SJohnathan Mantey 15033dfed536SEd Tanous for (std::variant<nlohmann::json::object_t, std::nullptr_t>& thisJson : 15043dfed536SEd Tanous input) 15051abe55efSEd Tanous { 150689492a15SPatrick Williams std::string pathString = "IPv4StaticAddresses/" + 150789492a15SPatrick Williams std::to_string(entryIdx); 15083dfed536SEd Tanous nlohmann::json::object_t* obj = 15093dfed536SEd Tanous std::get_if<nlohmann::json::object_t>(&thisJson); 15103dfed536SEd Tanous if (obj != nullptr && !obj->empty()) 1511f476acbfSRatan Gupta { 1512537174c4SEd Tanous std::optional<std::string> address; 1513537174c4SEd Tanous std::optional<std::string> subnetMask; 1514537174c4SEd Tanous std::optional<std::string> gateway; 1515537174c4SEd Tanous 15163dfed536SEd Tanous if (!json_util::readJsonObject(*obj, asyncResp->res, "Address", 15177e27d832SJohnathan Mantey address, "SubnetMask", subnetMask, 15187e27d832SJohnathan Mantey "Gateway", gateway)) 1519537174c4SEd Tanous { 15203dfed536SEd Tanous messages::propertyValueFormatError(asyncResp->res, *obj, 152171f52d96SEd Tanous pathString); 1522537174c4SEd Tanous return; 1523179db1d7SKowalski, Kamil } 1524179db1d7SKowalski, Kamil 152501784826SJohnathan Mantey // Find the address/subnet/gateway values. Any values that are 152601784826SJohnathan Mantey // not explicitly provided are assumed to be unmodified from the 152701784826SJohnathan Mantey // current state of the interface. Merge existing state into the 152801784826SJohnathan Mantey // current request. 1529537174c4SEd Tanous if (address) 15301abe55efSEd Tanous { 1531e01d0c36SEd Tanous if (!ip_util::ipv4VerifyIpAndGetBitcount(*address)) 153201784826SJohnathan Mantey { 1533bf648f77SEd Tanous messages::propertyValueFormatError(asyncResp->res, *address, 1534bf648f77SEd Tanous pathString + "/Address"); 1535e01d0c36SEd Tanous return; 153601784826SJohnathan Mantey } 153701784826SJohnathan Mantey } 153885ffe86aSJiaqing Zhao else if (nicIpEntry != ipv4Data.cend()) 153901784826SJohnathan Mantey { 1540e01d0c36SEd Tanous address = (nicIpEntry->address); 154101784826SJohnathan Mantey } 154201784826SJohnathan Mantey else 154301784826SJohnathan Mantey { 154401784826SJohnathan Mantey messages::propertyMissing(asyncResp->res, 154501784826SJohnathan Mantey pathString + "/Address"); 1546e01d0c36SEd Tanous return; 15474a0cb85cSEd Tanous } 15484a0cb85cSEd Tanous 1549e01d0c36SEd Tanous uint8_t prefixLength = 0; 1550537174c4SEd Tanous if (subnetMask) 15514a0cb85cSEd Tanous { 1552033f1e4dSEd Tanous if (!ip_util::ipv4VerifyIpAndGetBitcount(*subnetMask, 1553033f1e4dSEd Tanous &prefixLength)) 15544a0cb85cSEd Tanous { 1555f12894f8SJason M. Bills messages::propertyValueFormatError( 1556537174c4SEd Tanous asyncResp->res, *subnetMask, 15574a0cb85cSEd Tanous pathString + "/SubnetMask"); 1558e01d0c36SEd Tanous return; 15594a0cb85cSEd Tanous } 15604a0cb85cSEd Tanous } 156185ffe86aSJiaqing Zhao else if (nicIpEntry != ipv4Data.cend()) 15624a0cb85cSEd Tanous { 1563033f1e4dSEd Tanous if (!ip_util::ipv4VerifyIpAndGetBitcount(nicIpEntry->netmask, 156401784826SJohnathan Mantey &prefixLength)) 15654a0cb85cSEd Tanous { 156601784826SJohnathan Mantey messages::propertyValueFormatError( 156785ffe86aSJiaqing Zhao asyncResp->res, nicIpEntry->netmask, 156801784826SJohnathan Mantey pathString + "/SubnetMask"); 1569e01d0c36SEd Tanous return; 15704a0cb85cSEd Tanous } 15714a0cb85cSEd Tanous } 15721abe55efSEd Tanous else 15731abe55efSEd Tanous { 157401784826SJohnathan Mantey messages::propertyMissing(asyncResp->res, 157501784826SJohnathan Mantey pathString + "/SubnetMask"); 1576e01d0c36SEd Tanous return; 157701784826SJohnathan Mantey } 157801784826SJohnathan Mantey 157901784826SJohnathan Mantey if (gateway) 158001784826SJohnathan Mantey { 1581e01d0c36SEd Tanous if (!ip_util::ipv4VerifyIpAndGetBitcount(*gateway)) 158201784826SJohnathan Mantey { 1583bf648f77SEd Tanous messages::propertyValueFormatError(asyncResp->res, *gateway, 1584bf648f77SEd Tanous pathString + "/Gateway"); 1585e01d0c36SEd Tanous return; 158601784826SJohnathan Mantey } 158701784826SJohnathan Mantey } 158885ffe86aSJiaqing Zhao else if (nicIpEntry != ipv4Data.cend()) 158901784826SJohnathan Mantey { 1590e01d0c36SEd Tanous gateway = nicIpEntry->gateway; 159101784826SJohnathan Mantey } 159201784826SJohnathan Mantey else 15931abe55efSEd Tanous { 1594a08b46ccSJason M. Bills messages::propertyMissing(asyncResp->res, 15954a0cb85cSEd Tanous pathString + "/Gateway"); 159601784826SJohnathan Mantey return; 15974a0cb85cSEd Tanous } 15984a0cb85cSEd Tanous 159985ffe86aSJiaqing Zhao if (nicIpEntry != ipv4Data.cend()) 16001abe55efSEd Tanous { 16019c5e585cSRavi Teja deleteAndCreateIPAddress(IpVersion::IpV4, ifaceId, 160277eb0153SEd Tanous nicIpEntry->id, prefixLength, *address, 160377eb0153SEd Tanous *gateway, asyncResp); 160489492a15SPatrick Williams nicIpEntry = getNextStaticIpEntry(++nicIpEntry, 160589492a15SPatrick Williams ipv4Data.cend()); 1606588c3f0dSKowalski, Kamil } 160701784826SJohnathan Mantey else 160801784826SJohnathan Mantey { 1609cb13a392SEd Tanous createIPv4(ifaceId, prefixLength, *gateway, *address, 1610cb13a392SEd Tanous asyncResp); 16114a0cb85cSEd Tanous } 16124a0cb85cSEd Tanous entryIdx++; 16134a0cb85cSEd Tanous } 161401784826SJohnathan Mantey else 161501784826SJohnathan Mantey { 161685ffe86aSJiaqing Zhao if (nicIpEntry == ipv4Data.cend()) 161701784826SJohnathan Mantey { 161801784826SJohnathan Mantey // Requesting a DELETE/DO NOT MODIFY action for an item 161901784826SJohnathan Mantey // that isn't present on the eth(n) interface. Input JSON is 162001784826SJohnathan Mantey // in error, so bail out. 16213dfed536SEd Tanous if (obj == nullptr) 162201784826SJohnathan Mantey { 162301784826SJohnathan Mantey messages::resourceCannotBeDeleted(asyncResp->res); 162401784826SJohnathan Mantey return; 162501784826SJohnathan Mantey } 16263dfed536SEd Tanous messages::propertyValueFormatError(asyncResp->res, *obj, 162771f52d96SEd Tanous pathString); 162801784826SJohnathan Mantey return; 162901784826SJohnathan Mantey } 163001784826SJohnathan Mantey 16313dfed536SEd Tanous if (obj == nullptr) 163201784826SJohnathan Mantey { 16339c5e585cSRavi Teja deleteIPAddress(ifaceId, nicIpEntry->id, asyncResp); 163401784826SJohnathan Mantey } 163585ffe86aSJiaqing Zhao if (nicIpEntry != ipv4Data.cend()) 163601784826SJohnathan Mantey { 163789492a15SPatrick Williams nicIpEntry = getNextStaticIpEntry(++nicIpEntry, 163889492a15SPatrick Williams ipv4Data.cend()); 163901784826SJohnathan Mantey } 164001784826SJohnathan Mantey entryIdx++; 164101784826SJohnathan Mantey } 164201784826SJohnathan Mantey } 16434a0cb85cSEd Tanous } 16444a0cb85cSEd Tanous 16454f48d5f6SEd Tanous inline void handleStaticNameServersPatch( 1646f85837bfSRAJESWARAN THILLAIGOVINDAN const std::string& ifaceId, 1647f85837bfSRAJESWARAN THILLAIGOVINDAN const std::vector<std::string>& updatedStaticNameServers, 16488d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1649f85837bfSRAJESWARAN THILLAIGOVINDAN { 16501847f2a0SAsmitha Karunanithi setDbusProperty( 16511847f2a0SAsmitha Karunanithi asyncResp, "xyz.openbmc_project.Network", 16521847f2a0SAsmitha Karunanithi sdbusplus::message::object_path("/xyz/openbmc_project/network") / 16531847f2a0SAsmitha Karunanithi ifaceId, 16549ae226faSGeorge Liu "xyz.openbmc_project.Network.EthernetInterface", "StaticNameServers", 16551847f2a0SAsmitha Karunanithi "StaticNameServers", updatedStaticNameServers); 1656f85837bfSRAJESWARAN THILLAIGOVINDAN } 1657f85837bfSRAJESWARAN THILLAIGOVINDAN 16584f48d5f6SEd Tanous inline void handleIPv6StaticAddressesPatch( 16593dfed536SEd Tanous const std::string& ifaceId, 16603dfed536SEd Tanous std::vector<std::variant<nlohmann::json::object_t, std::nullptr_t>>& input, 166177179532SEd Tanous const std::vector<IPv6AddressData>& ipv6Data, 16628d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1663e48c0fc5SRavi Teja { 1664271584abSEd Tanous size_t entryIdx = 1; 166577179532SEd Tanous std::vector<IPv6AddressData>::const_iterator nicIpEntry = 16662c70f800SEd Tanous getNextStaticIpEntry(ipv6Data.cbegin(), ipv6Data.cend()); 16673dfed536SEd Tanous for (std::variant<nlohmann::json::object_t, std::nullptr_t>& thisJson : 16683dfed536SEd Tanous input) 1669e48c0fc5SRavi Teja { 167089492a15SPatrick Williams std::string pathString = "IPv6StaticAddresses/" + 167189492a15SPatrick Williams std::to_string(entryIdx); 16723dfed536SEd Tanous nlohmann::json::object_t* obj = 16733dfed536SEd Tanous std::get_if<nlohmann::json::object_t>(&thisJson); 16743dfed536SEd Tanous if (obj != nullptr && !obj->empty()) 1675e48c0fc5SRavi Teja { 1676e48c0fc5SRavi Teja std::optional<std::string> address; 1677e48c0fc5SRavi Teja std::optional<uint8_t> prefixLength; 16783dfed536SEd Tanous nlohmann::json::object_t thisJsonCopy = *obj; 16793dfed536SEd Tanous if (!json_util::readJsonObject(thisJsonCopy, asyncResp->res, 16803dfed536SEd Tanous "Address", address, "PrefixLength", 16813dfed536SEd Tanous prefixLength)) 1682e48c0fc5SRavi Teja { 16833dfed536SEd Tanous messages::propertyValueFormatError(asyncResp->res, thisJsonCopy, 168471f52d96SEd Tanous pathString); 1685e48c0fc5SRavi Teja return; 1686e48c0fc5SRavi Teja } 1687e48c0fc5SRavi Teja 168801784826SJohnathan Mantey // Find the address and prefixLength values. Any values that are 168901784826SJohnathan Mantey // not explicitly provided are assumed to be unmodified from the 169001784826SJohnathan Mantey // current state of the interface. Merge existing state into the 169101784826SJohnathan Mantey // current request. 1692d547d8d2SEd Tanous if (!address) 1693e48c0fc5SRavi Teja { 1694d547d8d2SEd Tanous if (nicIpEntry == ipv6Data.end()) 169501784826SJohnathan Mantey { 169601784826SJohnathan Mantey messages::propertyMissing(asyncResp->res, 169701784826SJohnathan Mantey pathString + "/Address"); 169801784826SJohnathan Mantey return; 1699e48c0fc5SRavi Teja } 1700d547d8d2SEd Tanous address = nicIpEntry->address; 1701d547d8d2SEd Tanous } 1702e48c0fc5SRavi Teja 1703d547d8d2SEd Tanous if (!prefixLength) 1704e48c0fc5SRavi Teja { 1705d547d8d2SEd Tanous if (nicIpEntry == ipv6Data.end()) 1706e48c0fc5SRavi Teja { 1707e48c0fc5SRavi Teja messages::propertyMissing(asyncResp->res, 1708e48c0fc5SRavi Teja pathString + "/PrefixLength"); 170901784826SJohnathan Mantey return; 1710e48c0fc5SRavi Teja } 1711d547d8d2SEd Tanous prefixLength = nicIpEntry->prefixLength; 1712d547d8d2SEd Tanous } 1713e48c0fc5SRavi Teja 171485ffe86aSJiaqing Zhao if (nicIpEntry != ipv6Data.end()) 1715e48c0fc5SRavi Teja { 17169c5e585cSRavi Teja deleteAndCreateIPAddress(IpVersion::IpV6, ifaceId, 1717d547d8d2SEd Tanous nicIpEntry->id, *prefixLength, 1718d547d8d2SEd Tanous *address, "", asyncResp); 171989492a15SPatrick Williams nicIpEntry = getNextStaticIpEntry(++nicIpEntry, 172089492a15SPatrick Williams ipv6Data.cend()); 172101784826SJohnathan Mantey } 172201784826SJohnathan Mantey else 172301784826SJohnathan Mantey { 1724d547d8d2SEd Tanous createIPv6(ifaceId, *prefixLength, *address, asyncResp); 1725e48c0fc5SRavi Teja } 1726e48c0fc5SRavi Teja entryIdx++; 1727e48c0fc5SRavi Teja } 172801784826SJohnathan Mantey else 172901784826SJohnathan Mantey { 173085ffe86aSJiaqing Zhao if (nicIpEntry == ipv6Data.end()) 173101784826SJohnathan Mantey { 173201784826SJohnathan Mantey // Requesting a DELETE/DO NOT MODIFY action for an item 173301784826SJohnathan Mantey // that isn't present on the eth(n) interface. Input JSON is 173401784826SJohnathan Mantey // in error, so bail out. 17353dfed536SEd Tanous if (obj == nullptr) 173601784826SJohnathan Mantey { 173701784826SJohnathan Mantey messages::resourceCannotBeDeleted(asyncResp->res); 173801784826SJohnathan Mantey return; 173901784826SJohnathan Mantey } 17403dfed536SEd Tanous messages::propertyValueFormatError(asyncResp->res, *obj, 174171f52d96SEd Tanous pathString); 174201784826SJohnathan Mantey return; 174301784826SJohnathan Mantey } 174401784826SJohnathan Mantey 17453dfed536SEd Tanous if (obj == nullptr) 174601784826SJohnathan Mantey { 17479c5e585cSRavi Teja deleteIPAddress(ifaceId, nicIpEntry->id, asyncResp); 174801784826SJohnathan Mantey } 174985ffe86aSJiaqing Zhao if (nicIpEntry != ipv6Data.cend()) 175001784826SJohnathan Mantey { 175189492a15SPatrick Williams nicIpEntry = getNextStaticIpEntry(++nicIpEntry, 175289492a15SPatrick Williams ipv6Data.cend()); 175301784826SJohnathan Mantey } 175401784826SJohnathan Mantey entryIdx++; 175501784826SJohnathan Mantey } 175601784826SJohnathan Mantey } 1757e48c0fc5SRavi Teja } 1758e48c0fc5SRavi Teja 17597857cb8dSJiaqing Zhao inline std::string extractParentInterfaceName(const std::string& ifaceId) 17607857cb8dSJiaqing Zhao { 17617857cb8dSJiaqing Zhao std::size_t pos = ifaceId.find('_'); 17627857cb8dSJiaqing Zhao return ifaceId.substr(0, pos); 17637857cb8dSJiaqing Zhao } 17647857cb8dSJiaqing Zhao 176577179532SEd Tanous inline void 176677179532SEd Tanous parseInterfaceData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 176777179532SEd Tanous const std::string& ifaceId, 176877179532SEd Tanous const EthernetInterfaceData& ethData, 176977179532SEd Tanous const std::vector<IPv4AddressData>& ipv4Data, 1770ce73d5c8SSunitha Harish const std::vector<IPv6AddressData>& ipv6Data, 1771ce73d5c8SSunitha Harish const std::vector<StaticGatewayData>& ipv6GatewayData) 17724a0cb85cSEd Tanous { 17732c70f800SEd Tanous nlohmann::json& jsonResponse = asyncResp->res.jsonValue; 177481ce609eSEd Tanous jsonResponse["Id"] = ifaceId; 1775ef4c65b7SEd Tanous jsonResponse["@odata.id"] = boost::urls::format( 1776ef4c65b7SEd Tanous "/redfish/v1/Managers/bmc/EthernetInterfaces/{}", ifaceId); 17772c70f800SEd Tanous jsonResponse["InterfaceEnabled"] = ethData.nicEnabled; 1778eeedda23SJohnathan Mantey 1779eeedda23SJohnathan Mantey if (ethData.nicEnabled) 1780eeedda23SJohnathan Mantey { 17810ef0e289SJohnathan Mantey jsonResponse["LinkStatus"] = ethData.linkUp ? "LinkUp" : "LinkDown"; 17822c70f800SEd Tanous jsonResponse["Status"]["State"] = "Enabled"; 1783029573d4SEd Tanous } 1784029573d4SEd Tanous else 1785029573d4SEd Tanous { 17862c70f800SEd Tanous jsonResponse["LinkStatus"] = "NoLink"; 17872c70f800SEd Tanous jsonResponse["Status"]["State"] = "Disabled"; 1788029573d4SEd Tanous } 1789aa05fb27SJohnathan Mantey 17902c70f800SEd Tanous jsonResponse["SpeedMbps"] = ethData.speed; 179135fb5311STejas Patil jsonResponse["MTUSize"] = ethData.mtuSize; 179282695a5bSJiaqing Zhao jsonResponse["MACAddress"] = ethData.macAddress; 17932c70f800SEd Tanous jsonResponse["DHCPv4"]["DHCPEnabled"] = 179482695a5bSJiaqing Zhao translateDhcpEnabledToBool(ethData.dhcpEnabled, true); 1795e4588158SJishnu CM jsonResponse["DHCPv4"]["UseNTPServers"] = ethData.ntpv4Enabled; 1796e4588158SJishnu CM jsonResponse["DHCPv4"]["UseDNSServers"] = ethData.dnsv4Enabled; 1797e4588158SJishnu CM jsonResponse["DHCPv4"]["UseDomainName"] = ethData.hostNamev4Enabled; 17982c70f800SEd Tanous jsonResponse["DHCPv6"]["OperatingMode"] = 1799b10d8db0SRavi Teja translateDhcpEnabledToBool(ethData.dhcpEnabled, false) ? "Enabled" 18001f8c7b5dSJohnathan Mantey : "Disabled"; 1801e4588158SJishnu CM jsonResponse["DHCPv6"]["UseNTPServers"] = ethData.ntpv6Enabled; 1802e4588158SJishnu CM jsonResponse["DHCPv6"]["UseDNSServers"] = ethData.dnsv6Enabled; 1803e4588158SJishnu CM jsonResponse["DHCPv6"]["UseDomainName"] = ethData.hostNamev6Enabled; 1804b10d8db0SRavi Teja jsonResponse["StatelessAddressAutoConfig"]["IPv6AutoConfigEnabled"] = 1805b10d8db0SRavi Teja ethData.ipv6AcceptRa; 18062a133282Smanojkiraneda 180782695a5bSJiaqing Zhao if (!ethData.hostName.empty()) 18084a0cb85cSEd Tanous { 180982695a5bSJiaqing Zhao jsonResponse["HostName"] = ethData.hostName; 1810ab6554f1SJoshi-Mansi 1811ab6554f1SJoshi-Mansi // When domain name is empty then it means, that it is a network 1812ab6554f1SJoshi-Mansi // without domain names, and the host name itself must be treated as 1813ab6554f1SJoshi-Mansi // FQDN 181482695a5bSJiaqing Zhao std::string fqdn = ethData.hostName; 1815d24bfc7aSJennifer Lee if (!ethData.domainnames.empty()) 1816d24bfc7aSJennifer Lee { 18172c70f800SEd Tanous fqdn += "." + ethData.domainnames[0]; 1818d24bfc7aSJennifer Lee } 18192c70f800SEd Tanous jsonResponse["FQDN"] = fqdn; 18204a0cb85cSEd Tanous } 18214a0cb85cSEd Tanous 18227857cb8dSJiaqing Zhao if (ethData.vlanId) 18237857cb8dSJiaqing Zhao { 18247857cb8dSJiaqing Zhao jsonResponse["EthernetInterfaceType"] = "Virtual"; 18257857cb8dSJiaqing Zhao jsonResponse["VLAN"]["VLANEnable"] = true; 18267857cb8dSJiaqing Zhao jsonResponse["VLAN"]["VLANId"] = *ethData.vlanId; 18277857cb8dSJiaqing Zhao jsonResponse["VLAN"]["Tagged"] = true; 18287857cb8dSJiaqing Zhao 18297857cb8dSJiaqing Zhao nlohmann::json::array_t relatedInterfaces; 18307857cb8dSJiaqing Zhao nlohmann::json& parentInterface = relatedInterfaces.emplace_back(); 18317857cb8dSJiaqing Zhao parentInterface["@odata.id"] = 18327857cb8dSJiaqing Zhao boost::urls::format("/redfish/v1/Managers/bmc/EthernetInterfaces", 18337857cb8dSJiaqing Zhao extractParentInterfaceName(ifaceId)); 18347857cb8dSJiaqing Zhao jsonResponse["Links"]["RelatedInterfaces"] = 18357857cb8dSJiaqing Zhao std::move(relatedInterfaces); 18367857cb8dSJiaqing Zhao } 18377857cb8dSJiaqing Zhao else 18387857cb8dSJiaqing Zhao { 18397857cb8dSJiaqing Zhao jsonResponse["EthernetInterfaceType"] = "Physical"; 18407857cb8dSJiaqing Zhao } 18417857cb8dSJiaqing Zhao 18422c70f800SEd Tanous jsonResponse["NameServers"] = ethData.nameServers; 18432c70f800SEd Tanous jsonResponse["StaticNameServers"] = ethData.staticNameServers; 18444a0cb85cSEd Tanous 18452c70f800SEd Tanous nlohmann::json& ipv4Array = jsonResponse["IPv4Addresses"]; 18462c70f800SEd Tanous nlohmann::json& ipv4StaticArray = jsonResponse["IPv4StaticAddresses"]; 18472c70f800SEd Tanous ipv4Array = nlohmann::json::array(); 18482c70f800SEd Tanous ipv4StaticArray = nlohmann::json::array(); 18499eb808c1SEd Tanous for (const auto& ipv4Config : ipv4Data) 18504a0cb85cSEd Tanous { 18512c70f800SEd Tanous std::string gatewayStr = ipv4Config.gateway; 1852fa5053a6SGunnar Mills if (gatewayStr.empty()) 1853fa5053a6SGunnar Mills { 1854fa5053a6SGunnar Mills gatewayStr = "0.0.0.0"; 1855fa5053a6SGunnar Mills } 18561476687dSEd Tanous nlohmann::json::object_t ipv4; 18571476687dSEd Tanous ipv4["AddressOrigin"] = ipv4Config.origin; 18581476687dSEd Tanous ipv4["SubnetMask"] = ipv4Config.netmask; 18591476687dSEd Tanous ipv4["Address"] = ipv4Config.address; 18601476687dSEd Tanous ipv4["Gateway"] = gatewayStr; 1861fa5053a6SGunnar Mills 18622c70f800SEd Tanous if (ipv4Config.origin == "Static") 1863d1d50814SRavi Teja { 18641476687dSEd Tanous ipv4StaticArray.push_back(ipv4); 1865d1d50814SRavi Teja } 18661476687dSEd Tanous 1867b2ba3072SPatrick Williams ipv4Array.emplace_back(std::move(ipv4)); 186801784826SJohnathan Mantey } 1869d1d50814SRavi Teja 187082695a5bSJiaqing Zhao std::string ipv6GatewayStr = ethData.ipv6DefaultGateway; 18717ea79e5eSRavi Teja if (ipv6GatewayStr.empty()) 18727ea79e5eSRavi Teja { 18737ea79e5eSRavi Teja ipv6GatewayStr = "0:0:0:0:0:0:0:0"; 18747ea79e5eSRavi Teja } 18757ea79e5eSRavi Teja 18767ea79e5eSRavi Teja jsonResponse["IPv6DefaultGateway"] = ipv6GatewayStr; 1877e48c0fc5SRavi Teja 1878ce73d5c8SSunitha Harish nlohmann::json::array_t ipv6StaticGatewayArray; 1879ce73d5c8SSunitha Harish for (const auto& ipv6GatewayConfig : ipv6GatewayData) 1880ce73d5c8SSunitha Harish { 1881ce73d5c8SSunitha Harish nlohmann::json::object_t ipv6Gateway; 1882ce73d5c8SSunitha Harish ipv6Gateway["Address"] = ipv6GatewayConfig.gateway; 1883ce73d5c8SSunitha Harish ipv6Gateway["PrefixLength"] = ipv6GatewayConfig.prefixLength; 1884ce73d5c8SSunitha Harish ipv6StaticGatewayArray.emplace_back(std::move(ipv6Gateway)); 1885ce73d5c8SSunitha Harish } 1886ce73d5c8SSunitha Harish jsonResponse["IPv6StaticDefaultGateways"] = 1887ce73d5c8SSunitha Harish std::move(ipv6StaticGatewayArray); 1888ce73d5c8SSunitha Harish 18892c70f800SEd Tanous nlohmann::json& ipv6Array = jsonResponse["IPv6Addresses"]; 18902c70f800SEd Tanous nlohmann::json& ipv6StaticArray = jsonResponse["IPv6StaticAddresses"]; 18912c70f800SEd Tanous ipv6Array = nlohmann::json::array(); 18922c70f800SEd Tanous ipv6StaticArray = nlohmann::json::array(); 18937f2e23e9SJohnathan Mantey nlohmann::json& ipv6AddrPolicyTable = 18942c70f800SEd Tanous jsonResponse["IPv6AddressPolicyTable"]; 18957f2e23e9SJohnathan Mantey ipv6AddrPolicyTable = nlohmann::json::array(); 18969eb808c1SEd Tanous for (const auto& ipv6Config : ipv6Data) 1897e48c0fc5SRavi Teja { 18981476687dSEd Tanous nlohmann::json::object_t ipv6; 18991476687dSEd Tanous ipv6["Address"] = ipv6Config.address; 19001476687dSEd Tanous ipv6["PrefixLength"] = ipv6Config.prefixLength; 19011476687dSEd Tanous ipv6["AddressOrigin"] = ipv6Config.origin; 1902f8361275SSunitha Harish 1903b2ba3072SPatrick Williams ipv6Array.emplace_back(std::move(ipv6)); 19042c70f800SEd Tanous if (ipv6Config.origin == "Static") 1905e48c0fc5SRavi Teja { 19061476687dSEd Tanous nlohmann::json::object_t ipv6Static; 19071476687dSEd Tanous ipv6Static["Address"] = ipv6Config.address; 19081476687dSEd Tanous ipv6Static["PrefixLength"] = ipv6Config.prefixLength; 1909b2ba3072SPatrick Williams ipv6StaticArray.emplace_back(std::move(ipv6Static)); 191001784826SJohnathan Mantey } 1911e48c0fc5SRavi Teja } 1912588c3f0dSKowalski, Kamil } 1913588c3f0dSKowalski, Kamil 1914e7caf250SJiaqing Zhao inline void afterDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1915e7caf250SJiaqing Zhao const std::string& ifaceId, 1916e7caf250SJiaqing Zhao const boost::system::error_code& ec, 1917e7caf250SJiaqing Zhao const sdbusplus::message_t& m) 1918e7caf250SJiaqing Zhao { 1919e7caf250SJiaqing Zhao if (!ec) 1920e7caf250SJiaqing Zhao { 1921e7caf250SJiaqing Zhao return; 1922e7caf250SJiaqing Zhao } 1923e7caf250SJiaqing Zhao const sd_bus_error* dbusError = m.get_error(); 1924e7caf250SJiaqing Zhao if (dbusError == nullptr) 1925e7caf250SJiaqing Zhao { 1926e7caf250SJiaqing Zhao messages::internalError(asyncResp->res); 1927e7caf250SJiaqing Zhao return; 1928e7caf250SJiaqing Zhao } 192962598e31SEd Tanous BMCWEB_LOG_DEBUG("DBus error: {}", dbusError->name); 1930e7caf250SJiaqing Zhao 1931e7caf250SJiaqing Zhao if (std::string_view("org.freedesktop.DBus.Error.UnknownObject") == 1932e7caf250SJiaqing Zhao dbusError->name) 1933e7caf250SJiaqing Zhao { 1934e7caf250SJiaqing Zhao messages::resourceNotFound(asyncResp->res, "EthernetInterface", 1935e7caf250SJiaqing Zhao ifaceId); 1936e7caf250SJiaqing Zhao return; 1937e7caf250SJiaqing Zhao } 1938e7caf250SJiaqing Zhao if (std::string_view("org.freedesktop.DBus.Error.UnknownMethod") == 1939e7caf250SJiaqing Zhao dbusError->name) 1940e7caf250SJiaqing Zhao { 1941e7caf250SJiaqing Zhao messages::resourceCannotBeDeleted(asyncResp->res); 1942e7caf250SJiaqing Zhao return; 1943e7caf250SJiaqing Zhao } 1944e7caf250SJiaqing Zhao messages::internalError(asyncResp->res); 1945e7caf250SJiaqing Zhao } 1946e7caf250SJiaqing Zhao 1947b5ca3fdcSJiaqing Zhao inline void afterVlanCreate(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1948b5ca3fdcSJiaqing Zhao const std::string& parentInterfaceUri, 1949b5ca3fdcSJiaqing Zhao const std::string& vlanInterface, 1950b5ca3fdcSJiaqing Zhao const boost::system::error_code& ec, 1951b5ca3fdcSJiaqing Zhao const sdbusplus::message_t& m 1952b5ca3fdcSJiaqing Zhao 1953b5ca3fdcSJiaqing Zhao ) 1954b5ca3fdcSJiaqing Zhao { 1955b5ca3fdcSJiaqing Zhao if (ec) 1956b5ca3fdcSJiaqing Zhao { 1957b5ca3fdcSJiaqing Zhao const sd_bus_error* dbusError = m.get_error(); 1958b5ca3fdcSJiaqing Zhao if (dbusError == nullptr) 1959b5ca3fdcSJiaqing Zhao { 1960b5ca3fdcSJiaqing Zhao messages::internalError(asyncResp->res); 1961b5ca3fdcSJiaqing Zhao return; 1962b5ca3fdcSJiaqing Zhao } 196362598e31SEd Tanous BMCWEB_LOG_DEBUG("DBus error: {}", dbusError->name); 1964b5ca3fdcSJiaqing Zhao 1965b5ca3fdcSJiaqing Zhao if (std::string_view( 1966b5ca3fdcSJiaqing Zhao "xyz.openbmc_project.Common.Error.ResourceNotFound") == 1967b5ca3fdcSJiaqing Zhao dbusError->name) 1968b5ca3fdcSJiaqing Zhao { 1969b5ca3fdcSJiaqing Zhao messages::propertyValueNotInList( 1970b5ca3fdcSJiaqing Zhao asyncResp->res, parentInterfaceUri, 1971b5ca3fdcSJiaqing Zhao "Links/RelatedInterfaces/0/@odata.id"); 1972b5ca3fdcSJiaqing Zhao return; 1973b5ca3fdcSJiaqing Zhao } 1974b5ca3fdcSJiaqing Zhao if (std::string_view( 1975b5ca3fdcSJiaqing Zhao "xyz.openbmc_project.Common.Error.InvalidArgument") == 1976b5ca3fdcSJiaqing Zhao dbusError->name) 1977b5ca3fdcSJiaqing Zhao { 1978b5ca3fdcSJiaqing Zhao messages::resourceAlreadyExists(asyncResp->res, "EthernetInterface", 1979b5ca3fdcSJiaqing Zhao "Id", vlanInterface); 1980b5ca3fdcSJiaqing Zhao return; 1981b5ca3fdcSJiaqing Zhao } 1982b5ca3fdcSJiaqing Zhao messages::internalError(asyncResp->res); 1983b5ca3fdcSJiaqing Zhao return; 1984b5ca3fdcSJiaqing Zhao } 1985b5ca3fdcSJiaqing Zhao 1986b5ca3fdcSJiaqing Zhao const boost::urls::url vlanInterfaceUri = boost::urls::format( 1987b5ca3fdcSJiaqing Zhao "/redfish/v1/Managers/bmc/EthernetInterfaces/{}", vlanInterface); 1988b5ca3fdcSJiaqing Zhao asyncResp->res.addHeader("Location", vlanInterfaceUri.buffer()); 1989b5ca3fdcSJiaqing Zhao } 1990b5ca3fdcSJiaqing Zhao 1991bf648f77SEd Tanous inline void requestEthernetInterfacesRoutes(App& app) 1992bf648f77SEd Tanous { 1993bf648f77SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/") 1994ed398213SEd Tanous .privileges(redfish::privileges::getEthernetInterfaceCollection) 19951476687dSEd Tanous .methods(boost::beast::http::verb::get)( 19961476687dSEd Tanous [&app](const crow::Request& req, 19971476687dSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 19983ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 199945ca1b86SEd Tanous { 200045ca1b86SEd Tanous return; 200145ca1b86SEd Tanous } 200245ca1b86SEd Tanous 2003bf648f77SEd Tanous asyncResp->res.jsonValue["@odata.type"] = 2004bf648f77SEd Tanous "#EthernetInterfaceCollection.EthernetInterfaceCollection"; 2005bf648f77SEd Tanous asyncResp->res.jsonValue["@odata.id"] = 2006bf648f77SEd Tanous "/redfish/v1/Managers/bmc/EthernetInterfaces"; 2007bf648f77SEd Tanous asyncResp->res.jsonValue["Name"] = 2008bf648f77SEd Tanous "Ethernet Network Interface Collection"; 2009bf648f77SEd Tanous asyncResp->res.jsonValue["Description"] = 2010bf648f77SEd Tanous "Collection of EthernetInterfaces for this Manager"; 2011bf648f77SEd Tanous 2012bf648f77SEd Tanous // Get eth interface list, and call the below callback for JSON 2013bf648f77SEd Tanous // preparation 2014002d39b4SEd Tanous getEthernetIfaceList( 201577179532SEd Tanous [asyncResp](const bool& success, 201677179532SEd Tanous const std::vector<std::string>& ifaceList) { 2017bf648f77SEd Tanous if (!success) 20181abe55efSEd Tanous { 2019f12894f8SJason M. Bills messages::internalError(asyncResp->res); 20209391bb9cSRapkiewicz, Pawel return; 20219391bb9cSRapkiewicz, Pawel } 20229391bb9cSRapkiewicz, Pawel 2023002d39b4SEd Tanous nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"]; 2024bf648f77SEd Tanous ifaceArray = nlohmann::json::array(); 2025bf648f77SEd Tanous for (const std::string& ifaceItem : ifaceList) 2026bf648f77SEd Tanous { 20271476687dSEd Tanous nlohmann::json::object_t iface; 2028ef4c65b7SEd Tanous iface["@odata.id"] = boost::urls::format( 2029ef4c65b7SEd Tanous "/redfish/v1/Managers/bmc/EthernetInterfaces/{}", 2030ef4c65b7SEd Tanous ifaceItem); 20317857cb8dSJiaqing Zhao ifaceArray.push_back(std::move(iface)); 2032bf648f77SEd Tanous } 2033bf648f77SEd Tanous 2034002d39b4SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = ifaceArray.size(); 2035bf648f77SEd Tanous asyncResp->res.jsonValue["@odata.id"] = 2036bf648f77SEd Tanous "/redfish/v1/Managers/bmc/EthernetInterfaces"; 2037bf648f77SEd Tanous }); 2038bf648f77SEd Tanous }); 2039bf648f77SEd Tanous 2040b5ca3fdcSJiaqing Zhao BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/") 2041b5ca3fdcSJiaqing Zhao .privileges(redfish::privileges::postEthernetInterfaceCollection) 2042b5ca3fdcSJiaqing Zhao .methods(boost::beast::http::verb::post)( 2043b5ca3fdcSJiaqing Zhao [&app](const crow::Request& req, 2044b5ca3fdcSJiaqing Zhao const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 2045b5ca3fdcSJiaqing Zhao if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2046b5ca3fdcSJiaqing Zhao { 2047b5ca3fdcSJiaqing Zhao return; 2048b5ca3fdcSJiaqing Zhao } 2049b5ca3fdcSJiaqing Zhao 2050b5ca3fdcSJiaqing Zhao bool vlanEnable = false; 2051b5ca3fdcSJiaqing Zhao uint32_t vlanId = 0; 20523dfed536SEd Tanous std::vector<nlohmann::json::object_t> relatedInterfaces; 2053b5ca3fdcSJiaqing Zhao 2054b5ca3fdcSJiaqing Zhao if (!json_util::readJsonPatch(req, asyncResp->res, "VLAN/VLANEnable", 2055b5ca3fdcSJiaqing Zhao vlanEnable, "VLAN/VLANId", vlanId, 2056b5ca3fdcSJiaqing Zhao "Links/RelatedInterfaces", 2057b5ca3fdcSJiaqing Zhao relatedInterfaces)) 2058b5ca3fdcSJiaqing Zhao { 2059b5ca3fdcSJiaqing Zhao return; 2060b5ca3fdcSJiaqing Zhao } 2061b5ca3fdcSJiaqing Zhao 2062b5ca3fdcSJiaqing Zhao if (relatedInterfaces.size() != 1) 2063b5ca3fdcSJiaqing Zhao { 2064b5ca3fdcSJiaqing Zhao messages::arraySizeTooLong(asyncResp->res, 2065b5ca3fdcSJiaqing Zhao "Links/RelatedInterfaces", 2066b5ca3fdcSJiaqing Zhao relatedInterfaces.size()); 2067b5ca3fdcSJiaqing Zhao return; 2068b5ca3fdcSJiaqing Zhao } 2069b5ca3fdcSJiaqing Zhao 2070b5ca3fdcSJiaqing Zhao std::string parentInterfaceUri; 20713dfed536SEd Tanous if (!json_util::readJsonObject(relatedInterfaces[0], asyncResp->res, 2072b5ca3fdcSJiaqing Zhao "@odata.id", parentInterfaceUri)) 2073b5ca3fdcSJiaqing Zhao { 2074b5ca3fdcSJiaqing Zhao messages::propertyMissing(asyncResp->res, 2075b5ca3fdcSJiaqing Zhao "Links/RelatedInterfaces/0/@odata.id"); 2076b5ca3fdcSJiaqing Zhao return; 2077b5ca3fdcSJiaqing Zhao } 207862598e31SEd Tanous BMCWEB_LOG_INFO("Parent Interface URI: {}", parentInterfaceUri); 2079b5ca3fdcSJiaqing Zhao 20806fd29553SEd Tanous boost::system::result<boost::urls::url_view> parsedUri = 2081b5ca3fdcSJiaqing Zhao boost::urls::parse_relative_ref(parentInterfaceUri); 2082b5ca3fdcSJiaqing Zhao if (!parsedUri) 2083b5ca3fdcSJiaqing Zhao { 2084b5ca3fdcSJiaqing Zhao messages::propertyValueFormatError( 2085b5ca3fdcSJiaqing Zhao asyncResp->res, parentInterfaceUri, 2086b5ca3fdcSJiaqing Zhao "Links/RelatedInterfaces/0/@odata.id"); 2087b5ca3fdcSJiaqing Zhao return; 2088b5ca3fdcSJiaqing Zhao } 2089b5ca3fdcSJiaqing Zhao 2090b5ca3fdcSJiaqing Zhao std::string parentInterface; 2091b5ca3fdcSJiaqing Zhao if (!crow::utility::readUrlSegments( 2092b5ca3fdcSJiaqing Zhao *parsedUri, "redfish", "v1", "Managers", "bmc", 2093b5ca3fdcSJiaqing Zhao "EthernetInterfaces", std::ref(parentInterface))) 2094b5ca3fdcSJiaqing Zhao { 2095b5ca3fdcSJiaqing Zhao messages::propertyValueNotInList( 2096b5ca3fdcSJiaqing Zhao asyncResp->res, parentInterfaceUri, 2097b5ca3fdcSJiaqing Zhao "Links/RelatedInterfaces/0/@odata.id"); 2098b5ca3fdcSJiaqing Zhao return; 2099b5ca3fdcSJiaqing Zhao } 2100b5ca3fdcSJiaqing Zhao 2101b5ca3fdcSJiaqing Zhao if (!vlanEnable) 2102b5ca3fdcSJiaqing Zhao { 2103b5ca3fdcSJiaqing Zhao // In OpenBMC implementation, VLANEnable cannot be false on 2104b5ca3fdcSJiaqing Zhao // create 2105b5ca3fdcSJiaqing Zhao messages::propertyValueIncorrect(asyncResp->res, "VLAN/VLANEnable", 2106b5ca3fdcSJiaqing Zhao "false"); 2107b5ca3fdcSJiaqing Zhao return; 2108b5ca3fdcSJiaqing Zhao } 2109b5ca3fdcSJiaqing Zhao 2110b5ca3fdcSJiaqing Zhao std::string vlanInterface = parentInterface + "_" + 2111b5ca3fdcSJiaqing Zhao std::to_string(vlanId); 2112b5ca3fdcSJiaqing Zhao crow::connections::systemBus->async_method_call( 2113b5ca3fdcSJiaqing Zhao [asyncResp, parentInterfaceUri, 2114b5ca3fdcSJiaqing Zhao vlanInterface](const boost::system::error_code& ec, 2115b5ca3fdcSJiaqing Zhao const sdbusplus::message_t& m) { 2116b5ca3fdcSJiaqing Zhao afterVlanCreate(asyncResp, parentInterfaceUri, vlanInterface, ec, 2117b5ca3fdcSJiaqing Zhao m); 2118b5ca3fdcSJiaqing Zhao }, 2119b5ca3fdcSJiaqing Zhao "xyz.openbmc_project.Network", "/xyz/openbmc_project/network", 2120b5ca3fdcSJiaqing Zhao "xyz.openbmc_project.Network.VLAN.Create", "VLAN", parentInterface, 2121b5ca3fdcSJiaqing Zhao vlanId); 2122b5ca3fdcSJiaqing Zhao }); 2123b5ca3fdcSJiaqing Zhao 2124bf648f77SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/") 2125ed398213SEd Tanous .privileges(redfish::privileges::getEthernetInterface) 2126bf648f77SEd Tanous .methods(boost::beast::http::verb::get)( 212745ca1b86SEd Tanous [&app](const crow::Request& req, 2128bf648f77SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2129bf648f77SEd Tanous const std::string& ifaceId) { 21303ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 213145ca1b86SEd Tanous { 213245ca1b86SEd Tanous return; 213345ca1b86SEd Tanous } 21344a0cb85cSEd Tanous getEthernetIfaceData( 2135bf648f77SEd Tanous ifaceId, 2136ce73d5c8SSunitha Harish [asyncResp, 2137ce73d5c8SSunitha Harish ifaceId](const bool& success, const EthernetInterfaceData& ethData, 213877179532SEd Tanous const std::vector<IPv4AddressData>& ipv4Data, 2139ce73d5c8SSunitha Harish const std::vector<IPv6AddressData>& ipv6Data, 2140ce73d5c8SSunitha Harish const std::vector<StaticGatewayData>& ipv6GatewayData) { 21414a0cb85cSEd Tanous if (!success) 21421abe55efSEd Tanous { 2143bf648f77SEd Tanous // TODO(Pawel)consider distinguish between non 2144bf648f77SEd Tanous // existing object, and other errors 2145002d39b4SEd Tanous messages::resourceNotFound(asyncResp->res, "EthernetInterface", 2146002d39b4SEd Tanous ifaceId); 21474a0cb85cSEd Tanous return; 21489391bb9cSRapkiewicz, Pawel } 21494c9afe43SEd Tanous 21500f74e643SEd Tanous asyncResp->res.jsonValue["@odata.type"] = 215193bbc953SJiaqing Zhao "#EthernetInterface.v1_9_0.EthernetInterface"; 2152002d39b4SEd Tanous asyncResp->res.jsonValue["Name"] = "Manager Ethernet Interface"; 21530f74e643SEd Tanous asyncResp->res.jsonValue["Description"] = 21540f74e643SEd Tanous "Management Network Interface"; 21550f74e643SEd Tanous 2156ce73d5c8SSunitha Harish parseInterfaceData(asyncResp, ifaceId, ethData, ipv4Data, ipv6Data, 2157ce73d5c8SSunitha Harish ipv6GatewayData); 21589391bb9cSRapkiewicz, Pawel }); 2159bf648f77SEd Tanous }); 21609391bb9cSRapkiewicz, Pawel 2161bf648f77SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/") 2162ed398213SEd Tanous .privileges(redfish::privileges::patchEthernetInterface) 2163bf648f77SEd Tanous .methods(boost::beast::http::verb::patch)( 216445ca1b86SEd Tanous [&app](const crow::Request& req, 2165bf648f77SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2166bf648f77SEd Tanous const std::string& ifaceId) { 21673ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 216845ca1b86SEd Tanous { 216945ca1b86SEd Tanous return; 217045ca1b86SEd Tanous } 2171bc0bd6e0SEd Tanous std::optional<std::string> hostname; 2172ab6554f1SJoshi-Mansi std::optional<std::string> fqdn; 2173d577665bSRatan Gupta std::optional<std::string> macAddress; 21749a6fc6feSRavi Teja std::optional<std::string> ipv6DefaultGateway; 21753dfed536SEd Tanous std::optional< 21763dfed536SEd Tanous std::vector<std::variant<nlohmann::json::object_t, std::nullptr_t>>> 21773dfed536SEd Tanous ipv4StaticAddresses; 21783dfed536SEd Tanous std::optional< 21793dfed536SEd Tanous std::vector<std::variant<nlohmann::json::object_t, std::nullptr_t>>> 21803dfed536SEd Tanous ipv6StaticAddresses; 21813dfed536SEd Tanous std::optional< 21823dfed536SEd Tanous std::vector<std::variant<nlohmann::json::object_t, std::nullptr_t>>> 21833dfed536SEd Tanous ipv6StaticDefaultGateways; 2184f85837bfSRAJESWARAN THILLAIGOVINDAN std::optional<std::vector<std::string>> staticNameServers; 2185b10d8db0SRavi Teja std::optional<bool> ipv6AutoConfigEnabled; 2186eeedda23SJohnathan Mantey std::optional<bool> interfaceEnabled; 218735fb5311STejas Patil std::optional<size_t> mtuSize; 21881f8c7b5dSJohnathan Mantey DHCPParameters v4dhcpParms; 21891f8c7b5dSJohnathan Mantey DHCPParameters v6dhcpParms; 2190b10d8db0SRavi Teja // clang-format off 21913dfed536SEd Tanous if (!json_util::readJsonPatch(req, asyncResp->res, 21923dfed536SEd Tanous "DHCPv4/DHCPEnabled", v4dhcpParms.dhcpv4Enabled, 21933dfed536SEd Tanous "DHCPv4/UseDNSServers", v4dhcpParms.useDnsServers, 21943dfed536SEd Tanous "DHCPv4/UseDomainName", v4dhcpParms.useDomainName, 21953dfed536SEd Tanous "DHCPv4/UseNTPServers", v4dhcpParms.useNtpServers, 21963dfed536SEd Tanous "DHCPv6/OperatingMode", v6dhcpParms.dhcpv6OperatingMode, 21973dfed536SEd Tanous "DHCPv6/UseDNSServers", v6dhcpParms.useDnsServers, 21983dfed536SEd Tanous "DHCPv6/UseDomainName", v6dhcpParms.useDomainName, 21993dfed536SEd Tanous "DHCPv6/UseNTPServers", v6dhcpParms.useNtpServers, 2200b10d8db0SRavi Teja "FQDN", fqdn, 2201b10d8db0SRavi Teja "HostName", hostname, 2202b10d8db0SRavi Teja "IPv4StaticAddresses", ipv4StaticAddresses, 2203b10d8db0SRavi Teja "IPv6DefaultGateway", ipv6DefaultGateway, 2204b10d8db0SRavi Teja "IPv6StaticAddresses", ipv6StaticAddresses, 2205ce73d5c8SSunitha Harish "IPv6StaticDefaultGateways", ipv6StaticDefaultGateways, 2206b10d8db0SRavi Teja "InterfaceEnabled", interfaceEnabled, 2207b10d8db0SRavi Teja "MACAddress", macAddress, 2208b10d8db0SRavi Teja "MTUSize", mtuSize, 2209b10d8db0SRavi Teja "StatelessAddressAutoConfig/IPv6AutoConfigEnabled", ipv6AutoConfigEnabled, 2210b10d8db0SRavi Teja "StaticNameServers", staticNameServers 2211b10d8db0SRavi Teja ) 2212b10d8db0SRavi Teja ) 22131abe55efSEd Tanous { 2214588c3f0dSKowalski, Kamil return; 2215588c3f0dSKowalski, Kamil } 2216b10d8db0SRavi Teja // clang-format on 2217da131a9aSJennifer Lee 2218bf648f77SEd Tanous // Get single eth interface data, and call the below callback 2219bf648f77SEd Tanous // for JSON preparation 22204a0cb85cSEd Tanous getEthernetIfaceData( 22212c70f800SEd Tanous ifaceId, 2222bf648f77SEd Tanous [asyncResp, ifaceId, hostname = std::move(hostname), 2223ab6554f1SJoshi-Mansi fqdn = std::move(fqdn), macAddress = std::move(macAddress), 2224d1d50814SRavi Teja ipv4StaticAddresses = std::move(ipv4StaticAddresses), 22259a6fc6feSRavi Teja ipv6DefaultGateway = std::move(ipv6DefaultGateway), 2226e48c0fc5SRavi Teja ipv6StaticAddresses = std::move(ipv6StaticAddresses), 2227ce73d5c8SSunitha Harish ipv6StaticDefaultGateway = std::move(ipv6StaticDefaultGateways), 22283dfed536SEd Tanous staticNameServers = std::move(staticNameServers), mtuSize, 2229b10d8db0SRavi Teja ipv6AutoConfigEnabled, v4dhcpParms = std::move(v4dhcpParms), 2230f23b7296SEd Tanous v6dhcpParms = std::move(v6dhcpParms), interfaceEnabled]( 22313dfed536SEd Tanous const bool success, const EthernetInterfaceData& ethData, 223277179532SEd Tanous const std::vector<IPv4AddressData>& ipv4Data, 2233ce73d5c8SSunitha Harish const std::vector<IPv6AddressData>& ipv6Data, 22343dfed536SEd Tanous const std::vector<StaticGatewayData>& ipv6GatewayData) mutable { 22351abe55efSEd Tanous if (!success) 22361abe55efSEd Tanous { 2237588c3f0dSKowalski, Kamil // ... otherwise return error 2238bf648f77SEd Tanous // TODO(Pawel)consider distinguish between non 2239bf648f77SEd Tanous // existing object, and other errors 2240002d39b4SEd Tanous messages::resourceNotFound(asyncResp->res, "EthernetInterface", 2241002d39b4SEd Tanous ifaceId); 2242588c3f0dSKowalski, Kamil return; 2243588c3f0dSKowalski, Kamil } 2244588c3f0dSKowalski, Kamil 2245002d39b4SEd Tanous handleDHCPPatch(ifaceId, ethData, v4dhcpParms, v6dhcpParms, 2246002d39b4SEd Tanous asyncResp); 22471f8c7b5dSJohnathan Mantey 22480627a2c7SEd Tanous if (hostname) 22491abe55efSEd Tanous { 22500627a2c7SEd Tanous handleHostnamePatch(*hostname, asyncResp); 22511abe55efSEd Tanous } 22520627a2c7SEd Tanous 2253b10d8db0SRavi Teja if (ipv6AutoConfigEnabled) 2254b10d8db0SRavi Teja { 2255b10d8db0SRavi Teja handleSLAACAutoConfigPatch(ifaceId, *ipv6AutoConfigEnabled, 2256b10d8db0SRavi Teja asyncResp); 2257b10d8db0SRavi Teja } 2258b10d8db0SRavi Teja 2259ab6554f1SJoshi-Mansi if (fqdn) 2260ab6554f1SJoshi-Mansi { 22612c70f800SEd Tanous handleFqdnPatch(ifaceId, *fqdn, asyncResp); 2262ab6554f1SJoshi-Mansi } 2263ab6554f1SJoshi-Mansi 2264d577665bSRatan Gupta if (macAddress) 2265d577665bSRatan Gupta { 2266002d39b4SEd Tanous handleMACAddressPatch(ifaceId, *macAddress, asyncResp); 2267d577665bSRatan Gupta } 2268d577665bSRatan Gupta 2269d1d50814SRavi Teja if (ipv4StaticAddresses) 2270d1d50814SRavi Teja { 22713dfed536SEd Tanous handleIPv4StaticPatch(ifaceId, *ipv4StaticAddresses, ipv4Data, 22723dfed536SEd Tanous asyncResp); 22731abe55efSEd Tanous } 22740627a2c7SEd Tanous 2275f85837bfSRAJESWARAN THILLAIGOVINDAN if (staticNameServers) 2276f85837bfSRAJESWARAN THILLAIGOVINDAN { 2277002d39b4SEd Tanous handleStaticNameServersPatch(ifaceId, *staticNameServers, 2278002d39b4SEd Tanous asyncResp); 2279f85837bfSRAJESWARAN THILLAIGOVINDAN } 22809a6fc6feSRavi Teja 22819a6fc6feSRavi Teja if (ipv6DefaultGateway) 22829a6fc6feSRavi Teja { 22839a6fc6feSRavi Teja messages::propertyNotWritable(asyncResp->res, 22849a6fc6feSRavi Teja "IPv6DefaultGateway"); 22859a6fc6feSRavi Teja } 2286e48c0fc5SRavi Teja 2287e48c0fc5SRavi Teja if (ipv6StaticAddresses) 2288e48c0fc5SRavi Teja { 2289ddd70dcaSEd Tanous handleIPv6StaticAddressesPatch(ifaceId, *ipv6StaticAddresses, 2290ddd70dcaSEd Tanous ipv6Data, asyncResp); 2291e48c0fc5SRavi Teja } 2292eeedda23SJohnathan Mantey 2293ce73d5c8SSunitha Harish if (ipv6StaticDefaultGateway) 2294ce73d5c8SSunitha Harish { 2295ce73d5c8SSunitha Harish handleIPv6DefaultGateway(ifaceId, *ipv6StaticDefaultGateway, 2296ce73d5c8SSunitha Harish ipv6GatewayData, asyncResp); 2297ce73d5c8SSunitha Harish } 2298ce73d5c8SSunitha Harish 2299eeedda23SJohnathan Mantey if (interfaceEnabled) 2300eeedda23SJohnathan Mantey { 2301d02aad39SEd Tanous setDbusProperty(asyncResp, "xyz.openbmc_project.Network", 2302d02aad39SEd Tanous sdbusplus::message::object_path( 2303d02aad39SEd Tanous "/xyz/openbmc_project/network") / 2304d02aad39SEd Tanous ifaceId, 2305d02aad39SEd Tanous "xyz.openbmc_project.Network.EthernetInterface", 2306d02aad39SEd Tanous "NICEnabled", "InterfaceEnabled", 2307d02aad39SEd Tanous *interfaceEnabled); 2308eeedda23SJohnathan Mantey } 230935fb5311STejas Patil 231035fb5311STejas Patil if (mtuSize) 231135fb5311STejas Patil { 231235fb5311STejas Patil handleMTUSizePatch(ifaceId, *mtuSize, asyncResp); 231335fb5311STejas Patil } 2314588c3f0dSKowalski, Kamil }); 2315bf648f77SEd Tanous }); 2316e7caf250SJiaqing Zhao 2317e7caf250SJiaqing Zhao BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/EthernetInterfaces/<str>/") 2318e7caf250SJiaqing Zhao .privileges(redfish::privileges::deleteEthernetInterface) 2319e7caf250SJiaqing Zhao .methods(boost::beast::http::verb::delete_)( 2320e7caf250SJiaqing Zhao [&app](const crow::Request& req, 2321e7caf250SJiaqing Zhao const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2322e7caf250SJiaqing Zhao const std::string& ifaceId) { 2323e7caf250SJiaqing Zhao if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2324e7caf250SJiaqing Zhao { 2325e7caf250SJiaqing Zhao return; 2326e7caf250SJiaqing Zhao } 2327e7caf250SJiaqing Zhao 2328e7caf250SJiaqing Zhao crow::connections::systemBus->async_method_call( 2329e7caf250SJiaqing Zhao [asyncResp, ifaceId](const boost::system::error_code& ec, 2330e7caf250SJiaqing Zhao const sdbusplus::message_t& m) { 2331e7caf250SJiaqing Zhao afterDelete(asyncResp, ifaceId, ec, m); 2332e7caf250SJiaqing Zhao }, 2333e7caf250SJiaqing Zhao "xyz.openbmc_project.Network", 2334e7caf250SJiaqing Zhao std::string("/xyz/openbmc_project/network/") + ifaceId, 2335e7caf250SJiaqing Zhao "xyz.openbmc_project.Object.Delete", "Delete"); 2336e7caf250SJiaqing Zhao }); 23374a0cb85cSEd Tanous } 2338bf648f77SEd Tanous 23399391bb9cSRapkiewicz, Pawel } // namespace redfish 2340