blob: f7c0fa38d9c4cc6759b16640966d5fc7c28fb13d [file] [log] [blame]
Ratan Gupta82549cc2017-04-21 08:45:23 +05301#pragma once
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -07002#include <fmt/core.h>
William A. Kennington III0d7ce482019-01-30 17:14:23 -08003#include <netinet/in.h>
Ratan Gupta3681a502017-06-17 19:20:04 +05304
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -07005#include <stdplus/net/addr/ether.hpp>
6
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -07007#include <algorithm>
8#include <array>
William A. Kennington III71de63a2022-11-08 10:50:54 -08009#include <numeric>
William A. Kennington IIIde70ccf2022-11-20 17:18:01 -080010#include <optional>
Patrick Venture189d44e2018-07-09 12:30:59 -070011#include <string>
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -070012#include <string_view>
13#include <type_traits>
William A. Kennington IIIdd9ef812022-10-05 02:08:02 -070014#include <unordered_map>
Willy Tuf7dce2e2022-10-07 05:48:08 +000015#include <unordered_set>
William A. Kennington III0d7ce482019-01-30 17:14:23 -080016#include <variant>
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +053017
William A. Kennington III454a0de2022-11-12 01:01:04 -080018constexpr bool operator==(in_addr lhs, in_addr rhs) noexcept
19{
20 return lhs.s_addr == rhs.s_addr;
21}
22
23constexpr bool operator==(in6_addr lhs, in6_addr rhs) noexcept
24{
25 return std::equal(lhs.s6_addr32, lhs.s6_addr32 + 4, rhs.s6_addr32);
26}
27
Ratan Gupta82549cc2017-04-21 08:45:23 +053028namespace phosphor
29{
30namespace network
31{
Ratan Guptae05083a2017-09-16 07:12:11 +053032
William A. Kennington III0d7ce482019-01-30 17:14:23 -080033// Byte representations for common address types in network byte order
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -070034using InAddrAny = std::variant<in_addr, in6_addr>;
William A. Kennington IIIb9d7cba2022-11-08 10:54:11 -080035class IfAddr
36{
37 private:
38 InAddrAny addr;
39 uint8_t pfx;
40
41 static void invalidPfx(uint8_t pfx);
42
43 public:
Patrick Williams89d734b2023-05-10 07:50:25 -050044 constexpr IfAddr() : addr({}), pfx(0) {}
William A. Kennington IIIb9d7cba2022-11-08 10:54:11 -080045
46 constexpr IfAddr(InAddrAny addr, uint8_t pfx) : addr(addr), pfx(pfx)
47 {
48 std::visit(
49 [pfx](auto v) {
Patrick Williams89d734b2023-05-10 07:50:25 -050050 if (sizeof(v) * 8 < pfx)
51 {
52 invalidPfx(pfx);
53 }
William A. Kennington IIIb9d7cba2022-11-08 10:54:11 -080054 },
55 addr);
56 }
57
58 constexpr auto getAddr() const
59 {
60 return addr;
61 }
62
63 constexpr auto getPfx() const
64 {
65 return pfx;
66 }
67
68 constexpr bool operator==(phosphor::network::IfAddr rhs) const noexcept
69 {
70 return addr == rhs.addr && pfx == rhs.pfx;
71 }
72};
William A. Kennington III0d7ce482019-01-30 17:14:23 -080073
William A. Kennington III454a0de2022-11-12 01:01:04 -080074/** @class InterfaceInfo
75 * @brief Information about interfaces from the kernel
76 */
77struct InterfaceInfo
78{
William A. Kennington III9c441fd2023-02-24 13:40:01 -080079 unsigned short type;
William A. Kennington III454a0de2022-11-12 01:01:04 -080080 unsigned idx;
81 unsigned flags;
82 std::optional<std::string> name = std::nullopt;
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -070083 std::optional<stdplus::EtherAddr> mac = std::nullopt;
William A. Kennington III454a0de2022-11-12 01:01:04 -080084 std::optional<unsigned> mtu = std::nullopt;
85 std::optional<unsigned> parent_idx = std::nullopt;
86 std::optional<std::string> kind = std::nullopt;
87 std::optional<uint16_t> vlan_id = std::nullopt;
88
89 constexpr bool operator==(const InterfaceInfo& rhs) const noexcept
90 {
91 return idx == rhs.idx && flags == rhs.flags && name == rhs.name &&
92 mac == rhs.mac && mtu == rhs.mtu &&
93 parent_idx == rhs.parent_idx && kind == rhs.kind &&
94 vlan_id == rhs.vlan_id;
95 }
96};
97
William A. Kennington III6a923632022-11-06 18:17:33 -080098/** @class AddressInfo
99 * @brief Information about a addresses from the kernel
100 */
101struct AddressInfo
102{
103 unsigned ifidx;
104 IfAddr ifaddr;
105 uint8_t scope;
106 uint32_t flags;
William A. Kennington III454a0de2022-11-12 01:01:04 -0800107
108 constexpr bool operator==(const AddressInfo& rhs) const noexcept
109 {
110 return ifidx == rhs.ifidx && ifaddr == rhs.ifaddr &&
111 scope == rhs.scope && flags == rhs.flags;
112 }
William A. Kennington III6a923632022-11-06 18:17:33 -0800113};
114
William A. Kennington IIIa8426902022-11-07 15:37:41 -0800115/** @class NeighborInfo
116 * @brief Information about a neighbor from the kernel
117 */
118struct NeighborInfo
119{
120 unsigned ifidx;
William A. Kennington III454a0de2022-11-12 01:01:04 -0800121 uint16_t state;
William A. Kennington IIId3615142022-11-12 01:28:33 -0800122 std::optional<InAddrAny> addr;
William A. Kennington IIIb7d6a1a2023-06-17 02:00:53 -0700123 std::optional<stdplus::EtherAddr> mac;
William A. Kennington III454a0de2022-11-12 01:01:04 -0800124
125 constexpr bool operator==(const NeighborInfo& rhs) const noexcept
126 {
127 return ifidx == rhs.ifidx && state == rhs.state && addr == rhs.addr &&
128 mac == rhs.mac;
129 }
William A. Kennington IIIa8426902022-11-07 15:37:41 -0800130};
131
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700132namespace detail
133{
134
William A. Kennington III71de63a2022-11-08 10:50:54 -0800135template <typename T, uint8_t size = sizeof(T)>
136struct BswapAlign
137{
138 using type = T;
139};
140
141template <typename T>
142struct BswapAlign<T, 2>
143{
144 using type alignas(uint16_t) = T;
145};
146
147template <typename T>
148struct BswapAlign<T, 4>
149{
150 using type alignas(uint32_t) = T;
151};
152
153template <typename T>
154struct BswapAlign<T, 8>
155{
156 using type alignas(uint64_t) = T;
157};
158
159template <typename T>
160constexpr T bswapInt(typename BswapAlign<T>::type n) noexcept
161{
162 static_assert(std::is_trivially_copyable_v<T>);
163 if constexpr (sizeof(T) == 2)
164 {
165 reinterpret_cast<uint16_t&>(n) =
166 __builtin_bswap16(reinterpret_cast<uint16_t&>(n));
167 }
168 else if constexpr (sizeof(T) == 4)
169 {
170 reinterpret_cast<uint32_t&>(n) =
171 __builtin_bswap32(reinterpret_cast<uint32_t&>(n));
172 }
173 else if constexpr (sizeof(T) == 8)
174 {
175 reinterpret_cast<uint64_t&>(n) =
176 __builtin_bswap64(reinterpret_cast<uint64_t&>(n));
177 }
178 else
179 {
180 auto b = reinterpret_cast<std::byte*>(&n);
181 std::reverse(b, b + sizeof(n));
182 }
183 return n;
184}
185
186} // namespace detail
187
188template <typename T>
189constexpr T bswap(T n) noexcept
190{
191 return detail::bswapInt<T>(n);
192}
193
194template <typename T>
195constexpr T hton(T n) noexcept
196{
197 if constexpr (std::endian::native == std::endian::big)
198 {
199 return n;
200 }
201 else if constexpr (std::endian::native == std::endian::little)
202 {
203 return bswap(n);
204 }
205 else
206 {
207 static_assert(std::is_same_v<T, void>);
208 }
209}
210
211template <typename T>
212constexpr T ntoh(T n) noexcept
213{
214 return hton(n);
215}
216
217namespace detail
218{
William A. Kennington III238ef992022-11-03 12:47:49 -0700219inline constexpr auto charLookup = []() {
220 std::array<int8_t, 256> ret;
221 std::fill(ret.begin(), ret.end(), -1);
222 for (int8_t i = 0; i < 10; ++i)
223 {
224 ret[i + '0'] = i;
225 }
226 for (int8_t i = 0; i < 26; ++i)
227 {
228 ret[i + 'A'] = i + 10;
229 ret[i + 'a'] = i + 10;
230 }
231 return ret;
232}();
William A. Kennington IIIdd7c7b32022-11-04 15:19:36 -0700233inline constexpr auto intLookup = []() {
234 std::array<char, 36> ret;
235 for (int8_t i = 0; i < 10; ++i)
236 {
237 ret[i] = i + '0';
238 }
239 for (int8_t i = 0; i < 26; ++i)
240 {
241 ret[i + 10] = i + 'a';
242 }
243 return ret;
244}();
245} // namespace detail
William A. Kennington III238ef992022-11-03 12:47:49 -0700246
247template <typename T, uint8_t base>
248struct DecodeInt
249{
250 static_assert(base > 1 && base <= 36);
251 static_assert(std::is_unsigned_v<T>);
252
253 constexpr T operator()(std::string_view str) const
254 {
255 if (str.empty())
256 {
257 throw std::invalid_argument("Empty Str");
258 }
259 constexpr auto max = std::numeric_limits<T>::max();
Patrick Williams89d734b2023-05-10 07:50:25 -0500260 auto ret = std::accumulate(str.begin(), str.end(), T{},
261 [&](T r, char c) {
262 auto v = detail::charLookup[c];
263 if (v < 0 || v >= base)
264 {
265 throw std::invalid_argument("Invalid numeral");
266 }
267 if constexpr (std::popcount(base) == 1)
268 {
269 constexpr auto shift = std::countr_zero(base);
270 constexpr auto maxshift = max >> shift;
271 if (r > maxshift)
William A. Kennington III238ef992022-11-03 12:47:49 -0700272 {
Patrick Williams89d734b2023-05-10 07:50:25 -0500273 throw std::overflow_error("Integer Decode");
William A. Kennington III238ef992022-11-03 12:47:49 -0700274 }
Patrick Williams89d734b2023-05-10 07:50:25 -0500275 return (r << shift) | v;
276 }
277 else
278 {
279 constexpr auto maxbase = max / base;
280 if (r > maxbase)
William A. Kennington III238ef992022-11-03 12:47:49 -0700281 {
Patrick Williams89d734b2023-05-10 07:50:25 -0500282 throw std::overflow_error("Integer Decode");
William A. Kennington III238ef992022-11-03 12:47:49 -0700283 }
Patrick Williams89d734b2023-05-10 07:50:25 -0500284 r *= base;
285 if (max - v < r)
William A. Kennington III238ef992022-11-03 12:47:49 -0700286 {
Patrick Williams89d734b2023-05-10 07:50:25 -0500287 throw std::overflow_error("Integer Decode");
William A. Kennington III238ef992022-11-03 12:47:49 -0700288 }
Patrick Williams89d734b2023-05-10 07:50:25 -0500289 return r + v;
290 }
291 });
William A. Kennington III238ef992022-11-03 12:47:49 -0700292 return ret;
293 }
294};
295
William A. Kennington IIIdd7c7b32022-11-04 15:19:36 -0700296template <typename T, uint8_t base>
297struct EncodeInt
298{
299 static_assert(base > 1 && base <= 36);
300 static_assert(std::is_unsigned_v<T>);
301
302 static constexpr uint8_t buf_size = []() {
303 T v = std::numeric_limits<T>::max();
304 uint8_t i = 0;
305 for (; v != 0; ++i)
306 {
307 v /= base;
308 }
309 return i;
310 }();
311 using buf_type = std::array<char, buf_size>;
312
313 constexpr uint8_t reverseFill(char* buf, T v) const noexcept
314 {
315 uint8_t i = 0;
316 do
317 {
318 if constexpr (std::popcount(base) == 1)
319 {
320 buf[i++] = detail::intLookup[v & 0xf];
321 v >>= 4;
322 }
323 else
324 {
325 buf[i++] = detail::intLookup[v % base];
326 v /= base;
327 }
328 } while (v > 0);
329 return i;
330 }
331
332 constexpr char* operator()(char* buf, T v) const noexcept
333 {
334 uint8_t i = reverseFill(buf, v);
335 std::reverse(buf, buf + i);
336 return buf + i;
337 }
338
339 constexpr char* operator()(char* buf, T v, uint8_t min_width) const noexcept
340 {
341 uint8_t i = reverseFill(buf, v);
342 auto end = buf + std::max(i, min_width);
343 std::fill(buf + i, end, '0');
344 std::reverse(buf, end);
345 return end;
346 }
347};
348
William A. Kennington IIIb01d08f2022-11-03 12:50:00 -0700349template <typename T>
350struct ToAddr
Patrick Williams89d734b2023-05-10 07:50:25 -0500351{};
William A. Kennington IIIb01d08f2022-11-03 12:50:00 -0700352
353template <>
William A. Kennington IIIdf1178e2022-11-03 12:56:33 -0700354struct ToAddr<in_addr>
355{
356 constexpr in_addr operator()(std::string_view str) const
357 {
358 constexpr DecodeInt<uint8_t, 10> di;
359 uint32_t addr = {};
360 for (size_t i = 0; i < 3; ++i)
361 {
362 auto loc = str.find(".");
363 addr |= di(str.substr(0, loc));
364 addr <<= 8;
365 str.remove_prefix(loc == str.npos ? str.size() : loc + 1);
366 if (str.empty())
367 {
368 throw std::invalid_argument("Missing addr data");
369 }
370 }
371 addr |= di(str);
372 return {hton(addr)};
373 }
374};
375
William A. Kennington IIIec496a82022-11-04 02:17:20 -0700376template <>
377struct ToAddr<in6_addr>
378{
379 constexpr in6_addr operator()(std::string_view str) const
380 {
381 constexpr DecodeInt<uint16_t, 16> di;
382 in6_addr ret = {};
383 size_t i = 0;
384 while (i < 8)
385 {
386 auto loc = str.find(':');
387 if (i == 6 && loc == str.npos)
388 {
389 ret.s6_addr32[3] = ToAddr<in_addr>{}(str).s_addr;
390 return ret;
391 }
392 if (loc != 0 && !str.empty())
393 {
394 ret.s6_addr16[i++] = hton(di(str.substr(0, loc)));
395 }
396 if (i < 8 && str.size() > loc + 1 && str[loc + 1] == ':')
397 {
398 str.remove_prefix(loc + 2);
399 break;
400 }
401 else if (str.empty())
402 {
403 throw std::invalid_argument("IPv6 Data");
404 }
405 str.remove_prefix(loc == str.npos ? str.size() : loc + 1);
406 }
407 if (str.starts_with(':'))
408 {
409 throw std::invalid_argument("Extra separator");
410 }
411 size_t j = 7;
412 if (!str.empty() && i < 6 && str.find('.') != str.npos)
413 {
414 auto loc = str.rfind(':');
415 ret.s6_addr32[3] =
416 ToAddr<in_addr>{}(str.substr(loc == str.npos ? 0 : loc + 1))
417 .s_addr;
418 str.remove_suffix(loc == str.npos ? str.size() : str.size() - loc);
419 j -= 2;
420 }
421 while (!str.empty() && j > i)
422 {
423 auto loc = str.rfind(':');
424 ret.s6_addr16[j--] =
425 hton(di(str.substr(loc == str.npos ? 0 : loc + 1)));
426 str.remove_suffix(loc == str.npos ? str.size() : str.size() - loc);
427 }
428 if (!str.empty())
429 {
430 throw std::invalid_argument("Too much data");
431 }
432 return ret;
433 }
434};
435
William A. Kennington IIIead71982022-11-04 02:18:10 -0700436template <>
437struct ToAddr<InAddrAny>
438{
439 constexpr InAddrAny operator()(std::string_view str) const
440 {
441 if (str.find(':') == str.npos)
442 {
443 return ToAddr<in_addr>{}(str);
444 }
445 return ToAddr<in6_addr>{}(str);
446 }
447};
448
449template <>
450struct ToAddr<IfAddr>
451{
452 constexpr IfAddr operator()(std::string_view str) const
453 {
454 auto pos = str.rfind('/');
455 if (pos == str.npos)
456 {
457 throw std::invalid_argument("Invalid IfAddr");
458 }
459 return {ToAddr<InAddrAny>{}(str.substr(0, pos)),
460 DecodeInt<uint8_t, 10>{}(str.substr(pos + 1))};
461 }
462};
463
William A. Kennington III55bdc362022-11-04 17:57:21 -0700464template <typename T>
465struct ToStr
Patrick Williams89d734b2023-05-10 07:50:25 -0500466{};
William A. Kennington III55bdc362022-11-04 17:57:21 -0700467
468template <>
469struct ToStr<char>
470{
471 static constexpr uint8_t buf_size = 1;
472 using buf_type = std::array<char, buf_size>;
473
474 constexpr char* operator()(char* buf, char v) const noexcept
475 {
476 buf[0] = v;
477 return buf + 1;
478 }
479};
480
481template <>
William A. Kennington III55bdc362022-11-04 17:57:21 -0700482struct ToStr<in_addr>
483{
484 // 4 octets * 3 dec chars + 3 separators
485 static constexpr uint8_t buf_size = 15;
486 using buf_type = std::array<char, buf_size>;
487
488 constexpr char* operator()(char* buf, in_addr v) const noexcept
489 {
490 auto n = bswap(ntoh(v.s_addr));
491 for (size_t i = 0; i < 3; ++i)
492 {
493 buf = ToStr<char>{}(EncodeInt<uint8_t, 10>{}(buf, n & 0xff), '.');
494 n >>= 8;
495 }
496 return EncodeInt<uint8_t, 10>{}(buf, n & 0xff);
497 }
498};
499
500template <>
501struct ToStr<in6_addr>
502{
503 // 8 hextets * 4 hex chars + 7 separators
504 static constexpr uint8_t buf_size = 39;
505 using buf_type = std::array<char, buf_size>;
506
507 constexpr char* operator()(char* buf, in6_addr v) const noexcept
508 {
509 // IPv4 in IPv6 Addr
510 if (v.s6_addr32[0] == 0 && v.s6_addr32[1] == 0 &&
511 v.s6_addr32[2] == hton(uint32_t(0xffff)))
512 {
513 constexpr auto prefix = std::string_view("::ffff:");
514 return ToStr<in_addr>{}(
515 std::copy(prefix.begin(), prefix.end(), buf), {v.s6_addr32[3]});
516 }
517
518 size_t skip_start = 0;
519 size_t skip_size = 0;
520 {
521 size_t new_start = 0;
522 size_t new_size = 0;
523 for (size_t i = 0; i < 9; ++i)
524 {
525 if (i < 8 && v.s6_addr16[i] == 0)
526 {
527 if (new_start + new_size == i)
528 {
529 new_size++;
530 }
531 else
532 {
533 new_start = i;
534 new_size = 1;
535 }
536 }
537 else if (new_start + new_size == i && new_size > skip_size)
538 {
539 skip_start = new_start;
540 skip_size = new_size;
541 }
542 }
543 }
544 for (size_t i = 0; i < 8; ++i)
545 {
546 if (i == skip_start && skip_size > 1)
547 {
548 if (i == 0)
549 {
550 *(buf++) = ':';
551 }
552 *(buf++) = ':';
553 i += skip_size - 1;
554 continue;
555 }
556 buf = EncodeInt<uint16_t, 16>{}(buf, ntoh(v.s6_addr16[i]));
557 if (i < 7)
558 {
559 *(buf++) = ':';
560 }
561 }
562 return buf;
563 }
564};
565
566template <>
567struct ToStr<InAddrAny>
568{
569 // IPv6 is the bigger of the addrs
570 static constexpr uint8_t buf_size = ToStr<in6_addr>::buf_size;
571 using buf_type = std::array<char, buf_size>;
572
573 constexpr char* operator()(char* buf, InAddrAny v) const noexcept
574 {
575 return std::visit([=](auto v) { return ToStr<decltype(v)>{}(buf, v); },
576 v);
577 }
578};
579
580template <>
581struct ToStr<IfAddr>
582{
583 // InAddrAny + sep + 3 prefix chars
584 static constexpr uint8_t buf_size = ToStr<InAddrAny>::buf_size + 4;
585 using buf_type = std::array<char, buf_size>;
586
587 constexpr char* operator()(char* buf, IfAddr v) const noexcept
588 {
589 buf = ToStr<InAddrAny>{}(buf, v.getAddr());
590 buf = ToStr<char>{}(buf, '/');
591 return EncodeInt<uint8_t, 10>{}(buf, v.getPfx());
592 }
593};
594
William A. Kennington III238ef992022-11-03 12:47:49 -0700595namespace detail
596{
William A. Kennington III71de63a2022-11-08 10:50:54 -0800597
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700598template <typename T>
599constexpr bool vcontains() noexcept
600{
601 return false;
602}
603
604template <typename T, typename V, typename... Vs>
605constexpr bool vcontains() noexcept
606{
607 return vcontains<T, Vs...>() || std::is_same_v<T, V>;
608}
609
610template <typename T, typename... Types>
611constexpr std::enable_if_t<vcontains<T, Types...>(), bool>
612 veq(T t, std::variant<Types...> v) noexcept
613{
614 return std::visit(
615 [t](auto v) {
Patrick Williams89d734b2023-05-10 07:50:25 -0500616 if constexpr (std::is_same_v<T, decltype(v)>)
617 {
618 return v == t;
619 }
620 else
621 {
622 return false;
623 }
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700624 },
625 v);
626}
627
628template <typename T>
William A. Kennington III55bdc362022-11-04 17:57:21 -0700629struct ToStrBuf
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700630{
631 public:
William A. Kennington III55bdc362022-11-04 17:57:21 -0700632 constexpr std::string_view operator()(T v) noexcept
633 {
634 return {buf.data(), ToStr<T>{}(buf.data(), v)};
635 }
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700636
637 private:
William A. Kennington III55bdc362022-11-04 17:57:21 -0700638 typename ToStr<T>::buf_type buf;
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700639};
640
William A. Kennington III55bdc362022-11-04 17:57:21 -0700641template <typename T>
642struct Format
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700643{
644 private:
645 fmt::formatter<std::string_view> formatter;
646
647 public:
648 template <typename ParseContext>
649 constexpr auto parse(ParseContext& ctx)
650 {
651 return ctx.begin();
652 }
653
654 template <typename FormatContext>
655 auto format(auto v, FormatContext& ctx) const
656 {
William A. Kennington III55bdc362022-11-04 17:57:21 -0700657 return formatter.format(ToStrBuf<T>{}(v), ctx);
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700658 }
659};
660} // namespace detail
Gunnar Mills57d9c502018-09-14 14:42:34 -0500661} // namespace network
662} // namespace phosphor
William A. Kennington III3e471c52022-10-27 19:46:07 -0700663
William A. Kennington III653114f2022-11-01 22:34:04 -0700664template <>
665struct std::hash<in_addr>
666{
667 std::size_t operator()(in_addr addr) const noexcept;
668};
669
670template <>
671struct std::hash<in6_addr>
672{
673 std::size_t operator()(in6_addr addr) const noexcept;
674};
675
William A. Kennington IIIb9d7cba2022-11-08 10:54:11 -0800676template <>
677struct std::hash<phosphor::network::IfAddr>
678{
679 std::size_t operator()(phosphor::network::IfAddr addr) const noexcept;
680};
681
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700682namespace fmt
683{
684template <>
William A. Kennington III55bdc362022-11-04 17:57:21 -0700685struct formatter<in_addr> : phosphor::network::detail::Format<in_addr>
Patrick Williams89d734b2023-05-10 07:50:25 -0500686{};
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700687template <>
William A. Kennington III55bdc362022-11-04 17:57:21 -0700688struct formatter<in6_addr> : phosphor::network::detail::Format<in6_addr>
Patrick Williams89d734b2023-05-10 07:50:25 -0500689{};
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700690template <>
Patrick Williams89d734b2023-05-10 07:50:25 -0500691struct formatter<phosphor::network::InAddrAny> :
692 phosphor::network::detail::Format<phosphor::network::InAddrAny>
693{};
William A. Kennington IIIb9d7cba2022-11-08 10:54:11 -0800694template <>
Patrick Williams89d734b2023-05-10 07:50:25 -0500695struct formatter<phosphor::network::IfAddr> :
696 phosphor::network::detail::Format<phosphor::network::IfAddr>
697{};
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700698} // namespace fmt
699
700namespace std
701{
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700702string to_string(in_addr value);
703string to_string(in6_addr value);
704string to_string(phosphor::network::InAddrAny value);
William A. Kennington IIIb9d7cba2022-11-08 10:54:11 -0800705string to_string(phosphor::network::IfAddr value);
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700706} // namespace std
707
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700708template <typename T>
709constexpr std::enable_if_t<!std::is_same_v<phosphor::network::InAddrAny, T>,
710 bool>
711 operator==(phosphor::network::InAddrAny lhs, T rhs) noexcept
712{
713 return phosphor::network::detail::veq(rhs, lhs);
714}
715
William A. Kennington III86eb8b72022-11-01 22:35:04 -0700716auto& operator<<(auto& os, in_addr v)
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700717{
William A. Kennington III55bdc362022-11-04 17:57:21 -0700718 return os << phosphor::network::detail::ToStrBuf<in_addr>{}(v);
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700719}
720
William A. Kennington III86eb8b72022-11-01 22:35:04 -0700721auto& operator<<(auto& os, in6_addr v)
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700722{
William A. Kennington III55bdc362022-11-04 17:57:21 -0700723 return os << phosphor::network::detail::ToStrBuf<in6_addr>{}(v);
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700724}
725
William A. Kennington III86eb8b72022-11-01 22:35:04 -0700726auto& operator<<(auto& os, phosphor::network::InAddrAny v)
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700727{
William A. Kennington III55bdc362022-11-04 17:57:21 -0700728 phosphor::network::detail::ToStrBuf<phosphor::network::InAddrAny> tsb;
729 return os << tsb(v);
William A. Kennington IIIbb0eacc2022-10-21 15:22:06 -0700730}
William A. Kennington IIIb9d7cba2022-11-08 10:54:11 -0800731
732auto& operator<<(auto& os, phosphor::network::IfAddr v)
733{
William A. Kennington III55bdc362022-11-04 17:57:21 -0700734 phosphor::network::detail::ToStrBuf<phosphor::network::IfAddr> tsb;
735 return os << tsb(v);
William A. Kennington IIIb9d7cba2022-11-08 10:54:11 -0800736}
William A. Kennington III13d665c2022-11-15 20:34:40 -0800737
738namespace phosphor::network
739{
740
741/** @brief Contains all of the object information about the interface */
742struct AllIntfInfo
743{
744 InterfaceInfo intf;
745 std::optional<in_addr> defgw4 = std::nullopt;
746 std::optional<in6_addr> defgw6 = std::nullopt;
747 std::unordered_map<IfAddr, AddressInfo> addrs = {};
748 std::unordered_map<InAddrAny, NeighborInfo> staticNeighs = {};
749};
750
751} // namespace phosphor::network