1690a2342SPatrick Venture #pragma once 2690a2342SPatrick Venture 38a7236aeSJohn Wang #include "app/channel.hpp" 48a7236aeSJohn Wang #include "user_channel/cipher_mgmt.hpp" 58a7236aeSJohn Wang 6fbc6c9d7SPatrick Williams #include <ipmid/api-types.hpp> 7fbc6c9d7SPatrick Williams #include <ipmid/api.hpp> 8fbc6c9d7SPatrick Williams #include <ipmid/message.hpp> 9fbc6c9d7SPatrick Williams #include <ipmid/message/types.hpp> 10fbc6c9d7SPatrick Williams #include <ipmid/types.hpp> 11fbc6c9d7SPatrick Williams #include <ipmid/utils.hpp> 12fbc6c9d7SPatrick Williams #include <phosphor-logging/elog-errors.hpp> 13fbc6c9d7SPatrick Williams #include <phosphor-logging/elog.hpp> 14fbc6c9d7SPatrick Williams #include <phosphor-logging/log.hpp> 15fbc6c9d7SPatrick Williams #include <sdbusplus/bus.hpp> 16fbc6c9d7SPatrick Williams #include <sdbusplus/exception.hpp> 17*726f2bddSWilliam A. Kennington III #include <stdplus/net/addr/ether.hpp> 18*726f2bddSWilliam A. Kennington III #include <stdplus/net/addr/ip.hpp> 19*726f2bddSWilliam A. Kennington III #include <stdplus/str/conv.hpp> 20fbc6c9d7SPatrick Williams #include <user_channel/channel_layer.hpp> 21fbc6c9d7SPatrick Williams #include <xyz/openbmc_project/Common/error.hpp> 22fbc6c9d7SPatrick Williams #include <xyz/openbmc_project/Network/EthernetInterface/server.hpp> 23fbc6c9d7SPatrick Williams #include <xyz/openbmc_project/Network/IP/server.hpp> 24fbc6c9d7SPatrick Williams #include <xyz/openbmc_project/Network/Neighbor/server.hpp> 25fbc6c9d7SPatrick Williams 268a7236aeSJohn Wang #include <cinttypes> 278a7236aeSJohn Wang #include <functional> 288a7236aeSJohn Wang #include <optional> 298a7236aeSJohn Wang #include <string> 308a7236aeSJohn Wang #include <string_view> 318a7236aeSJohn Wang #include <unordered_map> 328a7236aeSJohn Wang #include <unordered_set> 338a7236aeSJohn Wang #include <utility> 34690a2342SPatrick Venture 35690a2342SPatrick Venture namespace ipmi 36690a2342SPatrick Venture { 37690a2342SPatrick Venture namespace transport 38690a2342SPatrick Venture { 39690a2342SPatrick Venture 408a7236aeSJohn Wang // D-Bus Network Daemon definitions 418a7236aeSJohn Wang constexpr auto PATH_ROOT = "/xyz/openbmc_project/network"; 428a7236aeSJohn Wang constexpr auto INTF_ETHERNET = "xyz.openbmc_project.Network.EthernetInterface"; 438a7236aeSJohn Wang constexpr auto INTF_IP = "xyz.openbmc_project.Network.IP"; 448a7236aeSJohn Wang constexpr auto INTF_IP_CREATE = "xyz.openbmc_project.Network.IP.Create"; 458a7236aeSJohn Wang constexpr auto INTF_MAC = "xyz.openbmc_project.Network.MACAddress"; 468a7236aeSJohn Wang constexpr auto INTF_NEIGHBOR = "xyz.openbmc_project.Network.Neighbor"; 478a7236aeSJohn Wang constexpr auto INTF_NEIGHBOR_CREATE_STATIC = 488a7236aeSJohn Wang "xyz.openbmc_project.Network.Neighbor.CreateStatic"; 498a7236aeSJohn Wang constexpr auto INTF_VLAN = "xyz.openbmc_project.Network.VLAN"; 508a7236aeSJohn Wang constexpr auto INTF_VLAN_CREATE = "xyz.openbmc_project.Network.VLAN.Create"; 518a7236aeSJohn Wang 52690a2342SPatrick Venture /** @brief IPMI LAN Parameters */ 53690a2342SPatrick Venture enum class LanParam : uint8_t 54690a2342SPatrick Venture { 55690a2342SPatrick Venture SetStatus = 0, 56690a2342SPatrick Venture AuthSupport = 1, 57690a2342SPatrick Venture AuthEnables = 2, 58690a2342SPatrick Venture IP = 3, 59690a2342SPatrick Venture IPSrc = 4, 60690a2342SPatrick Venture MAC = 5, 61690a2342SPatrick Venture SubnetMask = 6, 62690a2342SPatrick Venture Gateway1 = 12, 63690a2342SPatrick Venture Gateway1MAC = 13, 64690a2342SPatrick Venture VLANId = 20, 65690a2342SPatrick Venture CiphersuiteSupport = 22, 66690a2342SPatrick Venture CiphersuiteEntries = 23, 67690a2342SPatrick Venture cipherSuitePrivilegeLevels = 24, 68690a2342SPatrick Venture IPFamilySupport = 50, 69690a2342SPatrick Venture IPFamilyEnables = 51, 70690a2342SPatrick Venture IPv6Status = 55, 71690a2342SPatrick Venture IPv6StaticAddresses = 56, 72690a2342SPatrick Venture IPv6DynamicAddresses = 59, 73690a2342SPatrick Venture IPv6RouterControl = 64, 74690a2342SPatrick Venture IPv6StaticRouter1IP = 65, 75690a2342SPatrick Venture IPv6StaticRouter1MAC = 66, 76690a2342SPatrick Venture IPv6StaticRouter1PrefixLength = 67, 77690a2342SPatrick Venture IPv6StaticRouter1PrefixValue = 68, 78690a2342SPatrick Venture }; 79690a2342SPatrick Venture 80690a2342SPatrick Venture /** @brief IPMI IP Origin Types */ 81690a2342SPatrick Venture enum class IPSrc : uint8_t 82690a2342SPatrick Venture { 83690a2342SPatrick Venture Unspecified = 0, 84690a2342SPatrick Venture Static = 1, 85690a2342SPatrick Venture DHCP = 2, 86690a2342SPatrick Venture BIOS = 3, 87690a2342SPatrick Venture BMC = 4, 88690a2342SPatrick Venture }; 89690a2342SPatrick Venture 90690a2342SPatrick Venture /** @brief IPMI Set Status */ 91690a2342SPatrick Venture enum class SetStatus : uint8_t 92690a2342SPatrick Venture { 93690a2342SPatrick Venture Complete = 0, 94690a2342SPatrick Venture InProgress = 1, 95690a2342SPatrick Venture Commit = 2, 96690a2342SPatrick Venture }; 97690a2342SPatrick Venture 98690a2342SPatrick Venture /** @brief IPMI Family Suport Bits */ 99690a2342SPatrick Venture namespace IPFamilySupportFlag 100690a2342SPatrick Venture { 101690a2342SPatrick Venture constexpr uint8_t IPv6Only = 0; 102690a2342SPatrick Venture constexpr uint8_t DualStack = 1; 103690a2342SPatrick Venture constexpr uint8_t IPv6Alerts = 2; 104690a2342SPatrick Venture } // namespace IPFamilySupportFlag 105690a2342SPatrick Venture 106690a2342SPatrick Venture /** @brief IPMI IPFamily Enables Flag */ 107690a2342SPatrick Venture enum class IPFamilyEnables : uint8_t 108690a2342SPatrick Venture { 109690a2342SPatrick Venture IPv4Only = 0, 110690a2342SPatrick Venture IPv6Only = 1, 111690a2342SPatrick Venture DualStack = 2, 112690a2342SPatrick Venture }; 113690a2342SPatrick Venture 114690a2342SPatrick Venture /** @brief IPMI IPv6 Dyanmic Status Bits */ 115690a2342SPatrick Venture namespace IPv6StatusFlag 116690a2342SPatrick Venture { 117690a2342SPatrick Venture constexpr uint8_t DHCP = 0; 118690a2342SPatrick Venture constexpr uint8_t SLAAC = 1; 119690a2342SPatrick Venture }; // namespace IPv6StatusFlag 120690a2342SPatrick Venture 121690a2342SPatrick Venture /** @brief IPMI IPv6 Source */ 122690a2342SPatrick Venture enum class IPv6Source : uint8_t 123690a2342SPatrick Venture { 124690a2342SPatrick Venture Static = 0, 125690a2342SPatrick Venture SLAAC = 1, 126690a2342SPatrick Venture DHCP = 2, 127690a2342SPatrick Venture }; 128690a2342SPatrick Venture 129690a2342SPatrick Venture /** @brief IPMI IPv6 Address Status */ 130690a2342SPatrick Venture enum class IPv6AddressStatus : uint8_t 131690a2342SPatrick Venture { 132690a2342SPatrick Venture Active = 0, 133690a2342SPatrick Venture Disabled = 1, 134690a2342SPatrick Venture }; 135690a2342SPatrick Venture 136690a2342SPatrick Venture namespace IPv6RouterControlFlag 137690a2342SPatrick Venture { 138690a2342SPatrick Venture constexpr uint8_t Static = 0; 139690a2342SPatrick Venture constexpr uint8_t Dynamic = 1; 140690a2342SPatrick Venture }; // namespace IPv6RouterControlFlag 141690a2342SPatrick Venture 142690a2342SPatrick Venture // LAN Handler specific response codes 143690a2342SPatrick Venture constexpr Cc ccParamNotSupported = 0x80; 144690a2342SPatrick Venture constexpr Cc ccParamSetLocked = 0x81; 145690a2342SPatrick Venture constexpr Cc ccParamReadOnly = 0x82; 146690a2342SPatrick Venture 147690a2342SPatrick Venture // VLANs are a 12-bit value 148690a2342SPatrick Venture constexpr uint16_t VLAN_VALUE_MASK = 0x0fff; 149690a2342SPatrick Venture constexpr uint16_t VLAN_ENABLE_FLAG = 0x8000; 150690a2342SPatrick Venture 151690a2342SPatrick Venture // Arbitrary v6 Address Limits to prevent too much output in ipmitool 152690a2342SPatrick Venture constexpr uint8_t MAX_IPV6_STATIC_ADDRESSES = 15; 153690a2342SPatrick Venture constexpr uint8_t MAX_IPV6_DYNAMIC_ADDRESSES = 15; 154690a2342SPatrick Venture 1556d4a44edSJiaqing Zhao // Prefix length limits of phosphor-networkd 1566d4a44edSJiaqing Zhao constexpr uint8_t MIN_IPV6_PREFIX_LENGTH = 1; 1576d4a44edSJiaqing Zhao constexpr uint8_t MAX_IPV6_PREFIX_LENGTH = 128; 1586d4a44edSJiaqing Zhao 1598a7236aeSJohn Wang /** @brief The dbus parameters for the interface corresponding to a channel 1608a7236aeSJohn Wang * This helps reduce the number of mapper lookups we need for each 1618a7236aeSJohn Wang * query and simplifies finding the VLAN interface if needed. 1628a7236aeSJohn Wang */ 1638a7236aeSJohn Wang struct ChannelParams 1648a7236aeSJohn Wang { 1658a7236aeSJohn Wang /** @brief The channel ID */ 1668a7236aeSJohn Wang int id; 1678a7236aeSJohn Wang /** @brief channel name for the interface */ 1688a7236aeSJohn Wang std::string ifname; 1698a7236aeSJohn Wang /** @brief Name of the service on the bus */ 1708a7236aeSJohn Wang std::string service; 1718a7236aeSJohn Wang /** @brief Lower level adapter path that is guaranteed to not be a VLAN */ 1728a7236aeSJohn Wang std::string ifPath; 1738a7236aeSJohn Wang /** @brief Logical adapter path used for address assignment */ 1748a7236aeSJohn Wang std::string logicalPath; 1758a7236aeSJohn Wang }; 1768a7236aeSJohn Wang 1778a7236aeSJohn Wang /** @brief Determines the ethernet interface name corresponding to a channel 1788a7236aeSJohn Wang * Tries to map a VLAN object first so that the address information 1798a7236aeSJohn Wang * is accurate. Otherwise it gets the standard ethernet interface. 1808a7236aeSJohn Wang * 1818a7236aeSJohn Wang * @param[in] bus - The bus object used for lookups 1828a7236aeSJohn Wang * @param[in] channel - The channel id corresponding to an ethernet interface 1838a7236aeSJohn Wang * @return Ethernet interface service and object path if it exists 1848a7236aeSJohn Wang */ 1855d82f474SPatrick Williams std::optional<ChannelParams> maybeGetChannelParams(sdbusplus::bus_t& bus, 1868a7236aeSJohn Wang uint8_t channel); 1878a7236aeSJohn Wang 1888a7236aeSJohn Wang /** @brief A trivial helper around maybeGetChannelParams() that throws an 1898a7236aeSJohn Wang * exception when it is unable to acquire parameters for the channel. 1908a7236aeSJohn Wang * 1918a7236aeSJohn Wang * @param[in] bus - The bus object used for lookups 1928a7236aeSJohn Wang * @param[in] channel - The channel id corresponding to an ethernet interface 1938a7236aeSJohn Wang * @return Ethernet interface service and object path 1948a7236aeSJohn Wang */ 1955d82f474SPatrick Williams ChannelParams getChannelParams(sdbusplus::bus_t& bus, uint8_t channel); 1968a7236aeSJohn Wang 1978a7236aeSJohn Wang /** @brief Trivializes using parameter getter functions by providing a bus 1988a7236aeSJohn Wang * and channel parameters automatically. 1998a7236aeSJohn Wang * 2008a7236aeSJohn Wang * @param[in] channel - The channel id corresponding to an ethernet interface 2018a7236aeSJohn Wang * ... 2028a7236aeSJohn Wang */ 2038a7236aeSJohn Wang template <auto func, typename... Args> 2048a7236aeSJohn Wang auto channelCall(uint8_t channel, Args&&... args) 2058a7236aeSJohn Wang { 2065d82f474SPatrick Williams sdbusplus::bus_t bus(ipmid_get_sd_bus_connection()); 2078a7236aeSJohn Wang auto params = getChannelParams(bus, channel); 2088a7236aeSJohn Wang return std::invoke(func, bus, params, std::forward<Args>(args)...); 2098a7236aeSJohn Wang } 2108a7236aeSJohn Wang 2118a7236aeSJohn Wang /** @brief Generic paramters for different address families */ 2128a7236aeSJohn Wang template <int family> 2138a7236aeSJohn Wang struct AddrFamily 214fbc6c9d7SPatrick Williams {}; 2158a7236aeSJohn Wang 2168a7236aeSJohn Wang /** @brief Parameter specialization for IPv4 */ 2178a7236aeSJohn Wang template <> 2188a7236aeSJohn Wang struct AddrFamily<AF_INET> 2198a7236aeSJohn Wang { 220*726f2bddSWilliam A. Kennington III using addr = stdplus::In4Addr; 2218a7236aeSJohn Wang static constexpr auto protocol = 222523e2d1bSWilly Tu sdbusplus::server::xyz::openbmc_project::network::IP::Protocol::IPv4; 2238a7236aeSJohn Wang static constexpr size_t maxStrLen = INET6_ADDRSTRLEN; 2248a7236aeSJohn Wang static constexpr uint8_t defaultPrefix = 32; 2258a7236aeSJohn Wang static constexpr char propertyGateway[] = "DefaultGateway"; 2268a7236aeSJohn Wang }; 2278a7236aeSJohn Wang 2288a7236aeSJohn Wang /** @brief Parameter specialization for IPv6 */ 2298a7236aeSJohn Wang template <> 2308a7236aeSJohn Wang struct AddrFamily<AF_INET6> 2318a7236aeSJohn Wang { 232*726f2bddSWilliam A. Kennington III using addr = stdplus::In6Addr; 2338a7236aeSJohn Wang static constexpr auto protocol = 234523e2d1bSWilly Tu sdbusplus::server::xyz::openbmc_project::network::IP::Protocol::IPv6; 2358a7236aeSJohn Wang static constexpr size_t maxStrLen = INET6_ADDRSTRLEN; 2368a7236aeSJohn Wang static constexpr uint8_t defaultPrefix = 128; 2378a7236aeSJohn Wang static constexpr char propertyGateway[] = "DefaultGateway6"; 2388a7236aeSJohn Wang }; 2398a7236aeSJohn Wang 2408a7236aeSJohn Wang /** @brief Interface Neighbor configuration parameters */ 2418a7236aeSJohn Wang template <int family> 2428a7236aeSJohn Wang struct IfNeigh 2438a7236aeSJohn Wang { 2448a7236aeSJohn Wang std::string path; 2458a7236aeSJohn Wang typename AddrFamily<family>::addr ip; 246*726f2bddSWilliam A. Kennington III stdplus::EtherAddr mac; 2478a7236aeSJohn Wang }; 2488a7236aeSJohn Wang 2498a7236aeSJohn Wang /** @brief Interface IP Address configuration parameters */ 2508a7236aeSJohn Wang template <int family> 2518a7236aeSJohn Wang struct IfAddr 2528a7236aeSJohn Wang { 2538a7236aeSJohn Wang std::string path; 2548a7236aeSJohn Wang typename AddrFamily<family>::addr address; 255523e2d1bSWilly Tu sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin origin; 2568a7236aeSJohn Wang uint8_t prefix; 2578a7236aeSJohn Wang }; 2588a7236aeSJohn Wang 2598a7236aeSJohn Wang /** @brief Valid address origins for IPv6 */ 2608a7236aeSJohn Wang static inline const std::unordered_set< 261523e2d1bSWilly Tu sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin> 262523e2d1bSWilly Tu originsV6Static = {sdbusplus::server::xyz::openbmc_project::network::IP:: 2638a7236aeSJohn Wang AddressOrigin::Static}; 2648a7236aeSJohn Wang static inline const std::unordered_set< 265523e2d1bSWilly Tu sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin> 2668a7236aeSJohn Wang originsV6Dynamic = { 267523e2d1bSWilly Tu sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin:: 2688a7236aeSJohn Wang DHCP, 269523e2d1bSWilly Tu sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin:: 2708a7236aeSJohn Wang SLAAC, 2718a7236aeSJohn Wang }; 2728a7236aeSJohn Wang 2738a7236aeSJohn Wang /** @brief A lazy lookup mechanism for iterating over object properties stored 2748a7236aeSJohn Wang * in DBus. This will only perform the object lookup when needed, and 2758a7236aeSJohn Wang * retains a cache of previous lookups to speed up future iterations. 2768a7236aeSJohn Wang */ 2778a7236aeSJohn Wang class ObjectLookupCache 2788a7236aeSJohn Wang { 2798a7236aeSJohn Wang public: 2808a7236aeSJohn Wang using PropertiesCache = std::unordered_map<std::string, PropertyMap>; 2818a7236aeSJohn Wang 2828a7236aeSJohn Wang /** @brief Creates a new ObjectLookupCache for the interface on the bus 2838a7236aeSJohn Wang * NOTE: The inputs to this object must outlive the object since 2848a7236aeSJohn Wang * they are only referenced by it. 2858a7236aeSJohn Wang * 2868a7236aeSJohn Wang * @param[in] bus - The bus object used for lookups 2878a7236aeSJohn Wang * @param[in] params - The parameters for the channel 2888a7236aeSJohn Wang * @param[in] intf - The interface we are looking up 2898a7236aeSJohn Wang */ 2905d82f474SPatrick Williams ObjectLookupCache(sdbusplus::bus_t& bus, const ChannelParams& params, 2918a7236aeSJohn Wang const char* intf) : 2928a7236aeSJohn Wang bus(bus), 2938a7236aeSJohn Wang params(params), intf(intf), 2948a7236aeSJohn Wang objs(getAllDbusObjects(bus, params.logicalPath, intf, "")) 295fbc6c9d7SPatrick Williams {} 2968a7236aeSJohn Wang 2978a7236aeSJohn Wang class iterator : public ObjectTree::const_iterator 2988a7236aeSJohn Wang { 2998a7236aeSJohn Wang public: 3008a7236aeSJohn Wang using value_type = PropertiesCache::value_type; 3018a7236aeSJohn Wang 3028a7236aeSJohn Wang iterator(ObjectTree::const_iterator it, ObjectLookupCache& container) : 3038a7236aeSJohn Wang ObjectTree::const_iterator(it), container(container), 3048a7236aeSJohn Wang ret(container.cache.end()) 305fbc6c9d7SPatrick Williams {} 3068a7236aeSJohn Wang value_type& operator*() 3078a7236aeSJohn Wang { 3088a7236aeSJohn Wang ret = container.get(ObjectTree::const_iterator::operator*().first); 3098a7236aeSJohn Wang return *ret; 3108a7236aeSJohn Wang } 3118a7236aeSJohn Wang value_type* operator->() 3128a7236aeSJohn Wang { 3138a7236aeSJohn Wang return &operator*(); 3148a7236aeSJohn Wang } 3158a7236aeSJohn Wang 3168a7236aeSJohn Wang private: 3178a7236aeSJohn Wang ObjectLookupCache& container; 3188a7236aeSJohn Wang PropertiesCache::iterator ret; 3198a7236aeSJohn Wang }; 3208a7236aeSJohn Wang 3218a7236aeSJohn Wang iterator begin() noexcept 3228a7236aeSJohn Wang { 3238a7236aeSJohn Wang return iterator(objs.begin(), *this); 3248a7236aeSJohn Wang } 3258a7236aeSJohn Wang 3268a7236aeSJohn Wang iterator end() noexcept 3278a7236aeSJohn Wang { 3288a7236aeSJohn Wang return iterator(objs.end(), *this); 3298a7236aeSJohn Wang } 3308a7236aeSJohn Wang 3318a7236aeSJohn Wang private: 3325d82f474SPatrick Williams sdbusplus::bus_t& bus; 3338a7236aeSJohn Wang const ChannelParams& params; 3348a7236aeSJohn Wang const char* const intf; 3358a7236aeSJohn Wang const ObjectTree objs; 3368a7236aeSJohn Wang PropertiesCache cache; 3378a7236aeSJohn Wang 3388a7236aeSJohn Wang /** @brief Gets a cached copy of the object properties if possible 3398a7236aeSJohn Wang * Otherwise performs a query on DBus to look them up 3408a7236aeSJohn Wang * 3418a7236aeSJohn Wang * @param[in] path - The object path to lookup 3428a7236aeSJohn Wang * @return An iterator for the specified object path + properties 3438a7236aeSJohn Wang */ 3448a7236aeSJohn Wang PropertiesCache::iterator get(const std::string& path) 3458a7236aeSJohn Wang { 3468a7236aeSJohn Wang auto it = cache.find(path); 3478a7236aeSJohn Wang if (it != cache.end()) 3488a7236aeSJohn Wang { 3498a7236aeSJohn Wang return it; 3508a7236aeSJohn Wang } 3518a7236aeSJohn Wang auto properties = getAllDbusProperties(bus, params.service, path, intf); 3528a7236aeSJohn Wang return cache.insert({path, std::move(properties)}).first; 3538a7236aeSJohn Wang } 3548a7236aeSJohn Wang }; 3558a7236aeSJohn Wang 3568a7236aeSJohn Wang /** @brief Searches the ip object lookup cache for an address matching 3578a7236aeSJohn Wang * the input parameters. NOTE: The index lacks stability across address 3588a7236aeSJohn Wang * changes since the network daemon has no notion of stable indicies. 3598a7236aeSJohn Wang * 3608a7236aeSJohn Wang * @param[in] bus - The bus object used for lookups 3618a7236aeSJohn Wang * @param[in] params - The parameters for the channel 3628a7236aeSJohn Wang * @param[in] idx - The index of the desired address on the interface 3638a7236aeSJohn Wang * @param[in] origins - The allowed origins for the address objects 3648a7236aeSJohn Wang * @param[in] ips - The object lookup cache holding all of the address info 3658a7236aeSJohn Wang * @return The address and prefix if it was found 3668a7236aeSJohn Wang */ 3678a7236aeSJohn Wang template <int family> 3688a7236aeSJohn Wang std::optional<IfAddr<family>> findIfAddr( 3695d82f474SPatrick Williams [[maybe_unused]] sdbusplus::bus_t& bus, 37011d68897SWilly Tu [[maybe_unused]] const ChannelParams& params, uint8_t idx, 3718a7236aeSJohn Wang const std::unordered_set< 372523e2d1bSWilly Tu sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin>& 3738a7236aeSJohn Wang origins, 3748a7236aeSJohn Wang ObjectLookupCache& ips) 3758a7236aeSJohn Wang { 3768a7236aeSJohn Wang for (const auto& [path, properties] : ips) 3778a7236aeSJohn Wang { 378*726f2bddSWilliam A. Kennington III std::optional<typename AddrFamily<family>::addr> addr; 379*726f2bddSWilliam A. Kennington III try 380*726f2bddSWilliam A. Kennington III { 381*726f2bddSWilliam A. Kennington III addr.emplace(stdplus::fromStr<typename AddrFamily<family>::addr>( 382*726f2bddSWilliam A. Kennington III std::get<std::string>(properties.at("Address")))); 383*726f2bddSWilliam A. Kennington III } 384*726f2bddSWilliam A. Kennington III catch (...) 3858a7236aeSJohn Wang { 3868a7236aeSJohn Wang continue; 3878a7236aeSJohn Wang } 3888a7236aeSJohn Wang 389523e2d1bSWilly Tu sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin 390523e2d1bSWilly Tu origin = sdbusplus::server::xyz::openbmc_project::network::IP:: 3918a7236aeSJohn Wang convertAddressOriginFromString( 3928a7236aeSJohn Wang std::get<std::string>(properties.at("Origin"))); 3938a7236aeSJohn Wang if (origins.find(origin) == origins.end()) 3948a7236aeSJohn Wang { 3958a7236aeSJohn Wang continue; 3968a7236aeSJohn Wang } 3978a7236aeSJohn Wang 3988a7236aeSJohn Wang if (idx > 0) 3998a7236aeSJohn Wang { 4008a7236aeSJohn Wang idx--; 4018a7236aeSJohn Wang continue; 4028a7236aeSJohn Wang } 4038a7236aeSJohn Wang 4048a7236aeSJohn Wang IfAddr<family> ifaddr; 4058a7236aeSJohn Wang ifaddr.path = path; 4068a7236aeSJohn Wang ifaddr.address = *addr; 4078a7236aeSJohn Wang ifaddr.prefix = std::get<uint8_t>(properties.at("PrefixLength")); 4088a7236aeSJohn Wang ifaddr.origin = origin; 40911d68897SWilly Tu return ifaddr; 4108a7236aeSJohn Wang } 4118a7236aeSJohn Wang 4128a7236aeSJohn Wang return std::nullopt; 4138a7236aeSJohn Wang } 4148a7236aeSJohn Wang /** @brief Trivial helper around findIfAddr that simplifies calls 4158a7236aeSJohn Wang * for one off lookups. Don't use this if you intend to do multiple 4168a7236aeSJohn Wang * lookups at a time. 4178a7236aeSJohn Wang * 4188a7236aeSJohn Wang * @param[in] bus - The bus object used for lookups 4198a7236aeSJohn Wang * @param[in] params - The parameters for the channel 4208a7236aeSJohn Wang * @param[in] idx - The index of the desired address on the interface 4218a7236aeSJohn Wang * @param[in] origins - The allowed origins for the address objects 4228a7236aeSJohn Wang * @return The address and prefix if it was found 4238a7236aeSJohn Wang */ 4248a7236aeSJohn Wang template <int family> 4258a7236aeSJohn Wang auto getIfAddr( 4265d82f474SPatrick Williams sdbusplus::bus_t& bus, const ChannelParams& params, uint8_t idx, 4278a7236aeSJohn Wang const std::unordered_set< 428523e2d1bSWilly Tu sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin>& 4298a7236aeSJohn Wang origins) 4308a7236aeSJohn Wang { 4318a7236aeSJohn Wang ObjectLookupCache ips(bus, params, INTF_IP); 4328a7236aeSJohn Wang return findIfAddr<family>(bus, params, idx, origins, ips); 4338a7236aeSJohn Wang } 4348a7236aeSJohn Wang 4358a7236aeSJohn Wang /** @brief Reconfigures the IPv6 address info configured for the interface 4368a7236aeSJohn Wang * 4378a7236aeSJohn Wang * @param[in] bus - The bus object used for lookups 4388a7236aeSJohn Wang * @param[in] params - The parameters for the channel 4398a7236aeSJohn Wang * @param[in] idx - The address index to operate on 4408a7236aeSJohn Wang * @param[in] address - The new address 4418a7236aeSJohn Wang * @param[in] prefix - The new address prefix 4428a7236aeSJohn Wang */ 4435d82f474SPatrick Williams void reconfigureIfAddr6(sdbusplus::bus_t& bus, const ChannelParams& params, 444*726f2bddSWilliam A. Kennington III uint8_t idx, stdplus::In6Addr address, uint8_t prefix); 4458a7236aeSJohn Wang 4468a7236aeSJohn Wang /** @brief Retrieves the current gateway for the address family on the system 447d1bd8c48SLei YU * NOTE: The gateway is per channel instead of the system wide one. 4488a7236aeSJohn Wang * 4498a7236aeSJohn Wang * @param[in] bus - The bus object used for lookups 4508a7236aeSJohn Wang * @param[in] params - The parameters for the channel 4518a7236aeSJohn Wang * @return An address representing the gateway address if it exists 4528a7236aeSJohn Wang */ 4538a7236aeSJohn Wang template <int family> 4548a7236aeSJohn Wang std::optional<typename AddrFamily<family>::addr> 4555d82f474SPatrick Williams getGatewayProperty(sdbusplus::bus_t& bus, const ChannelParams& params) 4568a7236aeSJohn Wang { 457d1bd8c48SLei YU auto objPath = "/xyz/openbmc_project/network/" + params.ifname; 458d1bd8c48SLei YU auto gatewayStr = std::get<std::string>( 459d1bd8c48SLei YU getDbusProperty(bus, params.service, objPath, INTF_ETHERNET, 4608a7236aeSJohn Wang AddrFamily<family>::propertyGateway)); 4618a7236aeSJohn Wang if (gatewayStr.empty()) 4628a7236aeSJohn Wang { 4638a7236aeSJohn Wang return std::nullopt; 4648a7236aeSJohn Wang } 465*726f2bddSWilliam A. Kennington III return stdplus::fromStr<typename AddrFamily<family>::addr>(gatewayStr); 4668a7236aeSJohn Wang } 4678a7236aeSJohn Wang 4688a7236aeSJohn Wang template <int family> 4698a7236aeSJohn Wang std::optional<IfNeigh<family>> 4705d82f474SPatrick Williams findStaticNeighbor(sdbusplus::bus_t&, const ChannelParams&, 471*726f2bddSWilliam A. Kennington III typename AddrFamily<family>::addr ip, 4728a7236aeSJohn Wang ObjectLookupCache& neighbors) 4738a7236aeSJohn Wang { 474523e2d1bSWilly Tu using sdbusplus::server::xyz::openbmc_project::network::Neighbor; 4758a7236aeSJohn Wang const auto state = 476523e2d1bSWilly Tu sdbusplus::common::xyz::openbmc_project::network::convertForMessage( 4778a7236aeSJohn Wang Neighbor::State::Permanent); 4788a7236aeSJohn Wang for (const auto& [path, neighbor] : neighbors) 4798a7236aeSJohn Wang { 480*726f2bddSWilliam A. Kennington III std::optional<typename AddrFamily<family>::addr> neighIP; 481*726f2bddSWilliam A. Kennington III try 482*726f2bddSWilliam A. Kennington III { 483*726f2bddSWilliam A. Kennington III neighIP.emplace(stdplus::fromStr<typename AddrFamily<family>::addr>( 484*726f2bddSWilliam A. Kennington III std::get<std::string>(neighbor.at("IPAddress")))); 485*726f2bddSWilliam A. Kennington III } 486*726f2bddSWilliam A. Kennington III catch (...) 4878a7236aeSJohn Wang { 4888a7236aeSJohn Wang continue; 4898a7236aeSJohn Wang } 490*726f2bddSWilliam A. Kennington III if (*neighIP != ip) 4918a7236aeSJohn Wang { 4928a7236aeSJohn Wang continue; 4938a7236aeSJohn Wang } 4948a7236aeSJohn Wang if (state != std::get<std::string>(neighbor.at("State"))) 4958a7236aeSJohn Wang { 4968a7236aeSJohn Wang continue; 4978a7236aeSJohn Wang } 4988a7236aeSJohn Wang 4998a7236aeSJohn Wang IfNeigh<family> ret; 5008a7236aeSJohn Wang ret.path = path; 5018a7236aeSJohn Wang ret.ip = ip; 502*726f2bddSWilliam A. Kennington III ret.mac = stdplus::fromStr<stdplus::EtherAddr>( 503*726f2bddSWilliam A. Kennington III std::get<std::string>(neighbor.at("MACAddress"))); 50411d68897SWilly Tu return ret; 5058a7236aeSJohn Wang } 5068a7236aeSJohn Wang 5078a7236aeSJohn Wang return std::nullopt; 5088a7236aeSJohn Wang } 5098a7236aeSJohn Wang 5108a7236aeSJohn Wang template <int family> 5115d82f474SPatrick Williams void createNeighbor(sdbusplus::bus_t& bus, const ChannelParams& params, 512*726f2bddSWilliam A. Kennington III typename AddrFamily<family>::addr address, 513*726f2bddSWilliam A. Kennington III stdplus::EtherAddr mac) 5148a7236aeSJohn Wang { 515fbc6c9d7SPatrick Williams auto newreq = bus.new_method_call(params.service.c_str(), 516fbc6c9d7SPatrick Williams params.logicalPath.c_str(), 5178a7236aeSJohn Wang INTF_NEIGHBOR_CREATE_STATIC, "Neighbor"); 518*726f2bddSWilliam A. Kennington III stdplus::ToStrHandle<stdplus::ToStr<stdplus::EtherAddr>> macToStr; 519*726f2bddSWilliam A. Kennington III stdplus::ToStrHandle<stdplus::ToStr<typename AddrFamily<family>::addr>> 520*726f2bddSWilliam A. Kennington III addrToStr; 521*726f2bddSWilliam A. Kennington III newreq.append(addrToStr(address), macToStr(mac)); 5228a7236aeSJohn Wang bus.call_noreply(newreq); 5238a7236aeSJohn Wang } 5248a7236aeSJohn Wang 5258a7236aeSJohn Wang /** @brief Deletes the dbus object. Ignores empty objects or objects that are 5268a7236aeSJohn Wang * missing from the bus. 5278a7236aeSJohn Wang * 5288a7236aeSJohn Wang * @param[in] bus - The bus object used for lookups 5298a7236aeSJohn Wang * @param[in] service - The name of the service 5308a7236aeSJohn Wang * @param[in] path - The path of the object to delete 5318a7236aeSJohn Wang */ 5325d82f474SPatrick Williams void deleteObjectIfExists(sdbusplus::bus_t& bus, const std::string& service, 5338a7236aeSJohn Wang const std::string& path); 5348a7236aeSJohn Wang 535d1bd8c48SLei YU /** @brief Sets the value for the default gateway of the channel 5368a7236aeSJohn Wang * 5378a7236aeSJohn Wang * @param[in] bus - The bus object used for lookups 5388a7236aeSJohn Wang * @param[in] params - The parameters for the channel 5398a7236aeSJohn Wang * @param[in] gateway - Gateway address to apply 5408a7236aeSJohn Wang */ 5418a7236aeSJohn Wang template <int family> 5425d82f474SPatrick Williams void setGatewayProperty(sdbusplus::bus_t& bus, const ChannelParams& params, 543*726f2bddSWilliam A. Kennington III typename AddrFamily<family>::addr address) 5448a7236aeSJohn Wang { 5458a7236aeSJohn Wang // Save the old gateway MAC address if it exists so we can recreate it 5468a7236aeSJohn Wang auto gateway = getGatewayProperty<family>(bus, params); 5478a7236aeSJohn Wang std::optional<IfNeigh<family>> neighbor; 5488a7236aeSJohn Wang if (gateway) 5498a7236aeSJohn Wang { 5508a7236aeSJohn Wang ObjectLookupCache neighbors(bus, params, INTF_NEIGHBOR); 5518a7236aeSJohn Wang neighbor = findStaticNeighbor<family>(bus, params, *gateway, neighbors); 5528a7236aeSJohn Wang } 5538a7236aeSJohn Wang 554d1bd8c48SLei YU auto objPath = "/xyz/openbmc_project/network/" + params.ifname; 555d1bd8c48SLei YU setDbusProperty(bus, params.service, objPath, INTF_ETHERNET, 5568a7236aeSJohn Wang AddrFamily<family>::propertyGateway, 557*726f2bddSWilliam A. Kennington III stdplus::toStr(address)); 5588a7236aeSJohn Wang 5598a7236aeSJohn Wang // Restore the gateway MAC if we had one 5608a7236aeSJohn Wang if (neighbor) 5618a7236aeSJohn Wang { 5628a7236aeSJohn Wang deleteObjectIfExists(bus, params.service, neighbor->path); 5638a7236aeSJohn Wang createNeighbor<family>(bus, params, address, neighbor->mac); 5648a7236aeSJohn Wang } 5658a7236aeSJohn Wang } 5668a7236aeSJohn Wang 56723f44657SJian Zhang /** @enum SolConfParam 56823f44657SJian Zhang * 56923f44657SJian Zhang * using for Set/Get SOL configuration parameters command. 57023f44657SJian Zhang */ 57123f44657SJian Zhang enum class SolConfParam : uint8_t 57223f44657SJian Zhang { 57323f44657SJian Zhang Progress, //!< Set In Progress. 57423f44657SJian Zhang Enable, //!< SOL Enable. 57523f44657SJian Zhang Authentication, //!< SOL Authentication. 57623f44657SJian Zhang Accumulate, //!< Character Accumulate Interval & Send Threshold. 57723f44657SJian Zhang Retry, //!< SOL Retry. 57823f44657SJian Zhang NonVbitrate, //!< SOL non-volatile bit rate. 57923f44657SJian Zhang Vbitrate, //!< SOL volatile bit rate. 58023f44657SJian Zhang Channel, //!< SOL payload channel. 58123f44657SJian Zhang Port, //!< SOL payload port. 58223f44657SJian Zhang }; 58323f44657SJian Zhang 58423f44657SJian Zhang constexpr uint8_t ipmiCCParamNotSupported = 0x80; 58523f44657SJian Zhang constexpr uint8_t ipmiCCWriteReadParameter = 0x82; 58623f44657SJian Zhang 587690a2342SPatrick Venture } // namespace transport 588690a2342SPatrick Venture } // namespace ipmi 589