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