xref: /openbmc/phosphor-networkd/src/types.hpp (revision 71de63a2)
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>
9*71de63a2SWilliam 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>;
351bbe3d1eSWilliam A. Kennington III 
361bbe3d1eSWilliam A. Kennington III using Timer = sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>;
371bbe3d1eSWilliam A. Kennington III 
38dd9ef815SWilliam A. Kennington III struct string_hash : public std::hash<std::string_view>
39dd9ef815SWilliam A. Kennington III {
40dd9ef815SWilliam A. Kennington III     using is_transparent = void;
41dd9ef815SWilliam A. Kennington III };
42dd9ef815SWilliam A. Kennington III template <typename V>
43dd9ef815SWilliam A. Kennington III using string_umap =
44dd9ef815SWilliam A. Kennington III     std::unordered_map<std::string, V, string_hash, std::equal_to<>>;
4596444795SWilliam A. Kennington III using string_uset =
4696444795SWilliam A. Kennington III     std::unordered_set<std::string, string_hash, std::equal_to<>>;
47dd9ef815SWilliam A. Kennington III 
483e471c5fSWilliam A. Kennington III constexpr std::size_t hash_multi() noexcept
49991a8e81SWilliam A. Kennington III {
50991a8e81SWilliam A. Kennington III     return 0;
51991a8e81SWilliam A. Kennington III }
52991a8e81SWilliam A. Kennington III 
53991a8e81SWilliam A. Kennington III template <typename T, typename... Args>
54becda1aaSWilliam A. Kennington III constexpr std::size_t hash_multi(const T& v, const Args&... args) noexcept
55991a8e81SWilliam A. Kennington III {
56991a8e81SWilliam A. Kennington III     const std::size_t seed = hash_multi(args...);
57991a8e81SWilliam A. Kennington III     return seed ^ (std::hash<T>{}(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
58991a8e81SWilliam A. Kennington III }
59991a8e81SWilliam A. Kennington III 
60bb0eaccbSWilliam A. Kennington III namespace detail
61bb0eaccbSWilliam A. Kennington III {
62bb0eaccbSWilliam A. Kennington III 
63*71de63a2SWilliam A. Kennington III template <typename T, uint8_t size = sizeof(T)>
64*71de63a2SWilliam A. Kennington III struct BswapAlign
65*71de63a2SWilliam A. Kennington III {
66*71de63a2SWilliam A. Kennington III     using type = T;
67*71de63a2SWilliam A. Kennington III };
68*71de63a2SWilliam A. Kennington III 
69*71de63a2SWilliam A. Kennington III template <typename T>
70*71de63a2SWilliam A. Kennington III struct BswapAlign<T, 2>
71*71de63a2SWilliam A. Kennington III {
72*71de63a2SWilliam A. Kennington III     using type alignas(uint16_t) = T;
73*71de63a2SWilliam A. Kennington III };
74*71de63a2SWilliam A. Kennington III 
75*71de63a2SWilliam A. Kennington III template <typename T>
76*71de63a2SWilliam A. Kennington III struct BswapAlign<T, 4>
77*71de63a2SWilliam A. Kennington III {
78*71de63a2SWilliam A. Kennington III     using type alignas(uint32_t) = T;
79*71de63a2SWilliam A. Kennington III };
80*71de63a2SWilliam A. Kennington III 
81*71de63a2SWilliam A. Kennington III template <typename T>
82*71de63a2SWilliam A. Kennington III struct BswapAlign<T, 8>
83*71de63a2SWilliam A. Kennington III {
84*71de63a2SWilliam A. Kennington III     using type alignas(uint64_t) = T;
85*71de63a2SWilliam A. Kennington III };
86*71de63a2SWilliam A. Kennington III 
87*71de63a2SWilliam A. Kennington III template <typename T>
88*71de63a2SWilliam A. Kennington III constexpr T bswapInt(typename BswapAlign<T>::type n) noexcept
89*71de63a2SWilliam A. Kennington III {
90*71de63a2SWilliam A. Kennington III     static_assert(std::is_trivially_copyable_v<T>);
91*71de63a2SWilliam A. Kennington III     if constexpr (sizeof(T) == 2)
92*71de63a2SWilliam A. Kennington III     {
93*71de63a2SWilliam A. Kennington III         reinterpret_cast<uint16_t&>(n) =
94*71de63a2SWilliam A. Kennington III             __builtin_bswap16(reinterpret_cast<uint16_t&>(n));
95*71de63a2SWilliam A. Kennington III     }
96*71de63a2SWilliam A. Kennington III     else if constexpr (sizeof(T) == 4)
97*71de63a2SWilliam A. Kennington III     {
98*71de63a2SWilliam A. Kennington III         reinterpret_cast<uint32_t&>(n) =
99*71de63a2SWilliam A. Kennington III             __builtin_bswap32(reinterpret_cast<uint32_t&>(n));
100*71de63a2SWilliam A. Kennington III     }
101*71de63a2SWilliam A. Kennington III     else if constexpr (sizeof(T) == 8)
102*71de63a2SWilliam A. Kennington III     {
103*71de63a2SWilliam A. Kennington III         reinterpret_cast<uint64_t&>(n) =
104*71de63a2SWilliam A. Kennington III             __builtin_bswap64(reinterpret_cast<uint64_t&>(n));
105*71de63a2SWilliam A. Kennington III     }
106*71de63a2SWilliam A. Kennington III     else
107*71de63a2SWilliam A. Kennington III     {
108*71de63a2SWilliam A. Kennington III         auto b = reinterpret_cast<std::byte*>(&n);
109*71de63a2SWilliam A. Kennington III         std::reverse(b, b + sizeof(n));
110*71de63a2SWilliam A. Kennington III     }
111*71de63a2SWilliam A. Kennington III     return n;
112*71de63a2SWilliam A. Kennington III }
113*71de63a2SWilliam A. Kennington III 
114*71de63a2SWilliam A. Kennington III } // namespace detail
115*71de63a2SWilliam A. Kennington III 
116*71de63a2SWilliam A. Kennington III template <typename T>
117*71de63a2SWilliam A. Kennington III constexpr T bswap(T n) noexcept
118*71de63a2SWilliam A. Kennington III {
119*71de63a2SWilliam A. Kennington III     return detail::bswapInt<T>(n);
120*71de63a2SWilliam A. Kennington III }
121*71de63a2SWilliam A. Kennington III 
122*71de63a2SWilliam A. Kennington III template <typename T>
123*71de63a2SWilliam A. Kennington III constexpr T hton(T n) noexcept
124*71de63a2SWilliam A. Kennington III {
125*71de63a2SWilliam A. Kennington III     if constexpr (std::endian::native == std::endian::big)
126*71de63a2SWilliam A. Kennington III     {
127*71de63a2SWilliam A. Kennington III         return n;
128*71de63a2SWilliam A. Kennington III     }
129*71de63a2SWilliam A. Kennington III     else if constexpr (std::endian::native == std::endian::little)
130*71de63a2SWilliam A. Kennington III     {
131*71de63a2SWilliam A. Kennington III         return bswap(n);
132*71de63a2SWilliam A. Kennington III     }
133*71de63a2SWilliam A. Kennington III     else
134*71de63a2SWilliam A. Kennington III     {
135*71de63a2SWilliam A. Kennington III         static_assert(std::is_same_v<T, void>);
136*71de63a2SWilliam A. Kennington III     }
137*71de63a2SWilliam A. Kennington III }
138*71de63a2SWilliam A. Kennington III 
139*71de63a2SWilliam A. Kennington III template <typename T>
140*71de63a2SWilliam A. Kennington III constexpr T ntoh(T n) noexcept
141*71de63a2SWilliam A. Kennington III {
142*71de63a2SWilliam A. Kennington III     return hton(n);
143*71de63a2SWilliam A. Kennington III }
144*71de63a2SWilliam A. Kennington III 
145*71de63a2SWilliam A. Kennington III namespace detail
146*71de63a2SWilliam A. Kennington III {
147*71de63a2SWilliam A. Kennington III 
148bb0eaccbSWilliam A. Kennington III template <typename T>
149bb0eaccbSWilliam A. Kennington III constexpr bool vcontains() noexcept
150bb0eaccbSWilliam A. Kennington III {
151bb0eaccbSWilliam A. Kennington III     return false;
152bb0eaccbSWilliam A. Kennington III }
153bb0eaccbSWilliam A. Kennington III 
154bb0eaccbSWilliam A. Kennington III template <typename T, typename V, typename... Vs>
155bb0eaccbSWilliam A. Kennington III constexpr bool vcontains() noexcept
156bb0eaccbSWilliam A. Kennington III {
157bb0eaccbSWilliam A. Kennington III     return vcontains<T, Vs...>() || std::is_same_v<T, V>;
158bb0eaccbSWilliam A. Kennington III }
159bb0eaccbSWilliam A. Kennington III 
160bb0eaccbSWilliam A. Kennington III template <typename T, typename... Types>
161bb0eaccbSWilliam A. Kennington III constexpr std::enable_if_t<vcontains<T, Types...>(), bool>
162bb0eaccbSWilliam A. Kennington III     veq(T t, std::variant<Types...> v) noexcept
163bb0eaccbSWilliam A. Kennington III {
164bb0eaccbSWilliam A. Kennington III     return std::visit(
165bb0eaccbSWilliam A. Kennington III         [t](auto v) {
166bb0eaccbSWilliam A. Kennington III             if constexpr (std::is_same_v<T, decltype(v)>)
167bb0eaccbSWilliam A. Kennington III             {
168bb0eaccbSWilliam A. Kennington III                 return v == t;
169bb0eaccbSWilliam A. Kennington III             }
170bb0eaccbSWilliam A. Kennington III             else
171bb0eaccbSWilliam A. Kennington III             {
172bb0eaccbSWilliam A. Kennington III                 return false;
173bb0eaccbSWilliam A. Kennington III             }
174bb0eaccbSWilliam A. Kennington III         },
175bb0eaccbSWilliam A. Kennington III         v);
176bb0eaccbSWilliam A. Kennington III }
177bb0eaccbSWilliam A. Kennington III 
178bb0eaccbSWilliam A. Kennington III template <typename T>
179bb0eaccbSWilliam A. Kennington III struct AddrBufMaker
180bb0eaccbSWilliam A. Kennington III {
181bb0eaccbSWilliam A. Kennington III };
182bb0eaccbSWilliam A. Kennington III 
183bb0eaccbSWilliam A. Kennington III template <>
184bb0eaccbSWilliam A. Kennington III struct AddrBufMaker<ether_addr>
185bb0eaccbSWilliam A. Kennington III {
186bb0eaccbSWilliam A. Kennington III   public:
187bb0eaccbSWilliam A. Kennington III     std::string_view operator()(ether_addr val) noexcept;
188bb0eaccbSWilliam A. Kennington III 
189bb0eaccbSWilliam A. Kennington III   private:
190bb0eaccbSWilliam A. Kennington III     std::array<char, /*octet*/ 2 * /*octets*/ 6 + /*seps*/ 5> buf;
191bb0eaccbSWilliam A. Kennington III };
192bb0eaccbSWilliam A. Kennington III 
193bb0eaccbSWilliam A. Kennington III template <>
194bb0eaccbSWilliam A. Kennington III struct AddrBufMaker<in_addr>
195bb0eaccbSWilliam A. Kennington III {
196bb0eaccbSWilliam A. Kennington III   public:
197bb0eaccbSWilliam A. Kennington III     std::string_view operator()(in_addr val) noexcept;
198bb0eaccbSWilliam A. Kennington III 
199bb0eaccbSWilliam A. Kennington III   private:
200bb0eaccbSWilliam A. Kennington III     std::array<char, /*octet*/ 3 * /*octets*/ 4 + /*seps*/ 3> buf;
201bb0eaccbSWilliam A. Kennington III };
202bb0eaccbSWilliam A. Kennington III 
203bb0eaccbSWilliam A. Kennington III template <>
204bb0eaccbSWilliam A. Kennington III struct AddrBufMaker<in6_addr>
205bb0eaccbSWilliam A. Kennington III {
206bb0eaccbSWilliam A. Kennington III   public:
207bb0eaccbSWilliam A. Kennington III     std::string_view operator()(in6_addr val) noexcept;
208bb0eaccbSWilliam A. Kennington III 
209bb0eaccbSWilliam A. Kennington III   private:
210bb0eaccbSWilliam A. Kennington III     std::array<char, /*hextet*/ 4 * /*hextets*/ 8 + /*seps*/ 7> buf;
211bb0eaccbSWilliam A. Kennington III };
212bb0eaccbSWilliam A. Kennington III 
213bb0eaccbSWilliam A. Kennington III template <typename BufMaker>
214bb0eaccbSWilliam A. Kennington III struct FormatFromBuf
215bb0eaccbSWilliam A. Kennington III {
216bb0eaccbSWilliam A. Kennington III   private:
217bb0eaccbSWilliam A. Kennington III     fmt::formatter<std::string_view> formatter;
218bb0eaccbSWilliam A. Kennington III 
219bb0eaccbSWilliam A. Kennington III   public:
220bb0eaccbSWilliam A. Kennington III     template <typename ParseContext>
221bb0eaccbSWilliam A. Kennington III     constexpr auto parse(ParseContext& ctx)
222bb0eaccbSWilliam A. Kennington III     {
223bb0eaccbSWilliam A. Kennington III         return ctx.begin();
224bb0eaccbSWilliam A. Kennington III     }
225bb0eaccbSWilliam A. Kennington III 
226bb0eaccbSWilliam A. Kennington III     template <typename FormatContext>
227bb0eaccbSWilliam A. Kennington III     auto format(auto v, FormatContext& ctx) const
228bb0eaccbSWilliam A. Kennington III     {
229bb0eaccbSWilliam A. Kennington III         return formatter.format(BufMaker{}(v), ctx);
230bb0eaccbSWilliam A. Kennington III     }
231bb0eaccbSWilliam A. Kennington III };
232bb0eaccbSWilliam A. Kennington III } // namespace detail
2331bbe3d1eSWilliam A. Kennington III } // namespace network
2341bbe3d1eSWilliam A. Kennington III } // namespace phosphor
2353e471c5fSWilliam A. Kennington III 
2363e471c5fSWilliam A. Kennington III template <typename... Ts>
2373e471c5fSWilliam A. Kennington III struct std::hash<std::tuple<Ts...>>
2383e471c5fSWilliam A. Kennington III {
2393e471c5fSWilliam A. Kennington III     constexpr auto operator()(const std::tuple<Ts...>& t) const noexcept
2403e471c5fSWilliam A. Kennington III     {
2413e471c5fSWilliam A. Kennington III         return std::apply(phosphor::network::hash_multi<Ts...>, t);
2423e471c5fSWilliam A. Kennington III     }
2433e471c5fSWilliam A. Kennington III };
244bb0eaccbSWilliam A. Kennington III 
245653114fcSWilliam A. Kennington III template <>
246653114fcSWilliam A. Kennington III struct std::hash<in_addr>
247653114fcSWilliam A. Kennington III {
248653114fcSWilliam A. Kennington III     std::size_t operator()(in_addr addr) const noexcept;
249653114fcSWilliam A. Kennington III };
250653114fcSWilliam A. Kennington III 
251653114fcSWilliam A. Kennington III template <>
252653114fcSWilliam A. Kennington III struct std::hash<in6_addr>
253653114fcSWilliam A. Kennington III {
254653114fcSWilliam A. Kennington III     std::size_t operator()(in6_addr addr) const noexcept;
255653114fcSWilliam A. Kennington III };
256653114fcSWilliam A. Kennington III 
257bb0eaccbSWilliam A. Kennington III namespace fmt
258bb0eaccbSWilliam A. Kennington III {
259bb0eaccbSWilliam A. Kennington III template <>
260bb0eaccbSWilliam A. Kennington III struct formatter<ether_addr>
261bb0eaccbSWilliam A. Kennington III     : phosphor::network::detail::FormatFromBuf<
262bb0eaccbSWilliam A. Kennington III           phosphor::network::detail::AddrBufMaker<ether_addr>>
263bb0eaccbSWilliam A. Kennington III {
264bb0eaccbSWilliam A. Kennington III };
265bb0eaccbSWilliam A. Kennington III template <>
266bb0eaccbSWilliam A. Kennington III struct formatter<in_addr>
267bb0eaccbSWilliam A. Kennington III     : phosphor::network::detail::FormatFromBuf<
268bb0eaccbSWilliam A. Kennington III           phosphor::network::detail::AddrBufMaker<in_addr>>
269bb0eaccbSWilliam A. Kennington III {
270bb0eaccbSWilliam A. Kennington III };
271bb0eaccbSWilliam A. Kennington III template <>
272bb0eaccbSWilliam A. Kennington III struct formatter<in6_addr>
273bb0eaccbSWilliam A. Kennington III     : phosphor::network::detail::FormatFromBuf<
274bb0eaccbSWilliam A. Kennington III           phosphor::network::detail::AddrBufMaker<in6_addr>>
275bb0eaccbSWilliam A. Kennington III {
276bb0eaccbSWilliam A. Kennington III };
277bb0eaccbSWilliam A. Kennington III template <>
278bb0eaccbSWilliam A. Kennington III struct formatter<phosphor::network::InAddrAny>
279bb0eaccbSWilliam A. Kennington III {
280bb0eaccbSWilliam A. Kennington III   private:
281bb0eaccbSWilliam A. Kennington III     fmt::formatter<std::string_view> formatter;
282bb0eaccbSWilliam A. Kennington III 
283bb0eaccbSWilliam A. Kennington III   public:
284bb0eaccbSWilliam A. Kennington III     template <typename ParseContext>
285bb0eaccbSWilliam A. Kennington III     constexpr auto parse(ParseContext& ctx)
286bb0eaccbSWilliam A. Kennington III     {
287bb0eaccbSWilliam A. Kennington III         return ctx.begin();
288bb0eaccbSWilliam A. Kennington III     }
289bb0eaccbSWilliam A. Kennington III 
290bb0eaccbSWilliam A. Kennington III     template <typename FormatContext>
291bb0eaccbSWilliam A. Kennington III     auto format(auto v, FormatContext& ctx) const
292bb0eaccbSWilliam A. Kennington III     {
293bb0eaccbSWilliam A. Kennington III         return std::visit(
294bb0eaccbSWilliam A. Kennington III             [&](auto v) {
295bb0eaccbSWilliam A. Kennington III                 auto abm =
296bb0eaccbSWilliam A. Kennington III                     phosphor::network::detail::AddrBufMaker<decltype(v)>{};
297bb0eaccbSWilliam A. Kennington III                 return formatter.format(abm(v), ctx);
298bb0eaccbSWilliam A. Kennington III             },
299bb0eaccbSWilliam A. Kennington III             v);
300bb0eaccbSWilliam A. Kennington III     }
301bb0eaccbSWilliam A. Kennington III };
302bb0eaccbSWilliam A. Kennington III } // namespace fmt
303bb0eaccbSWilliam A. Kennington III 
304bb0eaccbSWilliam A. Kennington III namespace std
305bb0eaccbSWilliam A. Kennington III {
306bb0eaccbSWilliam A. Kennington III string to_string(ether_addr value);
307bb0eaccbSWilliam A. Kennington III string to_string(in_addr value);
308bb0eaccbSWilliam A. Kennington III string to_string(in6_addr value);
309bb0eaccbSWilliam A. Kennington III string to_string(phosphor::network::InAddrAny value);
310bb0eaccbSWilliam A. Kennington III } // namespace std
311bb0eaccbSWilliam A. Kennington III 
312bb0eaccbSWilliam A. Kennington III constexpr bool operator==(ether_addr lhs, ether_addr rhs) noexcept
313bb0eaccbSWilliam A. Kennington III {
314bb0eaccbSWilliam A. Kennington III     return std::equal(lhs.ether_addr_octet, lhs.ether_addr_octet + 6,
315bb0eaccbSWilliam A. Kennington III                       rhs.ether_addr_octet);
316bb0eaccbSWilliam A. Kennington III }
317bb0eaccbSWilliam A. Kennington III 
318bb0eaccbSWilliam A. Kennington III constexpr bool operator==(in_addr lhs, in_addr rhs) noexcept
319bb0eaccbSWilliam A. Kennington III {
320bb0eaccbSWilliam A. Kennington III     return lhs.s_addr == rhs.s_addr;
321bb0eaccbSWilliam A. Kennington III }
322bb0eaccbSWilliam A. Kennington III 
323bb0eaccbSWilliam A. Kennington III constexpr bool operator==(in6_addr lhs, in6_addr rhs) noexcept
324bb0eaccbSWilliam A. Kennington III {
325bb0eaccbSWilliam A. Kennington III     return std::equal(lhs.s6_addr32, lhs.s6_addr32 + 4, rhs.s6_addr32);
326bb0eaccbSWilliam A. Kennington III }
327bb0eaccbSWilliam A. Kennington III 
328bb0eaccbSWilliam A. Kennington III template <typename T>
329bb0eaccbSWilliam A. Kennington III constexpr std::enable_if_t<!std::is_same_v<phosphor::network::InAddrAny, T>,
330bb0eaccbSWilliam A. Kennington III                            bool>
331bb0eaccbSWilliam A. Kennington III     operator==(phosphor::network::InAddrAny lhs, T rhs) noexcept
332bb0eaccbSWilliam A. Kennington III {
333bb0eaccbSWilliam A. Kennington III     return phosphor::network::detail::veq(rhs, lhs);
334bb0eaccbSWilliam A. Kennington III }
335bb0eaccbSWilliam A. Kennington III 
33686eb8b70SWilliam A. Kennington III auto& operator<<(auto& os, ether_addr v)
337bb0eaccbSWilliam A. Kennington III {
338bb0eaccbSWilliam A. Kennington III     return os << phosphor::network::detail::AddrBufMaker<ether_addr>{}(v);
339bb0eaccbSWilliam A. Kennington III }
340bb0eaccbSWilliam A. Kennington III 
34186eb8b70SWilliam A. Kennington III auto& operator<<(auto& os, in_addr v)
342bb0eaccbSWilliam A. Kennington III {
343bb0eaccbSWilliam A. Kennington III     return os << phosphor::network::detail::AddrBufMaker<in_addr>{}(v);
344bb0eaccbSWilliam A. Kennington III }
345bb0eaccbSWilliam A. Kennington III 
34686eb8b70SWilliam A. Kennington III auto& operator<<(auto& os, in6_addr v)
347bb0eaccbSWilliam A. Kennington III {
348bb0eaccbSWilliam A. Kennington III     return os << phosphor::network::detail::AddrBufMaker<in6_addr>{}(v);
349bb0eaccbSWilliam A. Kennington III }
350bb0eaccbSWilliam A. Kennington III 
35186eb8b70SWilliam A. Kennington III auto& operator<<(auto& os, phosphor::network::InAddrAny v)
352bb0eaccbSWilliam A. Kennington III {
353bb0eaccbSWilliam A. Kennington III     return os << std::visit(
354bb0eaccbSWilliam A. Kennington III                [](auto v) {
355bb0eaccbSWilliam A. Kennington III                    return phosphor::network::detail::AddrBufMaker<
356bb0eaccbSWilliam A. Kennington III                        decltype(v)>{}(v);
357bb0eaccbSWilliam A. Kennington III                },
358bb0eaccbSWilliam A. Kennington III                v);
359bb0eaccbSWilliam A. Kennington III }
360