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>; 35b9d7cbacSWilliam A. Kennington III class IfAddr 36b9d7cbacSWilliam A. Kennington III { 37b9d7cbacSWilliam A. Kennington III private: 38b9d7cbacSWilliam A. Kennington III InAddrAny addr; 39b9d7cbacSWilliam A. Kennington III uint8_t pfx; 40b9d7cbacSWilliam A. Kennington III 41b9d7cbacSWilliam A. Kennington III static void invalidPfx(uint8_t pfx); 42b9d7cbacSWilliam A. Kennington III 43b9d7cbacSWilliam A. Kennington III public: 44b9d7cbacSWilliam A. Kennington III constexpr IfAddr() : addr({}), pfx(0) 45b9d7cbacSWilliam A. Kennington III { 46b9d7cbacSWilliam A. Kennington III } 47b9d7cbacSWilliam A. Kennington III 48b9d7cbacSWilliam A. Kennington III constexpr IfAddr(InAddrAny addr, uint8_t pfx) : addr(addr), pfx(pfx) 49b9d7cbacSWilliam A. Kennington III { 50b9d7cbacSWilliam A. Kennington III std::visit( 51b9d7cbacSWilliam A. Kennington III [pfx](auto v) { 52b9d7cbacSWilliam A. Kennington III if (sizeof(v) * 8 < pfx) 53b9d7cbacSWilliam A. Kennington III { 54b9d7cbacSWilliam A. Kennington III invalidPfx(pfx); 55b9d7cbacSWilliam A. Kennington III } 56b9d7cbacSWilliam A. Kennington III }, 57b9d7cbacSWilliam A. Kennington III addr); 58b9d7cbacSWilliam A. Kennington III } 59b9d7cbacSWilliam A. Kennington III 60b9d7cbacSWilliam A. Kennington III constexpr auto getAddr() const 61b9d7cbacSWilliam A. Kennington III { 62b9d7cbacSWilliam A. Kennington III return addr; 63b9d7cbacSWilliam A. Kennington III } 64b9d7cbacSWilliam A. Kennington III 65b9d7cbacSWilliam A. Kennington III constexpr auto getPfx() const 66b9d7cbacSWilliam A. Kennington III { 67b9d7cbacSWilliam A. Kennington III return pfx; 68b9d7cbacSWilliam A. Kennington III } 69b9d7cbacSWilliam A. Kennington III 70b9d7cbacSWilliam A. Kennington III constexpr bool operator==(phosphor::network::IfAddr rhs) const noexcept 71b9d7cbacSWilliam A. Kennington III { 72b9d7cbacSWilliam A. Kennington III return addr == rhs.addr && pfx == rhs.pfx; 73b9d7cbacSWilliam A. Kennington III } 74b9d7cbacSWilliam 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 { 187*238ef992SWilliam A. Kennington III inline constexpr auto charLookup = []() { 188*238ef992SWilliam A. Kennington III std::array<int8_t, 256> ret; 189*238ef992SWilliam A. Kennington III std::fill(ret.begin(), ret.end(), -1); 190*238ef992SWilliam A. Kennington III for (int8_t i = 0; i < 10; ++i) 191*238ef992SWilliam A. Kennington III { 192*238ef992SWilliam A. Kennington III ret[i + '0'] = i; 193*238ef992SWilliam A. Kennington III } 194*238ef992SWilliam A. Kennington III for (int8_t i = 0; i < 26; ++i) 195*238ef992SWilliam A. Kennington III { 196*238ef992SWilliam A. Kennington III ret[i + 'A'] = i + 10; 197*238ef992SWilliam A. Kennington III ret[i + 'a'] = i + 10; 198*238ef992SWilliam A. Kennington III } 199*238ef992SWilliam A. Kennington III return ret; 200*238ef992SWilliam A. Kennington III }(); 201*238ef992SWilliam A. Kennington III } 202*238ef992SWilliam A. Kennington III 203*238ef992SWilliam A. Kennington III template <typename T, uint8_t base> 204*238ef992SWilliam A. Kennington III struct DecodeInt 205*238ef992SWilliam A. Kennington III { 206*238ef992SWilliam A. Kennington III static_assert(base > 1 && base <= 36); 207*238ef992SWilliam A. Kennington III static_assert(std::is_unsigned_v<T>); 208*238ef992SWilliam A. Kennington III 209*238ef992SWilliam A. Kennington III constexpr T operator()(std::string_view str) const 210*238ef992SWilliam A. Kennington III { 211*238ef992SWilliam A. Kennington III if (str.empty()) 212*238ef992SWilliam A. Kennington III { 213*238ef992SWilliam A. Kennington III throw std::invalid_argument("Empty Str"); 214*238ef992SWilliam A. Kennington III } 215*238ef992SWilliam A. Kennington III constexpr auto max = std::numeric_limits<T>::max(); 216*238ef992SWilliam A. Kennington III auto ret = 217*238ef992SWilliam A. Kennington III std::accumulate(str.begin(), str.end(), T{}, [&](T r, char c) { 218*238ef992SWilliam A. Kennington III auto v = detail::charLookup[c]; 219*238ef992SWilliam A. Kennington III if (v < 0 || v >= base) 220*238ef992SWilliam A. Kennington III { 221*238ef992SWilliam A. Kennington III throw std::invalid_argument("Invalid numeral"); 222*238ef992SWilliam A. Kennington III } 223*238ef992SWilliam A. Kennington III if constexpr (std::popcount(base) == 1) 224*238ef992SWilliam A. Kennington III { 225*238ef992SWilliam A. Kennington III constexpr auto shift = std::countr_zero(base); 226*238ef992SWilliam A. Kennington III constexpr auto maxshift = max >> shift; 227*238ef992SWilliam A. Kennington III if (r > maxshift) 228*238ef992SWilliam A. Kennington III { 229*238ef992SWilliam A. Kennington III throw std::overflow_error("Integer Decode"); 230*238ef992SWilliam A. Kennington III } 231*238ef992SWilliam A. Kennington III return (r << shift) | v; 232*238ef992SWilliam A. Kennington III } 233*238ef992SWilliam A. Kennington III else 234*238ef992SWilliam A. Kennington III { 235*238ef992SWilliam A. Kennington III constexpr auto maxbase = max / base; 236*238ef992SWilliam A. Kennington III if (r > maxbase) 237*238ef992SWilliam A. Kennington III { 238*238ef992SWilliam A. Kennington III throw std::overflow_error("Integer Decode"); 239*238ef992SWilliam A. Kennington III } 240*238ef992SWilliam A. Kennington III r *= base; 241*238ef992SWilliam A. Kennington III if (max - v < r) 242*238ef992SWilliam A. Kennington III { 243*238ef992SWilliam A. Kennington III throw std::overflow_error("Integer Decode"); 244*238ef992SWilliam A. Kennington III } 245*238ef992SWilliam A. Kennington III return r + v; 246*238ef992SWilliam A. Kennington III } 247*238ef992SWilliam A. Kennington III }); 248*238ef992SWilliam A. Kennington III return ret; 249*238ef992SWilliam A. Kennington III } 250*238ef992SWilliam A. Kennington III }; 251*238ef992SWilliam A. Kennington III 252*238ef992SWilliam A. Kennington III namespace detail 253*238ef992SWilliam A. Kennington III { 25471de63a2SWilliam A. Kennington III 255bb0eaccbSWilliam A. Kennington III template <typename T> 256bb0eaccbSWilliam A. Kennington III constexpr bool vcontains() noexcept 257bb0eaccbSWilliam A. Kennington III { 258bb0eaccbSWilliam A. Kennington III return false; 259bb0eaccbSWilliam A. Kennington III } 260bb0eaccbSWilliam A. Kennington III 261bb0eaccbSWilliam A. Kennington III template <typename T, typename V, typename... Vs> 262bb0eaccbSWilliam A. Kennington III constexpr bool vcontains() noexcept 263bb0eaccbSWilliam A. Kennington III { 264bb0eaccbSWilliam A. Kennington III return vcontains<T, Vs...>() || std::is_same_v<T, V>; 265bb0eaccbSWilliam A. Kennington III } 266bb0eaccbSWilliam A. Kennington III 267bb0eaccbSWilliam A. Kennington III template <typename T, typename... Types> 268bb0eaccbSWilliam A. Kennington III constexpr std::enable_if_t<vcontains<T, Types...>(), bool> 269bb0eaccbSWilliam A. Kennington III veq(T t, std::variant<Types...> v) noexcept 270bb0eaccbSWilliam A. Kennington III { 271bb0eaccbSWilliam A. Kennington III return std::visit( 272bb0eaccbSWilliam A. Kennington III [t](auto v) { 273bb0eaccbSWilliam A. Kennington III if constexpr (std::is_same_v<T, decltype(v)>) 274bb0eaccbSWilliam A. Kennington III { 275bb0eaccbSWilliam A. Kennington III return v == t; 276bb0eaccbSWilliam A. Kennington III } 277bb0eaccbSWilliam A. Kennington III else 278bb0eaccbSWilliam A. Kennington III { 279bb0eaccbSWilliam A. Kennington III return false; 280bb0eaccbSWilliam A. Kennington III } 281bb0eaccbSWilliam A. Kennington III }, 282bb0eaccbSWilliam A. Kennington III v); 283bb0eaccbSWilliam A. Kennington III } 284bb0eaccbSWilliam A. Kennington III 285bb0eaccbSWilliam A. Kennington III template <typename T> 286bb0eaccbSWilliam A. Kennington III struct AddrBufMaker 287bb0eaccbSWilliam A. Kennington III { 288bb0eaccbSWilliam A. Kennington III }; 289bb0eaccbSWilliam A. Kennington III 290bb0eaccbSWilliam A. Kennington III template <> 291bb0eaccbSWilliam A. Kennington III struct AddrBufMaker<ether_addr> 292bb0eaccbSWilliam A. Kennington III { 293bb0eaccbSWilliam A. Kennington III public: 294bb0eaccbSWilliam A. Kennington III std::string_view operator()(ether_addr val) noexcept; 295bb0eaccbSWilliam A. Kennington III 296bb0eaccbSWilliam A. Kennington III private: 297bb0eaccbSWilliam A. Kennington III std::array<char, /*octet*/ 2 * /*octets*/ 6 + /*seps*/ 5> buf; 298bb0eaccbSWilliam A. Kennington III }; 299bb0eaccbSWilliam A. Kennington III 300bb0eaccbSWilliam A. Kennington III template <> 301bb0eaccbSWilliam A. Kennington III struct AddrBufMaker<in_addr> 302bb0eaccbSWilliam A. Kennington III { 303bb0eaccbSWilliam A. Kennington III public: 304bb0eaccbSWilliam A. Kennington III std::string_view operator()(in_addr val) noexcept; 305bb0eaccbSWilliam A. Kennington III 306bb0eaccbSWilliam A. Kennington III private: 307bb0eaccbSWilliam A. Kennington III std::array<char, /*octet*/ 3 * /*octets*/ 4 + /*seps*/ 3> buf; 308bb0eaccbSWilliam A. Kennington III }; 309bb0eaccbSWilliam A. Kennington III 310bb0eaccbSWilliam A. Kennington III template <> 311bb0eaccbSWilliam A. Kennington III struct AddrBufMaker<in6_addr> 312bb0eaccbSWilliam A. Kennington III { 313bb0eaccbSWilliam A. Kennington III public: 314bb0eaccbSWilliam A. Kennington III std::string_view operator()(in6_addr val) noexcept; 315bb0eaccbSWilliam A. Kennington III 316bb0eaccbSWilliam A. Kennington III private: 317bb0eaccbSWilliam A. Kennington III std::array<char, /*hextet*/ 4 * /*hextets*/ 8 + /*seps*/ 7> buf; 318bb0eaccbSWilliam A. Kennington III }; 319bb0eaccbSWilliam A. Kennington III 320bb0eaccbSWilliam A. Kennington III template <typename BufMaker> 321bb0eaccbSWilliam A. Kennington III struct FormatFromBuf 322bb0eaccbSWilliam A. Kennington III { 323bb0eaccbSWilliam A. Kennington III private: 324bb0eaccbSWilliam A. Kennington III fmt::formatter<std::string_view> formatter; 325bb0eaccbSWilliam A. Kennington III 326bb0eaccbSWilliam A. Kennington III public: 327bb0eaccbSWilliam A. Kennington III template <typename ParseContext> 328bb0eaccbSWilliam A. Kennington III constexpr auto parse(ParseContext& ctx) 329bb0eaccbSWilliam A. Kennington III { 330bb0eaccbSWilliam A. Kennington III return ctx.begin(); 331bb0eaccbSWilliam A. Kennington III } 332bb0eaccbSWilliam A. Kennington III 333bb0eaccbSWilliam A. Kennington III template <typename FormatContext> 334bb0eaccbSWilliam A. Kennington III auto format(auto v, FormatContext& ctx) const 335bb0eaccbSWilliam A. Kennington III { 336bb0eaccbSWilliam A. Kennington III return formatter.format(BufMaker{}(v), ctx); 337bb0eaccbSWilliam A. Kennington III } 338bb0eaccbSWilliam A. Kennington III }; 339bb0eaccbSWilliam A. Kennington III } // namespace detail 3401bbe3d1eSWilliam A. Kennington III } // namespace network 3411bbe3d1eSWilliam A. Kennington III } // namespace phosphor 3423e471c5fSWilliam A. Kennington III 3433e471c5fSWilliam A. Kennington III template <typename... Ts> 3443e471c5fSWilliam A. Kennington III struct std::hash<std::tuple<Ts...>> 3453e471c5fSWilliam A. Kennington III { 3463e471c5fSWilliam A. Kennington III constexpr auto operator()(const std::tuple<Ts...>& t) const noexcept 3473e471c5fSWilliam A. Kennington III { 3483e471c5fSWilliam A. Kennington III return std::apply(phosphor::network::hash_multi<Ts...>, t); 3493e471c5fSWilliam A. Kennington III } 3503e471c5fSWilliam A. Kennington III }; 351bb0eaccbSWilliam A. Kennington III 352653114fcSWilliam A. Kennington III template <> 353653114fcSWilliam A. Kennington III struct std::hash<in_addr> 354653114fcSWilliam A. Kennington III { 355653114fcSWilliam A. Kennington III std::size_t operator()(in_addr addr) const noexcept; 356653114fcSWilliam A. Kennington III }; 357653114fcSWilliam A. Kennington III 358653114fcSWilliam A. Kennington III template <> 359653114fcSWilliam A. Kennington III struct std::hash<in6_addr> 360653114fcSWilliam A. Kennington III { 361653114fcSWilliam A. Kennington III std::size_t operator()(in6_addr addr) const noexcept; 362653114fcSWilliam A. Kennington III }; 363653114fcSWilliam A. Kennington III 364b9d7cbacSWilliam A. Kennington III template <> 365b9d7cbacSWilliam A. Kennington III struct std::hash<phosphor::network::IfAddr> 366b9d7cbacSWilliam A. Kennington III { 367b9d7cbacSWilliam A. Kennington III std::size_t operator()(phosphor::network::IfAddr addr) const noexcept; 368b9d7cbacSWilliam A. Kennington III }; 369b9d7cbacSWilliam A. Kennington III 370bb0eaccbSWilliam A. Kennington III namespace fmt 371bb0eaccbSWilliam A. Kennington III { 372bb0eaccbSWilliam A. Kennington III template <> 373bb0eaccbSWilliam A. Kennington III struct formatter<ether_addr> 374bb0eaccbSWilliam A. Kennington III : phosphor::network::detail::FormatFromBuf< 375bb0eaccbSWilliam A. Kennington III phosphor::network::detail::AddrBufMaker<ether_addr>> 376bb0eaccbSWilliam A. Kennington III { 377bb0eaccbSWilliam A. Kennington III }; 378bb0eaccbSWilliam A. Kennington III template <> 379bb0eaccbSWilliam A. Kennington III struct formatter<in_addr> 380bb0eaccbSWilliam A. Kennington III : phosphor::network::detail::FormatFromBuf< 381bb0eaccbSWilliam A. Kennington III phosphor::network::detail::AddrBufMaker<in_addr>> 382bb0eaccbSWilliam A. Kennington III { 383bb0eaccbSWilliam A. Kennington III }; 384bb0eaccbSWilliam A. Kennington III template <> 385bb0eaccbSWilliam A. Kennington III struct formatter<in6_addr> 386bb0eaccbSWilliam A. Kennington III : phosphor::network::detail::FormatFromBuf< 387bb0eaccbSWilliam A. Kennington III phosphor::network::detail::AddrBufMaker<in6_addr>> 388bb0eaccbSWilliam A. Kennington III { 389bb0eaccbSWilliam A. Kennington III }; 390bb0eaccbSWilliam A. Kennington III template <> 391bb0eaccbSWilliam A. Kennington III struct formatter<phosphor::network::InAddrAny> 392bb0eaccbSWilliam A. Kennington III { 393bb0eaccbSWilliam A. Kennington III private: 394bb0eaccbSWilliam A. Kennington III fmt::formatter<std::string_view> formatter; 395bb0eaccbSWilliam A. Kennington III 396bb0eaccbSWilliam A. Kennington III public: 397bb0eaccbSWilliam A. Kennington III template <typename ParseContext> 398bb0eaccbSWilliam A. Kennington III constexpr auto parse(ParseContext& ctx) 399bb0eaccbSWilliam A. Kennington III { 400bb0eaccbSWilliam A. Kennington III return ctx.begin(); 401bb0eaccbSWilliam A. Kennington III } 402bb0eaccbSWilliam A. Kennington III 403bb0eaccbSWilliam A. Kennington III template <typename FormatContext> 404bb0eaccbSWilliam A. Kennington III auto format(auto v, FormatContext& ctx) const 405bb0eaccbSWilliam A. Kennington III { 406bb0eaccbSWilliam A. Kennington III return std::visit( 407bb0eaccbSWilliam A. Kennington III [&](auto v) { 408bb0eaccbSWilliam A. Kennington III auto abm = 409bb0eaccbSWilliam A. Kennington III phosphor::network::detail::AddrBufMaker<decltype(v)>{}; 410bb0eaccbSWilliam A. Kennington III return formatter.format(abm(v), ctx); 411bb0eaccbSWilliam A. Kennington III }, 412bb0eaccbSWilliam A. Kennington III v); 413bb0eaccbSWilliam A. Kennington III } 414bb0eaccbSWilliam A. Kennington III }; 415b9d7cbacSWilliam A. Kennington III template <> 416b9d7cbacSWilliam A. Kennington III struct formatter<phosphor::network::IfAddr> 417b9d7cbacSWilliam A. Kennington III { 418b9d7cbacSWilliam A. Kennington III private: 419b9d7cbacSWilliam A. Kennington III fmt::formatter<phosphor::network::InAddrAny> addrF; 420b9d7cbacSWilliam A. Kennington III fmt::formatter<char> strF; 421b9d7cbacSWilliam A. Kennington III fmt::formatter<uint8_t> numF; 422b9d7cbacSWilliam A. Kennington III 423b9d7cbacSWilliam A. Kennington III public: 424b9d7cbacSWilliam A. Kennington III template <typename ParseContext> 425b9d7cbacSWilliam A. Kennington III constexpr auto parse(ParseContext& ctx) 426b9d7cbacSWilliam A. Kennington III { 427b9d7cbacSWilliam A. Kennington III return ctx.begin(); 428b9d7cbacSWilliam A. Kennington III } 429b9d7cbacSWilliam A. Kennington III 430b9d7cbacSWilliam A. Kennington III template <typename FormatContext> 431b9d7cbacSWilliam A. Kennington III auto format(auto v, FormatContext& ctx) const 432b9d7cbacSWilliam A. Kennington III { 433b9d7cbacSWilliam A. Kennington III addrF.format(v.getAddr(), ctx); 434b9d7cbacSWilliam A. Kennington III strF.format('/', ctx); 435b9d7cbacSWilliam A. Kennington III return numF.format(v.getPfx(), ctx); 436b9d7cbacSWilliam A. Kennington III } 437b9d7cbacSWilliam A. Kennington III }; 438bb0eaccbSWilliam A. Kennington III } // namespace fmt 439bb0eaccbSWilliam A. Kennington III 440bb0eaccbSWilliam A. Kennington III namespace std 441bb0eaccbSWilliam A. Kennington III { 442bb0eaccbSWilliam A. Kennington III string to_string(ether_addr value); 443bb0eaccbSWilliam A. Kennington III string to_string(in_addr value); 444bb0eaccbSWilliam A. Kennington III string to_string(in6_addr value); 445bb0eaccbSWilliam A. Kennington III string to_string(phosphor::network::InAddrAny value); 446b9d7cbacSWilliam A. Kennington III string to_string(phosphor::network::IfAddr value); 447bb0eaccbSWilliam A. Kennington III } // namespace std 448bb0eaccbSWilliam A. Kennington III 449bb0eaccbSWilliam A. Kennington III constexpr bool operator==(ether_addr lhs, ether_addr rhs) noexcept 450bb0eaccbSWilliam A. Kennington III { 451bb0eaccbSWilliam A. Kennington III return std::equal(lhs.ether_addr_octet, lhs.ether_addr_octet + 6, 452bb0eaccbSWilliam A. Kennington III rhs.ether_addr_octet); 453bb0eaccbSWilliam A. Kennington III } 454bb0eaccbSWilliam A. Kennington III 455bb0eaccbSWilliam A. Kennington III constexpr bool operator==(in_addr lhs, in_addr rhs) noexcept 456bb0eaccbSWilliam A. Kennington III { 457bb0eaccbSWilliam A. Kennington III return lhs.s_addr == rhs.s_addr; 458bb0eaccbSWilliam A. Kennington III } 459bb0eaccbSWilliam A. Kennington III 460bb0eaccbSWilliam A. Kennington III constexpr bool operator==(in6_addr lhs, in6_addr rhs) noexcept 461bb0eaccbSWilliam A. Kennington III { 462bb0eaccbSWilliam A. Kennington III return std::equal(lhs.s6_addr32, lhs.s6_addr32 + 4, rhs.s6_addr32); 463bb0eaccbSWilliam A. Kennington III } 464bb0eaccbSWilliam A. Kennington III 465bb0eaccbSWilliam A. Kennington III template <typename T> 466bb0eaccbSWilliam A. Kennington III constexpr std::enable_if_t<!std::is_same_v<phosphor::network::InAddrAny, T>, 467bb0eaccbSWilliam A. Kennington III bool> 468bb0eaccbSWilliam A. Kennington III operator==(phosphor::network::InAddrAny lhs, T rhs) noexcept 469bb0eaccbSWilliam A. Kennington III { 470bb0eaccbSWilliam A. Kennington III return phosphor::network::detail::veq(rhs, lhs); 471bb0eaccbSWilliam A. Kennington III } 472bb0eaccbSWilliam A. Kennington III 47386eb8b70SWilliam A. Kennington III auto& operator<<(auto& os, ether_addr v) 474bb0eaccbSWilliam A. Kennington III { 475bb0eaccbSWilliam A. Kennington III return os << phosphor::network::detail::AddrBufMaker<ether_addr>{}(v); 476bb0eaccbSWilliam A. Kennington III } 477bb0eaccbSWilliam A. Kennington III 47886eb8b70SWilliam A. Kennington III auto& operator<<(auto& os, in_addr v) 479bb0eaccbSWilliam A. Kennington III { 480bb0eaccbSWilliam A. Kennington III return os << phosphor::network::detail::AddrBufMaker<in_addr>{}(v); 481bb0eaccbSWilliam A. Kennington III } 482bb0eaccbSWilliam A. Kennington III 48386eb8b70SWilliam A. Kennington III auto& operator<<(auto& os, in6_addr v) 484bb0eaccbSWilliam A. Kennington III { 485bb0eaccbSWilliam A. Kennington III return os << phosphor::network::detail::AddrBufMaker<in6_addr>{}(v); 486bb0eaccbSWilliam A. Kennington III } 487bb0eaccbSWilliam A. Kennington III 48886eb8b70SWilliam A. Kennington III auto& operator<<(auto& os, phosphor::network::InAddrAny v) 489bb0eaccbSWilliam A. Kennington III { 490bb0eaccbSWilliam A. Kennington III return os << std::visit( 491bb0eaccbSWilliam A. Kennington III [](auto v) { 492bb0eaccbSWilliam A. Kennington III return phosphor::network::detail::AddrBufMaker< 493bb0eaccbSWilliam A. Kennington III decltype(v)>{}(v); 494bb0eaccbSWilliam A. Kennington III }, 495bb0eaccbSWilliam A. Kennington III v); 496bb0eaccbSWilliam A. Kennington III } 497b9d7cbacSWilliam A. Kennington III 498b9d7cbacSWilliam A. Kennington III auto& operator<<(auto& os, phosphor::network::IfAddr v) 499b9d7cbacSWilliam A. Kennington III { 500b9d7cbacSWilliam A. Kennington III return os << v.getAddr() << "/" << std::dec << int{v.getPfx()}; 501b9d7cbacSWilliam A. Kennington III } 502