140e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
240e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
340e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright 2018 Intel Corporation
49391bb9cSRapkiewicz, Pawel #pragma once
59391bb9cSRapkiewicz, Pawel
6d7857201SEd Tanous #include "bmcweb_config.h"
7d7857201SEd Tanous
83ccb3adbSEd Tanous #include "app.hpp"
9d7857201SEd Tanous #include "async_resp.hpp"
103ccb3adbSEd Tanous #include "dbus_singleton.hpp"
117a1dbc48SGeorge Liu #include "dbus_utility.hpp"
123ccb3adbSEd Tanous #include "error_messages.hpp"
13539d8c6bSEd Tanous #include "generated/enums/ethernet_interface.hpp"
14539d8c6bSEd Tanous #include "generated/enums/resource.hpp"
15d7857201SEd Tanous #include "http_request.hpp"
16d7857201SEd Tanous #include "http_response.hpp"
172c5875a2SEd Tanous #include "human_sort.hpp"
18d7857201SEd Tanous #include "logging.hpp"
193ccb3adbSEd Tanous #include "query.hpp"
203ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
21d7857201SEd Tanous #include "utility.hpp"
22d7857201SEd Tanous #include "utils/dbus_utils.hpp"
23033f1e4dSEd Tanous #include "utils/ip_utils.hpp"
243ccb3adbSEd Tanous #include "utils/json_utils.hpp"
25033f1e4dSEd Tanous
26d7857201SEd Tanous #include <systemd/sd-bus.h>
271214b7e7SGunnar Mills
28d7857201SEd Tanous #include <boost/beast/http/verb.hpp>
29d7857201SEd Tanous #include <boost/system/error_code.hpp>
30d7857201SEd Tanous #include <boost/system/result.hpp>
31d7857201SEd Tanous #include <boost/url/format.hpp>
32d7857201SEd Tanous #include <boost/url/parse.hpp>
33d7857201SEd Tanous #include <boost/url/url.hpp>
34d7857201SEd Tanous #include <boost/url/url_view.hpp>
35d7857201SEd Tanous #include <sdbusplus/message.hpp>
36d7857201SEd Tanous #include <sdbusplus/message/native_types.hpp>
37d7857201SEd Tanous #include <sdbusplus/unpack_properties.hpp>
38d7857201SEd Tanous
39d7857201SEd Tanous #include <algorithm>
40d7857201SEd Tanous #include <cctype>
413dfed536SEd Tanous #include <cstddef>
42d7857201SEd Tanous #include <cstdint>
43d7857201SEd Tanous #include <format>
44d7857201SEd Tanous #include <functional>
45ce73d5c8SSunitha Harish #include <memory>
46a24526dcSEd Tanous #include <optional>
473544d2a7SEd Tanous #include <ranges>
48ab6554f1SJoshi-Mansi #include <regex>
49d7857201SEd Tanous #include <string>
507a1dbc48SGeorge Liu #include <string_view>
51d7857201SEd Tanous #include <utility>
523dfed536SEd Tanous #include <variant>
5377179532SEd Tanous #include <vector>
549391bb9cSRapkiewicz, Pawel
551abe55efSEd Tanous namespace redfish
561abe55efSEd Tanous {
579391bb9cSRapkiewicz, Pawel
584a0cb85cSEd Tanous enum class LinkType
594a0cb85cSEd Tanous {
604a0cb85cSEd Tanous Local,
614a0cb85cSEd Tanous Global
624a0cb85cSEd Tanous };
639391bb9cSRapkiewicz, Pawel
64743eb1c0SJohnathan Mantey enum class IpVersion
65743eb1c0SJohnathan Mantey {
66743eb1c0SJohnathan Mantey IpV4,
67743eb1c0SJohnathan Mantey IpV6
68743eb1c0SJohnathan Mantey };
69743eb1c0SJohnathan Mantey
709391bb9cSRapkiewicz, Pawel /**
719391bb9cSRapkiewicz, Pawel * Structure for keeping IPv4 data required by Redfish
729391bb9cSRapkiewicz, Pawel */
731abe55efSEd Tanous struct IPv4AddressData
741abe55efSEd Tanous {
75179db1d7SKowalski, Kamil std::string id;
764a0cb85cSEd Tanous std::string address;
774a0cb85cSEd Tanous std::string domain;
784a0cb85cSEd Tanous std::string gateway;
799391bb9cSRapkiewicz, Pawel std::string netmask;
809391bb9cSRapkiewicz, Pawel std::string origin;
8177179532SEd Tanous LinkType linktype{};
8277179532SEd Tanous bool isActive{};
839391bb9cSRapkiewicz, Pawel };
849391bb9cSRapkiewicz, Pawel
859391bb9cSRapkiewicz, Pawel /**
86e48c0fc5SRavi Teja * Structure for keeping IPv6 data required by Redfish
87e48c0fc5SRavi Teja */
88e48c0fc5SRavi Teja struct IPv6AddressData
89e48c0fc5SRavi Teja {
90e48c0fc5SRavi Teja std::string id;
91e48c0fc5SRavi Teja std::string address;
92e48c0fc5SRavi Teja std::string origin;
9377179532SEd Tanous uint8_t prefixLength = 0;
94e48c0fc5SRavi Teja };
95ce73d5c8SSunitha Harish
96ce73d5c8SSunitha Harish /**
97ce73d5c8SSunitha Harish * Structure for keeping static route data required by Redfish
98ce73d5c8SSunitha Harish */
99ce73d5c8SSunitha Harish struct StaticGatewayData
100ce73d5c8SSunitha Harish {
101ce73d5c8SSunitha Harish std::string id;
102ce73d5c8SSunitha Harish std::string gateway;
103ce73d5c8SSunitha Harish size_t prefixLength = 0;
104ce73d5c8SSunitha Harish std::string protocol;
105ce73d5c8SSunitha Harish };
106ce73d5c8SSunitha Harish
107e48c0fc5SRavi Teja /**
1089391bb9cSRapkiewicz, Pawel * Structure for keeping basic single Ethernet Interface information
1099391bb9cSRapkiewicz, Pawel * available from DBus
1109391bb9cSRapkiewicz, Pawel */
1111abe55efSEd Tanous struct EthernetInterfaceData
1121abe55efSEd Tanous {
1134a0cb85cSEd Tanous uint32_t speed;
11435fb5311STejas Patil size_t mtuSize;
11582695a5bSJiaqing Zhao bool autoNeg;
116e4588158SJishnu CM bool dnsv4Enabled;
117e4588158SJishnu CM bool dnsv6Enabled;
11891c441ecSRavi Teja bool domainv4Enabled;
11991c441ecSRavi Teja bool domainv6Enabled;
120e4588158SJishnu CM bool ntpv4Enabled;
121e4588158SJishnu CM bool ntpv6Enabled;
122e4588158SJishnu CM bool hostNamev4Enabled;
123e4588158SJishnu CM bool hostNamev6Enabled;
124aa05fb27SJohnathan Mantey bool linkUp;
125eeedda23SJohnathan Mantey bool nicEnabled;
126b10d8db0SRavi Teja bool ipv6AcceptRa;
12782695a5bSJiaqing Zhao std::string dhcpEnabled;
1281f8c7b5dSJohnathan Mantey std::string operatingMode;
12982695a5bSJiaqing Zhao std::string hostName;
13082695a5bSJiaqing Zhao std::string defaultGateway;
13182695a5bSJiaqing Zhao std::string ipv6DefaultGateway;
132ce73d5c8SSunitha Harish std::string ipv6StaticDefaultGateway;
1334652c640SAsmitha Karunanithi std::optional<std::string> macAddress;
13417e22024SJiaqing Zhao std::optional<uint32_t> vlanId;
1350f6efdc1Smanojkiran.eda@gmail.com std::vector<std::string> nameServers;
1360f6efdc1Smanojkiran.eda@gmail.com std::vector<std::string> staticNameServers;
137d24bfc7aSJennifer Lee std::vector<std::string> domainnames;
1389391bb9cSRapkiewicz, Pawel };
1399391bb9cSRapkiewicz, Pawel
1401f8c7b5dSJohnathan Mantey struct DHCPParameters
1411f8c7b5dSJohnathan Mantey {
1421f8c7b5dSJohnathan Mantey std::optional<bool> dhcpv4Enabled;
14382695a5bSJiaqing Zhao std::optional<bool> useDnsServers;
14482695a5bSJiaqing Zhao std::optional<bool> useNtpServers;
14582695a5bSJiaqing Zhao std::optional<bool> useDomainName;
1461f8c7b5dSJohnathan Mantey std::optional<std::string> dhcpv6OperatingMode;
1471f8c7b5dSJohnathan Mantey };
1481f8c7b5dSJohnathan Mantey
1499391bb9cSRapkiewicz, Pawel // Helper function that changes bits netmask notation (i.e. /24)
1509391bb9cSRapkiewicz, Pawel // into full dot notation
getNetmask(unsigned int bits)1511abe55efSEd Tanous inline std::string getNetmask(unsigned int bits)
1521abe55efSEd Tanous {
1539391bb9cSRapkiewicz, Pawel uint32_t value = 0xffffffff << (32 - bits);
1549391bb9cSRapkiewicz, Pawel std::string netmask = std::to_string((value >> 24) & 0xff) + "." +
1559391bb9cSRapkiewicz, Pawel std::to_string((value >> 16) & 0xff) + "." +
1569391bb9cSRapkiewicz, Pawel std::to_string((value >> 8) & 0xff) + "." +
1579391bb9cSRapkiewicz, Pawel std::to_string(value & 0xff);
1589391bb9cSRapkiewicz, Pawel return netmask;
1599391bb9cSRapkiewicz, Pawel }
1609391bb9cSRapkiewicz, Pawel
translateDhcpEnabledToBool(const std::string & inputDHCP,bool isIPv4)16182695a5bSJiaqing Zhao inline bool translateDhcpEnabledToBool(const std::string& inputDHCP,
1621f8c7b5dSJohnathan Mantey bool isIPv4)
1631f8c7b5dSJohnathan Mantey {
1641f8c7b5dSJohnathan Mantey if (isIPv4)
1651f8c7b5dSJohnathan Mantey {
1661f8c7b5dSJohnathan Mantey return (
1671f8c7b5dSJohnathan Mantey (inputDHCP ==
1681f8c7b5dSJohnathan Mantey "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v4") ||
1691f8c7b5dSJohnathan Mantey (inputDHCP ==
1706e78b680SAsmitha Karunanithi "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.both") ||
1716e78b680SAsmitha Karunanithi (inputDHCP ==
1726e78b680SAsmitha Karunanithi "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v4v6stateless"));
1731f8c7b5dSJohnathan Mantey }
1741f8c7b5dSJohnathan Mantey return ((inputDHCP ==
1751f8c7b5dSJohnathan Mantey "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v6") ||
1761f8c7b5dSJohnathan Mantey (inputDHCP ==
1771f8c7b5dSJohnathan Mantey "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.both"));
1781f8c7b5dSJohnathan Mantey }
1791f8c7b5dSJohnathan Mantey
getDhcpEnabledEnumeration(bool isIPv4,bool isIPv6)1802c70f800SEd Tanous inline std::string getDhcpEnabledEnumeration(bool isIPv4, bool isIPv6)
1811f8c7b5dSJohnathan Mantey {
1821f8c7b5dSJohnathan Mantey if (isIPv4 && isIPv6)
1831f8c7b5dSJohnathan Mantey {
1841f8c7b5dSJohnathan Mantey return "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.both";
1851f8c7b5dSJohnathan Mantey }
1863174e4dfSEd Tanous if (isIPv4)
1871f8c7b5dSJohnathan Mantey {
1881f8c7b5dSJohnathan Mantey return "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v4";
1891f8c7b5dSJohnathan Mantey }
1903174e4dfSEd Tanous if (isIPv6)
1911f8c7b5dSJohnathan Mantey {
1921f8c7b5dSJohnathan Mantey return "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v6";
1931f8c7b5dSJohnathan Mantey }
1941f8c7b5dSJohnathan Mantey return "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.none";
1951f8c7b5dSJohnathan Mantey }
1961f8c7b5dSJohnathan Mantey
translateAddressOriginDbusToRedfish(const std::string & inputOrigin,bool isIPv4)197bd79bce8SPatrick Williams inline std::string translateAddressOriginDbusToRedfish(
198bd79bce8SPatrick Williams const std::string& inputOrigin, bool isIPv4)
1991abe55efSEd Tanous {
2004a0cb85cSEd Tanous if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.Static")
2011abe55efSEd Tanous {
2024a0cb85cSEd Tanous return "Static";
2039391bb9cSRapkiewicz, Pawel }
2044a0cb85cSEd Tanous if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.LinkLocal")
2051abe55efSEd Tanous {
2064a0cb85cSEd Tanous if (isIPv4)
2071abe55efSEd Tanous {
2084a0cb85cSEd Tanous return "IPv4LinkLocal";
2091abe55efSEd Tanous }
2104a0cb85cSEd Tanous return "LinkLocal";
2119391bb9cSRapkiewicz, Pawel }
2124a0cb85cSEd Tanous if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP")
2131abe55efSEd Tanous {
2144a0cb85cSEd Tanous if (isIPv4)
2154a0cb85cSEd Tanous {
2164a0cb85cSEd Tanous return "DHCP";
2174a0cb85cSEd Tanous }
2184a0cb85cSEd Tanous return "DHCPv6";
2194a0cb85cSEd Tanous }
2204a0cb85cSEd Tanous if (inputOrigin == "xyz.openbmc_project.Network.IP.AddressOrigin.SLAAC")
2214a0cb85cSEd Tanous {
2224a0cb85cSEd Tanous return "SLAAC";
2234a0cb85cSEd Tanous }
2244a0cb85cSEd Tanous return "";
2254a0cb85cSEd Tanous }
2264a0cb85cSEd Tanous
extractEthernetInterfaceData(const std::string & ethifaceId,const dbus::utility::ManagedObjectType & dbusData,EthernetInterfaceData & ethData)22702cad96eSEd Tanous inline bool extractEthernetInterfaceData(
22802cad96eSEd Tanous const std::string& ethifaceId,
22902cad96eSEd Tanous const dbus::utility::ManagedObjectType& dbusData,
2304a0cb85cSEd Tanous EthernetInterfaceData& ethData)
2314a0cb85cSEd Tanous {
2324c9afe43SEd Tanous bool idFound = false;
23302cad96eSEd Tanous for (const auto& objpath : dbusData)
2344a0cb85cSEd Tanous {
23502cad96eSEd Tanous for (const auto& ifacePair : objpath.second)
2364a0cb85cSEd Tanous {
23781ce609eSEd Tanous if (objpath.first == "/xyz/openbmc_project/network/" + ethifaceId)
238029573d4SEd Tanous {
2394c9afe43SEd Tanous idFound = true;
2404a0cb85cSEd Tanous if (ifacePair.first == "xyz.openbmc_project.Network.MACAddress")
2414a0cb85cSEd Tanous {
2424a0cb85cSEd Tanous for (const auto& propertyPair : ifacePair.second)
2434a0cb85cSEd Tanous {
2444a0cb85cSEd Tanous if (propertyPair.first == "MACAddress")
2454a0cb85cSEd Tanous {
2464a0cb85cSEd Tanous const std::string* mac =
247abf2add6SEd Tanous std::get_if<std::string>(&propertyPair.second);
2484a0cb85cSEd Tanous if (mac != nullptr)
2494a0cb85cSEd Tanous {
25082695a5bSJiaqing Zhao ethData.macAddress = *mac;
2514a0cb85cSEd Tanous }
2524a0cb85cSEd Tanous }
2534a0cb85cSEd Tanous }
2544a0cb85cSEd Tanous }
2554a0cb85cSEd Tanous else if (ifacePair.first == "xyz.openbmc_project.Network.VLAN")
2564a0cb85cSEd Tanous {
2574a0cb85cSEd Tanous for (const auto& propertyPair : ifacePair.second)
2584a0cb85cSEd Tanous {
2594a0cb85cSEd Tanous if (propertyPair.first == "Id")
2604a0cb85cSEd Tanous {
2611b6b96c5SEd Tanous const uint32_t* id =
262abf2add6SEd Tanous std::get_if<uint32_t>(&propertyPair.second);
2634a0cb85cSEd Tanous if (id != nullptr)
2644a0cb85cSEd Tanous {
26517e22024SJiaqing Zhao ethData.vlanId = *id;
2664a0cb85cSEd Tanous }
2674a0cb85cSEd Tanous }
2684a0cb85cSEd Tanous }
2694a0cb85cSEd Tanous }
2704a0cb85cSEd Tanous else if (ifacePair.first ==
2714a0cb85cSEd Tanous "xyz.openbmc_project.Network.EthernetInterface")
2724a0cb85cSEd Tanous {
2734a0cb85cSEd Tanous for (const auto& propertyPair : ifacePair.second)
2744a0cb85cSEd Tanous {
2754a0cb85cSEd Tanous if (propertyPair.first == "AutoNeg")
2764a0cb85cSEd Tanous {
2772c70f800SEd Tanous const bool* autoNeg =
278abf2add6SEd Tanous std::get_if<bool>(&propertyPair.second);
2792c70f800SEd Tanous if (autoNeg != nullptr)
2804a0cb85cSEd Tanous {
28182695a5bSJiaqing Zhao ethData.autoNeg = *autoNeg;
2824a0cb85cSEd Tanous }
2834a0cb85cSEd Tanous }
2844a0cb85cSEd Tanous else if (propertyPair.first == "Speed")
2854a0cb85cSEd Tanous {
2864a0cb85cSEd Tanous const uint32_t* speed =
287abf2add6SEd Tanous std::get_if<uint32_t>(&propertyPair.second);
2884a0cb85cSEd Tanous if (speed != nullptr)
2894a0cb85cSEd Tanous {
2904a0cb85cSEd Tanous ethData.speed = *speed;
2914a0cb85cSEd Tanous }
2924a0cb85cSEd Tanous }
29335fb5311STejas Patil else if (propertyPair.first == "MTU")
29435fb5311STejas Patil {
2953e7a8da6SAnthony const size_t* mtuSize =
2963e7a8da6SAnthony std::get_if<size_t>(&propertyPair.second);
29735fb5311STejas Patil if (mtuSize != nullptr)
29835fb5311STejas Patil {
29935fb5311STejas Patil ethData.mtuSize = *mtuSize;
30035fb5311STejas Patil }
30135fb5311STejas Patil }
302aa05fb27SJohnathan Mantey else if (propertyPair.first == "LinkUp")
303aa05fb27SJohnathan Mantey {
304aa05fb27SJohnathan Mantey const bool* linkUp =
305aa05fb27SJohnathan Mantey std::get_if<bool>(&propertyPair.second);
306aa05fb27SJohnathan Mantey if (linkUp != nullptr)
307aa05fb27SJohnathan Mantey {
308aa05fb27SJohnathan Mantey ethData.linkUp = *linkUp;
309aa05fb27SJohnathan Mantey }
310aa05fb27SJohnathan Mantey }
311eeedda23SJohnathan Mantey else if (propertyPair.first == "NICEnabled")
312eeedda23SJohnathan Mantey {
313eeedda23SJohnathan Mantey const bool* nicEnabled =
314eeedda23SJohnathan Mantey std::get_if<bool>(&propertyPair.second);
315eeedda23SJohnathan Mantey if (nicEnabled != nullptr)
316eeedda23SJohnathan Mantey {
317eeedda23SJohnathan Mantey ethData.nicEnabled = *nicEnabled;
318eeedda23SJohnathan Mantey }
319eeedda23SJohnathan Mantey }
320b10d8db0SRavi Teja else if (propertyPair.first == "IPv6AcceptRA")
321b10d8db0SRavi Teja {
322b10d8db0SRavi Teja const bool* ipv6AcceptRa =
323b10d8db0SRavi Teja std::get_if<bool>(&propertyPair.second);
324b10d8db0SRavi Teja if (ipv6AcceptRa != nullptr)
325b10d8db0SRavi Teja {
326b10d8db0SRavi Teja ethData.ipv6AcceptRa = *ipv6AcceptRa;
327b10d8db0SRavi Teja }
328b10d8db0SRavi Teja }
329f85837bfSRAJESWARAN THILLAIGOVINDAN else if (propertyPair.first == "Nameservers")
330029573d4SEd Tanous {
331029573d4SEd Tanous const std::vector<std::string>* nameservers =
3328d78b7a9SPatrick Williams std::get_if<std::vector<std::string>>(
333029573d4SEd Tanous &propertyPair.second);
334029573d4SEd Tanous if (nameservers != nullptr)
335029573d4SEd Tanous {
336f23b7296SEd Tanous ethData.nameServers = *nameservers;
3370f6efdc1Smanojkiran.eda@gmail.com }
3380f6efdc1Smanojkiran.eda@gmail.com }
3390f6efdc1Smanojkiran.eda@gmail.com else if (propertyPair.first == "StaticNameServers")
3400f6efdc1Smanojkiran.eda@gmail.com {
3410f6efdc1Smanojkiran.eda@gmail.com const std::vector<std::string>* staticNameServers =
3428d78b7a9SPatrick Williams std::get_if<std::vector<std::string>>(
3430f6efdc1Smanojkiran.eda@gmail.com &propertyPair.second);
3440f6efdc1Smanojkiran.eda@gmail.com if (staticNameServers != nullptr)
3450f6efdc1Smanojkiran.eda@gmail.com {
346f23b7296SEd Tanous ethData.staticNameServers = *staticNameServers;
3474a0cb85cSEd Tanous }
3484a0cb85cSEd Tanous }
3492a133282Smanojkiraneda else if (propertyPair.first == "DHCPEnabled")
3502a133282Smanojkiraneda {
3512c70f800SEd Tanous const std::string* dhcpEnabled =
3521f8c7b5dSJohnathan Mantey std::get_if<std::string>(&propertyPair.second);
3532c70f800SEd Tanous if (dhcpEnabled != nullptr)
3542a133282Smanojkiraneda {
35582695a5bSJiaqing Zhao ethData.dhcpEnabled = *dhcpEnabled;
3562a133282Smanojkiraneda }
3572a133282Smanojkiraneda }
358d24bfc7aSJennifer Lee else if (propertyPair.first == "DomainName")
359d24bfc7aSJennifer Lee {
360d24bfc7aSJennifer Lee const std::vector<std::string>* domainNames =
3618d78b7a9SPatrick Williams std::get_if<std::vector<std::string>>(
362d24bfc7aSJennifer Lee &propertyPair.second);
363d24bfc7aSJennifer Lee if (domainNames != nullptr)
364d24bfc7aSJennifer Lee {
365f23b7296SEd Tanous ethData.domainnames = *domainNames;
366d24bfc7aSJennifer Lee }
367d24bfc7aSJennifer Lee }
3689010ec2eSRavi Teja else if (propertyPair.first == "DefaultGateway")
3699010ec2eSRavi Teja {
3709010ec2eSRavi Teja const std::string* defaultGateway =
3719010ec2eSRavi Teja std::get_if<std::string>(&propertyPair.second);
3729010ec2eSRavi Teja if (defaultGateway != nullptr)
3739010ec2eSRavi Teja {
3749010ec2eSRavi Teja std::string defaultGatewayStr = *defaultGateway;
3759010ec2eSRavi Teja if (defaultGatewayStr.empty())
3769010ec2eSRavi Teja {
37782695a5bSJiaqing Zhao ethData.defaultGateway = "0.0.0.0";
3789010ec2eSRavi Teja }
3799010ec2eSRavi Teja else
3809010ec2eSRavi Teja {
38182695a5bSJiaqing Zhao ethData.defaultGateway = defaultGatewayStr;
3829010ec2eSRavi Teja }
3839010ec2eSRavi Teja }
3849010ec2eSRavi Teja }
3859010ec2eSRavi Teja else if (propertyPair.first == "DefaultGateway6")
3869010ec2eSRavi Teja {
3879010ec2eSRavi Teja const std::string* defaultGateway6 =
3889010ec2eSRavi Teja std::get_if<std::string>(&propertyPair.second);
3899010ec2eSRavi Teja if (defaultGateway6 != nullptr)
3909010ec2eSRavi Teja {
3919010ec2eSRavi Teja std::string defaultGateway6Str =
3929010ec2eSRavi Teja *defaultGateway6;
3939010ec2eSRavi Teja if (defaultGateway6Str.empty())
3949010ec2eSRavi Teja {
39582695a5bSJiaqing Zhao ethData.ipv6DefaultGateway =
3969010ec2eSRavi Teja "0:0:0:0:0:0:0:0";
3979010ec2eSRavi Teja }
3989010ec2eSRavi Teja else
3999010ec2eSRavi Teja {
40082695a5bSJiaqing Zhao ethData.ipv6DefaultGateway =
4019010ec2eSRavi Teja defaultGateway6Str;
4029010ec2eSRavi Teja }
4039010ec2eSRavi Teja }
4049010ec2eSRavi Teja }
405029573d4SEd Tanous }
406029573d4SEd Tanous }
407029573d4SEd Tanous }
4081f8c7b5dSJohnathan Mantey
409e4588158SJishnu CM sdbusplus::message::object_path path(
410e4588158SJishnu CM "/xyz/openbmc_project/network");
411bd79bce8SPatrick Williams sdbusplus::message::object_path dhcp4Path =
412bd79bce8SPatrick Williams path / ethifaceId / "dhcp4";
413e4588158SJishnu CM
414e4588158SJishnu CM if (sdbusplus::message::object_path(objpath.first) == dhcp4Path)
4151f8c7b5dSJohnathan Mantey {
4161f8c7b5dSJohnathan Mantey if (ifacePair.first ==
4171f8c7b5dSJohnathan Mantey "xyz.openbmc_project.Network.DHCPConfiguration")
4181f8c7b5dSJohnathan Mantey {
4191f8c7b5dSJohnathan Mantey for (const auto& propertyPair : ifacePair.second)
4201f8c7b5dSJohnathan Mantey {
4211f8c7b5dSJohnathan Mantey if (propertyPair.first == "DNSEnabled")
4221f8c7b5dSJohnathan Mantey {
4232c70f800SEd Tanous const bool* dnsEnabled =
4241f8c7b5dSJohnathan Mantey std::get_if<bool>(&propertyPair.second);
4252c70f800SEd Tanous if (dnsEnabled != nullptr)
4261f8c7b5dSJohnathan Mantey {
427e4588158SJishnu CM ethData.dnsv4Enabled = *dnsEnabled;
4281f8c7b5dSJohnathan Mantey }
4291f8c7b5dSJohnathan Mantey }
43091c441ecSRavi Teja else if (propertyPair.first == "DomainEnabled")
43191c441ecSRavi Teja {
43291c441ecSRavi Teja const bool* domainEnabled =
43391c441ecSRavi Teja std::get_if<bool>(&propertyPair.second);
43491c441ecSRavi Teja if (domainEnabled != nullptr)
43591c441ecSRavi Teja {
43691c441ecSRavi Teja ethData.domainv4Enabled = *domainEnabled;
43791c441ecSRavi Teja }
43891c441ecSRavi Teja }
4391f8c7b5dSJohnathan Mantey else if (propertyPair.first == "NTPEnabled")
4401f8c7b5dSJohnathan Mantey {
4412c70f800SEd Tanous const bool* ntpEnabled =
4421f8c7b5dSJohnathan Mantey std::get_if<bool>(&propertyPair.second);
4432c70f800SEd Tanous if (ntpEnabled != nullptr)
4441f8c7b5dSJohnathan Mantey {
445e4588158SJishnu CM ethData.ntpv4Enabled = *ntpEnabled;
4461f8c7b5dSJohnathan Mantey }
4471f8c7b5dSJohnathan Mantey }
4481f8c7b5dSJohnathan Mantey else if (propertyPair.first == "HostNameEnabled")
4491f8c7b5dSJohnathan Mantey {
4502c70f800SEd Tanous const bool* hostNameEnabled =
4511f8c7b5dSJohnathan Mantey std::get_if<bool>(&propertyPair.second);
4522c70f800SEd Tanous if (hostNameEnabled != nullptr)
4531f8c7b5dSJohnathan Mantey {
454e4588158SJishnu CM ethData.hostNamev4Enabled = *hostNameEnabled;
455e4588158SJishnu CM }
456e4588158SJishnu CM }
457e4588158SJishnu CM }
458e4588158SJishnu CM }
459e4588158SJishnu CM }
460e4588158SJishnu CM
461bd79bce8SPatrick Williams sdbusplus::message::object_path dhcp6Path =
462bd79bce8SPatrick Williams path / ethifaceId / "dhcp6";
463e4588158SJishnu CM
464e4588158SJishnu CM if (sdbusplus::message::object_path(objpath.first) == dhcp6Path)
465e4588158SJishnu CM {
466e4588158SJishnu CM if (ifacePair.first ==
467e4588158SJishnu CM "xyz.openbmc_project.Network.DHCPConfiguration")
468e4588158SJishnu CM {
469e4588158SJishnu CM for (const auto& propertyPair : ifacePair.second)
470e4588158SJishnu CM {
471e4588158SJishnu CM if (propertyPair.first == "DNSEnabled")
472e4588158SJishnu CM {
473e4588158SJishnu CM const bool* dnsEnabled =
474e4588158SJishnu CM std::get_if<bool>(&propertyPair.second);
475e4588158SJishnu CM if (dnsEnabled != nullptr)
476e4588158SJishnu CM {
477e4588158SJishnu CM ethData.dnsv6Enabled = *dnsEnabled;
478e4588158SJishnu CM }
479e4588158SJishnu CM }
48091c441ecSRavi Teja if (propertyPair.first == "DomainEnabled")
48191c441ecSRavi Teja {
48291c441ecSRavi Teja const bool* domainEnabled =
48391c441ecSRavi Teja std::get_if<bool>(&propertyPair.second);
48491c441ecSRavi Teja if (domainEnabled != nullptr)
48591c441ecSRavi Teja {
48691c441ecSRavi Teja ethData.domainv6Enabled = *domainEnabled;
48791c441ecSRavi Teja }
48891c441ecSRavi Teja }
489e4588158SJishnu CM else if (propertyPair.first == "NTPEnabled")
490e4588158SJishnu CM {
491e4588158SJishnu CM const bool* ntpEnabled =
492e4588158SJishnu CM std::get_if<bool>(&propertyPair.second);
493e4588158SJishnu CM if (ntpEnabled != nullptr)
494e4588158SJishnu CM {
495e4588158SJishnu CM ethData.ntpv6Enabled = *ntpEnabled;
496e4588158SJishnu CM }
497e4588158SJishnu CM }
498e4588158SJishnu CM else if (propertyPair.first == "HostNameEnabled")
499e4588158SJishnu CM {
500e4588158SJishnu CM const bool* hostNameEnabled =
501e4588158SJishnu CM std::get_if<bool>(&propertyPair.second);
502e4588158SJishnu CM if (hostNameEnabled != nullptr)
503e4588158SJishnu CM {
504e4588158SJishnu CM ethData.hostNamev6Enabled = *hostNameEnabled;
5051f8c7b5dSJohnathan Mantey }
5061f8c7b5dSJohnathan Mantey }
5071f8c7b5dSJohnathan Mantey }
5081f8c7b5dSJohnathan Mantey }
5091f8c7b5dSJohnathan Mantey }
510029573d4SEd Tanous // System configuration shows up in the global namespace, so no need
511029573d4SEd Tanous // to check eth number
512029573d4SEd Tanous if (ifacePair.first ==
5134a0cb85cSEd Tanous "xyz.openbmc_project.Network.SystemConfiguration")
5144a0cb85cSEd Tanous {
5154a0cb85cSEd Tanous for (const auto& propertyPair : ifacePair.second)
5164a0cb85cSEd Tanous {
5174a0cb85cSEd Tanous if (propertyPair.first == "HostName")
5184a0cb85cSEd Tanous {
5194a0cb85cSEd Tanous const std::string* hostname =
5208d78b7a9SPatrick Williams std::get_if<std::string>(&propertyPair.second);
5214a0cb85cSEd Tanous if (hostname != nullptr)
5224a0cb85cSEd Tanous {
52382695a5bSJiaqing Zhao ethData.hostName = *hostname;
5244a0cb85cSEd Tanous }
5254a0cb85cSEd Tanous }
5264a0cb85cSEd Tanous }
5274a0cb85cSEd Tanous }
5284a0cb85cSEd Tanous }
5294a0cb85cSEd Tanous }
5304c9afe43SEd Tanous return idFound;
5314a0cb85cSEd Tanous }
5324a0cb85cSEd Tanous
533e48c0fc5SRavi Teja // Helper function that extracts data for single ethernet ipv6 address
extractIPV6Data(const std::string & ethifaceId,const dbus::utility::ManagedObjectType & dbusData,std::vector<IPv6AddressData> & ipv6Config)53477179532SEd Tanous inline void extractIPV6Data(const std::string& ethifaceId,
535711ac7a9SEd Tanous const dbus::utility::ManagedObjectType& dbusData,
53677179532SEd Tanous std::vector<IPv6AddressData>& ipv6Config)
537e48c0fc5SRavi Teja {
538bd79bce8SPatrick Williams const std::string ipPathStart =
539bd79bce8SPatrick Williams "/xyz/openbmc_project/network/" + ethifaceId;
540e48c0fc5SRavi Teja
541e48c0fc5SRavi Teja // Since there might be several IPv6 configurations aligned with
542e48c0fc5SRavi Teja // single ethernet interface, loop over all of them
54381ce609eSEd Tanous for (const auto& objpath : dbusData)
544e48c0fc5SRavi Teja {
545e48c0fc5SRavi Teja // Check if proper pattern for object path appears
546353163e9STony Lee if (objpath.first.str.starts_with(ipPathStart + "/"))
547e48c0fc5SRavi Teja {
5489eb808c1SEd Tanous for (const auto& interface : objpath.second)
549e48c0fc5SRavi Teja {
550e48c0fc5SRavi Teja if (interface.first == "xyz.openbmc_project.Network.IP")
551e48c0fc5SRavi Teja {
552bd79bce8SPatrick Williams auto type = std::ranges::find_if(
553bd79bce8SPatrick Williams interface.second, [](const auto& property) {
554353163e9STony Lee return property.first == "Type";
555353163e9STony Lee });
556353163e9STony Lee if (type == interface.second.end())
557353163e9STony Lee {
558353163e9STony Lee continue;
559353163e9STony Lee }
560353163e9STony Lee
561353163e9STony Lee const std::string* typeStr =
562353163e9STony Lee std::get_if<std::string>(&type->second);
563353163e9STony Lee
564353163e9STony Lee if (typeStr == nullptr ||
565353163e9STony Lee (*typeStr !=
566353163e9STony Lee "xyz.openbmc_project.Network.IP.Protocol.IPv6"))
567353163e9STony Lee {
568353163e9STony Lee continue;
569353163e9STony Lee }
570353163e9STony Lee
571e48c0fc5SRavi Teja // Instance IPv6AddressData structure, and set as
572e48c0fc5SRavi Teja // appropriate
57377179532SEd Tanous IPv6AddressData& ipv6Address = ipv6Config.emplace_back();
5742c70f800SEd Tanous ipv6Address.id =
575353163e9STony Lee objpath.first.str.substr(ipPathStart.size());
5769eb808c1SEd Tanous for (const auto& property : interface.second)
577e48c0fc5SRavi Teja {
578e48c0fc5SRavi Teja if (property.first == "Address")
579e48c0fc5SRavi Teja {
580e48c0fc5SRavi Teja const std::string* address =
581e48c0fc5SRavi Teja std::get_if<std::string>(&property.second);
582e48c0fc5SRavi Teja if (address != nullptr)
583e48c0fc5SRavi Teja {
5842c70f800SEd Tanous ipv6Address.address = *address;
585e48c0fc5SRavi Teja }
586e48c0fc5SRavi Teja }
587e48c0fc5SRavi Teja else if (property.first == "Origin")
588e48c0fc5SRavi Teja {
589e48c0fc5SRavi Teja const std::string* origin =
590e48c0fc5SRavi Teja std::get_if<std::string>(&property.second);
591e48c0fc5SRavi Teja if (origin != nullptr)
592e48c0fc5SRavi Teja {
5932c70f800SEd Tanous ipv6Address.origin =
594e48c0fc5SRavi Teja translateAddressOriginDbusToRedfish(*origin,
595e48c0fc5SRavi Teja false);
596e48c0fc5SRavi Teja }
597e48c0fc5SRavi Teja }
598e48c0fc5SRavi Teja else if (property.first == "PrefixLength")
599e48c0fc5SRavi Teja {
600e48c0fc5SRavi Teja const uint8_t* prefix =
601e48c0fc5SRavi Teja std::get_if<uint8_t>(&property.second);
602e48c0fc5SRavi Teja if (prefix != nullptr)
603e48c0fc5SRavi Teja {
6042c70f800SEd Tanous ipv6Address.prefixLength = *prefix;
605e48c0fc5SRavi Teja }
606e48c0fc5SRavi Teja }
607889ff694SAsmitha Karunanithi else if (property.first == "Type" ||
608889ff694SAsmitha Karunanithi property.first == "Gateway")
609889ff694SAsmitha Karunanithi {
610889ff694SAsmitha Karunanithi // Type & Gateway is not used
611889ff694SAsmitha Karunanithi }
612e48c0fc5SRavi Teja else
613e48c0fc5SRavi Teja {
61462598e31SEd Tanous BMCWEB_LOG_ERROR(
61562598e31SEd Tanous "Got extra property: {} on the {} object",
61662598e31SEd Tanous property.first, objpath.first.str);
617e48c0fc5SRavi Teja }
618e48c0fc5SRavi Teja }
619e48c0fc5SRavi Teja }
620e48c0fc5SRavi Teja }
621e48c0fc5SRavi Teja }
622e48c0fc5SRavi Teja }
623e48c0fc5SRavi Teja }
624e48c0fc5SRavi Teja
6254a0cb85cSEd Tanous // Helper function that extracts data for single ethernet ipv4 address
extractIPData(const std::string & ethifaceId,const dbus::utility::ManagedObjectType & dbusData,std::vector<IPv4AddressData> & ipv4Config)62677179532SEd Tanous inline void extractIPData(const std::string& ethifaceId,
627711ac7a9SEd Tanous const dbus::utility::ManagedObjectType& dbusData,
62877179532SEd Tanous std::vector<IPv4AddressData>& ipv4Config)
6294a0cb85cSEd Tanous {
630bd79bce8SPatrick Williams const std::string ipPathStart =
631bd79bce8SPatrick Williams "/xyz/openbmc_project/network/" + ethifaceId;
6324a0cb85cSEd Tanous
6334a0cb85cSEd Tanous // Since there might be several IPv4 configurations aligned with
6344a0cb85cSEd Tanous // single ethernet interface, loop over all of them
63581ce609eSEd Tanous for (const auto& objpath : dbusData)
6364a0cb85cSEd Tanous {
6374a0cb85cSEd Tanous // Check if proper pattern for object path appears
638353163e9STony Lee if (objpath.first.str.starts_with(ipPathStart + "/"))
6394a0cb85cSEd Tanous {
6409eb808c1SEd Tanous for (const auto& interface : objpath.second)
6414a0cb85cSEd Tanous {
6424a0cb85cSEd Tanous if (interface.first == "xyz.openbmc_project.Network.IP")
6434a0cb85cSEd Tanous {
644bd79bce8SPatrick Williams auto type = std::ranges::find_if(
645bd79bce8SPatrick Williams interface.second, [](const auto& property) {
646353163e9STony Lee return property.first == "Type";
647353163e9STony Lee });
648353163e9STony Lee if (type == interface.second.end())
649353163e9STony Lee {
650353163e9STony Lee continue;
651353163e9STony Lee }
652353163e9STony Lee
653353163e9STony Lee const std::string* typeStr =
654353163e9STony Lee std::get_if<std::string>(&type->second);
655353163e9STony Lee
656353163e9STony Lee if (typeStr == nullptr ||
657353163e9STony Lee (*typeStr !=
658353163e9STony Lee "xyz.openbmc_project.Network.IP.Protocol.IPv4"))
659353163e9STony Lee {
660353163e9STony Lee continue;
661353163e9STony Lee }
662353163e9STony Lee
6634a0cb85cSEd Tanous // Instance IPv4AddressData structure, and set as
6644a0cb85cSEd Tanous // appropriate
66577179532SEd Tanous IPv4AddressData& ipv4Address = ipv4Config.emplace_back();
6662c70f800SEd Tanous ipv4Address.id =
667353163e9STony Lee objpath.first.str.substr(ipPathStart.size());
6689eb808c1SEd Tanous for (const auto& property : interface.second)
6694a0cb85cSEd Tanous {
6704a0cb85cSEd Tanous if (property.first == "Address")
6714a0cb85cSEd Tanous {
6724a0cb85cSEd Tanous const std::string* address =
673abf2add6SEd Tanous std::get_if<std::string>(&property.second);
6744a0cb85cSEd Tanous if (address != nullptr)
6754a0cb85cSEd Tanous {
6762c70f800SEd Tanous ipv4Address.address = *address;
6774a0cb85cSEd Tanous }
6784a0cb85cSEd Tanous }
6794a0cb85cSEd Tanous else if (property.first == "Origin")
6804a0cb85cSEd Tanous {
6814a0cb85cSEd Tanous const std::string* origin =
682abf2add6SEd Tanous std::get_if<std::string>(&property.second);
6834a0cb85cSEd Tanous if (origin != nullptr)
6844a0cb85cSEd Tanous {
6852c70f800SEd Tanous ipv4Address.origin =
6864a0cb85cSEd Tanous translateAddressOriginDbusToRedfish(*origin,
6874a0cb85cSEd Tanous true);
6884a0cb85cSEd Tanous }
6894a0cb85cSEd Tanous }
6904a0cb85cSEd Tanous else if (property.first == "PrefixLength")
6914a0cb85cSEd Tanous {
6924a0cb85cSEd Tanous const uint8_t* mask =
693abf2add6SEd Tanous std::get_if<uint8_t>(&property.second);
6944a0cb85cSEd Tanous if (mask != nullptr)
6954a0cb85cSEd Tanous {
6964a0cb85cSEd Tanous // convert it to the string
6972c70f800SEd Tanous ipv4Address.netmask = getNetmask(*mask);
6984a0cb85cSEd Tanous }
6994a0cb85cSEd Tanous }
700889ff694SAsmitha Karunanithi else if (property.first == "Type" ||
701889ff694SAsmitha Karunanithi property.first == "Gateway")
702889ff694SAsmitha Karunanithi {
703889ff694SAsmitha Karunanithi // Type & Gateway is not used
704889ff694SAsmitha Karunanithi }
7054a0cb85cSEd Tanous else
7064a0cb85cSEd Tanous {
70762598e31SEd Tanous BMCWEB_LOG_ERROR(
70862598e31SEd Tanous "Got extra property: {} on the {} object",
70962598e31SEd Tanous property.first, objpath.first.str);
7104a0cb85cSEd Tanous }
7114a0cb85cSEd Tanous }
7124a0cb85cSEd Tanous // Check if given address is local, or global
7132c70f800SEd Tanous ipv4Address.linktype =
71411ba3979SEd Tanous ipv4Address.address.starts_with("169.254.")
71518659d10SJohnathan Mantey ? LinkType::Local
71618659d10SJohnathan Mantey : LinkType::Global;
7174a0cb85cSEd Tanous }
7184a0cb85cSEd Tanous }
7194a0cb85cSEd Tanous }
7204a0cb85cSEd Tanous }
7214a0cb85cSEd Tanous }
722588c3f0dSKowalski, Kamil
723588c3f0dSKowalski, Kamil /**
724743eb1c0SJohnathan Mantey * @brief Modifies the default gateway assigned to the NIC
725743eb1c0SJohnathan Mantey *
726743eb1c0SJohnathan Mantey * @param[in] ifaceId Id of network interface whose default gateway is to be
727743eb1c0SJohnathan Mantey * changed
728743eb1c0SJohnathan Mantey * @param[in] gateway The new gateway value. Assigning an empty string
729743eb1c0SJohnathan Mantey * causes the gateway to be deleted
730743eb1c0SJohnathan Mantey * @param[io] asyncResp Response object that will be returned to client
731743eb1c0SJohnathan Mantey *
732743eb1c0SJohnathan Mantey * @return None
733743eb1c0SJohnathan Mantey */
updateIPv4DefaultGateway(const std::string & ifaceId,const std::string & gateway,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)734743eb1c0SJohnathan Mantey inline void updateIPv4DefaultGateway(
735743eb1c0SJohnathan Mantey const std::string& ifaceId, const std::string& gateway,
736743eb1c0SJohnathan Mantey const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
737743eb1c0SJohnathan Mantey {
738743eb1c0SJohnathan Mantey setDbusProperty(
739e93abac6SGinu George asyncResp, "Gateway", "xyz.openbmc_project.Network",
740743eb1c0SJohnathan Mantey sdbusplus::message::object_path("/xyz/openbmc_project/network") /
741743eb1c0SJohnathan Mantey ifaceId,
742743eb1c0SJohnathan Mantey "xyz.openbmc_project.Network.EthernetInterface", "DefaultGateway",
743e93abac6SGinu George gateway);
744743eb1c0SJohnathan Mantey }
745743eb1c0SJohnathan Mantey
746743eb1c0SJohnathan Mantey /**
747743eb1c0SJohnathan Mantey * @brief Deletes given static IP address for the interface
748179db1d7SKowalski, Kamil *
749179db1d7SKowalski, Kamil * @param[in] ifaceId Id of interface whose IP should be deleted
750179db1d7SKowalski, Kamil * @param[in] ipHash DBus Hash id of IP that should be deleted
751179db1d7SKowalski, Kamil * @param[io] asyncResp Response object that will be returned to client
752179db1d7SKowalski, Kamil *
753179db1d7SKowalski, Kamil * @return None
754179db1d7SKowalski, Kamil */
deleteIPAddress(const std::string & ifaceId,const std::string & ipHash,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)7559c5e585cSRavi Teja inline void deleteIPAddress(const std::string& ifaceId,
7569c5e585cSRavi Teja const std::string& ipHash,
7578d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
7581abe55efSEd Tanous {
75955c7b7a2SEd Tanous crow::connections::systemBus->async_method_call(
7605e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) {
7611abe55efSEd Tanous if (ec)
7621abe55efSEd Tanous {
763a08b46ccSJason M. Bills messages::internalError(asyncResp->res);
7641abe55efSEd Tanous }
765179db1d7SKowalski, Kamil },
766179db1d7SKowalski, Kamil "xyz.openbmc_project.Network",
7679c5e585cSRavi Teja "/xyz/openbmc_project/network/" + ifaceId + ipHash,
768179db1d7SKowalski, Kamil "xyz.openbmc_project.Object.Delete", "Delete");
769179db1d7SKowalski, Kamil }
770179db1d7SKowalski, Kamil
771179db1d7SKowalski, Kamil /**
77201784826SJohnathan Mantey * @brief Creates a static IPv4 entry
773179db1d7SKowalski, Kamil *
77401784826SJohnathan Mantey * @param[in] ifaceId Id of interface upon which to create the IPv4 entry
77501784826SJohnathan Mantey * @param[in] prefixLength IPv4 prefix syntax for the subnet mask
77601784826SJohnathan Mantey * @param[in] gateway IPv4 address of this interfaces gateway
77701784826SJohnathan Mantey * @param[in] address IPv4 address to assign to this interface
778179db1d7SKowalski, Kamil * @param[io] asyncResp Response object that will be returned to client
779179db1d7SKowalski, Kamil *
780179db1d7SKowalski, Kamil * @return None
781179db1d7SKowalski, Kamil */
createIPv4(const std::string & ifaceId,uint8_t prefixLength,const std::string & gateway,const std::string & address,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)782cb13a392SEd Tanous inline void createIPv4(const std::string& ifaceId, uint8_t prefixLength,
783cb13a392SEd Tanous const std::string& gateway, const std::string& address,
7848d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
7851abe55efSEd Tanous {
786bd79bce8SPatrick Williams auto createIpHandler =
787bd79bce8SPatrick Williams [asyncResp, ifaceId, gateway](const boost::system::error_code& ec) {
7881abe55efSEd Tanous if (ec)
7891abe55efSEd Tanous {
790a08b46ccSJason M. Bills messages::internalError(asyncResp->res);
7919010ec2eSRavi Teja return;
792179db1d7SKowalski, Kamil }
7939010ec2eSRavi Teja };
7949010ec2eSRavi Teja
7959010ec2eSRavi Teja crow::connections::systemBus->async_method_call(
7969010ec2eSRavi Teja std::move(createIpHandler), "xyz.openbmc_project.Network",
797179db1d7SKowalski, Kamil "/xyz/openbmc_project/network/" + ifaceId,
798179db1d7SKowalski, Kamil "xyz.openbmc_project.Network.IP.Create", "IP",
79901784826SJohnathan Mantey "xyz.openbmc_project.Network.IP.Protocol.IPv4", address, prefixLength,
800179db1d7SKowalski, Kamil gateway);
801179db1d7SKowalski, Kamil }
802e48c0fc5SRavi Teja
803e48c0fc5SRavi Teja /**
804743eb1c0SJohnathan Mantey * @brief Deletes the IP entry for this interface and creates a replacement
805743eb1c0SJohnathan Mantey * static entry
80601784826SJohnathan Mantey *
80701784826SJohnathan Mantey * @param[in] ifaceId Id of interface upon which to create the IPv6 entry
80801784826SJohnathan Mantey * @param[in] id The unique hash entry identifying the DBus entry
809743eb1c0SJohnathan Mantey * @param[in] prefixLength Prefix syntax for the subnet mask
810743eb1c0SJohnathan Mantey * @param[in] address Address to assign to this interface
811743eb1c0SJohnathan Mantey * @param[in] numStaticAddrs Count of IPv4 static addresses
81201784826SJohnathan Mantey * @param[io] asyncResp Response object that will be returned to client
81301784826SJohnathan Mantey *
81401784826SJohnathan Mantey * @return None
81501784826SJohnathan Mantey */
8169c5e585cSRavi Teja
deleteAndCreateIPAddress(IpVersion version,const std::string & ifaceId,const std::string & id,uint8_t prefixLength,const std::string & address,const std::string & gateway,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)8179c5e585cSRavi Teja inline void deleteAndCreateIPAddress(
8189c5e585cSRavi Teja IpVersion version, const std::string& ifaceId, const std::string& id,
8198d1b46d7Szhanghch05 uint8_t prefixLength, const std::string& address,
8209c5e585cSRavi Teja const std::string& gateway,
8218d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
82201784826SJohnathan Mantey {
82301784826SJohnathan Mantey crow::connections::systemBus->async_method_call(
8249c5e585cSRavi Teja [asyncResp, version, ifaceId, address, prefixLength,
8259c5e585cSRavi Teja gateway](const boost::system::error_code& ec) {
82601784826SJohnathan Mantey if (ec)
82701784826SJohnathan Mantey {
82801784826SJohnathan Mantey messages::internalError(asyncResp->res);
82901784826SJohnathan Mantey }
8309c5e585cSRavi Teja std::string protocol = "xyz.openbmc_project.Network.IP.Protocol.";
8319c5e585cSRavi Teja protocol += version == IpVersion::IpV4 ? "IPv4" : "IPv6";
83201784826SJohnathan Mantey crow::connections::systemBus->async_method_call(
8335e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2) {
83423a21a1cSEd Tanous if (ec2)
83501784826SJohnathan Mantey {
83601784826SJohnathan Mantey messages::internalError(asyncResp->res);
83701784826SJohnathan Mantey }
83801784826SJohnathan Mantey },
83901784826SJohnathan Mantey "xyz.openbmc_project.Network",
84001784826SJohnathan Mantey "/xyz/openbmc_project/network/" + ifaceId,
841bd79bce8SPatrick Williams "xyz.openbmc_project.Network.IP.Create", "IP", protocol,
842bd79bce8SPatrick Williams address, prefixLength, gateway);
84301784826SJohnathan Mantey },
84401784826SJohnathan Mantey "xyz.openbmc_project.Network",
8459c5e585cSRavi Teja "/xyz/openbmc_project/network/" + ifaceId + id,
84601784826SJohnathan Mantey "xyz.openbmc_project.Object.Delete", "Delete");
84701784826SJohnathan Mantey }
84801784826SJohnathan Mantey
extractIPv6DefaultGatewayData(const std::string & ethifaceId,const dbus::utility::ManagedObjectType & dbusData,std::vector<StaticGatewayData> & staticGatewayConfig)849ce73d5c8SSunitha Harish inline bool extractIPv6DefaultGatewayData(
850ce73d5c8SSunitha Harish const std::string& ethifaceId,
851ce73d5c8SSunitha Harish const dbus::utility::ManagedObjectType& dbusData,
852ce73d5c8SSunitha Harish std::vector<StaticGatewayData>& staticGatewayConfig)
853ce73d5c8SSunitha Harish {
854ce73d5c8SSunitha Harish std::string staticGatewayPathStart("/xyz/openbmc_project/network/");
855ce73d5c8SSunitha Harish staticGatewayPathStart += ethifaceId;
856ce73d5c8SSunitha Harish
857ce73d5c8SSunitha Harish for (const auto& objpath : dbusData)
858ce73d5c8SSunitha Harish {
859ce73d5c8SSunitha Harish if (!std::string_view(objpath.first.str)
860ce73d5c8SSunitha Harish .starts_with(staticGatewayPathStart))
861ce73d5c8SSunitha Harish {
862ce73d5c8SSunitha Harish continue;
863ce73d5c8SSunitha Harish }
864ce73d5c8SSunitha Harish for (const auto& interface : objpath.second)
865ce73d5c8SSunitha Harish {
866ce73d5c8SSunitha Harish if (interface.first != "xyz.openbmc_project.Network.StaticGateway")
867ce73d5c8SSunitha Harish {
868ce73d5c8SSunitha Harish continue;
869ce73d5c8SSunitha Harish }
870ce73d5c8SSunitha Harish StaticGatewayData& staticGateway =
871ce73d5c8SSunitha Harish staticGatewayConfig.emplace_back();
872ce73d5c8SSunitha Harish staticGateway.id = objpath.first.filename();
873ce73d5c8SSunitha Harish
874ce73d5c8SSunitha Harish bool success = sdbusplus::unpackPropertiesNoThrow(
875ce73d5c8SSunitha Harish redfish::dbus_utils::UnpackErrorPrinter(), interface.second,
876ab0d4390SRavi Teja "Gateway", staticGateway.gateway, "ProtocolType",
877ce73d5c8SSunitha Harish staticGateway.protocol);
878ce73d5c8SSunitha Harish if (!success)
879ce73d5c8SSunitha Harish {
880ce73d5c8SSunitha Harish return false;
881ce73d5c8SSunitha Harish }
882ce73d5c8SSunitha Harish }
883ce73d5c8SSunitha Harish }
884ce73d5c8SSunitha Harish return true;
885ce73d5c8SSunitha Harish }
886ce73d5c8SSunitha Harish
88701784826SJohnathan Mantey /**
888e48c0fc5SRavi Teja * @brief Creates IPv6 with given data
889e48c0fc5SRavi Teja *
890e48c0fc5SRavi Teja * @param[in] ifaceId Id of interface whose IP should be added
891e48c0fc5SRavi Teja * @param[in] prefixLength Prefix length that needs to be added
892e48c0fc5SRavi Teja * @param[in] address IP address that needs to be added
893e48c0fc5SRavi Teja * @param[io] asyncResp Response object that will be returned to client
894e48c0fc5SRavi Teja *
895e48c0fc5SRavi Teja * @return None
896e48c0fc5SRavi Teja */
createIPv6(const std::string & ifaceId,uint8_t prefixLength,const std::string & address,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)89701784826SJohnathan Mantey inline void createIPv6(const std::string& ifaceId, uint8_t prefixLength,
89801784826SJohnathan Mantey const std::string& address,
8998d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
900e48c0fc5SRavi Teja {
901ce73d5c8SSunitha Harish sdbusplus::message::object_path path("/xyz/openbmc_project/network");
902ce73d5c8SSunitha Harish path /= ifaceId;
903ce73d5c8SSunitha Harish
904bd79bce8SPatrick Williams auto createIpHandler =
905bd79bce8SPatrick Williams [asyncResp, address](const boost::system::error_code& ec) {
906e48c0fc5SRavi Teja if (ec)
907e48c0fc5SRavi Teja {
908fc23ef8aSNitin Kumar Kotania if (ec == boost::system::errc::io_error)
909fc23ef8aSNitin Kumar Kotania {
910fc23ef8aSNitin Kumar Kotania messages::propertyValueFormatError(asyncResp->res, address,
911fc23ef8aSNitin Kumar Kotania "Address");
912fc23ef8aSNitin Kumar Kotania }
913fc23ef8aSNitin Kumar Kotania else
914fc23ef8aSNitin Kumar Kotania {
915e48c0fc5SRavi Teja messages::internalError(asyncResp->res);
916e48c0fc5SRavi Teja }
917fc23ef8aSNitin Kumar Kotania }
918e48c0fc5SRavi Teja };
919ce73d5c8SSunitha Harish // Passing null for gateway, as per redfish spec IPv6StaticAddresses
920ce73d5c8SSunitha Harish // object does not have associated gateway property
921e48c0fc5SRavi Teja crow::connections::systemBus->async_method_call(
922ce73d5c8SSunitha Harish std::move(createIpHandler), "xyz.openbmc_project.Network", path,
923e48c0fc5SRavi Teja "xyz.openbmc_project.Network.IP.Create", "IP",
924e48c0fc5SRavi Teja "xyz.openbmc_project.Network.IP.Protocol.IPv6", address, prefixLength,
925e48c0fc5SRavi Teja "");
926e48c0fc5SRavi Teja }
927e48c0fc5SRavi Teja
928179db1d7SKowalski, Kamil /**
929ce73d5c8SSunitha Harish * @brief Deletes given IPv6 Static Gateway
930ce73d5c8SSunitha Harish *
931ce73d5c8SSunitha Harish * @param[in] ifaceId Id of interface whose IP should be deleted
932ce73d5c8SSunitha Harish * @param[in] ipHash DBus Hash id of IP that should be deleted
933ce73d5c8SSunitha Harish * @param[io] asyncResp Response object that will be returned to client
934ce73d5c8SSunitha Harish *
935ce73d5c8SSunitha Harish * @return None
936ce73d5c8SSunitha Harish */
deleteIPv6Gateway(std::string_view ifaceId,std::string_view gatewayId,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)937*504af5a0SPatrick Williams inline void deleteIPv6Gateway(
938*504af5a0SPatrick Williams std::string_view ifaceId, std::string_view gatewayId,
939ce73d5c8SSunitha Harish const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
940ce73d5c8SSunitha Harish {
941ce73d5c8SSunitha Harish sdbusplus::message::object_path path("/xyz/openbmc_project/network");
942739b27b2SRavi Teja path /= ifaceId;
943ce73d5c8SSunitha Harish path /= gatewayId;
944ce73d5c8SSunitha Harish crow::connections::systemBus->async_method_call(
945ce73d5c8SSunitha Harish [asyncResp](const boost::system::error_code& ec) {
946ce73d5c8SSunitha Harish if (ec)
947ce73d5c8SSunitha Harish {
948ce73d5c8SSunitha Harish messages::internalError(asyncResp->res);
949ce73d5c8SSunitha Harish }
950ce73d5c8SSunitha Harish },
951ce73d5c8SSunitha Harish "xyz.openbmc_project.Network", path,
952ce73d5c8SSunitha Harish "xyz.openbmc_project.Object.Delete", "Delete");
953ce73d5c8SSunitha Harish }
954ce73d5c8SSunitha Harish
955ce73d5c8SSunitha Harish /**
956ce73d5c8SSunitha Harish * @brief Creates IPv6 static default gateway with given data
957ce73d5c8SSunitha Harish *
958ce73d5c8SSunitha Harish * @param[in] ifaceId Id of interface whose IP should be added
959ce73d5c8SSunitha Harish * @param[in] gateway Gateway address that needs to be added
960ce73d5c8SSunitha Harish * @param[io] asyncResp Response object that will be returned to client
961ce73d5c8SSunitha Harish *
962ce73d5c8SSunitha Harish * @return None
963ce73d5c8SSunitha Harish */
createIPv6DefaultGateway(std::string_view ifaceId,const std::string & gateway,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)964ce73d5c8SSunitha Harish inline void createIPv6DefaultGateway(
965cf91c8c4SAsmitha Karunanithi std::string_view ifaceId, const std::string& gateway,
966ce73d5c8SSunitha Harish const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
967ce73d5c8SSunitha Harish {
968ce73d5c8SSunitha Harish sdbusplus::message::object_path path("/xyz/openbmc_project/network");
969ce73d5c8SSunitha Harish path /= ifaceId;
970ce73d5c8SSunitha Harish auto createIpHandler = [asyncResp](const boost::system::error_code& ec) {
971ce73d5c8SSunitha Harish if (ec)
972ce73d5c8SSunitha Harish {
973ce73d5c8SSunitha Harish messages::internalError(asyncResp->res);
974ce73d5c8SSunitha Harish }
975ce73d5c8SSunitha Harish };
976ce73d5c8SSunitha Harish crow::connections::systemBus->async_method_call(
977ce73d5c8SSunitha Harish std::move(createIpHandler), "xyz.openbmc_project.Network", path,
978ce73d5c8SSunitha Harish "xyz.openbmc_project.Network.StaticGateway.Create", "StaticGateway",
979ab0d4390SRavi Teja gateway, "xyz.openbmc_project.Network.IP.Protocol.IPv6");
980ce73d5c8SSunitha Harish }
981ce73d5c8SSunitha Harish
982ce73d5c8SSunitha Harish /**
983ce73d5c8SSunitha Harish * @brief Deletes the IPv6 default gateway entry for this interface and
984ce73d5c8SSunitha Harish * creates a replacement IPv6 default gateway entry
985ce73d5c8SSunitha Harish *
986ce73d5c8SSunitha Harish * @param[in] ifaceId Id of interface upon which to create the IPv6
987ce73d5c8SSunitha Harish * entry
988ce73d5c8SSunitha Harish * @param[in] gateway IPv6 gateway to assign to this interface
989ce73d5c8SSunitha Harish * @param[io] asyncResp Response object that will be returned to client
990ce73d5c8SSunitha Harish *
991ce73d5c8SSunitha Harish * @return None
992ce73d5c8SSunitha Harish */
deleteAndCreateIPv6DefaultGateway(std::string_view ifaceId,std::string_view gatewayId,const std::string & gateway,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)993ce73d5c8SSunitha Harish inline void deleteAndCreateIPv6DefaultGateway(
994ce73d5c8SSunitha Harish std::string_view ifaceId, std::string_view gatewayId,
995cf91c8c4SAsmitha Karunanithi const std::string& gateway,
996ce73d5c8SSunitha Harish const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
997ce73d5c8SSunitha Harish {
998ce73d5c8SSunitha Harish sdbusplus::message::object_path path("/xyz/openbmc_project/network");
999739b27b2SRavi Teja path /= ifaceId;
1000ce73d5c8SSunitha Harish path /= gatewayId;
1001ce73d5c8SSunitha Harish crow::connections::systemBus->async_method_call(
1002ab0d4390SRavi Teja [asyncResp, ifaceId, gateway](const boost::system::error_code& ec) {
1003ce73d5c8SSunitha Harish if (ec)
1004ce73d5c8SSunitha Harish {
1005ce73d5c8SSunitha Harish messages::internalError(asyncResp->res);
1006ce73d5c8SSunitha Harish return;
1007ce73d5c8SSunitha Harish }
1008ab0d4390SRavi Teja createIPv6DefaultGateway(ifaceId, gateway, asyncResp);
1009ce73d5c8SSunitha Harish },
1010ce73d5c8SSunitha Harish "xyz.openbmc_project.Network", path,
1011ce73d5c8SSunitha Harish "xyz.openbmc_project.Object.Delete", "Delete");
1012ce73d5c8SSunitha Harish }
1013ce73d5c8SSunitha Harish
1014ce73d5c8SSunitha Harish /**
1015ce73d5c8SSunitha Harish * @brief Sets IPv6 default gateway with given data
1016ce73d5c8SSunitha Harish *
1017ce73d5c8SSunitha Harish * @param[in] ifaceId Id of interface whose gateway should be added
1018ce73d5c8SSunitha Harish * @param[in] input Contains address that needs to be added
1019ce73d5c8SSunitha Harish * @param[in] staticGatewayData Current static gateways in the system
1020ce73d5c8SSunitha Harish * @param[io] asyncResp Response object that will be returned to client
1021ce73d5c8SSunitha Harish *
1022ce73d5c8SSunitha Harish * @return None
1023ce73d5c8SSunitha Harish */
1024ce73d5c8SSunitha Harish
handleIPv6DefaultGateway(const std::string & ifaceId,std::vector<std::variant<nlohmann::json::object_t,std::nullptr_t>> & input,const std::vector<StaticGatewayData> & staticGatewayData,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)1025ce73d5c8SSunitha Harish inline void handleIPv6DefaultGateway(
10263dfed536SEd Tanous const std::string& ifaceId,
10273dfed536SEd Tanous std::vector<std::variant<nlohmann::json::object_t, std::nullptr_t>>& input,
1028ce73d5c8SSunitha Harish const std::vector<StaticGatewayData>& staticGatewayData,
1029ce73d5c8SSunitha Harish const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1030ce73d5c8SSunitha Harish {
1031ce73d5c8SSunitha Harish size_t entryIdx = 1;
1032ce73d5c8SSunitha Harish std::vector<StaticGatewayData>::const_iterator staticGatewayEntry =
1033ce73d5c8SSunitha Harish staticGatewayData.begin();
1034ce73d5c8SSunitha Harish
10353dfed536SEd Tanous for (std::variant<nlohmann::json::object_t, std::nullptr_t>& thisJson :
10363dfed536SEd Tanous input)
1037ce73d5c8SSunitha Harish {
1038ce73d5c8SSunitha Harish // find the next gateway entry
1039ce73d5c8SSunitha Harish while (staticGatewayEntry != staticGatewayData.end())
1040ce73d5c8SSunitha Harish {
1041ce73d5c8SSunitha Harish if (staticGatewayEntry->protocol ==
1042ce73d5c8SSunitha Harish "xyz.openbmc_project.Network.IP.Protocol.IPv6")
1043ce73d5c8SSunitha Harish {
1044ce73d5c8SSunitha Harish break;
1045ce73d5c8SSunitha Harish }
1046ce73d5c8SSunitha Harish staticGatewayEntry++;
1047ce73d5c8SSunitha Harish }
1048bd79bce8SPatrick Williams std::string pathString =
1049bd79bce8SPatrick Williams "IPv6StaticDefaultGateways/" + std::to_string(entryIdx);
10503dfed536SEd Tanous nlohmann::json::object_t* obj =
10513dfed536SEd Tanous std::get_if<nlohmann::json::object_t>(&thisJson);
10523dfed536SEd Tanous if (obj == nullptr)
1053ce73d5c8SSunitha Harish {
1054ce73d5c8SSunitha Harish if (staticGatewayEntry == staticGatewayData.end())
1055ce73d5c8SSunitha Harish {
1056ce73d5c8SSunitha Harish messages::resourceCannotBeDeleted(asyncResp->res);
1057ce73d5c8SSunitha Harish return;
1058ce73d5c8SSunitha Harish }
1059739b27b2SRavi Teja deleteIPv6Gateway(ifaceId, staticGatewayEntry->id, asyncResp);
1060ce73d5c8SSunitha Harish return;
1061ce73d5c8SSunitha Harish }
10623dfed536SEd Tanous if (obj->empty())
1063ce73d5c8SSunitha Harish {
1064ce73d5c8SSunitha Harish // Do nothing, but make sure the entry exists.
1065ce73d5c8SSunitha Harish if (staticGatewayEntry == staticGatewayData.end())
1066ce73d5c8SSunitha Harish {
10673dfed536SEd Tanous messages::propertyValueFormatError(asyncResp->res, *obj,
1068ce73d5c8SSunitha Harish pathString);
1069ce73d5c8SSunitha Harish return;
1070ce73d5c8SSunitha Harish }
1071ce73d5c8SSunitha Harish }
1072ce73d5c8SSunitha Harish std::optional<std::string> address;
1073ce73d5c8SSunitha Harish
1074ab0d4390SRavi Teja if (!json_util::readJsonObject(*obj, asyncResp->res, "Address",
1075ab0d4390SRavi Teja address))
1076ce73d5c8SSunitha Harish {
1077ce73d5c8SSunitha Harish return;
1078ce73d5c8SSunitha Harish }
1079ce73d5c8SSunitha Harish const std::string* addr = nullptr;
1080ce73d5c8SSunitha Harish if (address)
1081ce73d5c8SSunitha Harish {
1082ce73d5c8SSunitha Harish addr = &(*address);
1083ce73d5c8SSunitha Harish }
1084ce73d5c8SSunitha Harish else if (staticGatewayEntry != staticGatewayData.end())
1085ce73d5c8SSunitha Harish {
1086ce73d5c8SSunitha Harish addr = &(staticGatewayEntry->gateway);
1087ce73d5c8SSunitha Harish }
1088ce73d5c8SSunitha Harish else
1089ce73d5c8SSunitha Harish {
1090ce73d5c8SSunitha Harish messages::propertyMissing(asyncResp->res, pathString + "/Address");
1091ce73d5c8SSunitha Harish return;
1092ce73d5c8SSunitha Harish }
1093ce73d5c8SSunitha Harish if (staticGatewayEntry != staticGatewayData.end())
1094ce73d5c8SSunitha Harish {
1095ce73d5c8SSunitha Harish deleteAndCreateIPv6DefaultGateway(ifaceId, staticGatewayEntry->id,
1096ab0d4390SRavi Teja *addr, asyncResp);
1097ce73d5c8SSunitha Harish staticGatewayEntry++;
1098ce73d5c8SSunitha Harish }
1099ce73d5c8SSunitha Harish else
1100ce73d5c8SSunitha Harish {
1101ab0d4390SRavi Teja createIPv6DefaultGateway(ifaceId, *addr, asyncResp);
1102ce73d5c8SSunitha Harish }
1103ce73d5c8SSunitha Harish entryIdx++;
1104ce73d5c8SSunitha Harish }
1105ce73d5c8SSunitha Harish }
1106ce73d5c8SSunitha Harish
1107ce73d5c8SSunitha Harish /**
1108179db1d7SKowalski, Kamil * Function that retrieves all properties for given Ethernet Interface
1109179db1d7SKowalski, Kamil * Object
1110179db1d7SKowalski, Kamil * from EntityManager Network Manager
11114a0cb85cSEd Tanous * @param ethiface_id a eth interface id to query on DBus
1112179db1d7SKowalski, Kamil * @param callback a function that shall be called to convert Dbus output
1113179db1d7SKowalski, Kamil * into JSON
1114179db1d7SKowalski, Kamil */
1115179db1d7SKowalski, Kamil template <typename CallbackFunc>
getEthernetIfaceData(const std::string & ethifaceId,CallbackFunc && callback)111681ce609eSEd Tanous void getEthernetIfaceData(const std::string& ethifaceId,
11171abe55efSEd Tanous CallbackFunc&& callback)
11181abe55efSEd Tanous {
1119f5892d0dSGeorge Liu sdbusplus::message::object_path path("/xyz/openbmc_project/network");
1120f5892d0dSGeorge Liu dbus::utility::getManagedObjects(
1121f5892d0dSGeorge Liu "xyz.openbmc_project.Network", path,
1122f94c4ecfSEd Tanous [ethifaceId{std::string{ethifaceId}},
11238cb2c024SEd Tanous callback = std::forward<CallbackFunc>(callback)](
11248b24275dSEd Tanous const boost::system::error_code& ec,
11253dfed536SEd Tanous const dbus::utility::ManagedObjectType& resp) mutable {
112655c7b7a2SEd Tanous EthernetInterfaceData ethData{};
112777179532SEd Tanous std::vector<IPv4AddressData> ipv4Data;
112877179532SEd Tanous std::vector<IPv6AddressData> ipv6Data;
1129ce73d5c8SSunitha Harish std::vector<StaticGatewayData> ipv6GatewayData;
1130179db1d7SKowalski, Kamil
11318b24275dSEd Tanous if (ec)
11321abe55efSEd Tanous {
1133ce73d5c8SSunitha Harish callback(false, ethData, ipv4Data, ipv6Data, ipv6GatewayData);
1134179db1d7SKowalski, Kamil return;
1135179db1d7SKowalski, Kamil }
1136179db1d7SKowalski, Kamil
1137bd79bce8SPatrick Williams bool found =
1138bd79bce8SPatrick Williams extractEthernetInterfaceData(ethifaceId, resp, ethData);
11394c9afe43SEd Tanous if (!found)
11404c9afe43SEd Tanous {
1141ce73d5c8SSunitha Harish callback(false, ethData, ipv4Data, ipv6Data, ipv6GatewayData);
11424c9afe43SEd Tanous return;
11434c9afe43SEd Tanous }
11444c9afe43SEd Tanous
11452c70f800SEd Tanous extractIPData(ethifaceId, resp, ipv4Data);
1146179db1d7SKowalski, Kamil // Fix global GW
11471abe55efSEd Tanous for (IPv4AddressData& ipv4 : ipv4Data)
11481abe55efSEd Tanous {
1149c619141bSRavi Teja if (((ipv4.linktype == LinkType::Global) &&
1150c619141bSRavi Teja (ipv4.gateway == "0.0.0.0")) ||
11519010ec2eSRavi Teja (ipv4.origin == "DHCP") || (ipv4.origin == "Static"))
11521abe55efSEd Tanous {
115382695a5bSJiaqing Zhao ipv4.gateway = ethData.defaultGateway;
1154179db1d7SKowalski, Kamil }
1155179db1d7SKowalski, Kamil }
1156179db1d7SKowalski, Kamil
11572c70f800SEd Tanous extractIPV6Data(ethifaceId, resp, ipv6Data);
1158bd79bce8SPatrick Williams if (!extractIPv6DefaultGatewayData(ethifaceId, resp,
1159bd79bce8SPatrick Williams ipv6GatewayData))
1160ce73d5c8SSunitha Harish {
1161ce73d5c8SSunitha Harish callback(false, ethData, ipv4Data, ipv6Data, ipv6GatewayData);
1162ce73d5c8SSunitha Harish }
11634e0453b1SGunnar Mills // Finally make a callback with useful data
1164ce73d5c8SSunitha Harish callback(true, ethData, ipv4Data, ipv6Data, ipv6GatewayData);
1165f5892d0dSGeorge Liu });
1166271584abSEd Tanous }
1167179db1d7SKowalski, Kamil
1168179db1d7SKowalski, Kamil /**
11699391bb9cSRapkiewicz, Pawel * Function that retrieves all Ethernet Interfaces available through Network
11709391bb9cSRapkiewicz, Pawel * Manager
11711abe55efSEd Tanous * @param callback a function that shall be called to convert Dbus output
11721abe55efSEd Tanous * into JSON.
11739391bb9cSRapkiewicz, Pawel */
11749391bb9cSRapkiewicz, Pawel template <typename CallbackFunc>
getEthernetIfaceList(CallbackFunc && callback)11751abe55efSEd Tanous void getEthernetIfaceList(CallbackFunc&& callback)
11761abe55efSEd Tanous {
1177f5892d0dSGeorge Liu sdbusplus::message::object_path path("/xyz/openbmc_project/network");
1178f5892d0dSGeorge Liu dbus::utility::getManagedObjects(
1179f5892d0dSGeorge Liu "xyz.openbmc_project.Network", path,
11808cb2c024SEd Tanous [callback = std::forward<CallbackFunc>(callback)](
11818b24275dSEd Tanous const boost::system::error_code& ec,
1182f5892d0dSGeorge Liu const dbus::utility::ManagedObjectType& resp) {
11831abe55efSEd Tanous // Callback requires vector<string> to retrieve all available
11841abe55efSEd Tanous // ethernet interfaces
118577179532SEd Tanous std::vector<std::string> ifaceList;
11862c70f800SEd Tanous ifaceList.reserve(resp.size());
11878b24275dSEd Tanous if (ec)
11881abe55efSEd Tanous {
11892c70f800SEd Tanous callback(false, ifaceList);
11909391bb9cSRapkiewicz, Pawel return;
11919391bb9cSRapkiewicz, Pawel }
11929391bb9cSRapkiewicz, Pawel
11939391bb9cSRapkiewicz, Pawel // Iterate over all retrieved ObjectPaths.
11944a0cb85cSEd Tanous for (const auto& objpath : resp)
11951abe55efSEd Tanous {
11969391bb9cSRapkiewicz, Pawel // And all interfaces available for certain ObjectPath.
11974a0cb85cSEd Tanous for (const auto& interface : objpath.second)
11981abe55efSEd Tanous {
11991abe55efSEd Tanous // If interface is
12004a0cb85cSEd Tanous // xyz.openbmc_project.Network.EthernetInterface, this is
12014a0cb85cSEd Tanous // what we're looking for.
12029391bb9cSRapkiewicz, Pawel if (interface.first ==
12031abe55efSEd Tanous "xyz.openbmc_project.Network.EthernetInterface")
12041abe55efSEd Tanous {
12052dfd18efSEd Tanous std::string ifaceId = objpath.first.filename();
12062dfd18efSEd Tanous if (ifaceId.empty())
12071abe55efSEd Tanous {
12082dfd18efSEd Tanous continue;
12099391bb9cSRapkiewicz, Pawel }
12102dfd18efSEd Tanous // and put it into output vector.
121177179532SEd Tanous ifaceList.emplace_back(ifaceId);
12129391bb9cSRapkiewicz, Pawel }
12139391bb9cSRapkiewicz, Pawel }
12149391bb9cSRapkiewicz, Pawel }
12152c5875a2SEd Tanous
12163544d2a7SEd Tanous std::ranges::sort(ifaceList, AlphanumLess<std::string>());
12172c5875a2SEd Tanous
1218a434f2bdSEd Tanous // Finally make a callback with useful data
12192c70f800SEd Tanous callback(true, ifaceList);
1220f5892d0dSGeorge Liu });
1221271584abSEd Tanous }
12229391bb9cSRapkiewicz, Pawel
handleHostnamePatch(const std::string & hostname,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)1223*504af5a0SPatrick Williams inline void handleHostnamePatch(
1224*504af5a0SPatrick Williams const std::string& hostname,
12258d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
12261abe55efSEd Tanous {
1227ab6554f1SJoshi-Mansi // SHOULD handle host names of up to 255 characters(RFC 1123)
1228ab6554f1SJoshi-Mansi if (hostname.length() > 255)
1229ab6554f1SJoshi-Mansi {
1230ab6554f1SJoshi-Mansi messages::propertyValueFormatError(asyncResp->res, hostname,
1231ab6554f1SJoshi-Mansi "HostName");
1232ab6554f1SJoshi-Mansi return;
1233ab6554f1SJoshi-Mansi }
1234d02aad39SEd Tanous setDbusProperty(
1235e93abac6SGinu George asyncResp, "HostName", "xyz.openbmc_project.Network",
1236d02aad39SEd Tanous sdbusplus::message::object_path("/xyz/openbmc_project/network/config"),
1237d02aad39SEd Tanous "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
1238e93abac6SGinu George hostname);
1239588c3f0dSKowalski, Kamil }
1240588c3f0dSKowalski, Kamil
handleMTUSizePatch(const std::string & ifaceId,const size_t mtuSize,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)1241*504af5a0SPatrick Williams inline void handleMTUSizePatch(
1242*504af5a0SPatrick Williams const std::string& ifaceId, const size_t mtuSize,
124335fb5311STejas Patil const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
124435fb5311STejas Patil {
1245d02aad39SEd Tanous sdbusplus::message::object_path objPath("/xyz/openbmc_project/network");
1246d02aad39SEd Tanous objPath /= ifaceId;
1247e93abac6SGinu George setDbusProperty(asyncResp, "MTUSize", "xyz.openbmc_project.Network",
1248e93abac6SGinu George objPath, "xyz.openbmc_project.Network.EthernetInterface",
1249e93abac6SGinu George "MTU", mtuSize);
125035fb5311STejas Patil }
125135fb5311STejas Patil
handleDomainnamePatch(const std::string & ifaceId,const std::string & domainname,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)1252bd79bce8SPatrick Williams inline void handleDomainnamePatch(
1253bd79bce8SPatrick Williams const std::string& ifaceId, const std::string& domainname,
12548d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1255ab6554f1SJoshi-Mansi {
1256ab6554f1SJoshi-Mansi std::vector<std::string> vectorDomainname = {domainname};
1257d02aad39SEd Tanous setDbusProperty(
1258e93abac6SGinu George asyncResp, "FQDN", "xyz.openbmc_project.Network",
1259d02aad39SEd Tanous sdbusplus::message::object_path("/xyz/openbmc_project/network") /
1260d02aad39SEd Tanous ifaceId,
1261e93abac6SGinu George "xyz.openbmc_project.Network.EthernetInterface", "DomainName",
1262d02aad39SEd Tanous vectorDomainname);
1263ab6554f1SJoshi-Mansi }
1264ab6554f1SJoshi-Mansi
isHostnameValid(const std::string & hostname)12654f48d5f6SEd Tanous inline bool isHostnameValid(const std::string& hostname)
1266bf648f77SEd Tanous {
1267bf648f77SEd Tanous // A valid host name can never have the dotted-decimal form (RFC 1123)
12683544d2a7SEd Tanous if (std::ranges::all_of(hostname, ::isdigit))
1269bf648f77SEd Tanous {
1270bf648f77SEd Tanous return false;
1271bf648f77SEd Tanous }
1272bf648f77SEd Tanous // Each label(hostname/subdomains) within a valid FQDN
1273bf648f77SEd Tanous // MUST handle host names of up to 63 characters (RFC 1123)
1274bf648f77SEd Tanous // labels cannot start or end with hyphens (RFC 952)
1275bf648f77SEd Tanous // labels can start with numbers (RFC 1123)
12764b242749SEd Tanous const static std::regex pattern(
1277bf648f77SEd Tanous "^[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]$");
1278bf648f77SEd Tanous
1279bf648f77SEd Tanous return std::regex_match(hostname, pattern);
1280bf648f77SEd Tanous }
1281bf648f77SEd Tanous
isDomainnameValid(const std::string & domainname)12824f48d5f6SEd Tanous inline bool isDomainnameValid(const std::string& domainname)
1283bf648f77SEd Tanous {
1284bf648f77SEd Tanous // Can have multiple subdomains
1285bf648f77SEd Tanous // Top Level Domain's min length is 2 character
12864b242749SEd Tanous const static std::regex pattern(
12870fda0f12SGeorge Liu "^([A-Za-z0-9][a-zA-Z0-9\\-]{1,61}|[a-zA-Z0-9]{1,30}\\.)*[a-zA-Z]{2,}$");
1288bf648f77SEd Tanous
1289bf648f77SEd Tanous return std::regex_match(domainname, pattern);
1290bf648f77SEd Tanous }
1291bf648f77SEd Tanous
handleFqdnPatch(const std::string & ifaceId,const std::string & fqdn,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)12924f48d5f6SEd Tanous inline void handleFqdnPatch(const std::string& ifaceId, const std::string& fqdn,
12938d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1294ab6554f1SJoshi-Mansi {
1295ab6554f1SJoshi-Mansi // Total length of FQDN must not exceed 255 characters(RFC 1035)
1296ab6554f1SJoshi-Mansi if (fqdn.length() > 255)
1297ab6554f1SJoshi-Mansi {
1298ab6554f1SJoshi-Mansi messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN");
1299ab6554f1SJoshi-Mansi return;
1300ab6554f1SJoshi-Mansi }
1301ab6554f1SJoshi-Mansi
1302ab6554f1SJoshi-Mansi size_t pos = fqdn.find('.');
1303ab6554f1SJoshi-Mansi if (pos == std::string::npos)
1304ab6554f1SJoshi-Mansi {
1305ab6554f1SJoshi-Mansi messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN");
1306ab6554f1SJoshi-Mansi return;
1307ab6554f1SJoshi-Mansi }
1308ab6554f1SJoshi-Mansi
1309ab6554f1SJoshi-Mansi std::string hostname;
1310ab6554f1SJoshi-Mansi std::string domainname;
1311ab6554f1SJoshi-Mansi domainname = (fqdn).substr(pos + 1);
1312ab6554f1SJoshi-Mansi hostname = (fqdn).substr(0, pos);
1313ab6554f1SJoshi-Mansi
1314ab6554f1SJoshi-Mansi if (!isHostnameValid(hostname) || !isDomainnameValid(domainname))
1315ab6554f1SJoshi-Mansi {
1316ab6554f1SJoshi-Mansi messages::propertyValueFormatError(asyncResp->res, fqdn, "FQDN");
1317ab6554f1SJoshi-Mansi return;
1318ab6554f1SJoshi-Mansi }
1319ab6554f1SJoshi-Mansi
1320ab6554f1SJoshi-Mansi handleHostnamePatch(hostname, asyncResp);
1321ab6554f1SJoshi-Mansi handleDomainnamePatch(ifaceId, domainname, asyncResp);
1322ab6554f1SJoshi-Mansi }
1323ab6554f1SJoshi-Mansi
handleMACAddressPatch(const std::string & ifaceId,const std::string & macAddress,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)1324bd79bce8SPatrick Williams inline void handleMACAddressPatch(
1325bd79bce8SPatrick Williams const std::string& ifaceId, const std::string& macAddress,
13268d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1327d577665bSRatan Gupta {
1328d02aad39SEd Tanous setDbusProperty(
1329e93abac6SGinu George asyncResp, "MACAddress", "xyz.openbmc_project.Network",
1330d02aad39SEd Tanous sdbusplus::message::object_path("/xyz/openbmc_project/network") /
1331d02aad39SEd Tanous ifaceId,
1332e93abac6SGinu George "xyz.openbmc_project.Network.MACAddress", "MACAddress", macAddress);
1333d577665bSRatan Gupta }
1334286b9118SJohnathan Mantey
setDHCPEnabled(const std::string & ifaceId,const std::string & propertyName,const bool v4Value,const bool v6Value,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)13354f48d5f6SEd Tanous inline void setDHCPEnabled(const std::string& ifaceId,
13364f48d5f6SEd Tanous const std::string& propertyName, const bool v4Value,
13374f48d5f6SEd Tanous const bool v6Value,
13388d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1339da131a9aSJennifer Lee {
13402c70f800SEd Tanous const std::string dhcp = getDhcpEnabledEnumeration(v4Value, v6Value);
1341d02aad39SEd Tanous setDbusProperty(
1342e93abac6SGinu George asyncResp, "DHCPv4", "xyz.openbmc_project.Network",
1343d02aad39SEd Tanous sdbusplus::message::object_path("/xyz/openbmc_project/network") /
1344d02aad39SEd Tanous ifaceId,
1345e93abac6SGinu George "xyz.openbmc_project.Network.EthernetInterface", propertyName, dhcp);
1346eeedda23SJohnathan Mantey }
1347eeedda23SJohnathan Mantey
1348e4588158SJishnu CM enum class NetworkType
1349e4588158SJishnu CM {
1350e4588158SJishnu CM dhcp4,
1351e4588158SJishnu CM dhcp6
1352e4588158SJishnu CM };
1353e4588158SJishnu CM
setDHCPConfig(const std::string & propertyName,const bool & value,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & ethifaceId,NetworkType type)1354e4588158SJishnu CM inline void setDHCPConfig(const std::string& propertyName, const bool& value,
1355e4588158SJishnu CM const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1356e4588158SJishnu CM const std::string& ethifaceId, NetworkType type)
1357da131a9aSJennifer Lee {
135862598e31SEd Tanous BMCWEB_LOG_DEBUG("{} = {}", propertyName, value);
13591847f2a0SAsmitha Karunanithi std::string redfishPropertyName;
1360e4588158SJishnu CM sdbusplus::message::object_path path("/xyz/openbmc_project/network/");
1361e4588158SJishnu CM path /= ethifaceId;
1362e4588158SJishnu CM
1363e4588158SJishnu CM if (type == NetworkType::dhcp4)
1364e4588158SJishnu CM {
1365e4588158SJishnu CM path /= "dhcp4";
13661847f2a0SAsmitha Karunanithi redfishPropertyName = "DHCPv4";
1367e4588158SJishnu CM }
1368e4588158SJishnu CM else
1369e4588158SJishnu CM {
1370e4588158SJishnu CM path /= "dhcp6";
13711847f2a0SAsmitha Karunanithi redfishPropertyName = "DHCPv6";
1372e4588158SJishnu CM }
1373e4588158SJishnu CM
1374e93abac6SGinu George setDbusProperty(
1375e93abac6SGinu George asyncResp, redfishPropertyName, "xyz.openbmc_project.Network", path,
1376e93abac6SGinu George "xyz.openbmc_project.Network.DHCPConfiguration", propertyName, value);
1377da131a9aSJennifer Lee }
1378d577665bSRatan Gupta
handleSLAACAutoConfigPatch(const std::string & ifaceId,bool ipv6AutoConfigEnabled,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)1379b10d8db0SRavi Teja inline void handleSLAACAutoConfigPatch(
1380b10d8db0SRavi Teja const std::string& ifaceId, bool ipv6AutoConfigEnabled,
1381b10d8db0SRavi Teja const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1382b10d8db0SRavi Teja {
1383b10d8db0SRavi Teja sdbusplus::message::object_path path("/xyz/openbmc_project/network");
1384b10d8db0SRavi Teja path /= ifaceId;
1385e93abac6SGinu George setDbusProperty(asyncResp,
13861847f2a0SAsmitha Karunanithi "StatelessAddressAutoConfig/IPv6AutoConfigEnabled",
1387e93abac6SGinu George "xyz.openbmc_project.Network", path,
1388e93abac6SGinu George "xyz.openbmc_project.Network.EthernetInterface",
1389e93abac6SGinu George "IPv6AcceptRA", ipv6AutoConfigEnabled);
1390b10d8db0SRavi Teja }
1391b10d8db0SRavi Teja
handleDHCPPatch(const std::string & ifaceId,const EthernetInterfaceData & ethData,const DHCPParameters & v4dhcpParms,const DHCPParameters & v6dhcpParms,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)1392bd79bce8SPatrick Williams inline void handleDHCPPatch(
1393bd79bce8SPatrick Williams const std::string& ifaceId, const EthernetInterfaceData& ethData,
1394bd79bce8SPatrick Williams const DHCPParameters& v4dhcpParms, const DHCPParameters& v6dhcpParms,
13958d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1396da131a9aSJennifer Lee {
139782695a5bSJiaqing Zhao bool ipv4Active = translateDhcpEnabledToBool(ethData.dhcpEnabled, true);
139882695a5bSJiaqing Zhao bool ipv6Active = translateDhcpEnabledToBool(ethData.dhcpEnabled, false);
1399da131a9aSJennifer Lee
1400743eb1c0SJohnathan Mantey if (ipv4Active)
1401743eb1c0SJohnathan Mantey {
1402743eb1c0SJohnathan Mantey updateIPv4DefaultGateway(ifaceId, "", asyncResp);
1403743eb1c0SJohnathan Mantey }
14041f8c7b5dSJohnathan Mantey bool nextv4DHCPState =
14051f8c7b5dSJohnathan Mantey v4dhcpParms.dhcpv4Enabled ? *v4dhcpParms.dhcpv4Enabled : ipv4Active;
14061f8c7b5dSJohnathan Mantey
14071f8c7b5dSJohnathan Mantey bool nextv6DHCPState{};
14081f8c7b5dSJohnathan Mantey if (v6dhcpParms.dhcpv6OperatingMode)
1409da131a9aSJennifer Lee {
1410b10d8db0SRavi Teja if ((*v6dhcpParms.dhcpv6OperatingMode != "Enabled") &&
14111f8c7b5dSJohnathan Mantey (*v6dhcpParms.dhcpv6OperatingMode != "Disabled"))
14121f8c7b5dSJohnathan Mantey {
1413bf648f77SEd Tanous messages::propertyValueFormatError(asyncResp->res,
1414bf648f77SEd Tanous *v6dhcpParms.dhcpv6OperatingMode,
14151f8c7b5dSJohnathan Mantey "OperatingMode");
1416da131a9aSJennifer Lee return;
1417da131a9aSJennifer Lee }
1418b10d8db0SRavi Teja nextv6DHCPState = (*v6dhcpParms.dhcpv6OperatingMode == "Enabled");
14191f8c7b5dSJohnathan Mantey }
14201f8c7b5dSJohnathan Mantey else
1421da131a9aSJennifer Lee {
14221f8c7b5dSJohnathan Mantey nextv6DHCPState = ipv6Active;
14231f8c7b5dSJohnathan Mantey }
14241f8c7b5dSJohnathan Mantey
1425e4588158SJishnu CM bool nextDNSv4 = ethData.dnsv4Enabled;
1426e4588158SJishnu CM bool nextDNSv6 = ethData.dnsv6Enabled;
1427e4588158SJishnu CM if (v4dhcpParms.useDnsServers)
14281f8c7b5dSJohnathan Mantey {
1429e4588158SJishnu CM nextDNSv4 = *v4dhcpParms.useDnsServers;
14301f8c7b5dSJohnathan Mantey }
1431e4588158SJishnu CM if (v6dhcpParms.useDnsServers)
14321f8c7b5dSJohnathan Mantey {
1433e4588158SJishnu CM nextDNSv6 = *v6dhcpParms.useDnsServers;
14341f8c7b5dSJohnathan Mantey }
14351f8c7b5dSJohnathan Mantey
1436e4588158SJishnu CM bool nextNTPv4 = ethData.ntpv4Enabled;
1437e4588158SJishnu CM bool nextNTPv6 = ethData.ntpv6Enabled;
1438e4588158SJishnu CM if (v4dhcpParms.useNtpServers)
14391f8c7b5dSJohnathan Mantey {
1440e4588158SJishnu CM nextNTPv4 = *v4dhcpParms.useNtpServers;
14411f8c7b5dSJohnathan Mantey }
1442e4588158SJishnu CM if (v6dhcpParms.useNtpServers)
14431f8c7b5dSJohnathan Mantey {
1444e4588158SJishnu CM nextNTPv6 = *v6dhcpParms.useNtpServers;
14451f8c7b5dSJohnathan Mantey }
14461f8c7b5dSJohnathan Mantey
144791c441ecSRavi Teja bool nextUsev4Domain = ethData.domainv4Enabled;
144891c441ecSRavi Teja bool nextUsev6Domain = ethData.domainv6Enabled;
1449e4588158SJishnu CM if (v4dhcpParms.useDomainName)
14501f8c7b5dSJohnathan Mantey {
1451e4588158SJishnu CM nextUsev4Domain = *v4dhcpParms.useDomainName;
14521f8c7b5dSJohnathan Mantey }
1453e4588158SJishnu CM if (v6dhcpParms.useDomainName)
14541f8c7b5dSJohnathan Mantey {
1455e4588158SJishnu CM nextUsev6Domain = *v6dhcpParms.useDomainName;
14561f8c7b5dSJohnathan Mantey }
14571f8c7b5dSJohnathan Mantey
145862598e31SEd Tanous BMCWEB_LOG_DEBUG("set DHCPEnabled...");
14591f8c7b5dSJohnathan Mantey setDHCPEnabled(ifaceId, "DHCPEnabled", nextv4DHCPState, nextv6DHCPState,
14601f8c7b5dSJohnathan Mantey asyncResp);
146162598e31SEd Tanous BMCWEB_LOG_DEBUG("set DNSEnabled...");
1462e4588158SJishnu CM setDHCPConfig("DNSEnabled", nextDNSv4, asyncResp, ifaceId,
1463e4588158SJishnu CM NetworkType::dhcp4);
146462598e31SEd Tanous BMCWEB_LOG_DEBUG("set NTPEnabled...");
1465e4588158SJishnu CM setDHCPConfig("NTPEnabled", nextNTPv4, asyncResp, ifaceId,
1466e4588158SJishnu CM NetworkType::dhcp4);
146791c441ecSRavi Teja BMCWEB_LOG_DEBUG("set DomainEnabled...");
146891c441ecSRavi Teja setDHCPConfig("DomainEnabled", nextUsev4Domain, asyncResp, ifaceId,
1469e4588158SJishnu CM NetworkType::dhcp4);
1470e4588158SJishnu CM BMCWEB_LOG_DEBUG("set DNSEnabled for dhcp6...");
1471e4588158SJishnu CM setDHCPConfig("DNSEnabled", nextDNSv6, asyncResp, ifaceId,
1472e4588158SJishnu CM NetworkType::dhcp6);
1473e4588158SJishnu CM BMCWEB_LOG_DEBUG("set NTPEnabled for dhcp6...");
1474e4588158SJishnu CM setDHCPConfig("NTPEnabled", nextNTPv6, asyncResp, ifaceId,
1475e4588158SJishnu CM NetworkType::dhcp6);
147691c441ecSRavi Teja BMCWEB_LOG_DEBUG("set DomainEnabled for dhcp6...");
147791c441ecSRavi Teja setDHCPConfig("DomainEnabled", nextUsev6Domain, asyncResp, ifaceId,
1478e4588158SJishnu CM NetworkType::dhcp6);
1479da131a9aSJennifer Lee }
148001784826SJohnathan Mantey
getNextStaticIpEntry(const std::vector<IPv4AddressData>::const_iterator & head,const std::vector<IPv4AddressData>::const_iterator & end)148177179532SEd Tanous inline std::vector<IPv4AddressData>::const_iterator getNextStaticIpEntry(
148277179532SEd Tanous const std::vector<IPv4AddressData>::const_iterator& head,
148377179532SEd Tanous const std::vector<IPv4AddressData>::const_iterator& end)
148401784826SJohnathan Mantey {
148517a897dfSManojkiran Eda return std::find_if(head, end, [](const IPv4AddressData& value) {
148617a897dfSManojkiran Eda return value.origin == "Static";
148717a897dfSManojkiran Eda });
148801784826SJohnathan Mantey }
148901784826SJohnathan Mantey
getNextStaticIpEntry(const std::vector<IPv6AddressData>::const_iterator & head,const std::vector<IPv6AddressData>::const_iterator & end)149077179532SEd Tanous inline std::vector<IPv6AddressData>::const_iterator getNextStaticIpEntry(
149177179532SEd Tanous const std::vector<IPv6AddressData>::const_iterator& head,
149277179532SEd Tanous const std::vector<IPv6AddressData>::const_iterator& end)
149301784826SJohnathan Mantey {
149417a897dfSManojkiran Eda return std::find_if(head, end, [](const IPv6AddressData& value) {
149517a897dfSManojkiran Eda return value.origin == "Static";
149617a897dfSManojkiran Eda });
149701784826SJohnathan Mantey }
149801784826SJohnathan Mantey
14996e1a52faSEd Tanous enum class AddrChange
15001abe55efSEd Tanous {
15016e1a52faSEd Tanous Noop,
15026e1a52faSEd Tanous Delete,
15036e1a52faSEd Tanous Update,
15046e1a52faSEd Tanous };
15056e1a52faSEd Tanous
15066e1a52faSEd Tanous // Struct representing a dbus change
15076e1a52faSEd Tanous struct AddressPatch
15086e1a52faSEd Tanous {
15096e1a52faSEd Tanous std::string address;
15106e1a52faSEd Tanous std::string gateway;
15116e1a52faSEd Tanous uint8_t prefixLength = 0;
15126e1a52faSEd Tanous std::string existingDbusId;
15136e1a52faSEd Tanous AddrChange operation = AddrChange::Noop;
15146e1a52faSEd Tanous };
15156e1a52faSEd Tanous
parseAddresses(std::vector<std::variant<nlohmann::json::object_t,std::nullptr_t>> & input,const std::vector<IPv4AddressData> & ipv4Data,crow::Response & res,std::vector<AddressPatch> & addressesOut,std::string & gatewayOut)15166e1a52faSEd Tanous inline bool parseAddresses(
15176e1a52faSEd Tanous std::vector<std::variant<nlohmann::json::object_t, std::nullptr_t>>& input,
15186e1a52faSEd Tanous const std::vector<IPv4AddressData>& ipv4Data, crow::Response& res,
15196e1a52faSEd Tanous std::vector<AddressPatch>& addressesOut, std::string& gatewayOut)
15206e1a52faSEd Tanous {
152177179532SEd Tanous std::vector<IPv4AddressData>::const_iterator nicIpEntry =
15222c70f800SEd Tanous getNextStaticIpEntry(ipv4Data.cbegin(), ipv4Data.cend());
152301784826SJohnathan Mantey
15246e1a52faSEd Tanous std::string lastGatewayPath;
15256e1a52faSEd Tanous size_t entryIdx = 0;
15263dfed536SEd Tanous for (std::variant<nlohmann::json::object_t, std::nullptr_t>& thisJson :
15273dfed536SEd Tanous input)
15281abe55efSEd Tanous {
1529bd79bce8SPatrick Williams std::string pathString =
15306e1a52faSEd Tanous std::format("IPv4StaticAddresses/{}", entryIdx);
15316e1a52faSEd Tanous AddressPatch& thisAddress = addressesOut.emplace_back();
15323dfed536SEd Tanous nlohmann::json::object_t* obj =
15333dfed536SEd Tanous std::get_if<nlohmann::json::object_t>(&thisJson);
1534743eb1c0SJohnathan Mantey if (nicIpEntry != ipv4Data.cend())
1535743eb1c0SJohnathan Mantey {
15366e1a52faSEd Tanous thisAddress.existingDbusId = nicIpEntry->id;
1537743eb1c0SJohnathan Mantey }
1538743eb1c0SJohnathan Mantey
15396e1a52faSEd Tanous if (obj == nullptr)
15406e1a52faSEd Tanous {
15416e1a52faSEd Tanous if (thisAddress.existingDbusId.empty())
15426e1a52faSEd Tanous {
15436e1a52faSEd Tanous // Received a DELETE action on an entry not assigned to the NIC
15446e1a52faSEd Tanous messages::resourceCannotBeDeleted(res);
15456e1a52faSEd Tanous return false;
15466e1a52faSEd Tanous }
15476e1a52faSEd Tanous thisAddress.operation = AddrChange::Delete;
15486e1a52faSEd Tanous }
15496e1a52faSEd Tanous else
1550f476acbfSRatan Gupta {
1551537174c4SEd Tanous std::optional<std::string> address;
1552537174c4SEd Tanous std::optional<std::string> gateway;
15536e1a52faSEd Tanous std::optional<std::string> subnetMask;
15546e1a52faSEd Tanous if (!obj->empty())
15556e1a52faSEd Tanous {
1556afc474aeSMyung Bae if (!json_util::readJsonObject( //
15576e1a52faSEd Tanous *obj, res, //
1558afc474aeSMyung Bae "Address", address, //
1559afc474aeSMyung Bae "Gateway", gateway, //
1560afc474aeSMyung Bae "SubnetMask", subnetMask //
1561afc474aeSMyung Bae ))
1562537174c4SEd Tanous {
15636e1a52faSEd Tanous messages::propertyValueFormatError(res, *obj, pathString);
15646e1a52faSEd Tanous return false;
1565179db1d7SKowalski, Kamil }
15666e1a52faSEd Tanous }
156701784826SJohnathan Mantey // Find the address/subnet/gateway values. Any values that are
156801784826SJohnathan Mantey // not explicitly provided are assumed to be unmodified from the
156901784826SJohnathan Mantey // current state of the interface. Merge existing state into the
157001784826SJohnathan Mantey // current request.
1571537174c4SEd Tanous if (address)
15721abe55efSEd Tanous {
1573e01d0c36SEd Tanous if (!ip_util::ipv4VerifyIpAndGetBitcount(*address))
157401784826SJohnathan Mantey {
15756e1a52faSEd Tanous messages::propertyValueFormatError(res, *address,
1576bf648f77SEd Tanous pathString + "/Address");
15776e1a52faSEd Tanous return false;
157801784826SJohnathan Mantey }
15796e1a52faSEd Tanous thisAddress.operation = AddrChange::Update;
15806e1a52faSEd Tanous thisAddress.address = *address;
158101784826SJohnathan Mantey }
15826e1a52faSEd Tanous else if (thisAddress.existingDbusId.empty())
158301784826SJohnathan Mantey {
15846e1a52faSEd Tanous messages::propertyMissing(res, pathString + "/Address");
15856e1a52faSEd Tanous return false;
158601784826SJohnathan Mantey }
158701784826SJohnathan Mantey else
158801784826SJohnathan Mantey {
15896e1a52faSEd Tanous thisAddress.address = nicIpEntry->address;
15904a0cb85cSEd Tanous }
15914a0cb85cSEd Tanous
1592537174c4SEd Tanous if (subnetMask)
15934a0cb85cSEd Tanous {
15946e1a52faSEd Tanous uint8_t prefixLength = 0;
1595033f1e4dSEd Tanous if (!ip_util::ipv4VerifyIpAndGetBitcount(*subnetMask,
1596033f1e4dSEd Tanous &prefixLength))
15974a0cb85cSEd Tanous {
1598f12894f8SJason M. Bills messages::propertyValueFormatError(
15996e1a52faSEd Tanous res, *subnetMask, pathString + "/SubnetMask");
16006e1a52faSEd Tanous return false;
16014a0cb85cSEd Tanous }
16026e1a52faSEd Tanous thisAddress.prefixLength = prefixLength;
16036e1a52faSEd Tanous thisAddress.operation = AddrChange::Update;
16044a0cb85cSEd Tanous }
16056e1a52faSEd Tanous else if (thisAddress.existingDbusId.empty())
16064a0cb85cSEd Tanous {
16076e1a52faSEd Tanous messages::propertyMissing(res, pathString + "/SubnetMask");
16086e1a52faSEd Tanous return false;
16094a0cb85cSEd Tanous }
16101abe55efSEd Tanous else
16111abe55efSEd Tanous {
16126e1a52faSEd Tanous uint8_t prefixLength = 0;
16136e1a52faSEd Tanous // Ignore return code. It came from internal, it's it's invalid
16146e1a52faSEd Tanous // nothing we can do
16156e1a52faSEd Tanous ip_util::ipv4VerifyIpAndGetBitcount(nicIpEntry->netmask,
16166e1a52faSEd Tanous &prefixLength);
161701784826SJohnathan Mantey
16186e1a52faSEd Tanous thisAddress.prefixLength = prefixLength;
16196e1a52faSEd Tanous }
162001784826SJohnathan Mantey if (gateway)
162101784826SJohnathan Mantey {
1622e01d0c36SEd Tanous if (!ip_util::ipv4VerifyIpAndGetBitcount(*gateway))
162301784826SJohnathan Mantey {
16246e1a52faSEd Tanous messages::propertyValueFormatError(res, *gateway,
1625bf648f77SEd Tanous pathString + "/Gateway");
16266e1a52faSEd Tanous return false;
162701784826SJohnathan Mantey }
16286e1a52faSEd Tanous thisAddress.operation = AddrChange::Update;
16296e1a52faSEd Tanous thisAddress.gateway = *gateway;
163001784826SJohnathan Mantey }
16316e1a52faSEd Tanous else if (thisAddress.existingDbusId.empty())
163201784826SJohnathan Mantey {
16336e1a52faSEd Tanous // Default to null gateway
16346e1a52faSEd Tanous gateway = "";
163501784826SJohnathan Mantey }
163601784826SJohnathan Mantey else
16371abe55efSEd Tanous {
16386e1a52faSEd Tanous thisAddress.gateway = nicIpEntry->gateway;
16394a0cb85cSEd Tanous }
16404a0cb85cSEd Tanous
16416e1a52faSEd Tanous // Changing gateway from existing
16426e1a52faSEd Tanous if (!thisAddress.gateway.empty() &&
16436e1a52faSEd Tanous thisAddress.gateway != "0.0.0.0")
1644743eb1c0SJohnathan Mantey {
16456e1a52faSEd Tanous if (!gatewayOut.empty() && gatewayOut != thisAddress.gateway)
1646743eb1c0SJohnathan Mantey {
1647743eb1c0SJohnathan Mantey // A NIC can only have a single active gateway value.
1648743eb1c0SJohnathan Mantey // If any gateway in the array of static addresses
1649743eb1c0SJohnathan Mantey // mismatch the PATCH is in error.
1650743eb1c0SJohnathan Mantey std::string arg1 = pathString + "/Gateway";
16516e1a52faSEd Tanous std::string arg2 = lastGatewayPath + "/Gateway";
16526e1a52faSEd Tanous messages::propertyValueConflict(res, arg1, arg2);
16536e1a52faSEd Tanous return false;
16546e1a52faSEd Tanous }
16556e1a52faSEd Tanous gatewayOut = thisAddress.gateway;
16566e1a52faSEd Tanous lastGatewayPath = pathString;
1657743eb1c0SJohnathan Mantey }
1658743eb1c0SJohnathan Mantey }
16596e1a52faSEd Tanous nicIpEntry++;
16606e1a52faSEd Tanous nicIpEntry = getNextStaticIpEntry(nicIpEntry, ipv4Data.cend());
16616e1a52faSEd Tanous entryIdx++;
1662743eb1c0SJohnathan Mantey }
1663743eb1c0SJohnathan Mantey
16646e1a52faSEd Tanous // Delete the remaining IPs
16656e1a52faSEd Tanous while (nicIpEntry != ipv4Data.cend())
16661abe55efSEd Tanous {
16676e1a52faSEd Tanous AddressPatch& thisAddress = addressesOut.emplace_back();
16686e1a52faSEd Tanous thisAddress.operation = AddrChange::Delete;
16696e1a52faSEd Tanous thisAddress.existingDbusId = nicIpEntry->id;
16706e1a52faSEd Tanous nicIpEntry++;
16716e1a52faSEd Tanous nicIpEntry = getNextStaticIpEntry(nicIpEntry, ipv4Data.cend());
1672588c3f0dSKowalski, Kamil }
16736e1a52faSEd Tanous
16746e1a52faSEd Tanous return true;
16754a0cb85cSEd Tanous }
16766e1a52faSEd Tanous
handleIPv4StaticPatch(const std::string & ifaceId,std::vector<std::variant<nlohmann::json::object_t,std::nullptr_t>> & input,const EthernetInterfaceData & ethData,const std::vector<IPv4AddressData> & ipv4Data,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)16776e1a52faSEd Tanous inline void handleIPv4StaticPatch(
16786e1a52faSEd Tanous const std::string& ifaceId,
16796e1a52faSEd Tanous std::vector<std::variant<nlohmann::json::object_t, std::nullptr_t>>& input,
16806e1a52faSEd Tanous const EthernetInterfaceData& ethData,
16816e1a52faSEd Tanous const std::vector<IPv4AddressData>& ipv4Data,
16826e1a52faSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
168301784826SJohnathan Mantey {
16846e1a52faSEd Tanous std::vector<AddressPatch> addresses;
16856e1a52faSEd Tanous std::string gatewayOut;
16866e1a52faSEd Tanous if (!parseAddresses(input, ipv4Data, asyncResp->res, addresses, gatewayOut))
168701784826SJohnathan Mantey {
1688743eb1c0SJohnathan Mantey return;
1689743eb1c0SJohnathan Mantey }
16906e1a52faSEd Tanous
16916e1a52faSEd Tanous // If we're setting the gateway to something new, delete the
16926e1a52faSEd Tanous // existing so we won't conflict
16936e1a52faSEd Tanous if (!ethData.defaultGateway.empty() && ethData.defaultGateway != gatewayOut)
16946e1a52faSEd Tanous {
16956e1a52faSEd Tanous updateIPv4DefaultGateway(ifaceId, "", asyncResp);
1696743eb1c0SJohnathan Mantey }
16976e1a52faSEd Tanous
16986e1a52faSEd Tanous for (const AddressPatch& address : addresses)
16996e1a52faSEd Tanous {
17006e1a52faSEd Tanous switch (address.operation)
17016e1a52faSEd Tanous {
17026e1a52faSEd Tanous case AddrChange::Delete:
17036e1a52faSEd Tanous {
17046e1a52faSEd Tanous BMCWEB_LOG_ERROR("Deleting id {} on interface {}",
17056e1a52faSEd Tanous address.existingDbusId, ifaceId);
17066e1a52faSEd Tanous deleteIPAddress(ifaceId, address.existingDbusId, asyncResp);
17076e1a52faSEd Tanous }
17086e1a52faSEd Tanous break;
17096e1a52faSEd Tanous case AddrChange::Update:
17106e1a52faSEd Tanous {
17116e1a52faSEd Tanous // Update is a delete then a recreate
17126e1a52faSEd Tanous // Only need to update if there is an existing ip at this index
17136e1a52faSEd Tanous if (!address.existingDbusId.empty())
17146e1a52faSEd Tanous {
17156e1a52faSEd Tanous BMCWEB_LOG_ERROR("Deleting id {} on interface {}",
17166e1a52faSEd Tanous address.existingDbusId, ifaceId);
17176e1a52faSEd Tanous deleteAndCreateIPAddress(
17186e1a52faSEd Tanous IpVersion::IpV4, ifaceId, address.existingDbusId,
17196e1a52faSEd Tanous address.prefixLength, address.address, address.gateway,
17206e1a52faSEd Tanous asyncResp);
17216e1a52faSEd Tanous }
17226e1a52faSEd Tanous else
17236e1a52faSEd Tanous {
17246e1a52faSEd Tanous // Otherwise, just create a new one
17256e1a52faSEd Tanous BMCWEB_LOG_ERROR(
17266e1a52faSEd Tanous "creating ip {} prefix {} gateway {} on interface {}",
17276e1a52faSEd Tanous address.address, address.prefixLength, address.gateway,
17286e1a52faSEd Tanous ifaceId);
17296e1a52faSEd Tanous createIPv4(ifaceId, address.prefixLength, address.gateway,
17306e1a52faSEd Tanous address.address, asyncResp);
17316e1a52faSEd Tanous }
17326e1a52faSEd Tanous }
17336e1a52faSEd Tanous break;
17346e1a52faSEd Tanous default:
17356e1a52faSEd Tanous {
17366e1a52faSEd Tanous // Leave alone
17376e1a52faSEd Tanous }
17386e1a52faSEd Tanous break;
17396e1a52faSEd Tanous }
17406e1a52faSEd Tanous }
17416e1a52faSEd Tanous
17426e1a52faSEd Tanous // now update to the new gateway.
17436e1a52faSEd Tanous // Default gateway is already empty, so no need to update if we're clearing
17446e1a52faSEd Tanous if (!gatewayOut.empty() && ethData.defaultGateway != gatewayOut)
17456e1a52faSEd Tanous {
17466e1a52faSEd Tanous updateIPv4DefaultGateway(ifaceId, gatewayOut, asyncResp);
174701784826SJohnathan Mantey }
17484a0cb85cSEd Tanous }
17494a0cb85cSEd Tanous
handleStaticNameServersPatch(const std::string & ifaceId,const std::vector<std::string> & updatedStaticNameServers,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)17504f48d5f6SEd Tanous inline void handleStaticNameServersPatch(
1751f85837bfSRAJESWARAN THILLAIGOVINDAN const std::string& ifaceId,
1752f85837bfSRAJESWARAN THILLAIGOVINDAN const std::vector<std::string>& updatedStaticNameServers,
17538d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1754f85837bfSRAJESWARAN THILLAIGOVINDAN {
17551847f2a0SAsmitha Karunanithi setDbusProperty(
1756e93abac6SGinu George asyncResp, "StaticNameServers", "xyz.openbmc_project.Network",
17571847f2a0SAsmitha Karunanithi sdbusplus::message::object_path("/xyz/openbmc_project/network") /
17581847f2a0SAsmitha Karunanithi ifaceId,
17599ae226faSGeorge Liu "xyz.openbmc_project.Network.EthernetInterface", "StaticNameServers",
1760e93abac6SGinu George updatedStaticNameServers);
1761f85837bfSRAJESWARAN THILLAIGOVINDAN }
1762f85837bfSRAJESWARAN THILLAIGOVINDAN
handleIPv6StaticAddressesPatch(const std::string & ifaceId,std::vector<std::variant<nlohmann::json::object_t,std::nullptr_t>> & input,const std::vector<IPv6AddressData> & ipv6Data,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)17634f48d5f6SEd Tanous inline void handleIPv6StaticAddressesPatch(
17643dfed536SEd Tanous const std::string& ifaceId,
17653dfed536SEd Tanous std::vector<std::variant<nlohmann::json::object_t, std::nullptr_t>>& input,
176677179532SEd Tanous const std::vector<IPv6AddressData>& ipv6Data,
17678d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1768e48c0fc5SRavi Teja {
1769271584abSEd Tanous size_t entryIdx = 1;
177077179532SEd Tanous std::vector<IPv6AddressData>::const_iterator nicIpEntry =
17712c70f800SEd Tanous getNextStaticIpEntry(ipv6Data.cbegin(), ipv6Data.cend());
17723dfed536SEd Tanous for (std::variant<nlohmann::json::object_t, std::nullptr_t>& thisJson :
17733dfed536SEd Tanous input)
1774e48c0fc5SRavi Teja {
1775bd79bce8SPatrick Williams std::string pathString =
1776bd79bce8SPatrick Williams "IPv6StaticAddresses/" + std::to_string(entryIdx);
17773dfed536SEd Tanous nlohmann::json::object_t* obj =
17783dfed536SEd Tanous std::get_if<nlohmann::json::object_t>(&thisJson);
17793dfed536SEd Tanous if (obj != nullptr && !obj->empty())
1780e48c0fc5SRavi Teja {
1781e48c0fc5SRavi Teja std::optional<std::string> address;
1782e48c0fc5SRavi Teja std::optional<uint8_t> prefixLength;
17833dfed536SEd Tanous nlohmann::json::object_t thisJsonCopy = *obj;
1784afc474aeSMyung Bae if (!json_util::readJsonObject( //
1785afc474aeSMyung Bae thisJsonCopy, asyncResp->res, //
1786afc474aeSMyung Bae "Address", address, //
1787afc474aeSMyung Bae "PrefixLength", prefixLength //
1788afc474aeSMyung Bae ))
1789e48c0fc5SRavi Teja {
17903dfed536SEd Tanous messages::propertyValueFormatError(asyncResp->res, thisJsonCopy,
179171f52d96SEd Tanous pathString);
1792e48c0fc5SRavi Teja return;
1793e48c0fc5SRavi Teja }
1794e48c0fc5SRavi Teja
179501784826SJohnathan Mantey // Find the address and prefixLength values. Any values that are
179601784826SJohnathan Mantey // not explicitly provided are assumed to be unmodified from the
179701784826SJohnathan Mantey // current state of the interface. Merge existing state into the
179801784826SJohnathan Mantey // current request.
1799d547d8d2SEd Tanous if (!address)
1800e48c0fc5SRavi Teja {
1801d547d8d2SEd Tanous if (nicIpEntry == ipv6Data.end())
180201784826SJohnathan Mantey {
180301784826SJohnathan Mantey messages::propertyMissing(asyncResp->res,
180401784826SJohnathan Mantey pathString + "/Address");
180501784826SJohnathan Mantey return;
1806e48c0fc5SRavi Teja }
1807d547d8d2SEd Tanous address = nicIpEntry->address;
1808d547d8d2SEd Tanous }
1809e48c0fc5SRavi Teja
1810d547d8d2SEd Tanous if (!prefixLength)
1811e48c0fc5SRavi Teja {
1812d547d8d2SEd Tanous if (nicIpEntry == ipv6Data.end())
1813e48c0fc5SRavi Teja {
1814e48c0fc5SRavi Teja messages::propertyMissing(asyncResp->res,
1815e48c0fc5SRavi Teja pathString + "/PrefixLength");
181601784826SJohnathan Mantey return;
1817e48c0fc5SRavi Teja }
1818d547d8d2SEd Tanous prefixLength = nicIpEntry->prefixLength;
1819d547d8d2SEd Tanous }
1820e48c0fc5SRavi Teja
182185ffe86aSJiaqing Zhao if (nicIpEntry != ipv6Data.end())
1822e48c0fc5SRavi Teja {
18239c5e585cSRavi Teja deleteAndCreateIPAddress(IpVersion::IpV6, ifaceId,
1824d547d8d2SEd Tanous nicIpEntry->id, *prefixLength,
1825d547d8d2SEd Tanous *address, "", asyncResp);
1826bd79bce8SPatrick Williams nicIpEntry =
1827bd79bce8SPatrick Williams getNextStaticIpEntry(++nicIpEntry, ipv6Data.cend());
182801784826SJohnathan Mantey }
182901784826SJohnathan Mantey else
183001784826SJohnathan Mantey {
1831d547d8d2SEd Tanous createIPv6(ifaceId, *prefixLength, *address, asyncResp);
1832e48c0fc5SRavi Teja }
1833e48c0fc5SRavi Teja entryIdx++;
1834e48c0fc5SRavi Teja }
183501784826SJohnathan Mantey else
183601784826SJohnathan Mantey {
183785ffe86aSJiaqing Zhao if (nicIpEntry == ipv6Data.end())
183801784826SJohnathan Mantey {
183901784826SJohnathan Mantey // Requesting a DELETE/DO NOT MODIFY action for an item
184001784826SJohnathan Mantey // that isn't present on the eth(n) interface. Input JSON is
184101784826SJohnathan Mantey // in error, so bail out.
18423dfed536SEd Tanous if (obj == nullptr)
184301784826SJohnathan Mantey {
184401784826SJohnathan Mantey messages::resourceCannotBeDeleted(asyncResp->res);
184501784826SJohnathan Mantey return;
184601784826SJohnathan Mantey }
18473dfed536SEd Tanous messages::propertyValueFormatError(asyncResp->res, *obj,
184871f52d96SEd Tanous pathString);
184901784826SJohnathan Mantey return;
185001784826SJohnathan Mantey }
185101784826SJohnathan Mantey
18523dfed536SEd Tanous if (obj == nullptr)
185301784826SJohnathan Mantey {
18549c5e585cSRavi Teja deleteIPAddress(ifaceId, nicIpEntry->id, asyncResp);
185501784826SJohnathan Mantey }
185685ffe86aSJiaqing Zhao if (nicIpEntry != ipv6Data.cend())
185701784826SJohnathan Mantey {
1858bd79bce8SPatrick Williams nicIpEntry =
1859bd79bce8SPatrick Williams getNextStaticIpEntry(++nicIpEntry, ipv6Data.cend());
186001784826SJohnathan Mantey }
186101784826SJohnathan Mantey entryIdx++;
186201784826SJohnathan Mantey }
186301784826SJohnathan Mantey }
1864e48c0fc5SRavi Teja }
1865e48c0fc5SRavi Teja
extractParentInterfaceName(const std::string & ifaceId)18667857cb8dSJiaqing Zhao inline std::string extractParentInterfaceName(const std::string& ifaceId)
18677857cb8dSJiaqing Zhao {
18687857cb8dSJiaqing Zhao std::size_t pos = ifaceId.find('_');
18697857cb8dSJiaqing Zhao return ifaceId.substr(0, pos);
18707857cb8dSJiaqing Zhao }
18717857cb8dSJiaqing Zhao
parseInterfaceData(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & ifaceId,const EthernetInterfaceData & ethData,const std::vector<IPv4AddressData> & ipv4Data,const std::vector<IPv6AddressData> & ipv6Data,const std::vector<StaticGatewayData> & ipv6GatewayData)1872bd79bce8SPatrick Williams inline void parseInterfaceData(
1873bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1874bd79bce8SPatrick Williams const std::string& ifaceId, const EthernetInterfaceData& ethData,
187577179532SEd Tanous const std::vector<IPv4AddressData>& ipv4Data,
1876ce73d5c8SSunitha Harish const std::vector<IPv6AddressData>& ipv6Data,
1877ce73d5c8SSunitha Harish const std::vector<StaticGatewayData>& ipv6GatewayData)
18784a0cb85cSEd Tanous {
18792c70f800SEd Tanous nlohmann::json& jsonResponse = asyncResp->res.jsonValue;
188081ce609eSEd Tanous jsonResponse["Id"] = ifaceId;
1881253f11b8SEd Tanous jsonResponse["@odata.id"] =
1882253f11b8SEd Tanous boost::urls::format("/redfish/v1/Managers/{}/EthernetInterfaces/{}",
1883253f11b8SEd Tanous BMCWEB_REDFISH_MANAGER_URI_NAME, ifaceId);
18842c70f800SEd Tanous jsonResponse["InterfaceEnabled"] = ethData.nicEnabled;
1885eeedda23SJohnathan Mantey
1886eeedda23SJohnathan Mantey if (ethData.nicEnabled)
1887eeedda23SJohnathan Mantey {
1888539d8c6bSEd Tanous jsonResponse["LinkStatus"] =
1889539d8c6bSEd Tanous ethData.linkUp ? ethernet_interface::LinkStatus::LinkUp
1890539d8c6bSEd Tanous : ethernet_interface::LinkStatus::LinkDown;
1891539d8c6bSEd Tanous jsonResponse["Status"]["State"] = resource::State::Enabled;
1892029573d4SEd Tanous }
1893029573d4SEd Tanous else
1894029573d4SEd Tanous {
1895539d8c6bSEd Tanous jsonResponse["LinkStatus"] = ethernet_interface::LinkStatus::NoLink;
1896539d8c6bSEd Tanous jsonResponse["Status"]["State"] = resource::State::Disabled;
1897029573d4SEd Tanous }
1898aa05fb27SJohnathan Mantey
18992c70f800SEd Tanous jsonResponse["SpeedMbps"] = ethData.speed;
190035fb5311STejas Patil jsonResponse["MTUSize"] = ethData.mtuSize;
19014652c640SAsmitha Karunanithi if (ethData.macAddress)
19024652c640SAsmitha Karunanithi {
19034652c640SAsmitha Karunanithi jsonResponse["MACAddress"] = *ethData.macAddress;
19044652c640SAsmitha Karunanithi }
19052c70f800SEd Tanous jsonResponse["DHCPv4"]["DHCPEnabled"] =
190682695a5bSJiaqing Zhao translateDhcpEnabledToBool(ethData.dhcpEnabled, true);
1907e4588158SJishnu CM jsonResponse["DHCPv4"]["UseNTPServers"] = ethData.ntpv4Enabled;
1908e4588158SJishnu CM jsonResponse["DHCPv4"]["UseDNSServers"] = ethData.dnsv4Enabled;
1909de9ad764SRavi Teja jsonResponse["DHCPv4"]["UseDomainName"] = ethData.domainv4Enabled;
19102c70f800SEd Tanous jsonResponse["DHCPv6"]["OperatingMode"] =
1911bd79bce8SPatrick Williams translateDhcpEnabledToBool(ethData.dhcpEnabled, false)
1912bd79bce8SPatrick Williams ? "Enabled"
19131f8c7b5dSJohnathan Mantey : "Disabled";
1914e4588158SJishnu CM jsonResponse["DHCPv6"]["UseNTPServers"] = ethData.ntpv6Enabled;
1915e4588158SJishnu CM jsonResponse["DHCPv6"]["UseDNSServers"] = ethData.dnsv6Enabled;
1916de9ad764SRavi Teja jsonResponse["DHCPv6"]["UseDomainName"] = ethData.domainv6Enabled;
1917b10d8db0SRavi Teja jsonResponse["StatelessAddressAutoConfig"]["IPv6AutoConfigEnabled"] =
1918b10d8db0SRavi Teja ethData.ipv6AcceptRa;
19192a133282Smanojkiraneda
192082695a5bSJiaqing Zhao if (!ethData.hostName.empty())
19214a0cb85cSEd Tanous {
192282695a5bSJiaqing Zhao jsonResponse["HostName"] = ethData.hostName;
1923ab6554f1SJoshi-Mansi
1924ab6554f1SJoshi-Mansi // When domain name is empty then it means, that it is a network
1925ab6554f1SJoshi-Mansi // without domain names, and the host name itself must be treated as
1926ab6554f1SJoshi-Mansi // FQDN
192782695a5bSJiaqing Zhao std::string fqdn = ethData.hostName;
1928d24bfc7aSJennifer Lee if (!ethData.domainnames.empty())
1929d24bfc7aSJennifer Lee {
19302c70f800SEd Tanous fqdn += "." + ethData.domainnames[0];
1931d24bfc7aSJennifer Lee }
19322c70f800SEd Tanous jsonResponse["FQDN"] = fqdn;
19334a0cb85cSEd Tanous }
19344a0cb85cSEd Tanous
19357857cb8dSJiaqing Zhao if (ethData.vlanId)
19367857cb8dSJiaqing Zhao {
1937539d8c6bSEd Tanous jsonResponse["EthernetInterfaceType"] =
1938539d8c6bSEd Tanous ethernet_interface::EthernetDeviceType::Virtual;
19397857cb8dSJiaqing Zhao jsonResponse["VLAN"]["VLANEnable"] = true;
19407857cb8dSJiaqing Zhao jsonResponse["VLAN"]["VLANId"] = *ethData.vlanId;
19417857cb8dSJiaqing Zhao jsonResponse["VLAN"]["Tagged"] = true;
19427857cb8dSJiaqing Zhao
19437857cb8dSJiaqing Zhao nlohmann::json::array_t relatedInterfaces;
19447857cb8dSJiaqing Zhao nlohmann::json& parentInterface = relatedInterfaces.emplace_back();
19457857cb8dSJiaqing Zhao parentInterface["@odata.id"] =
1946253f11b8SEd Tanous boost::urls::format("/redfish/v1/Managers/{}/EthernetInterfaces",
1947253f11b8SEd Tanous BMCWEB_REDFISH_MANAGER_URI_NAME,
19487857cb8dSJiaqing Zhao extractParentInterfaceName(ifaceId));
19497857cb8dSJiaqing Zhao jsonResponse["Links"]["RelatedInterfaces"] =
19507857cb8dSJiaqing Zhao std::move(relatedInterfaces);
19517857cb8dSJiaqing Zhao }
19527857cb8dSJiaqing Zhao else
19537857cb8dSJiaqing Zhao {
1954539d8c6bSEd Tanous jsonResponse["EthernetInterfaceType"] =
1955539d8c6bSEd Tanous ethernet_interface::EthernetDeviceType::Physical;
19567857cb8dSJiaqing Zhao }
19577857cb8dSJiaqing Zhao
19582c70f800SEd Tanous jsonResponse["NameServers"] = ethData.nameServers;
19592c70f800SEd Tanous jsonResponse["StaticNameServers"] = ethData.staticNameServers;
19604a0cb85cSEd Tanous
19612c70f800SEd Tanous nlohmann::json& ipv4Array = jsonResponse["IPv4Addresses"];
19622c70f800SEd Tanous nlohmann::json& ipv4StaticArray = jsonResponse["IPv4StaticAddresses"];
19632c70f800SEd Tanous ipv4Array = nlohmann::json::array();
19642c70f800SEd Tanous ipv4StaticArray = nlohmann::json::array();
19659eb808c1SEd Tanous for (const auto& ipv4Config : ipv4Data)
19664a0cb85cSEd Tanous {
19672c70f800SEd Tanous std::string gatewayStr = ipv4Config.gateway;
1968fa5053a6SGunnar Mills if (gatewayStr.empty())
1969fa5053a6SGunnar Mills {
1970fa5053a6SGunnar Mills gatewayStr = "0.0.0.0";
1971fa5053a6SGunnar Mills }
19721476687dSEd Tanous nlohmann::json::object_t ipv4;
19731476687dSEd Tanous ipv4["AddressOrigin"] = ipv4Config.origin;
19741476687dSEd Tanous ipv4["SubnetMask"] = ipv4Config.netmask;
19751476687dSEd Tanous ipv4["Address"] = ipv4Config.address;
19761476687dSEd Tanous ipv4["Gateway"] = gatewayStr;
1977fa5053a6SGunnar Mills
19782c70f800SEd Tanous if (ipv4Config.origin == "Static")
1979d1d50814SRavi Teja {
19801476687dSEd Tanous ipv4StaticArray.push_back(ipv4);
1981d1d50814SRavi Teja }
19821476687dSEd Tanous
1983b2ba3072SPatrick Williams ipv4Array.emplace_back(std::move(ipv4));
198401784826SJohnathan Mantey }
1985d1d50814SRavi Teja
198682695a5bSJiaqing Zhao std::string ipv6GatewayStr = ethData.ipv6DefaultGateway;
19877ea79e5eSRavi Teja if (ipv6GatewayStr.empty())
19887ea79e5eSRavi Teja {
19897ea79e5eSRavi Teja ipv6GatewayStr = "0:0:0:0:0:0:0:0";
19907ea79e5eSRavi Teja }
19917ea79e5eSRavi Teja
19927ea79e5eSRavi Teja jsonResponse["IPv6DefaultGateway"] = ipv6GatewayStr;
1993e48c0fc5SRavi Teja
1994ce73d5c8SSunitha Harish nlohmann::json::array_t ipv6StaticGatewayArray;
1995ce73d5c8SSunitha Harish for (const auto& ipv6GatewayConfig : ipv6GatewayData)
1996ce73d5c8SSunitha Harish {
1997ce73d5c8SSunitha Harish nlohmann::json::object_t ipv6Gateway;
1998ce73d5c8SSunitha Harish ipv6Gateway["Address"] = ipv6GatewayConfig.gateway;
1999ce73d5c8SSunitha Harish ipv6StaticGatewayArray.emplace_back(std::move(ipv6Gateway));
2000ce73d5c8SSunitha Harish }
2001ce73d5c8SSunitha Harish jsonResponse["IPv6StaticDefaultGateways"] =
2002ce73d5c8SSunitha Harish std::move(ipv6StaticGatewayArray);
2003ce73d5c8SSunitha Harish
20042c70f800SEd Tanous nlohmann::json& ipv6Array = jsonResponse["IPv6Addresses"];
20052c70f800SEd Tanous nlohmann::json& ipv6StaticArray = jsonResponse["IPv6StaticAddresses"];
20062c70f800SEd Tanous ipv6Array = nlohmann::json::array();
20072c70f800SEd Tanous ipv6StaticArray = nlohmann::json::array();
20087f2e23e9SJohnathan Mantey nlohmann::json& ipv6AddrPolicyTable =
20092c70f800SEd Tanous jsonResponse["IPv6AddressPolicyTable"];
20107f2e23e9SJohnathan Mantey ipv6AddrPolicyTable = nlohmann::json::array();
20119eb808c1SEd Tanous for (const auto& ipv6Config : ipv6Data)
2012e48c0fc5SRavi Teja {
20131476687dSEd Tanous nlohmann::json::object_t ipv6;
20141476687dSEd Tanous ipv6["Address"] = ipv6Config.address;
20151476687dSEd Tanous ipv6["PrefixLength"] = ipv6Config.prefixLength;
20161476687dSEd Tanous ipv6["AddressOrigin"] = ipv6Config.origin;
2017f8361275SSunitha Harish
2018b2ba3072SPatrick Williams ipv6Array.emplace_back(std::move(ipv6));
20192c70f800SEd Tanous if (ipv6Config.origin == "Static")
2020e48c0fc5SRavi Teja {
20211476687dSEd Tanous nlohmann::json::object_t ipv6Static;
20221476687dSEd Tanous ipv6Static["Address"] = ipv6Config.address;
20231476687dSEd Tanous ipv6Static["PrefixLength"] = ipv6Config.prefixLength;
2024b2ba3072SPatrick Williams ipv6StaticArray.emplace_back(std::move(ipv6Static));
202501784826SJohnathan Mantey }
2026e48c0fc5SRavi Teja }
2027588c3f0dSKowalski, Kamil }
2028588c3f0dSKowalski, Kamil
afterDelete(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & ifaceId,const boost::system::error_code & ec,const sdbusplus::message_t & m)2029e7caf250SJiaqing Zhao inline void afterDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2030e7caf250SJiaqing Zhao const std::string& ifaceId,
2031e7caf250SJiaqing Zhao const boost::system::error_code& ec,
2032e7caf250SJiaqing Zhao const sdbusplus::message_t& m)
2033e7caf250SJiaqing Zhao {
2034e7caf250SJiaqing Zhao if (!ec)
2035e7caf250SJiaqing Zhao {
2036e7caf250SJiaqing Zhao return;
2037e7caf250SJiaqing Zhao }
2038e7caf250SJiaqing Zhao const sd_bus_error* dbusError = m.get_error();
2039e7caf250SJiaqing Zhao if (dbusError == nullptr)
2040e7caf250SJiaqing Zhao {
2041e7caf250SJiaqing Zhao messages::internalError(asyncResp->res);
2042e7caf250SJiaqing Zhao return;
2043e7caf250SJiaqing Zhao }
204462598e31SEd Tanous BMCWEB_LOG_DEBUG("DBus error: {}", dbusError->name);
2045e7caf250SJiaqing Zhao
2046e7caf250SJiaqing Zhao if (std::string_view("org.freedesktop.DBus.Error.UnknownObject") ==
2047e7caf250SJiaqing Zhao dbusError->name)
2048e7caf250SJiaqing Zhao {
2049e7caf250SJiaqing Zhao messages::resourceNotFound(asyncResp->res, "EthernetInterface",
2050e7caf250SJiaqing Zhao ifaceId);
2051e7caf250SJiaqing Zhao return;
2052e7caf250SJiaqing Zhao }
2053e7caf250SJiaqing Zhao if (std::string_view("org.freedesktop.DBus.Error.UnknownMethod") ==
2054e7caf250SJiaqing Zhao dbusError->name)
2055e7caf250SJiaqing Zhao {
2056e7caf250SJiaqing Zhao messages::resourceCannotBeDeleted(asyncResp->res);
2057e7caf250SJiaqing Zhao return;
2058e7caf250SJiaqing Zhao }
2059e7caf250SJiaqing Zhao messages::internalError(asyncResp->res);
2060e7caf250SJiaqing Zhao }
2061e7caf250SJiaqing Zhao
afterVlanCreate(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & parentInterfaceUri,const std::string & vlanInterface,const boost::system::error_code & ec,const sdbusplus::message_t & m)2062bd79bce8SPatrick Williams inline void afterVlanCreate(
2063bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2064bd79bce8SPatrick Williams const std::string& parentInterfaceUri, const std::string& vlanInterface,
2065bd79bce8SPatrick Williams const boost::system::error_code& ec, const sdbusplus::message_t& m
2066b5ca3fdcSJiaqing Zhao
2067b5ca3fdcSJiaqing Zhao )
2068b5ca3fdcSJiaqing Zhao {
2069b5ca3fdcSJiaqing Zhao if (ec)
2070b5ca3fdcSJiaqing Zhao {
2071b5ca3fdcSJiaqing Zhao const sd_bus_error* dbusError = m.get_error();
2072b5ca3fdcSJiaqing Zhao if (dbusError == nullptr)
2073b5ca3fdcSJiaqing Zhao {
2074b5ca3fdcSJiaqing Zhao messages::internalError(asyncResp->res);
2075b5ca3fdcSJiaqing Zhao return;
2076b5ca3fdcSJiaqing Zhao }
207762598e31SEd Tanous BMCWEB_LOG_DEBUG("DBus error: {}", dbusError->name);
2078b5ca3fdcSJiaqing Zhao
2079b5ca3fdcSJiaqing Zhao if (std::string_view(
2080b5ca3fdcSJiaqing Zhao "xyz.openbmc_project.Common.Error.ResourceNotFound") ==
2081b5ca3fdcSJiaqing Zhao dbusError->name)
2082b5ca3fdcSJiaqing Zhao {
2083b5ca3fdcSJiaqing Zhao messages::propertyValueNotInList(
2084b5ca3fdcSJiaqing Zhao asyncResp->res, parentInterfaceUri,
2085b5ca3fdcSJiaqing Zhao "Links/RelatedInterfaces/0/@odata.id");
2086b5ca3fdcSJiaqing Zhao return;
2087b5ca3fdcSJiaqing Zhao }
2088b5ca3fdcSJiaqing Zhao if (std::string_view(
2089b5ca3fdcSJiaqing Zhao "xyz.openbmc_project.Common.Error.InvalidArgument") ==
2090b5ca3fdcSJiaqing Zhao dbusError->name)
2091b5ca3fdcSJiaqing Zhao {
2092b5ca3fdcSJiaqing Zhao messages::resourceAlreadyExists(asyncResp->res, "EthernetInterface",
2093b5ca3fdcSJiaqing Zhao "Id", vlanInterface);
2094b5ca3fdcSJiaqing Zhao return;
2095b5ca3fdcSJiaqing Zhao }
2096b5ca3fdcSJiaqing Zhao messages::internalError(asyncResp->res);
2097b5ca3fdcSJiaqing Zhao return;
2098b5ca3fdcSJiaqing Zhao }
2099b5ca3fdcSJiaqing Zhao
2100253f11b8SEd Tanous const boost::urls::url vlanInterfaceUri =
2101253f11b8SEd Tanous boost::urls::format("/redfish/v1/Managers/{}/EthernetInterfaces/{}",
2102253f11b8SEd Tanous BMCWEB_REDFISH_MANAGER_URI_NAME, vlanInterface);
2103b5ca3fdcSJiaqing Zhao asyncResp->res.addHeader("Location", vlanInterfaceUri.buffer());
2104b5ca3fdcSJiaqing Zhao }
2105b5ca3fdcSJiaqing Zhao
requestEthernetInterfacesRoutes(App & app)2106bf648f77SEd Tanous inline void requestEthernetInterfacesRoutes(App& app)
2107bf648f77SEd Tanous {
2108253f11b8SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/EthernetInterfaces/")
2109ed398213SEd Tanous .privileges(redfish::privileges::getEthernetInterfaceCollection)
21101476687dSEd Tanous .methods(boost::beast::http::verb::get)(
21111476687dSEd Tanous [&app](const crow::Request& req,
2112253f11b8SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2113253f11b8SEd Tanous const std::string& managerId) {
21143ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp))
211545ca1b86SEd Tanous {
211645ca1b86SEd Tanous return;
211745ca1b86SEd Tanous }
211845ca1b86SEd Tanous
2119253f11b8SEd Tanous if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
2120253f11b8SEd Tanous {
2121bd79bce8SPatrick Williams messages::resourceNotFound(asyncResp->res, "Manager",
2122bd79bce8SPatrick Williams managerId);
2123253f11b8SEd Tanous return;
2124253f11b8SEd Tanous }
2125253f11b8SEd Tanous
2126bf648f77SEd Tanous asyncResp->res.jsonValue["@odata.type"] =
2127bf648f77SEd Tanous "#EthernetInterfaceCollection.EthernetInterfaceCollection";
2128bd79bce8SPatrick Williams asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
2129bd79bce8SPatrick Williams "/redfish/v1/Managers/{}/EthernetInterfaces",
2130253f11b8SEd Tanous BMCWEB_REDFISH_MANAGER_URI_NAME);
2131bf648f77SEd Tanous asyncResp->res.jsonValue["Name"] =
2132bf648f77SEd Tanous "Ethernet Network Interface Collection";
2133bf648f77SEd Tanous asyncResp->res.jsonValue["Description"] =
2134bf648f77SEd Tanous "Collection of EthernetInterfaces for this Manager";
2135bf648f77SEd Tanous
2136bf648f77SEd Tanous // Get eth interface list, and call the below callback for JSON
2137bf648f77SEd Tanous // preparation
2138002d39b4SEd Tanous getEthernetIfaceList(
213977179532SEd Tanous [asyncResp](const bool& success,
214077179532SEd Tanous const std::vector<std::string>& ifaceList) {
2141bf648f77SEd Tanous if (!success)
21421abe55efSEd Tanous {
2143f12894f8SJason M. Bills messages::internalError(asyncResp->res);
21449391bb9cSRapkiewicz, Pawel return;
21459391bb9cSRapkiewicz, Pawel }
21469391bb9cSRapkiewicz, Pawel
2147bd79bce8SPatrick Williams nlohmann::json& ifaceArray =
2148bd79bce8SPatrick Williams asyncResp->res.jsonValue["Members"];
2149bf648f77SEd Tanous ifaceArray = nlohmann::json::array();
2150bf648f77SEd Tanous for (const std::string& ifaceItem : ifaceList)
2151bf648f77SEd Tanous {
21521476687dSEd Tanous nlohmann::json::object_t iface;
2153ef4c65b7SEd Tanous iface["@odata.id"] = boost::urls::format(
2154253f11b8SEd Tanous "/redfish/v1/Managers/{}/EthernetInterfaces/{}",
2155253f11b8SEd Tanous BMCWEB_REDFISH_MANAGER_URI_NAME, ifaceItem);
21567857cb8dSJiaqing Zhao ifaceArray.push_back(std::move(iface));
2157bf648f77SEd Tanous }
2158bf648f77SEd Tanous
2159bd79bce8SPatrick Williams asyncResp->res.jsonValue["Members@odata.count"] =
2160bd79bce8SPatrick Williams ifaceArray.size();
2161bd79bce8SPatrick Williams asyncResp->res.jsonValue["@odata.id"] =
2162bd79bce8SPatrick Williams boost::urls::format(
2163253f11b8SEd Tanous "/redfish/v1/Managers/{}/EthernetInterfaces",
2164253f11b8SEd Tanous BMCWEB_REDFISH_MANAGER_URI_NAME);
2165bf648f77SEd Tanous });
2166bf648f77SEd Tanous });
2167bf648f77SEd Tanous
2168253f11b8SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/EthernetInterfaces/")
2169b5ca3fdcSJiaqing Zhao .privileges(redfish::privileges::postEthernetInterfaceCollection)
2170b5ca3fdcSJiaqing Zhao .methods(boost::beast::http::verb::post)(
2171b5ca3fdcSJiaqing Zhao [&app](const crow::Request& req,
2172253f11b8SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2173253f11b8SEd Tanous const std::string& managerId) {
2174b5ca3fdcSJiaqing Zhao if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2175b5ca3fdcSJiaqing Zhao {
2176b5ca3fdcSJiaqing Zhao return;
2177b5ca3fdcSJiaqing Zhao }
2178b5ca3fdcSJiaqing Zhao
2179253f11b8SEd Tanous if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
2180253f11b8SEd Tanous {
2181bd79bce8SPatrick Williams messages::resourceNotFound(asyncResp->res, "Manager",
2182bd79bce8SPatrick Williams managerId);
2183253f11b8SEd Tanous return;
2184253f11b8SEd Tanous }
2185253f11b8SEd Tanous
2186b5ca3fdcSJiaqing Zhao bool vlanEnable = false;
2187b5ca3fdcSJiaqing Zhao uint32_t vlanId = 0;
21883dfed536SEd Tanous std::vector<nlohmann::json::object_t> relatedInterfaces;
2189b5ca3fdcSJiaqing Zhao
2190afc474aeSMyung Bae if (!json_util::readJsonPatch( //
2191afc474aeSMyung Bae req, asyncResp->res, //
2192afc474aeSMyung Bae "Links/RelatedInterfaces", relatedInterfaces, //
2193afc474aeSMyung Bae "VLAN/VLANEnable", vlanEnable, //
2194afc474aeSMyung Bae "VLAN/VLANId", vlanId //
2195afc474aeSMyung Bae ))
2196b5ca3fdcSJiaqing Zhao {
2197b5ca3fdcSJiaqing Zhao return;
2198b5ca3fdcSJiaqing Zhao }
2199b5ca3fdcSJiaqing Zhao
2200b5ca3fdcSJiaqing Zhao if (relatedInterfaces.size() != 1)
2201b5ca3fdcSJiaqing Zhao {
2202b5ca3fdcSJiaqing Zhao messages::arraySizeTooLong(asyncResp->res,
2203b5ca3fdcSJiaqing Zhao "Links/RelatedInterfaces",
2204b5ca3fdcSJiaqing Zhao relatedInterfaces.size());
2205b5ca3fdcSJiaqing Zhao return;
2206b5ca3fdcSJiaqing Zhao }
2207b5ca3fdcSJiaqing Zhao
2208b5ca3fdcSJiaqing Zhao std::string parentInterfaceUri;
2209bd79bce8SPatrick Williams if (!json_util::readJsonObject(relatedInterfaces[0],
2210bd79bce8SPatrick Williams asyncResp->res, "@odata.id",
2211bd79bce8SPatrick Williams parentInterfaceUri))
2212b5ca3fdcSJiaqing Zhao {
2213bd79bce8SPatrick Williams messages::propertyMissing(
2214bd79bce8SPatrick Williams asyncResp->res, "Links/RelatedInterfaces/0/@odata.id");
2215b5ca3fdcSJiaqing Zhao return;
2216b5ca3fdcSJiaqing Zhao }
221762598e31SEd Tanous BMCWEB_LOG_INFO("Parent Interface URI: {}", parentInterfaceUri);
2218b5ca3fdcSJiaqing Zhao
22196fd29553SEd Tanous boost::system::result<boost::urls::url_view> parsedUri =
2220b5ca3fdcSJiaqing Zhao boost::urls::parse_relative_ref(parentInterfaceUri);
2221b5ca3fdcSJiaqing Zhao if (!parsedUri)
2222b5ca3fdcSJiaqing Zhao {
2223b5ca3fdcSJiaqing Zhao messages::propertyValueFormatError(
2224b5ca3fdcSJiaqing Zhao asyncResp->res, parentInterfaceUri,
2225b5ca3fdcSJiaqing Zhao "Links/RelatedInterfaces/0/@odata.id");
2226b5ca3fdcSJiaqing Zhao return;
2227b5ca3fdcSJiaqing Zhao }
2228b5ca3fdcSJiaqing Zhao
2229b5ca3fdcSJiaqing Zhao std::string parentInterface;
2230b5ca3fdcSJiaqing Zhao if (!crow::utility::readUrlSegments(
2231b5ca3fdcSJiaqing Zhao *parsedUri, "redfish", "v1", "Managers", "bmc",
2232b5ca3fdcSJiaqing Zhao "EthernetInterfaces", std::ref(parentInterface)))
2233b5ca3fdcSJiaqing Zhao {
2234b5ca3fdcSJiaqing Zhao messages::propertyValueNotInList(
2235b5ca3fdcSJiaqing Zhao asyncResp->res, parentInterfaceUri,
2236b5ca3fdcSJiaqing Zhao "Links/RelatedInterfaces/0/@odata.id");
2237b5ca3fdcSJiaqing Zhao return;
2238b5ca3fdcSJiaqing Zhao }
2239b5ca3fdcSJiaqing Zhao
2240b5ca3fdcSJiaqing Zhao if (!vlanEnable)
2241b5ca3fdcSJiaqing Zhao {
2242b5ca3fdcSJiaqing Zhao // In OpenBMC implementation, VLANEnable cannot be false on
2243b5ca3fdcSJiaqing Zhao // create
2244bd79bce8SPatrick Williams messages::propertyValueIncorrect(
2245bd79bce8SPatrick Williams asyncResp->res, "VLAN/VLANEnable", "false");
2246b5ca3fdcSJiaqing Zhao return;
2247b5ca3fdcSJiaqing Zhao }
2248b5ca3fdcSJiaqing Zhao
2249bd79bce8SPatrick Williams std::string vlanInterface =
2250bd79bce8SPatrick Williams parentInterface + "_" + std::to_string(vlanId);
2251b5ca3fdcSJiaqing Zhao crow::connections::systemBus->async_method_call(
2252b5ca3fdcSJiaqing Zhao [asyncResp, parentInterfaceUri,
2253b5ca3fdcSJiaqing Zhao vlanInterface](const boost::system::error_code& ec,
2254b5ca3fdcSJiaqing Zhao const sdbusplus::message_t& m) {
2255bd79bce8SPatrick Williams afterVlanCreate(asyncResp, parentInterfaceUri,
2256bd79bce8SPatrick Williams vlanInterface, ec, m);
2257b5ca3fdcSJiaqing Zhao },
2258bd79bce8SPatrick Williams "xyz.openbmc_project.Network",
2259bd79bce8SPatrick Williams "/xyz/openbmc_project/network",
2260bd79bce8SPatrick Williams "xyz.openbmc_project.Network.VLAN.Create", "VLAN",
2261bd79bce8SPatrick Williams parentInterface, vlanId);
2262b5ca3fdcSJiaqing Zhao });
2263b5ca3fdcSJiaqing Zhao
2264253f11b8SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/EthernetInterfaces/<str>/")
2265ed398213SEd Tanous .privileges(redfish::privileges::getEthernetInterface)
2266bf648f77SEd Tanous .methods(boost::beast::http::verb::get)(
226745ca1b86SEd Tanous [&app](const crow::Request& req,
2268bf648f77SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2269253f11b8SEd Tanous const std::string& managerId, const std::string& ifaceId) {
22703ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp))
227145ca1b86SEd Tanous {
227245ca1b86SEd Tanous return;
227345ca1b86SEd Tanous }
2274253f11b8SEd Tanous
2275253f11b8SEd Tanous if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
2276253f11b8SEd Tanous {
2277bd79bce8SPatrick Williams messages::resourceNotFound(asyncResp->res, "Manager",
2278bd79bce8SPatrick Williams managerId);
2279253f11b8SEd Tanous return;
2280253f11b8SEd Tanous }
2281253f11b8SEd Tanous
22824a0cb85cSEd Tanous getEthernetIfaceData(
2283bf648f77SEd Tanous ifaceId,
2284bd79bce8SPatrick Williams [asyncResp, ifaceId](
2285bd79bce8SPatrick Williams const bool& success,
2286bd79bce8SPatrick Williams const EthernetInterfaceData& ethData,
228777179532SEd Tanous const std::vector<IPv4AddressData>& ipv4Data,
2288ce73d5c8SSunitha Harish const std::vector<IPv6AddressData>& ipv6Data,
2289ce73d5c8SSunitha Harish const std::vector<StaticGatewayData>& ipv6GatewayData) {
22904a0cb85cSEd Tanous if (!success)
22911abe55efSEd Tanous {
2292bf648f77SEd Tanous // TODO(Pawel)consider distinguish between non
2293bf648f77SEd Tanous // existing object, and other errors
2294bd79bce8SPatrick Williams messages::resourceNotFound(
2295bd79bce8SPatrick Williams asyncResp->res, "EthernetInterface", ifaceId);
22964a0cb85cSEd Tanous return;
22979391bb9cSRapkiewicz, Pawel }
22984c9afe43SEd Tanous
22990f74e643SEd Tanous asyncResp->res.jsonValue["@odata.type"] =
230093bbc953SJiaqing Zhao "#EthernetInterface.v1_9_0.EthernetInterface";
2301bd79bce8SPatrick Williams asyncResp->res.jsonValue["Name"] =
2302bd79bce8SPatrick Williams "Manager Ethernet Interface";
23030f74e643SEd Tanous asyncResp->res.jsonValue["Description"] =
23040f74e643SEd Tanous "Management Network Interface";
23050f74e643SEd Tanous
2306bd79bce8SPatrick Williams parseInterfaceData(asyncResp, ifaceId, ethData,
2307bd79bce8SPatrick Williams ipv4Data, ipv6Data, ipv6GatewayData);
23089391bb9cSRapkiewicz, Pawel });
2309bf648f77SEd Tanous });
23109391bb9cSRapkiewicz, Pawel
2311253f11b8SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/EthernetInterfaces/<str>/")
2312ed398213SEd Tanous .privileges(redfish::privileges::patchEthernetInterface)
2313bf648f77SEd Tanous .methods(boost::beast::http::verb::patch)(
231445ca1b86SEd Tanous [&app](const crow::Request& req,
2315bf648f77SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2316253f11b8SEd Tanous const std::string& managerId, const std::string& ifaceId) {
23173ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp))
231845ca1b86SEd Tanous {
231945ca1b86SEd Tanous return;
232045ca1b86SEd Tanous }
2321253f11b8SEd Tanous
2322253f11b8SEd Tanous if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
2323253f11b8SEd Tanous {
2324bd79bce8SPatrick Williams messages::resourceNotFound(asyncResp->res, "Manager",
2325bd79bce8SPatrick Williams managerId);
2326253f11b8SEd Tanous return;
2327253f11b8SEd Tanous }
2328253f11b8SEd Tanous
2329bc0bd6e0SEd Tanous std::optional<std::string> hostname;
2330ab6554f1SJoshi-Mansi std::optional<std::string> fqdn;
2331d577665bSRatan Gupta std::optional<std::string> macAddress;
23329a6fc6feSRavi Teja std::optional<std::string> ipv6DefaultGateway;
2333bd79bce8SPatrick Williams std::optional<std::vector<
2334bd79bce8SPatrick Williams std::variant<nlohmann::json::object_t, std::nullptr_t>>>
23353dfed536SEd Tanous ipv4StaticAddresses;
2336bd79bce8SPatrick Williams std::optional<std::vector<
2337bd79bce8SPatrick Williams std::variant<nlohmann::json::object_t, std::nullptr_t>>>
23383dfed536SEd Tanous ipv6StaticAddresses;
2339bd79bce8SPatrick Williams std::optional<std::vector<
2340bd79bce8SPatrick Williams std::variant<nlohmann::json::object_t, std::nullptr_t>>>
23413dfed536SEd Tanous ipv6StaticDefaultGateways;
2342f85837bfSRAJESWARAN THILLAIGOVINDAN std::optional<std::vector<std::string>> staticNameServers;
2343b10d8db0SRavi Teja std::optional<bool> ipv6AutoConfigEnabled;
2344eeedda23SJohnathan Mantey std::optional<bool> interfaceEnabled;
234535fb5311STejas Patil std::optional<size_t> mtuSize;
23461f8c7b5dSJohnathan Mantey DHCPParameters v4dhcpParms;
23471f8c7b5dSJohnathan Mantey DHCPParameters v6dhcpParms;
2348afc474aeSMyung Bae
2349afc474aeSMyung Bae if (!json_util::readJsonPatch( //
2350afc474aeSMyung Bae req, asyncResp->res, //
2351afc474aeSMyung Bae "DHCPv4/DHCPEnabled", v4dhcpParms.dhcpv4Enabled, //
2352afc474aeSMyung Bae "DHCPv4/UseDNSServers", v4dhcpParms.useDnsServers, //
2353afc474aeSMyung Bae "DHCPv4/UseDomainName", v4dhcpParms.useDomainName, //
2354afc474aeSMyung Bae "DHCPv4/UseNTPServers", v4dhcpParms.useNtpServers, //
2355afc474aeSMyung Bae "DHCPv6/OperatingMode",
2356afc474aeSMyung Bae v6dhcpParms.dhcpv6OperatingMode, //
2357afc474aeSMyung Bae "DHCPv6/UseDNSServers", v6dhcpParms.useDnsServers, //
2358afc474aeSMyung Bae "DHCPv6/UseDomainName", v6dhcpParms.useDomainName, //
2359afc474aeSMyung Bae "DHCPv6/UseNTPServers", v6dhcpParms.useNtpServers, //
2360afc474aeSMyung Bae "FQDN", fqdn, //
2361afc474aeSMyung Bae "HostName", hostname, //
2362afc474aeSMyung Bae "InterfaceEnabled", interfaceEnabled, //
2363afc474aeSMyung Bae "IPv4StaticAddresses", ipv4StaticAddresses, //
2364afc474aeSMyung Bae "IPv6DefaultGateway", ipv6DefaultGateway, //
2365afc474aeSMyung Bae "IPv6StaticAddresses", ipv6StaticAddresses, //
2366afc474aeSMyung Bae "IPv6StaticDefaultGateways",
2367afc474aeSMyung Bae ipv6StaticDefaultGateways, //
2368afc474aeSMyung Bae "InterfaceEnabled", interfaceEnabled, //
2369afc474aeSMyung Bae "MACAddress", macAddress, //
2370afc474aeSMyung Bae "MTUSize", mtuSize, //
2371afc474aeSMyung Bae "StatelessAddressAutoConfig/IPv6AutoConfigEnabled",
2372afc474aeSMyung Bae ipv6AutoConfigEnabled, //
2373afc474aeSMyung Bae "StaticNameServers", staticNameServers //
2374afc474aeSMyung Bae ))
23751abe55efSEd Tanous {
2376588c3f0dSKowalski, Kamil return;
2377588c3f0dSKowalski, Kamil }
2378da131a9aSJennifer Lee
2379bf648f77SEd Tanous // Get single eth interface data, and call the below callback
2380bf648f77SEd Tanous // for JSON preparation
23814a0cb85cSEd Tanous getEthernetIfaceData(
23822c70f800SEd Tanous ifaceId,
2383bf648f77SEd Tanous [asyncResp, ifaceId, hostname = std::move(hostname),
2384ab6554f1SJoshi-Mansi fqdn = std::move(fqdn), macAddress = std::move(macAddress),
2385d1d50814SRavi Teja ipv4StaticAddresses = std::move(ipv4StaticAddresses),
23869a6fc6feSRavi Teja ipv6DefaultGateway = std::move(ipv6DefaultGateway),
2387e48c0fc5SRavi Teja ipv6StaticAddresses = std::move(ipv6StaticAddresses),
2388bd79bce8SPatrick Williams ipv6StaticDefaultGateway =
2389bd79bce8SPatrick Williams std::move(ipv6StaticDefaultGateways),
23903dfed536SEd Tanous staticNameServers = std::move(staticNameServers), mtuSize,
2391bd79bce8SPatrick Williams ipv6AutoConfigEnabled,
2392bd79bce8SPatrick Williams v4dhcpParms = std::move(v4dhcpParms),
2393f23b7296SEd Tanous v6dhcpParms = std::move(v6dhcpParms), interfaceEnabled](
2394bd79bce8SPatrick Williams const bool success,
2395bd79bce8SPatrick Williams const EthernetInterfaceData& ethData,
239677179532SEd Tanous const std::vector<IPv4AddressData>& ipv4Data,
2397ce73d5c8SSunitha Harish const std::vector<IPv6AddressData>& ipv6Data,
2398bd79bce8SPatrick Williams const std::vector<StaticGatewayData>&
2399bd79bce8SPatrick Williams ipv6GatewayData) mutable {
24001abe55efSEd Tanous if (!success)
24011abe55efSEd Tanous {
2402588c3f0dSKowalski, Kamil // ... otherwise return error
2403bf648f77SEd Tanous // TODO(Pawel)consider distinguish between non
2404bf648f77SEd Tanous // existing object, and other errors
2405bd79bce8SPatrick Williams messages::resourceNotFound(
2406bd79bce8SPatrick Williams asyncResp->res, "EthernetInterface", ifaceId);
2407588c3f0dSKowalski, Kamil return;
2408588c3f0dSKowalski, Kamil }
2409588c3f0dSKowalski, Kamil
2410bd79bce8SPatrick Williams handleDHCPPatch(ifaceId, ethData, v4dhcpParms,
2411bd79bce8SPatrick Williams v6dhcpParms, asyncResp);
24121f8c7b5dSJohnathan Mantey
24130627a2c7SEd Tanous if (hostname)
24141abe55efSEd Tanous {
24150627a2c7SEd Tanous handleHostnamePatch(*hostname, asyncResp);
24161abe55efSEd Tanous }
24170627a2c7SEd Tanous
2418b10d8db0SRavi Teja if (ipv6AutoConfigEnabled)
2419b10d8db0SRavi Teja {
2420bd79bce8SPatrick Williams handleSLAACAutoConfigPatch(
2421bd79bce8SPatrick Williams ifaceId, *ipv6AutoConfigEnabled, asyncResp);
2422b10d8db0SRavi Teja }
2423b10d8db0SRavi Teja
2424ab6554f1SJoshi-Mansi if (fqdn)
2425ab6554f1SJoshi-Mansi {
24262c70f800SEd Tanous handleFqdnPatch(ifaceId, *fqdn, asyncResp);
2427ab6554f1SJoshi-Mansi }
2428ab6554f1SJoshi-Mansi
2429d577665bSRatan Gupta if (macAddress)
2430d577665bSRatan Gupta {
2431bd79bce8SPatrick Williams handleMACAddressPatch(ifaceId, *macAddress,
2432bd79bce8SPatrick Williams asyncResp);
2433d577665bSRatan Gupta }
2434d577665bSRatan Gupta
2435d1d50814SRavi Teja if (ipv4StaticAddresses)
2436d1d50814SRavi Teja {
2437bd79bce8SPatrick Williams handleIPv4StaticPatch(ifaceId, *ipv4StaticAddresses,
2438bd79bce8SPatrick Williams ethData, ipv4Data, asyncResp);
24391abe55efSEd Tanous }
24400627a2c7SEd Tanous
2441f85837bfSRAJESWARAN THILLAIGOVINDAN if (staticNameServers)
2442f85837bfSRAJESWARAN THILLAIGOVINDAN {
2443bd79bce8SPatrick Williams handleStaticNameServersPatch(
2444bd79bce8SPatrick Williams ifaceId, *staticNameServers, asyncResp);
2445f85837bfSRAJESWARAN THILLAIGOVINDAN }
24469a6fc6feSRavi Teja
24479a6fc6feSRavi Teja if (ipv6DefaultGateway)
24489a6fc6feSRavi Teja {
24499a6fc6feSRavi Teja messages::propertyNotWritable(asyncResp->res,
24509a6fc6feSRavi Teja "IPv6DefaultGateway");
24519a6fc6feSRavi Teja }
2452e48c0fc5SRavi Teja
2453e48c0fc5SRavi Teja if (ipv6StaticAddresses)
2454e48c0fc5SRavi Teja {
2455bd79bce8SPatrick Williams handleIPv6StaticAddressesPatch(ifaceId,
2456bd79bce8SPatrick Williams *ipv6StaticAddresses,
2457ddd70dcaSEd Tanous ipv6Data, asyncResp);
2458e48c0fc5SRavi Teja }
2459eeedda23SJohnathan Mantey
2460ce73d5c8SSunitha Harish if (ipv6StaticDefaultGateway)
2461ce73d5c8SSunitha Harish {
2462bd79bce8SPatrick Williams handleIPv6DefaultGateway(
2463bd79bce8SPatrick Williams ifaceId, *ipv6StaticDefaultGateway,
2464ce73d5c8SSunitha Harish ipv6GatewayData, asyncResp);
2465ce73d5c8SSunitha Harish }
2466ce73d5c8SSunitha Harish
2467eeedda23SJohnathan Mantey if (interfaceEnabled)
2468eeedda23SJohnathan Mantey {
2469bd79bce8SPatrick Williams setDbusProperty(
2470bd79bce8SPatrick Williams asyncResp, "InterfaceEnabled",
2471e93abac6SGinu George "xyz.openbmc_project.Network",
2472d02aad39SEd Tanous sdbusplus::message::object_path(
2473d02aad39SEd Tanous "/xyz/openbmc_project/network") /
2474d02aad39SEd Tanous ifaceId,
2475d02aad39SEd Tanous "xyz.openbmc_project.Network.EthernetInterface",
2476e93abac6SGinu George "NICEnabled", *interfaceEnabled);
2477eeedda23SJohnathan Mantey }
247835fb5311STejas Patil
247935fb5311STejas Patil if (mtuSize)
248035fb5311STejas Patil {
248135fb5311STejas Patil handleMTUSizePatch(ifaceId, *mtuSize, asyncResp);
248235fb5311STejas Patil }
2483588c3f0dSKowalski, Kamil });
2484bf648f77SEd Tanous });
2485e7caf250SJiaqing Zhao
2486253f11b8SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/EthernetInterfaces/<str>/")
2487e7caf250SJiaqing Zhao .privileges(redfish::privileges::deleteEthernetInterface)
2488e7caf250SJiaqing Zhao .methods(boost::beast::http::verb::delete_)(
2489e7caf250SJiaqing Zhao [&app](const crow::Request& req,
2490e7caf250SJiaqing Zhao const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2491253f11b8SEd Tanous const std::string& managerId, const std::string& ifaceId) {
2492e7caf250SJiaqing Zhao if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2493e7caf250SJiaqing Zhao {
2494e7caf250SJiaqing Zhao return;
2495e7caf250SJiaqing Zhao }
2496e7caf250SJiaqing Zhao
2497253f11b8SEd Tanous if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
2498253f11b8SEd Tanous {
2499bd79bce8SPatrick Williams messages::resourceNotFound(asyncResp->res, "Manager",
2500bd79bce8SPatrick Williams managerId);
2501253f11b8SEd Tanous return;
2502253f11b8SEd Tanous }
2503253f11b8SEd Tanous
2504e7caf250SJiaqing Zhao crow::connections::systemBus->async_method_call(
2505e7caf250SJiaqing Zhao [asyncResp, ifaceId](const boost::system::error_code& ec,
2506e7caf250SJiaqing Zhao const sdbusplus::message_t& m) {
2507e7caf250SJiaqing Zhao afterDelete(asyncResp, ifaceId, ec, m);
2508e7caf250SJiaqing Zhao },
2509e7caf250SJiaqing Zhao "xyz.openbmc_project.Network",
2510e7caf250SJiaqing Zhao std::string("/xyz/openbmc_project/network/") + ifaceId,
2511e7caf250SJiaqing Zhao "xyz.openbmc_project.Object.Delete", "Delete");
2512e7caf250SJiaqing Zhao });
25134a0cb85cSEd Tanous }
2514bf648f77SEd Tanous
25159391bb9cSRapkiewicz, Pawel } // namespace redfish
2516