xref: /openbmc/phosphor-networkd/src/types.hpp (revision b9d7cbac)
11bbe3d1eSWilliam A. Kennington III #pragma once
2bb0eaccbSWilliam A. Kennington III #include <fmt/core.h>
3bb0eaccbSWilliam A. Kennington III #include <net/ethernet.h>
41bbe3d1eSWilliam A. Kennington III #include <netinet/in.h>
51bbe3d1eSWilliam A. Kennington III 
6bb0eaccbSWilliam A. Kennington III #include <algorithm>
7bb0eaccbSWilliam A. Kennington III #include <array>
81bbe3d1eSWilliam A. Kennington III #include <chrono>
971de63a2SWilliam A. Kennington III #include <numeric>
101bbe3d1eSWilliam A. Kennington III #include <sdeventplus/clock.hpp>
111bbe3d1eSWilliam A. Kennington III #include <sdeventplus/utility/timer.hpp>
121bbe3d1eSWilliam A. Kennington III #include <string>
13bb0eaccbSWilliam A. Kennington III #include <string_view>
14bb0eaccbSWilliam A. Kennington III #include <type_traits>
15dd9ef815SWilliam A. Kennington III #include <unordered_map>
16f7dce2e8SWilly Tu #include <unordered_set>
171bbe3d1eSWilliam A. Kennington III #include <variant>
181bbe3d1eSWilliam A. Kennington III 
191bbe3d1eSWilliam A. Kennington III namespace phosphor
201bbe3d1eSWilliam A. Kennington III {
211bbe3d1eSWilliam A. Kennington III namespace network
221bbe3d1eSWilliam A. Kennington III {
231bbe3d1eSWilliam A. Kennington III 
241bbe3d1eSWilliam A. Kennington III using namespace std::chrono_literals;
251bbe3d1eSWilliam A. Kennington III 
26c7cf25f7SWilliam A. Kennington III // wait for three seconds before reloading systemd-networkd
27c7cf25f7SWilliam A. Kennington III constexpr auto reloadTimeout = 3s;
281bbe3d1eSWilliam A. Kennington III 
29d41db383SWilliam A. Kennington III // refresh the objets after four seconds as network
30d41db383SWilliam A. Kennington III // configuration takes 3-4 sec to reconfigure at most.
31d41db383SWilliam A. Kennington III constexpr auto refreshTimeout = 4s;
321bbe3d1eSWilliam A. Kennington III 
331bbe3d1eSWilliam A. Kennington III // Byte representations for common address types in network byte order
34bb0eaccbSWilliam A. Kennington III using InAddrAny = std::variant<in_addr, in6_addr>;
35*b9d7cbacSWilliam A. Kennington III class IfAddr
36*b9d7cbacSWilliam A. Kennington III {
37*b9d7cbacSWilliam A. Kennington III   private:
38*b9d7cbacSWilliam A. Kennington III     InAddrAny addr;
39*b9d7cbacSWilliam A. Kennington III     uint8_t pfx;
40*b9d7cbacSWilliam A. Kennington III 
41*b9d7cbacSWilliam A. Kennington III     static void invalidPfx(uint8_t pfx);
42*b9d7cbacSWilliam A. Kennington III 
43*b9d7cbacSWilliam A. Kennington III   public:
44*b9d7cbacSWilliam A. Kennington III     constexpr IfAddr() : addr({}), pfx(0)
45*b9d7cbacSWilliam A. Kennington III     {
46*b9d7cbacSWilliam A. Kennington III     }
47*b9d7cbacSWilliam A. Kennington III 
48*b9d7cbacSWilliam A. Kennington III     constexpr IfAddr(InAddrAny addr, uint8_t pfx) : addr(addr), pfx(pfx)
49*b9d7cbacSWilliam A. Kennington III     {
50*b9d7cbacSWilliam A. Kennington III         std::visit(
51*b9d7cbacSWilliam A. Kennington III             [pfx](auto v) {
52*b9d7cbacSWilliam A. Kennington III                 if (sizeof(v) * 8 < pfx)
53*b9d7cbacSWilliam A. Kennington III                 {
54*b9d7cbacSWilliam A. Kennington III                     invalidPfx(pfx);
55*b9d7cbacSWilliam A. Kennington III                 }
56*b9d7cbacSWilliam A. Kennington III             },
57*b9d7cbacSWilliam A. Kennington III             addr);
58*b9d7cbacSWilliam A. Kennington III     }
59*b9d7cbacSWilliam A. Kennington III 
60*b9d7cbacSWilliam A. Kennington III     constexpr auto getAddr() const
61*b9d7cbacSWilliam A. Kennington III     {
62*b9d7cbacSWilliam A. Kennington III         return addr;
63*b9d7cbacSWilliam A. Kennington III     }
64*b9d7cbacSWilliam A. Kennington III 
65*b9d7cbacSWilliam A. Kennington III     constexpr auto getPfx() const
66*b9d7cbacSWilliam A. Kennington III     {
67*b9d7cbacSWilliam A. Kennington III         return pfx;
68*b9d7cbacSWilliam A. Kennington III     }
69*b9d7cbacSWilliam A. Kennington III 
70*b9d7cbacSWilliam A. Kennington III     constexpr bool operator==(phosphor::network::IfAddr rhs) const noexcept
71*b9d7cbacSWilliam A. Kennington III     {
72*b9d7cbacSWilliam A. Kennington III         return addr == rhs.addr && pfx == rhs.pfx;
73*b9d7cbacSWilliam A. Kennington III     }
74*b9d7cbacSWilliam A. Kennington III };
751bbe3d1eSWilliam A. Kennington III 
761bbe3d1eSWilliam A. Kennington III using Timer = sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>;
771bbe3d1eSWilliam A. Kennington III 
78dd9ef815SWilliam A. Kennington III struct string_hash : public std::hash<std::string_view>
79dd9ef815SWilliam A. Kennington III {
80dd9ef815SWilliam A. Kennington III     using is_transparent = void;
81dd9ef815SWilliam A. Kennington III };
82dd9ef815SWilliam A. Kennington III template <typename V>
83dd9ef815SWilliam A. Kennington III using string_umap =
84dd9ef815SWilliam A. Kennington III     std::unordered_map<std::string, V, string_hash, std::equal_to<>>;
8596444795SWilliam A. Kennington III using string_uset =
8696444795SWilliam A. Kennington III     std::unordered_set<std::string, string_hash, std::equal_to<>>;
87dd9ef815SWilliam A. Kennington III 
883e471c5fSWilliam A. Kennington III constexpr std::size_t hash_multi() noexcept
89991a8e81SWilliam A. Kennington III {
90991a8e81SWilliam A. Kennington III     return 0;
91991a8e81SWilliam A. Kennington III }
92991a8e81SWilliam A. Kennington III 
93991a8e81SWilliam A. Kennington III template <typename T, typename... Args>
94becda1aaSWilliam A. Kennington III constexpr std::size_t hash_multi(const T& v, const Args&... args) noexcept
95991a8e81SWilliam A. Kennington III {
96991a8e81SWilliam A. Kennington III     const std::size_t seed = hash_multi(args...);
97991a8e81SWilliam A. Kennington III     return seed ^ (std::hash<T>{}(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
98991a8e81SWilliam A. Kennington III }
99991a8e81SWilliam A. Kennington III 
100bb0eaccbSWilliam A. Kennington III namespace detail
101bb0eaccbSWilliam A. Kennington III {
102bb0eaccbSWilliam A. Kennington III 
10371de63a2SWilliam A. Kennington III template <typename T, uint8_t size = sizeof(T)>
10471de63a2SWilliam A. Kennington III struct BswapAlign
10571de63a2SWilliam A. Kennington III {
10671de63a2SWilliam A. Kennington III     using type = T;
10771de63a2SWilliam A. Kennington III };
10871de63a2SWilliam A. Kennington III 
10971de63a2SWilliam A. Kennington III template <typename T>
11071de63a2SWilliam A. Kennington III struct BswapAlign<T, 2>
11171de63a2SWilliam A. Kennington III {
11271de63a2SWilliam A. Kennington III     using type alignas(uint16_t) = T;
11371de63a2SWilliam A. Kennington III };
11471de63a2SWilliam A. Kennington III 
11571de63a2SWilliam A. Kennington III template <typename T>
11671de63a2SWilliam A. Kennington III struct BswapAlign<T, 4>
11771de63a2SWilliam A. Kennington III {
11871de63a2SWilliam A. Kennington III     using type alignas(uint32_t) = T;
11971de63a2SWilliam A. Kennington III };
12071de63a2SWilliam A. Kennington III 
12171de63a2SWilliam A. Kennington III template <typename T>
12271de63a2SWilliam A. Kennington III struct BswapAlign<T, 8>
12371de63a2SWilliam A. Kennington III {
12471de63a2SWilliam A. Kennington III     using type alignas(uint64_t) = T;
12571de63a2SWilliam A. Kennington III };
12671de63a2SWilliam A. Kennington III 
12771de63a2SWilliam A. Kennington III template <typename T>
12871de63a2SWilliam A. Kennington III constexpr T bswapInt(typename BswapAlign<T>::type n) noexcept
12971de63a2SWilliam A. Kennington III {
13071de63a2SWilliam A. Kennington III     static_assert(std::is_trivially_copyable_v<T>);
13171de63a2SWilliam A. Kennington III     if constexpr (sizeof(T) == 2)
13271de63a2SWilliam A. Kennington III     {
13371de63a2SWilliam A. Kennington III         reinterpret_cast<uint16_t&>(n) =
13471de63a2SWilliam A. Kennington III             __builtin_bswap16(reinterpret_cast<uint16_t&>(n));
13571de63a2SWilliam A. Kennington III     }
13671de63a2SWilliam A. Kennington III     else if constexpr (sizeof(T) == 4)
13771de63a2SWilliam A. Kennington III     {
13871de63a2SWilliam A. Kennington III         reinterpret_cast<uint32_t&>(n) =
13971de63a2SWilliam A. Kennington III             __builtin_bswap32(reinterpret_cast<uint32_t&>(n));
14071de63a2SWilliam A. Kennington III     }
14171de63a2SWilliam A. Kennington III     else if constexpr (sizeof(T) == 8)
14271de63a2SWilliam A. Kennington III     {
14371de63a2SWilliam A. Kennington III         reinterpret_cast<uint64_t&>(n) =
14471de63a2SWilliam A. Kennington III             __builtin_bswap64(reinterpret_cast<uint64_t&>(n));
14571de63a2SWilliam A. Kennington III     }
14671de63a2SWilliam A. Kennington III     else
14771de63a2SWilliam A. Kennington III     {
14871de63a2SWilliam A. Kennington III         auto b = reinterpret_cast<std::byte*>(&n);
14971de63a2SWilliam A. Kennington III         std::reverse(b, b + sizeof(n));
15071de63a2SWilliam A. Kennington III     }
15171de63a2SWilliam A. Kennington III     return n;
15271de63a2SWilliam A. Kennington III }
15371de63a2SWilliam A. Kennington III 
15471de63a2SWilliam A. Kennington III } // namespace detail
15571de63a2SWilliam A. Kennington III 
15671de63a2SWilliam A. Kennington III template <typename T>
15771de63a2SWilliam A. Kennington III constexpr T bswap(T n) noexcept
15871de63a2SWilliam A. Kennington III {
15971de63a2SWilliam A. Kennington III     return detail::bswapInt<T>(n);
16071de63a2SWilliam A. Kennington III }
16171de63a2SWilliam A. Kennington III 
16271de63a2SWilliam A. Kennington III template <typename T>
16371de63a2SWilliam A. Kennington III constexpr T hton(T n) noexcept
16471de63a2SWilliam A. Kennington III {
16571de63a2SWilliam A. Kennington III     if constexpr (std::endian::native == std::endian::big)
16671de63a2SWilliam A. Kennington III     {
16771de63a2SWilliam A. Kennington III         return n;
16871de63a2SWilliam A. Kennington III     }
16971de63a2SWilliam A. Kennington III     else if constexpr (std::endian::native == std::endian::little)
17071de63a2SWilliam A. Kennington III     {
17171de63a2SWilliam A. Kennington III         return bswap(n);
17271de63a2SWilliam A. Kennington III     }
17371de63a2SWilliam A. Kennington III     else
17471de63a2SWilliam A. Kennington III     {
17571de63a2SWilliam A. Kennington III         static_assert(std::is_same_v<T, void>);
17671de63a2SWilliam A. Kennington III     }
17771de63a2SWilliam A. Kennington III }
17871de63a2SWilliam A. Kennington III 
17971de63a2SWilliam A. Kennington III template <typename T>
18071de63a2SWilliam A. Kennington III constexpr T ntoh(T n) noexcept
18171de63a2SWilliam A. Kennington III {
18271de63a2SWilliam A. Kennington III     return hton(n);
18371de63a2SWilliam A. Kennington III }
18471de63a2SWilliam A. Kennington III 
18571de63a2SWilliam A. Kennington III namespace detail
18671de63a2SWilliam A. Kennington III {
18771de63a2SWilliam A. Kennington III 
188bb0eaccbSWilliam A. Kennington III template <typename T>
189bb0eaccbSWilliam A. Kennington III constexpr bool vcontains() noexcept
190bb0eaccbSWilliam A. Kennington III {
191bb0eaccbSWilliam A. Kennington III     return false;
192bb0eaccbSWilliam A. Kennington III }
193bb0eaccbSWilliam A. Kennington III 
194bb0eaccbSWilliam A. Kennington III template <typename T, typename V, typename... Vs>
195bb0eaccbSWilliam A. Kennington III constexpr bool vcontains() noexcept
196bb0eaccbSWilliam A. Kennington III {
197bb0eaccbSWilliam A. Kennington III     return vcontains<T, Vs...>() || std::is_same_v<T, V>;
198bb0eaccbSWilliam A. Kennington III }
199bb0eaccbSWilliam A. Kennington III 
200bb0eaccbSWilliam A. Kennington III template <typename T, typename... Types>
201bb0eaccbSWilliam A. Kennington III constexpr std::enable_if_t<vcontains<T, Types...>(), bool>
202bb0eaccbSWilliam A. Kennington III     veq(T t, std::variant<Types...> v) noexcept
203bb0eaccbSWilliam A. Kennington III {
204bb0eaccbSWilliam A. Kennington III     return std::visit(
205bb0eaccbSWilliam A. Kennington III         [t](auto v) {
206bb0eaccbSWilliam A. Kennington III             if constexpr (std::is_same_v<T, decltype(v)>)
207bb0eaccbSWilliam A. Kennington III             {
208bb0eaccbSWilliam A. Kennington III                 return v == t;
209bb0eaccbSWilliam A. Kennington III             }
210bb0eaccbSWilliam A. Kennington III             else
211bb0eaccbSWilliam A. Kennington III             {
212bb0eaccbSWilliam A. Kennington III                 return false;
213bb0eaccbSWilliam A. Kennington III             }
214bb0eaccbSWilliam A. Kennington III         },
215bb0eaccbSWilliam A. Kennington III         v);
216bb0eaccbSWilliam A. Kennington III }
217bb0eaccbSWilliam A. Kennington III 
218bb0eaccbSWilliam A. Kennington III template <typename T>
219bb0eaccbSWilliam A. Kennington III struct AddrBufMaker
220bb0eaccbSWilliam A. Kennington III {
221bb0eaccbSWilliam A. Kennington III };
222bb0eaccbSWilliam A. Kennington III 
223bb0eaccbSWilliam A. Kennington III template <>
224bb0eaccbSWilliam A. Kennington III struct AddrBufMaker<ether_addr>
225bb0eaccbSWilliam A. Kennington III {
226bb0eaccbSWilliam A. Kennington III   public:
227bb0eaccbSWilliam A. Kennington III     std::string_view operator()(ether_addr val) noexcept;
228bb0eaccbSWilliam A. Kennington III 
229bb0eaccbSWilliam A. Kennington III   private:
230bb0eaccbSWilliam A. Kennington III     std::array<char, /*octet*/ 2 * /*octets*/ 6 + /*seps*/ 5> buf;
231bb0eaccbSWilliam A. Kennington III };
232bb0eaccbSWilliam A. Kennington III 
233bb0eaccbSWilliam A. Kennington III template <>
234bb0eaccbSWilliam A. Kennington III struct AddrBufMaker<in_addr>
235bb0eaccbSWilliam A. Kennington III {
236bb0eaccbSWilliam A. Kennington III   public:
237bb0eaccbSWilliam A. Kennington III     std::string_view operator()(in_addr val) noexcept;
238bb0eaccbSWilliam A. Kennington III 
239bb0eaccbSWilliam A. Kennington III   private:
240bb0eaccbSWilliam A. Kennington III     std::array<char, /*octet*/ 3 * /*octets*/ 4 + /*seps*/ 3> buf;
241bb0eaccbSWilliam A. Kennington III };
242bb0eaccbSWilliam A. Kennington III 
243bb0eaccbSWilliam A. Kennington III template <>
244bb0eaccbSWilliam A. Kennington III struct AddrBufMaker<in6_addr>
245bb0eaccbSWilliam A. Kennington III {
246bb0eaccbSWilliam A. Kennington III   public:
247bb0eaccbSWilliam A. Kennington III     std::string_view operator()(in6_addr val) noexcept;
248bb0eaccbSWilliam A. Kennington III 
249bb0eaccbSWilliam A. Kennington III   private:
250bb0eaccbSWilliam A. Kennington III     std::array<char, /*hextet*/ 4 * /*hextets*/ 8 + /*seps*/ 7> buf;
251bb0eaccbSWilliam A. Kennington III };
252bb0eaccbSWilliam A. Kennington III 
253bb0eaccbSWilliam A. Kennington III template <typename BufMaker>
254bb0eaccbSWilliam A. Kennington III struct FormatFromBuf
255bb0eaccbSWilliam A. Kennington III {
256bb0eaccbSWilliam A. Kennington III   private:
257bb0eaccbSWilliam A. Kennington III     fmt::formatter<std::string_view> formatter;
258bb0eaccbSWilliam A. Kennington III 
259bb0eaccbSWilliam A. Kennington III   public:
260bb0eaccbSWilliam A. Kennington III     template <typename ParseContext>
261bb0eaccbSWilliam A. Kennington III     constexpr auto parse(ParseContext& ctx)
262bb0eaccbSWilliam A. Kennington III     {
263bb0eaccbSWilliam A. Kennington III         return ctx.begin();
264bb0eaccbSWilliam A. Kennington III     }
265bb0eaccbSWilliam A. Kennington III 
266bb0eaccbSWilliam A. Kennington III     template <typename FormatContext>
267bb0eaccbSWilliam A. Kennington III     auto format(auto v, FormatContext& ctx) const
268bb0eaccbSWilliam A. Kennington III     {
269bb0eaccbSWilliam A. Kennington III         return formatter.format(BufMaker{}(v), ctx);
270bb0eaccbSWilliam A. Kennington III     }
271bb0eaccbSWilliam A. Kennington III };
272bb0eaccbSWilliam A. Kennington III } // namespace detail
2731bbe3d1eSWilliam A. Kennington III } // namespace network
2741bbe3d1eSWilliam A. Kennington III } // namespace phosphor
2753e471c5fSWilliam A. Kennington III 
2763e471c5fSWilliam A. Kennington III template <typename... Ts>
2773e471c5fSWilliam A. Kennington III struct std::hash<std::tuple<Ts...>>
2783e471c5fSWilliam A. Kennington III {
2793e471c5fSWilliam A. Kennington III     constexpr auto operator()(const std::tuple<Ts...>& t) const noexcept
2803e471c5fSWilliam A. Kennington III     {
2813e471c5fSWilliam A. Kennington III         return std::apply(phosphor::network::hash_multi<Ts...>, t);
2823e471c5fSWilliam A. Kennington III     }
2833e471c5fSWilliam A. Kennington III };
284bb0eaccbSWilliam A. Kennington III 
285653114fcSWilliam A. Kennington III template <>
286653114fcSWilliam A. Kennington III struct std::hash<in_addr>
287653114fcSWilliam A. Kennington III {
288653114fcSWilliam A. Kennington III     std::size_t operator()(in_addr addr) const noexcept;
289653114fcSWilliam A. Kennington III };
290653114fcSWilliam A. Kennington III 
291653114fcSWilliam A. Kennington III template <>
292653114fcSWilliam A. Kennington III struct std::hash<in6_addr>
293653114fcSWilliam A. Kennington III {
294653114fcSWilliam A. Kennington III     std::size_t operator()(in6_addr addr) const noexcept;
295653114fcSWilliam A. Kennington III };
296653114fcSWilliam A. Kennington III 
297*b9d7cbacSWilliam A. Kennington III template <>
298*b9d7cbacSWilliam A. Kennington III struct std::hash<phosphor::network::IfAddr>
299*b9d7cbacSWilliam A. Kennington III {
300*b9d7cbacSWilliam A. Kennington III     std::size_t operator()(phosphor::network::IfAddr addr) const noexcept;
301*b9d7cbacSWilliam A. Kennington III };
302*b9d7cbacSWilliam A. Kennington III 
303bb0eaccbSWilliam A. Kennington III namespace fmt
304bb0eaccbSWilliam A. Kennington III {
305bb0eaccbSWilliam A. Kennington III template <>
306bb0eaccbSWilliam A. Kennington III struct formatter<ether_addr>
307bb0eaccbSWilliam A. Kennington III     : phosphor::network::detail::FormatFromBuf<
308bb0eaccbSWilliam A. Kennington III           phosphor::network::detail::AddrBufMaker<ether_addr>>
309bb0eaccbSWilliam A. Kennington III {
310bb0eaccbSWilliam A. Kennington III };
311bb0eaccbSWilliam A. Kennington III template <>
312bb0eaccbSWilliam A. Kennington III struct formatter<in_addr>
313bb0eaccbSWilliam A. Kennington III     : phosphor::network::detail::FormatFromBuf<
314bb0eaccbSWilliam A. Kennington III           phosphor::network::detail::AddrBufMaker<in_addr>>
315bb0eaccbSWilliam A. Kennington III {
316bb0eaccbSWilliam A. Kennington III };
317bb0eaccbSWilliam A. Kennington III template <>
318bb0eaccbSWilliam A. Kennington III struct formatter<in6_addr>
319bb0eaccbSWilliam A. Kennington III     : phosphor::network::detail::FormatFromBuf<
320bb0eaccbSWilliam A. Kennington III           phosphor::network::detail::AddrBufMaker<in6_addr>>
321bb0eaccbSWilliam A. Kennington III {
322bb0eaccbSWilliam A. Kennington III };
323bb0eaccbSWilliam A. Kennington III template <>
324bb0eaccbSWilliam A. Kennington III struct formatter<phosphor::network::InAddrAny>
325bb0eaccbSWilliam A. Kennington III {
326bb0eaccbSWilliam A. Kennington III   private:
327bb0eaccbSWilliam A. Kennington III     fmt::formatter<std::string_view> formatter;
328bb0eaccbSWilliam A. Kennington III 
329bb0eaccbSWilliam A. Kennington III   public:
330bb0eaccbSWilliam A. Kennington III     template <typename ParseContext>
331bb0eaccbSWilliam A. Kennington III     constexpr auto parse(ParseContext& ctx)
332bb0eaccbSWilliam A. Kennington III     {
333bb0eaccbSWilliam A. Kennington III         return ctx.begin();
334bb0eaccbSWilliam A. Kennington III     }
335bb0eaccbSWilliam A. Kennington III 
336bb0eaccbSWilliam A. Kennington III     template <typename FormatContext>
337bb0eaccbSWilliam A. Kennington III     auto format(auto v, FormatContext& ctx) const
338bb0eaccbSWilliam A. Kennington III     {
339bb0eaccbSWilliam A. Kennington III         return std::visit(
340bb0eaccbSWilliam A. Kennington III             [&](auto v) {
341bb0eaccbSWilliam A. Kennington III                 auto abm =
342bb0eaccbSWilliam A. Kennington III                     phosphor::network::detail::AddrBufMaker<decltype(v)>{};
343bb0eaccbSWilliam A. Kennington III                 return formatter.format(abm(v), ctx);
344bb0eaccbSWilliam A. Kennington III             },
345bb0eaccbSWilliam A. Kennington III             v);
346bb0eaccbSWilliam A. Kennington III     }
347bb0eaccbSWilliam A. Kennington III };
348*b9d7cbacSWilliam A. Kennington III template <>
349*b9d7cbacSWilliam A. Kennington III struct formatter<phosphor::network::IfAddr>
350*b9d7cbacSWilliam A. Kennington III {
351*b9d7cbacSWilliam A. Kennington III   private:
352*b9d7cbacSWilliam A. Kennington III     fmt::formatter<phosphor::network::InAddrAny> addrF;
353*b9d7cbacSWilliam A. Kennington III     fmt::formatter<char> strF;
354*b9d7cbacSWilliam A. Kennington III     fmt::formatter<uint8_t> numF;
355*b9d7cbacSWilliam A. Kennington III 
356*b9d7cbacSWilliam A. Kennington III   public:
357*b9d7cbacSWilliam A. Kennington III     template <typename ParseContext>
358*b9d7cbacSWilliam A. Kennington III     constexpr auto parse(ParseContext& ctx)
359*b9d7cbacSWilliam A. Kennington III     {
360*b9d7cbacSWilliam A. Kennington III         return ctx.begin();
361*b9d7cbacSWilliam A. Kennington III     }
362*b9d7cbacSWilliam A. Kennington III 
363*b9d7cbacSWilliam A. Kennington III     template <typename FormatContext>
364*b9d7cbacSWilliam A. Kennington III     auto format(auto v, FormatContext& ctx) const
365*b9d7cbacSWilliam A. Kennington III     {
366*b9d7cbacSWilliam A. Kennington III         addrF.format(v.getAddr(), ctx);
367*b9d7cbacSWilliam A. Kennington III         strF.format('/', ctx);
368*b9d7cbacSWilliam A. Kennington III         return numF.format(v.getPfx(), ctx);
369*b9d7cbacSWilliam A. Kennington III     }
370*b9d7cbacSWilliam A. Kennington III };
371bb0eaccbSWilliam A. Kennington III } // namespace fmt
372bb0eaccbSWilliam A. Kennington III 
373bb0eaccbSWilliam A. Kennington III namespace std
374bb0eaccbSWilliam A. Kennington III {
375bb0eaccbSWilliam A. Kennington III string to_string(ether_addr value);
376bb0eaccbSWilliam A. Kennington III string to_string(in_addr value);
377bb0eaccbSWilliam A. Kennington III string to_string(in6_addr value);
378bb0eaccbSWilliam A. Kennington III string to_string(phosphor::network::InAddrAny value);
379*b9d7cbacSWilliam A. Kennington III string to_string(phosphor::network::IfAddr value);
380bb0eaccbSWilliam A. Kennington III } // namespace std
381bb0eaccbSWilliam A. Kennington III 
382bb0eaccbSWilliam A. Kennington III constexpr bool operator==(ether_addr lhs, ether_addr rhs) noexcept
383bb0eaccbSWilliam A. Kennington III {
384bb0eaccbSWilliam A. Kennington III     return std::equal(lhs.ether_addr_octet, lhs.ether_addr_octet + 6,
385bb0eaccbSWilliam A. Kennington III                       rhs.ether_addr_octet);
386bb0eaccbSWilliam A. Kennington III }
387bb0eaccbSWilliam A. Kennington III 
388bb0eaccbSWilliam A. Kennington III constexpr bool operator==(in_addr lhs, in_addr rhs) noexcept
389bb0eaccbSWilliam A. Kennington III {
390bb0eaccbSWilliam A. Kennington III     return lhs.s_addr == rhs.s_addr;
391bb0eaccbSWilliam A. Kennington III }
392bb0eaccbSWilliam A. Kennington III 
393bb0eaccbSWilliam A. Kennington III constexpr bool operator==(in6_addr lhs, in6_addr rhs) noexcept
394bb0eaccbSWilliam A. Kennington III {
395bb0eaccbSWilliam A. Kennington III     return std::equal(lhs.s6_addr32, lhs.s6_addr32 + 4, rhs.s6_addr32);
396bb0eaccbSWilliam A. Kennington III }
397bb0eaccbSWilliam A. Kennington III 
398bb0eaccbSWilliam A. Kennington III template <typename T>
399bb0eaccbSWilliam A. Kennington III constexpr std::enable_if_t<!std::is_same_v<phosphor::network::InAddrAny, T>,
400bb0eaccbSWilliam A. Kennington III                            bool>
401bb0eaccbSWilliam A. Kennington III     operator==(phosphor::network::InAddrAny lhs, T rhs) noexcept
402bb0eaccbSWilliam A. Kennington III {
403bb0eaccbSWilliam A. Kennington III     return phosphor::network::detail::veq(rhs, lhs);
404bb0eaccbSWilliam A. Kennington III }
405bb0eaccbSWilliam A. Kennington III 
40686eb8b70SWilliam A. Kennington III auto& operator<<(auto& os, ether_addr v)
407bb0eaccbSWilliam A. Kennington III {
408bb0eaccbSWilliam A. Kennington III     return os << phosphor::network::detail::AddrBufMaker<ether_addr>{}(v);
409bb0eaccbSWilliam A. Kennington III }
410bb0eaccbSWilliam A. Kennington III 
41186eb8b70SWilliam A. Kennington III auto& operator<<(auto& os, in_addr v)
412bb0eaccbSWilliam A. Kennington III {
413bb0eaccbSWilliam A. Kennington III     return os << phosphor::network::detail::AddrBufMaker<in_addr>{}(v);
414bb0eaccbSWilliam A. Kennington III }
415bb0eaccbSWilliam A. Kennington III 
41686eb8b70SWilliam A. Kennington III auto& operator<<(auto& os, in6_addr v)
417bb0eaccbSWilliam A. Kennington III {
418bb0eaccbSWilliam A. Kennington III     return os << phosphor::network::detail::AddrBufMaker<in6_addr>{}(v);
419bb0eaccbSWilliam A. Kennington III }
420bb0eaccbSWilliam A. Kennington III 
42186eb8b70SWilliam A. Kennington III auto& operator<<(auto& os, phosphor::network::InAddrAny v)
422bb0eaccbSWilliam A. Kennington III {
423bb0eaccbSWilliam A. Kennington III     return os << std::visit(
424bb0eaccbSWilliam A. Kennington III                [](auto v) {
425bb0eaccbSWilliam A. Kennington III                    return phosphor::network::detail::AddrBufMaker<
426bb0eaccbSWilliam A. Kennington III                        decltype(v)>{}(v);
427bb0eaccbSWilliam A. Kennington III                },
428bb0eaccbSWilliam A. Kennington III                v);
429bb0eaccbSWilliam A. Kennington III }
430*b9d7cbacSWilliam A. Kennington III 
431*b9d7cbacSWilliam A. Kennington III auto& operator<<(auto& os, phosphor::network::IfAddr v)
432*b9d7cbacSWilliam A. Kennington III {
433*b9d7cbacSWilliam A. Kennington III     return os << v.getAddr() << "/" << std::dec << int{v.getPfx()};
434*b9d7cbacSWilliam A. Kennington III }
435