blob: db5df563efffc1bae2c1ccc137827b735f120723 [file] [log] [blame]
Patrick Venture690a2342020-05-17 11:51:31 -07001#pragma once
2
John Wang8a7236a2021-01-04 15:31:44 +08003#include "app/channel.hpp"
4#include "user_channel/cipher_mgmt.hpp"
5
6#include <arpa/inet.h>
7#include <netinet/ether.h>
8
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -05009#include <ipmid/api-types.hpp>
10#include <ipmid/api.hpp>
11#include <ipmid/message.hpp>
12#include <ipmid/message/types.hpp>
13#include <ipmid/types.hpp>
14#include <ipmid/utils.hpp>
15#include <phosphor-logging/elog-errors.hpp>
16#include <phosphor-logging/elog.hpp>
17#include <phosphor-logging/log.hpp>
18#include <sdbusplus/bus.hpp>
19#include <sdbusplus/exception.hpp>
William A. Kennington III7a3831b2023-06-21 01:10:49 -070020#include <stdplus/raw.hpp>
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -050021#include <user_channel/channel_layer.hpp>
22#include <xyz/openbmc_project/Common/error.hpp>
23#include <xyz/openbmc_project/Network/EthernetInterface/server.hpp>
24#include <xyz/openbmc_project/Network/IP/server.hpp>
25#include <xyz/openbmc_project/Network/Neighbor/server.hpp>
26
John Wang8a7236a2021-01-04 15:31:44 +080027#include <bitset>
28#include <cinttypes>
Patrick Venture690a2342020-05-17 11:51:31 -070029#include <cstdint>
John Wang8a7236a2021-01-04 15:31:44 +080030#include <fstream>
31#include <functional>
John Wang8a7236a2021-01-04 15:31:44 +080032#include <optional>
John Wang8a7236a2021-01-04 15:31:44 +080033#include <string>
34#include <string_view>
John Wang8a7236a2021-01-04 15:31:44 +080035#include <unordered_map>
36#include <unordered_set>
John Wang8a7236a2021-01-04 15:31:44 +080037#include <utility>
38#include <vector>
Patrick Venture690a2342020-05-17 11:51:31 -070039
40namespace ipmi
41{
42namespace transport
43{
44
John Wang8a7236a2021-01-04 15:31:44 +080045// D-Bus Network Daemon definitions
46constexpr auto PATH_ROOT = "/xyz/openbmc_project/network";
John Wang8a7236a2021-01-04 15:31:44 +080047constexpr auto INTF_ETHERNET = "xyz.openbmc_project.Network.EthernetInterface";
48constexpr auto INTF_IP = "xyz.openbmc_project.Network.IP";
49constexpr auto INTF_IP_CREATE = "xyz.openbmc_project.Network.IP.Create";
50constexpr auto INTF_MAC = "xyz.openbmc_project.Network.MACAddress";
51constexpr auto INTF_NEIGHBOR = "xyz.openbmc_project.Network.Neighbor";
52constexpr auto INTF_NEIGHBOR_CREATE_STATIC =
53 "xyz.openbmc_project.Network.Neighbor.CreateStatic";
54constexpr auto INTF_VLAN = "xyz.openbmc_project.Network.VLAN";
55constexpr auto INTF_VLAN_CREATE = "xyz.openbmc_project.Network.VLAN.Create";
56
Patrick Venture690a2342020-05-17 11:51:31 -070057/** @brief IPMI LAN Parameters */
58enum class LanParam : uint8_t
59{
60 SetStatus = 0,
61 AuthSupport = 1,
62 AuthEnables = 2,
63 IP = 3,
64 IPSrc = 4,
65 MAC = 5,
66 SubnetMask = 6,
67 Gateway1 = 12,
68 Gateway1MAC = 13,
69 VLANId = 20,
70 CiphersuiteSupport = 22,
71 CiphersuiteEntries = 23,
72 cipherSuitePrivilegeLevels = 24,
73 IPFamilySupport = 50,
74 IPFamilyEnables = 51,
75 IPv6Status = 55,
76 IPv6StaticAddresses = 56,
77 IPv6DynamicAddresses = 59,
78 IPv6RouterControl = 64,
79 IPv6StaticRouter1IP = 65,
80 IPv6StaticRouter1MAC = 66,
81 IPv6StaticRouter1PrefixLength = 67,
82 IPv6StaticRouter1PrefixValue = 68,
83};
84
85/** @brief IPMI IP Origin Types */
86enum class IPSrc : uint8_t
87{
88 Unspecified = 0,
89 Static = 1,
90 DHCP = 2,
91 BIOS = 3,
92 BMC = 4,
93};
94
95/** @brief IPMI Set Status */
96enum class SetStatus : uint8_t
97{
98 Complete = 0,
99 InProgress = 1,
100 Commit = 2,
101};
102
103/** @brief IPMI Family Suport Bits */
104namespace IPFamilySupportFlag
105{
106constexpr uint8_t IPv6Only = 0;
107constexpr uint8_t DualStack = 1;
108constexpr uint8_t IPv6Alerts = 2;
109} // namespace IPFamilySupportFlag
110
111/** @brief IPMI IPFamily Enables Flag */
112enum class IPFamilyEnables : uint8_t
113{
114 IPv4Only = 0,
115 IPv6Only = 1,
116 DualStack = 2,
117};
118
119/** @brief IPMI IPv6 Dyanmic Status Bits */
120namespace IPv6StatusFlag
121{
122constexpr uint8_t DHCP = 0;
123constexpr uint8_t SLAAC = 1;
124}; // namespace IPv6StatusFlag
125
126/** @brief IPMI IPv6 Source */
127enum class IPv6Source : uint8_t
128{
129 Static = 0,
130 SLAAC = 1,
131 DHCP = 2,
132};
133
134/** @brief IPMI IPv6 Address Status */
135enum class IPv6AddressStatus : uint8_t
136{
137 Active = 0,
138 Disabled = 1,
139};
140
141namespace IPv6RouterControlFlag
142{
143constexpr uint8_t Static = 0;
144constexpr uint8_t Dynamic = 1;
145}; // namespace IPv6RouterControlFlag
146
147// LAN Handler specific response codes
148constexpr Cc ccParamNotSupported = 0x80;
149constexpr Cc ccParamSetLocked = 0x81;
150constexpr Cc ccParamReadOnly = 0x82;
151
152// VLANs are a 12-bit value
153constexpr uint16_t VLAN_VALUE_MASK = 0x0fff;
154constexpr uint16_t VLAN_ENABLE_FLAG = 0x8000;
155
156// Arbitrary v6 Address Limits to prevent too much output in ipmitool
157constexpr uint8_t MAX_IPV6_STATIC_ADDRESSES = 15;
158constexpr uint8_t MAX_IPV6_DYNAMIC_ADDRESSES = 15;
159
Jiaqing Zhao6d4a44e2022-01-24 15:04:00 +0800160// Prefix length limits of phosphor-networkd
161constexpr uint8_t MIN_IPV4_PREFIX_LENGTH = 1;
162constexpr uint8_t MAX_IPV4_PREFIX_LENGTH = 32;
163constexpr uint8_t MIN_IPV6_PREFIX_LENGTH = 1;
164constexpr uint8_t MAX_IPV6_PREFIX_LENGTH = 128;
165
John Wang8a7236a2021-01-04 15:31:44 +0800166/** @brief The dbus parameters for the interface corresponding to a channel
167 * This helps reduce the number of mapper lookups we need for each
168 * query and simplifies finding the VLAN interface if needed.
169 */
170struct ChannelParams
171{
172 /** @brief The channel ID */
173 int id;
174 /** @brief channel name for the interface */
175 std::string ifname;
176 /** @brief Name of the service on the bus */
177 std::string service;
178 /** @brief Lower level adapter path that is guaranteed to not be a VLAN */
179 std::string ifPath;
180 /** @brief Logical adapter path used for address assignment */
181 std::string logicalPath;
182};
183
John Wang8a7236a2021-01-04 15:31:44 +0800184/** @brief Determines the ethernet interface name corresponding to a channel
185 * Tries to map a VLAN object first so that the address information
186 * is accurate. Otherwise it gets the standard ethernet interface.
187 *
188 * @param[in] bus - The bus object used for lookups
189 * @param[in] channel - The channel id corresponding to an ethernet interface
190 * @return Ethernet interface service and object path if it exists
191 */
Patrick Williams5d82f472022-07-22 19:26:53 -0500192std::optional<ChannelParams> maybeGetChannelParams(sdbusplus::bus_t& bus,
John Wang8a7236a2021-01-04 15:31:44 +0800193 uint8_t channel);
194
195/** @brief A trivial helper around maybeGetChannelParams() that throws an
196 * exception when it is unable to acquire parameters for the channel.
197 *
198 * @param[in] bus - The bus object used for lookups
199 * @param[in] channel - The channel id corresponding to an ethernet interface
200 * @return Ethernet interface service and object path
201 */
Patrick Williams5d82f472022-07-22 19:26:53 -0500202ChannelParams getChannelParams(sdbusplus::bus_t& bus, uint8_t channel);
John Wang8a7236a2021-01-04 15:31:44 +0800203
204/** @brief Trivializes using parameter getter functions by providing a bus
205 * and channel parameters automatically.
206 *
207 * @param[in] channel - The channel id corresponding to an ethernet interface
208 * ...
209 */
210template <auto func, typename... Args>
211auto channelCall(uint8_t channel, Args&&... args)
212{
Patrick Williams5d82f472022-07-22 19:26:53 -0500213 sdbusplus::bus_t bus(ipmid_get_sd_bus_connection());
John Wang8a7236a2021-01-04 15:31:44 +0800214 auto params = getChannelParams(bus, channel);
215 return std::invoke(func, bus, params, std::forward<Args>(args)...);
216}
217
218/** @brief Generic paramters for different address families */
219template <int family>
220struct AddrFamily
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500221{};
John Wang8a7236a2021-01-04 15:31:44 +0800222
223/** @brief Parameter specialization for IPv4 */
224template <>
225struct AddrFamily<AF_INET>
226{
227 using addr = in_addr;
228 static constexpr auto protocol =
Willy Tu523e2d12023-09-05 11:36:48 -0700229 sdbusplus::server::xyz::openbmc_project::network::IP::Protocol::IPv4;
John Wang8a7236a2021-01-04 15:31:44 +0800230 static constexpr size_t maxStrLen = INET6_ADDRSTRLEN;
231 static constexpr uint8_t defaultPrefix = 32;
232 static constexpr char propertyGateway[] = "DefaultGateway";
233};
234
235/** @brief Parameter specialization for IPv6 */
236template <>
237struct AddrFamily<AF_INET6>
238{
239 using addr = in6_addr;
240 static constexpr auto protocol =
Willy Tu523e2d12023-09-05 11:36:48 -0700241 sdbusplus::server::xyz::openbmc_project::network::IP::Protocol::IPv6;
John Wang8a7236a2021-01-04 15:31:44 +0800242 static constexpr size_t maxStrLen = INET6_ADDRSTRLEN;
243 static constexpr uint8_t defaultPrefix = 128;
244 static constexpr char propertyGateway[] = "DefaultGateway6";
245};
246
247/** @brief Interface Neighbor configuration parameters */
248template <int family>
249struct IfNeigh
250{
251 std::string path;
252 typename AddrFamily<family>::addr ip;
253 ether_addr mac;
254};
255
256/** @brief Interface IP Address configuration parameters */
257template <int family>
258struct IfAddr
259{
260 std::string path;
261 typename AddrFamily<family>::addr address;
Willy Tu523e2d12023-09-05 11:36:48 -0700262 sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin origin;
John Wang8a7236a2021-01-04 15:31:44 +0800263 uint8_t prefix;
264};
265
266/** @brief Valid address origins for IPv6 */
267static inline const std::unordered_set<
Willy Tu523e2d12023-09-05 11:36:48 -0700268 sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin>
269 originsV6Static = {sdbusplus::server::xyz::openbmc_project::network::IP::
John Wang8a7236a2021-01-04 15:31:44 +0800270 AddressOrigin::Static};
271static inline const std::unordered_set<
Willy Tu523e2d12023-09-05 11:36:48 -0700272 sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin>
John Wang8a7236a2021-01-04 15:31:44 +0800273 originsV6Dynamic = {
Willy Tu523e2d12023-09-05 11:36:48 -0700274 sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin::
John Wang8a7236a2021-01-04 15:31:44 +0800275 DHCP,
Willy Tu523e2d12023-09-05 11:36:48 -0700276 sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin::
John Wang8a7236a2021-01-04 15:31:44 +0800277 SLAAC,
278};
279
280/** @brief A lazy lookup mechanism for iterating over object properties stored
281 * in DBus. This will only perform the object lookup when needed, and
282 * retains a cache of previous lookups to speed up future iterations.
283 */
284class ObjectLookupCache
285{
286 public:
287 using PropertiesCache = std::unordered_map<std::string, PropertyMap>;
288
289 /** @brief Creates a new ObjectLookupCache for the interface on the bus
290 * NOTE: The inputs to this object must outlive the object since
291 * they are only referenced by it.
292 *
293 * @param[in] bus - The bus object used for lookups
294 * @param[in] params - The parameters for the channel
295 * @param[in] intf - The interface we are looking up
296 */
Patrick Williams5d82f472022-07-22 19:26:53 -0500297 ObjectLookupCache(sdbusplus::bus_t& bus, const ChannelParams& params,
John Wang8a7236a2021-01-04 15:31:44 +0800298 const char* intf) :
299 bus(bus),
300 params(params), intf(intf),
301 objs(getAllDbusObjects(bus, params.logicalPath, intf, ""))
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500302 {}
John Wang8a7236a2021-01-04 15:31:44 +0800303
304 class iterator : public ObjectTree::const_iterator
305 {
306 public:
307 using value_type = PropertiesCache::value_type;
308
309 iterator(ObjectTree::const_iterator it, ObjectLookupCache& container) :
310 ObjectTree::const_iterator(it), container(container),
311 ret(container.cache.end())
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500312 {}
John Wang8a7236a2021-01-04 15:31:44 +0800313 value_type& operator*()
314 {
315 ret = container.get(ObjectTree::const_iterator::operator*().first);
316 return *ret;
317 }
318 value_type* operator->()
319 {
320 return &operator*();
321 }
322
323 private:
324 ObjectLookupCache& container;
325 PropertiesCache::iterator ret;
326 };
327
328 iterator begin() noexcept
329 {
330 return iterator(objs.begin(), *this);
331 }
332
333 iterator end() noexcept
334 {
335 return iterator(objs.end(), *this);
336 }
337
338 private:
Patrick Williams5d82f472022-07-22 19:26:53 -0500339 sdbusplus::bus_t& bus;
John Wang8a7236a2021-01-04 15:31:44 +0800340 const ChannelParams& params;
341 const char* const intf;
342 const ObjectTree objs;
343 PropertiesCache cache;
344
345 /** @brief Gets a cached copy of the object properties if possible
346 * Otherwise performs a query on DBus to look them up
347 *
348 * @param[in] path - The object path to lookup
349 * @return An iterator for the specified object path + properties
350 */
351 PropertiesCache::iterator get(const std::string& path)
352 {
353 auto it = cache.find(path);
354 if (it != cache.end())
355 {
356 return it;
357 }
358 auto properties = getAllDbusProperties(bus, params.service, path, intf);
359 return cache.insert({path, std::move(properties)}).first;
360 }
361};
362
363/** @brief Turns an IP address string into the network byte order form
364 * NOTE: This version strictly validates family matches
365 *
366 * @param[in] address - The string form of the address
367 * @return A network byte order address or none if conversion failed
368 */
369template <int family>
370std::optional<typename AddrFamily<family>::addr>
371 maybeStringToAddr(const char* address)
372{
373 typename AddrFamily<family>::addr ret;
374 if (inet_pton(family, address, &ret) == 1)
375 {
376 return ret;
377 }
378 return std::nullopt;
379}
380
381/** @brief Turns an IP address string into the network byte order form
382 * NOTE: This version strictly validates family matches
383 *
384 * @param[in] address - The string form of the address
385 * @return A network byte order address
386 */
387template <int family>
388typename AddrFamily<family>::addr stringToAddr(const char* address)
389{
390 auto ret = maybeStringToAddr<family>(address);
391 if (!ret)
392 {
393 phosphor::logging::log<phosphor::logging::level::ERR>(
394 "Failed to convert IP Address",
395 phosphor::logging::entry("FAMILY=%d", family),
396 phosphor::logging::entry("ADDRESS=%s", address));
397 phosphor::logging::elog<
Willy Tu523e2d12023-09-05 11:36:48 -0700398 sdbusplus::error::xyz::openbmc_project::common::InternalFailure>();
John Wang8a7236a2021-01-04 15:31:44 +0800399 }
400 return *ret;
401}
402
403/** @brief Turns an IP address in network byte order into a string
404 *
405 * @param[in] address - The string form of the address
406 * @return A network byte order address
407 */
408template <int family>
409std::string addrToString(const typename AddrFamily<family>::addr& address)
410{
411 std::string ret(AddrFamily<family>::maxStrLen, '\0');
412 inet_ntop(family, &address, ret.data(), ret.size());
413 ret.resize(strlen(ret.c_str()));
414 return ret;
415}
416
417/** @brief Converts a human readable MAC string into MAC bytes
418 *
419 * @param[in] mac - The MAC string
420 * @return MAC in bytes
421 */
422ether_addr stringToMAC(const char* mac);
423/** @brief Searches the ip object lookup cache for an address matching
424 * the input parameters. NOTE: The index lacks stability across address
425 * changes since the network daemon has no notion of stable indicies.
426 *
427 * @param[in] bus - The bus object used for lookups
428 * @param[in] params - The parameters for the channel
429 * @param[in] idx - The index of the desired address on the interface
430 * @param[in] origins - The allowed origins for the address objects
431 * @param[in] ips - The object lookup cache holding all of the address info
432 * @return The address and prefix if it was found
433 */
434template <int family>
435std::optional<IfAddr<family>> findIfAddr(
Patrick Williams5d82f472022-07-22 19:26:53 -0500436 [[maybe_unused]] sdbusplus::bus_t& bus,
Willy Tu11d68892022-01-20 10:37:34 -0800437 [[maybe_unused]] const ChannelParams& params, uint8_t idx,
John Wang8a7236a2021-01-04 15:31:44 +0800438 const std::unordered_set<
Willy Tu523e2d12023-09-05 11:36:48 -0700439 sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin>&
John Wang8a7236a2021-01-04 15:31:44 +0800440 origins,
441 ObjectLookupCache& ips)
442{
443 for (const auto& [path, properties] : ips)
444 {
445 const auto& addrStr = std::get<std::string>(properties.at("Address"));
446 auto addr = maybeStringToAddr<family>(addrStr.c_str());
447 if (!addr)
448 {
449 continue;
450 }
451
Willy Tu523e2d12023-09-05 11:36:48 -0700452 sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin
453 origin = sdbusplus::server::xyz::openbmc_project::network::IP::
John Wang8a7236a2021-01-04 15:31:44 +0800454 convertAddressOriginFromString(
455 std::get<std::string>(properties.at("Origin")));
456 if (origins.find(origin) == origins.end())
457 {
458 continue;
459 }
460
461 if (idx > 0)
462 {
463 idx--;
464 continue;
465 }
466
467 IfAddr<family> ifaddr;
468 ifaddr.path = path;
469 ifaddr.address = *addr;
470 ifaddr.prefix = std::get<uint8_t>(properties.at("PrefixLength"));
471 ifaddr.origin = origin;
Willy Tu11d68892022-01-20 10:37:34 -0800472 return ifaddr;
John Wang8a7236a2021-01-04 15:31:44 +0800473 }
474
475 return std::nullopt;
476}
477/** @brief Trivial helper around findIfAddr that simplifies calls
478 * for one off lookups. Don't use this if you intend to do multiple
479 * lookups at a time.
480 *
481 * @param[in] bus - The bus object used for lookups
482 * @param[in] params - The parameters for the channel
483 * @param[in] idx - The index of the desired address on the interface
484 * @param[in] origins - The allowed origins for the address objects
485 * @return The address and prefix if it was found
486 */
487template <int family>
488auto getIfAddr(
Patrick Williams5d82f472022-07-22 19:26:53 -0500489 sdbusplus::bus_t& bus, const ChannelParams& params, uint8_t idx,
John Wang8a7236a2021-01-04 15:31:44 +0800490 const std::unordered_set<
Willy Tu523e2d12023-09-05 11:36:48 -0700491 sdbusplus::server::xyz::openbmc_project::network::IP::AddressOrigin>&
John Wang8a7236a2021-01-04 15:31:44 +0800492 origins)
493{
494 ObjectLookupCache ips(bus, params, INTF_IP);
495 return findIfAddr<family>(bus, params, idx, origins, ips);
496}
497
John Wang8a7236a2021-01-04 15:31:44 +0800498/** @brief Reconfigures the IPv6 address info configured for the interface
499 *
500 * @param[in] bus - The bus object used for lookups
501 * @param[in] params - The parameters for the channel
502 * @param[in] idx - The address index to operate on
503 * @param[in] address - The new address
504 * @param[in] prefix - The new address prefix
505 */
Patrick Williams5d82f472022-07-22 19:26:53 -0500506void reconfigureIfAddr6(sdbusplus::bus_t& bus, const ChannelParams& params,
John Wang8a7236a2021-01-04 15:31:44 +0800507 uint8_t idx, const in6_addr& address, uint8_t prefix);
508
509/** @brief Retrieves the current gateway for the address family on the system
Lei YUd1bd8c42021-08-11 17:13:56 +0800510 * NOTE: The gateway is per channel instead of the system wide one.
John Wang8a7236a2021-01-04 15:31:44 +0800511 *
512 * @param[in] bus - The bus object used for lookups
513 * @param[in] params - The parameters for the channel
514 * @return An address representing the gateway address if it exists
515 */
516template <int family>
517std::optional<typename AddrFamily<family>::addr>
Patrick Williams5d82f472022-07-22 19:26:53 -0500518 getGatewayProperty(sdbusplus::bus_t& bus, const ChannelParams& params)
John Wang8a7236a2021-01-04 15:31:44 +0800519{
Lei YUd1bd8c42021-08-11 17:13:56 +0800520 auto objPath = "/xyz/openbmc_project/network/" + params.ifname;
521 auto gatewayStr = std::get<std::string>(
522 getDbusProperty(bus, params.service, objPath, INTF_ETHERNET,
523 AddrFamily<family>::propertyGateway));
John Wang8a7236a2021-01-04 15:31:44 +0800524 if (gatewayStr.empty())
525 {
526 return std::nullopt;
527 }
528 return stringToAddr<family>(gatewayStr.c_str());
529}
530
531template <int family>
532std::optional<IfNeigh<family>>
Patrick Williams5d82f472022-07-22 19:26:53 -0500533 findStaticNeighbor(sdbusplus::bus_t&, const ChannelParams&,
John Wang8a7236a2021-01-04 15:31:44 +0800534 const typename AddrFamily<family>::addr& ip,
535 ObjectLookupCache& neighbors)
536{
Willy Tu523e2d12023-09-05 11:36:48 -0700537 using sdbusplus::server::xyz::openbmc_project::network::Neighbor;
John Wang8a7236a2021-01-04 15:31:44 +0800538 const auto state =
Willy Tu523e2d12023-09-05 11:36:48 -0700539 sdbusplus::common::xyz::openbmc_project::network::convertForMessage(
John Wang8a7236a2021-01-04 15:31:44 +0800540 Neighbor::State::Permanent);
541 for (const auto& [path, neighbor] : neighbors)
542 {
543 const auto& ipStr = std::get<std::string>(neighbor.at("IPAddress"));
544 auto neighIP = maybeStringToAddr<family>(ipStr.c_str());
545 if (!neighIP)
546 {
547 continue;
548 }
William A. Kennington III7a3831b2023-06-21 01:10:49 -0700549 if (!stdplus::raw::equal(*neighIP, ip))
John Wang8a7236a2021-01-04 15:31:44 +0800550 {
551 continue;
552 }
553 if (state != std::get<std::string>(neighbor.at("State")))
554 {
555 continue;
556 }
557
558 IfNeigh<family> ret;
559 ret.path = path;
560 ret.ip = ip;
561 const auto& macStr = std::get<std::string>(neighbor.at("MACAddress"));
562 ret.mac = stringToMAC(macStr.c_str());
Willy Tu11d68892022-01-20 10:37:34 -0800563 return ret;
John Wang8a7236a2021-01-04 15:31:44 +0800564 }
565
566 return std::nullopt;
567}
568
569template <int family>
Patrick Williams5d82f472022-07-22 19:26:53 -0500570void createNeighbor(sdbusplus::bus_t& bus, const ChannelParams& params,
John Wang8a7236a2021-01-04 15:31:44 +0800571 const typename AddrFamily<family>::addr& address,
572 const ether_addr& mac)
573{
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500574 auto newreq = bus.new_method_call(params.service.c_str(),
575 params.logicalPath.c_str(),
576 INTF_NEIGHBOR_CREATE_STATIC, "Neighbor");
John Wang8a7236a2021-01-04 15:31:44 +0800577 std::string macStr = ether_ntoa(&mac);
578 newreq.append(addrToString<family>(address), macStr);
579 bus.call_noreply(newreq);
580}
581
582/** @brief Deletes the dbus object. Ignores empty objects or objects that are
583 * missing from the bus.
584 *
585 * @param[in] bus - The bus object used for lookups
586 * @param[in] service - The name of the service
587 * @param[in] path - The path of the object to delete
588 */
Patrick Williams5d82f472022-07-22 19:26:53 -0500589void deleteObjectIfExists(sdbusplus::bus_t& bus, const std::string& service,
John Wang8a7236a2021-01-04 15:31:44 +0800590 const std::string& path);
591
Lei YUd1bd8c42021-08-11 17:13:56 +0800592/** @brief Sets the value for the default gateway of the channel
John Wang8a7236a2021-01-04 15:31:44 +0800593 *
594 * @param[in] bus - The bus object used for lookups
595 * @param[in] params - The parameters for the channel
596 * @param[in] gateway - Gateway address to apply
597 */
598template <int family>
Patrick Williams5d82f472022-07-22 19:26:53 -0500599void setGatewayProperty(sdbusplus::bus_t& bus, const ChannelParams& params,
John Wang8a7236a2021-01-04 15:31:44 +0800600 const typename AddrFamily<family>::addr& address)
601{
602 // Save the old gateway MAC address if it exists so we can recreate it
603 auto gateway = getGatewayProperty<family>(bus, params);
604 std::optional<IfNeigh<family>> neighbor;
605 if (gateway)
606 {
607 ObjectLookupCache neighbors(bus, params, INTF_NEIGHBOR);
608 neighbor = findStaticNeighbor<family>(bus, params, *gateway, neighbors);
609 }
610
Lei YUd1bd8c42021-08-11 17:13:56 +0800611 auto objPath = "/xyz/openbmc_project/network/" + params.ifname;
612 setDbusProperty(bus, params.service, objPath, INTF_ETHERNET,
John Wang8a7236a2021-01-04 15:31:44 +0800613 AddrFamily<family>::propertyGateway,
614 addrToString<family>(address));
615
616 // Restore the gateway MAC if we had one
617 if (neighbor)
618 {
619 deleteObjectIfExists(bus, params.service, neighbor->path);
620 createNeighbor<family>(bus, params, address, neighbor->mac);
621 }
622}
623
Jian Zhang23f44652022-03-17 17:13:10 +0800624/** @enum SolConfParam
625 *
626 * using for Set/Get SOL configuration parameters command.
627 */
628enum class SolConfParam : uint8_t
629{
630 Progress, //!< Set In Progress.
631 Enable, //!< SOL Enable.
632 Authentication, //!< SOL Authentication.
633 Accumulate, //!< Character Accumulate Interval & Send Threshold.
634 Retry, //!< SOL Retry.
635 NonVbitrate, //!< SOL non-volatile bit rate.
636 Vbitrate, //!< SOL volatile bit rate.
637 Channel, //!< SOL payload channel.
638 Port, //!< SOL payload port.
639};
640
641constexpr uint8_t ipmiCCParamNotSupported = 0x80;
642constexpr uint8_t ipmiCCWriteReadParameter = 0x82;
643
Patrick Venture690a2342020-05-17 11:51:31 -0700644} // namespace transport
645} // namespace ipmi