xref: /openbmc/phosphor-networkd/src/types.hpp (revision becda1aa)
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>
91bbe3d1eSWilliam A. Kennington III #include <sdeventplus/clock.hpp>
101bbe3d1eSWilliam A. Kennington III #include <sdeventplus/utility/timer.hpp>
111bbe3d1eSWilliam A. Kennington III #include <string>
12bb0eaccbSWilliam A. Kennington III #include <string_view>
13bb0eaccbSWilliam A. Kennington III #include <type_traits>
14dd9ef815SWilliam A. Kennington III #include <unordered_map>
15f7dce2e8SWilly Tu #include <unordered_set>
161bbe3d1eSWilliam A. Kennington III #include <variant>
171bbe3d1eSWilliam A. Kennington III 
181bbe3d1eSWilliam A. Kennington III namespace phosphor
191bbe3d1eSWilliam A. Kennington III {
201bbe3d1eSWilliam A. Kennington III namespace network
211bbe3d1eSWilliam A. Kennington III {
221bbe3d1eSWilliam A. Kennington III 
231bbe3d1eSWilliam A. Kennington III using namespace std::chrono_literals;
241bbe3d1eSWilliam A. Kennington III 
25c7cf25f7SWilliam A. Kennington III // wait for three seconds before reloading systemd-networkd
26c7cf25f7SWilliam A. Kennington III constexpr auto reloadTimeout = 3s;
271bbe3d1eSWilliam A. Kennington III 
28d41db383SWilliam A. Kennington III // refresh the objets after four seconds as network
29d41db383SWilliam A. Kennington III // configuration takes 3-4 sec to reconfigure at most.
30d41db383SWilliam A. Kennington III constexpr auto refreshTimeout = 4s;
311bbe3d1eSWilliam A. Kennington III 
321bbe3d1eSWilliam A. Kennington III // Byte representations for common address types in network byte order
33bb0eaccbSWilliam A. Kennington III using InAddrAny = std::variant<in_addr, in6_addr>;
341bbe3d1eSWilliam A. Kennington III 
351bbe3d1eSWilliam A. Kennington III using Timer = sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>;
361bbe3d1eSWilliam A. Kennington III 
37dd9ef815SWilliam A. Kennington III struct string_hash : public std::hash<std::string_view>
38dd9ef815SWilliam A. Kennington III {
39dd9ef815SWilliam A. Kennington III     using is_transparent = void;
40dd9ef815SWilliam A. Kennington III };
41dd9ef815SWilliam A. Kennington III template <typename V>
42dd9ef815SWilliam A. Kennington III using string_umap =
43dd9ef815SWilliam A. Kennington III     std::unordered_map<std::string, V, string_hash, std::equal_to<>>;
4496444795SWilliam A. Kennington III using string_uset =
4596444795SWilliam A. Kennington III     std::unordered_set<std::string, string_hash, std::equal_to<>>;
46dd9ef815SWilliam A. Kennington III 
473e471c5fSWilliam A. Kennington III constexpr std::size_t hash_multi() noexcept
48991a8e81SWilliam A. Kennington III {
49991a8e81SWilliam A. Kennington III     return 0;
50991a8e81SWilliam A. Kennington III }
51991a8e81SWilliam A. Kennington III 
52991a8e81SWilliam A. Kennington III template <typename T, typename... Args>
53*becda1aaSWilliam A. Kennington III constexpr std::size_t hash_multi(const T& v, const Args&... args) noexcept
54991a8e81SWilliam A. Kennington III {
55991a8e81SWilliam A. Kennington III     const std::size_t seed = hash_multi(args...);
56991a8e81SWilliam A. Kennington III     return seed ^ (std::hash<T>{}(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
57991a8e81SWilliam A. Kennington III }
58991a8e81SWilliam A. Kennington III 
59bb0eaccbSWilliam A. Kennington III namespace detail
60bb0eaccbSWilliam A. Kennington III {
61bb0eaccbSWilliam A. Kennington III 
62bb0eaccbSWilliam A. Kennington III template <typename T>
63bb0eaccbSWilliam A. Kennington III constexpr bool vcontains() noexcept
64bb0eaccbSWilliam A. Kennington III {
65bb0eaccbSWilliam A. Kennington III     return false;
66bb0eaccbSWilliam A. Kennington III }
67bb0eaccbSWilliam A. Kennington III 
68bb0eaccbSWilliam A. Kennington III template <typename T, typename V, typename... Vs>
69bb0eaccbSWilliam A. Kennington III constexpr bool vcontains() noexcept
70bb0eaccbSWilliam A. Kennington III {
71bb0eaccbSWilliam A. Kennington III     return vcontains<T, Vs...>() || std::is_same_v<T, V>;
72bb0eaccbSWilliam A. Kennington III }
73bb0eaccbSWilliam A. Kennington III 
74bb0eaccbSWilliam A. Kennington III template <typename T, typename... Types>
75bb0eaccbSWilliam A. Kennington III constexpr std::enable_if_t<vcontains<T, Types...>(), bool>
76bb0eaccbSWilliam A. Kennington III     veq(T t, std::variant<Types...> v) noexcept
77bb0eaccbSWilliam A. Kennington III {
78bb0eaccbSWilliam A. Kennington III     return std::visit(
79bb0eaccbSWilliam A. Kennington III         [t](auto v) {
80bb0eaccbSWilliam A. Kennington III             if constexpr (std::is_same_v<T, decltype(v)>)
81bb0eaccbSWilliam A. Kennington III             {
82bb0eaccbSWilliam A. Kennington III                 return v == t;
83bb0eaccbSWilliam A. Kennington III             }
84bb0eaccbSWilliam A. Kennington III             else
85bb0eaccbSWilliam A. Kennington III             {
86bb0eaccbSWilliam A. Kennington III                 return false;
87bb0eaccbSWilliam A. Kennington III             }
88bb0eaccbSWilliam A. Kennington III         },
89bb0eaccbSWilliam A. Kennington III         v);
90bb0eaccbSWilliam A. Kennington III }
91bb0eaccbSWilliam A. Kennington III 
92bb0eaccbSWilliam A. Kennington III template <typename T>
93bb0eaccbSWilliam A. Kennington III struct AddrBufMaker
94bb0eaccbSWilliam A. Kennington III {
95bb0eaccbSWilliam A. Kennington III };
96bb0eaccbSWilliam A. Kennington III 
97bb0eaccbSWilliam A. Kennington III template <>
98bb0eaccbSWilliam A. Kennington III struct AddrBufMaker<ether_addr>
99bb0eaccbSWilliam A. Kennington III {
100bb0eaccbSWilliam A. Kennington III   public:
101bb0eaccbSWilliam A. Kennington III     std::string_view operator()(ether_addr val) noexcept;
102bb0eaccbSWilliam A. Kennington III 
103bb0eaccbSWilliam A. Kennington III   private:
104bb0eaccbSWilliam A. Kennington III     std::array<char, /*octet*/ 2 * /*octets*/ 6 + /*seps*/ 5> buf;
105bb0eaccbSWilliam A. Kennington III };
106bb0eaccbSWilliam A. Kennington III 
107bb0eaccbSWilliam A. Kennington III template <>
108bb0eaccbSWilliam A. Kennington III struct AddrBufMaker<in_addr>
109bb0eaccbSWilliam A. Kennington III {
110bb0eaccbSWilliam A. Kennington III   public:
111bb0eaccbSWilliam A. Kennington III     std::string_view operator()(in_addr val) noexcept;
112bb0eaccbSWilliam A. Kennington III 
113bb0eaccbSWilliam A. Kennington III   private:
114bb0eaccbSWilliam A. Kennington III     std::array<char, /*octet*/ 3 * /*octets*/ 4 + /*seps*/ 3> buf;
115bb0eaccbSWilliam A. Kennington III };
116bb0eaccbSWilliam A. Kennington III 
117bb0eaccbSWilliam A. Kennington III template <>
118bb0eaccbSWilliam A. Kennington III struct AddrBufMaker<in6_addr>
119bb0eaccbSWilliam A. Kennington III {
120bb0eaccbSWilliam A. Kennington III   public:
121bb0eaccbSWilliam A. Kennington III     std::string_view operator()(in6_addr val) noexcept;
122bb0eaccbSWilliam A. Kennington III 
123bb0eaccbSWilliam A. Kennington III   private:
124bb0eaccbSWilliam A. Kennington III     std::array<char, /*hextet*/ 4 * /*hextets*/ 8 + /*seps*/ 7> buf;
125bb0eaccbSWilliam A. Kennington III };
126bb0eaccbSWilliam A. Kennington III 
127bb0eaccbSWilliam A. Kennington III template <typename BufMaker>
128bb0eaccbSWilliam A. Kennington III struct FormatFromBuf
129bb0eaccbSWilliam A. Kennington III {
130bb0eaccbSWilliam A. Kennington III   private:
131bb0eaccbSWilliam A. Kennington III     fmt::formatter<std::string_view> formatter;
132bb0eaccbSWilliam A. Kennington III 
133bb0eaccbSWilliam A. Kennington III   public:
134bb0eaccbSWilliam A. Kennington III     template <typename ParseContext>
135bb0eaccbSWilliam A. Kennington III     constexpr auto parse(ParseContext& ctx)
136bb0eaccbSWilliam A. Kennington III     {
137bb0eaccbSWilliam A. Kennington III         return ctx.begin();
138bb0eaccbSWilliam A. Kennington III     }
139bb0eaccbSWilliam A. Kennington III 
140bb0eaccbSWilliam A. Kennington III     template <typename FormatContext>
141bb0eaccbSWilliam A. Kennington III     auto format(auto v, FormatContext& ctx) const
142bb0eaccbSWilliam A. Kennington III     {
143bb0eaccbSWilliam A. Kennington III         return formatter.format(BufMaker{}(v), ctx);
144bb0eaccbSWilliam A. Kennington III     }
145bb0eaccbSWilliam A. Kennington III };
146bb0eaccbSWilliam A. Kennington III } // namespace detail
1471bbe3d1eSWilliam A. Kennington III } // namespace network
1481bbe3d1eSWilliam A. Kennington III } // namespace phosphor
1493e471c5fSWilliam A. Kennington III 
1503e471c5fSWilliam A. Kennington III template <typename... Ts>
1513e471c5fSWilliam A. Kennington III struct std::hash<std::tuple<Ts...>>
1523e471c5fSWilliam A. Kennington III {
1533e471c5fSWilliam A. Kennington III     constexpr auto operator()(const std::tuple<Ts...>& t) const noexcept
1543e471c5fSWilliam A. Kennington III     {
1553e471c5fSWilliam A. Kennington III         return std::apply(phosphor::network::hash_multi<Ts...>, t);
1563e471c5fSWilliam A. Kennington III     }
1573e471c5fSWilliam A. Kennington III };
158bb0eaccbSWilliam A. Kennington III 
159653114fcSWilliam A. Kennington III template <>
160653114fcSWilliam A. Kennington III struct std::hash<in_addr>
161653114fcSWilliam A. Kennington III {
162653114fcSWilliam A. Kennington III     std::size_t operator()(in_addr addr) const noexcept;
163653114fcSWilliam A. Kennington III };
164653114fcSWilliam A. Kennington III 
165653114fcSWilliam A. Kennington III template <>
166653114fcSWilliam A. Kennington III struct std::hash<in6_addr>
167653114fcSWilliam A. Kennington III {
168653114fcSWilliam A. Kennington III     std::size_t operator()(in6_addr addr) const noexcept;
169653114fcSWilliam A. Kennington III };
170653114fcSWilliam A. Kennington III 
171bb0eaccbSWilliam A. Kennington III namespace fmt
172bb0eaccbSWilliam A. Kennington III {
173bb0eaccbSWilliam A. Kennington III template <>
174bb0eaccbSWilliam A. Kennington III struct formatter<ether_addr>
175bb0eaccbSWilliam A. Kennington III     : phosphor::network::detail::FormatFromBuf<
176bb0eaccbSWilliam A. Kennington III           phosphor::network::detail::AddrBufMaker<ether_addr>>
177bb0eaccbSWilliam A. Kennington III {
178bb0eaccbSWilliam A. Kennington III };
179bb0eaccbSWilliam A. Kennington III template <>
180bb0eaccbSWilliam A. Kennington III struct formatter<in_addr>
181bb0eaccbSWilliam A. Kennington III     : phosphor::network::detail::FormatFromBuf<
182bb0eaccbSWilliam A. Kennington III           phosphor::network::detail::AddrBufMaker<in_addr>>
183bb0eaccbSWilliam A. Kennington III {
184bb0eaccbSWilliam A. Kennington III };
185bb0eaccbSWilliam A. Kennington III template <>
186bb0eaccbSWilliam A. Kennington III struct formatter<in6_addr>
187bb0eaccbSWilliam A. Kennington III     : phosphor::network::detail::FormatFromBuf<
188bb0eaccbSWilliam A. Kennington III           phosphor::network::detail::AddrBufMaker<in6_addr>>
189bb0eaccbSWilliam A. Kennington III {
190bb0eaccbSWilliam A. Kennington III };
191bb0eaccbSWilliam A. Kennington III template <>
192bb0eaccbSWilliam A. Kennington III struct formatter<phosphor::network::InAddrAny>
193bb0eaccbSWilliam A. Kennington III {
194bb0eaccbSWilliam A. Kennington III   private:
195bb0eaccbSWilliam A. Kennington III     fmt::formatter<std::string_view> formatter;
196bb0eaccbSWilliam A. Kennington III 
197bb0eaccbSWilliam A. Kennington III   public:
198bb0eaccbSWilliam A. Kennington III     template <typename ParseContext>
199bb0eaccbSWilliam A. Kennington III     constexpr auto parse(ParseContext& ctx)
200bb0eaccbSWilliam A. Kennington III     {
201bb0eaccbSWilliam A. Kennington III         return ctx.begin();
202bb0eaccbSWilliam A. Kennington III     }
203bb0eaccbSWilliam A. Kennington III 
204bb0eaccbSWilliam A. Kennington III     template <typename FormatContext>
205bb0eaccbSWilliam A. Kennington III     auto format(auto v, FormatContext& ctx) const
206bb0eaccbSWilliam A. Kennington III     {
207bb0eaccbSWilliam A. Kennington III         return std::visit(
208bb0eaccbSWilliam A. Kennington III             [&](auto v) {
209bb0eaccbSWilliam A. Kennington III                 auto abm =
210bb0eaccbSWilliam A. Kennington III                     phosphor::network::detail::AddrBufMaker<decltype(v)>{};
211bb0eaccbSWilliam A. Kennington III                 return formatter.format(abm(v), ctx);
212bb0eaccbSWilliam A. Kennington III             },
213bb0eaccbSWilliam A. Kennington III             v);
214bb0eaccbSWilliam A. Kennington III     }
215bb0eaccbSWilliam A. Kennington III };
216bb0eaccbSWilliam A. Kennington III } // namespace fmt
217bb0eaccbSWilliam A. Kennington III 
218bb0eaccbSWilliam A. Kennington III namespace std
219bb0eaccbSWilliam A. Kennington III {
220bb0eaccbSWilliam A. Kennington III string to_string(ether_addr value);
221bb0eaccbSWilliam A. Kennington III string to_string(in_addr value);
222bb0eaccbSWilliam A. Kennington III string to_string(in6_addr value);
223bb0eaccbSWilliam A. Kennington III string to_string(phosphor::network::InAddrAny value);
224bb0eaccbSWilliam A. Kennington III } // namespace std
225bb0eaccbSWilliam A. Kennington III 
226bb0eaccbSWilliam A. Kennington III constexpr bool operator==(ether_addr lhs, ether_addr rhs) noexcept
227bb0eaccbSWilliam A. Kennington III {
228bb0eaccbSWilliam A. Kennington III     return std::equal(lhs.ether_addr_octet, lhs.ether_addr_octet + 6,
229bb0eaccbSWilliam A. Kennington III                       rhs.ether_addr_octet);
230bb0eaccbSWilliam A. Kennington III }
231bb0eaccbSWilliam A. Kennington III 
232bb0eaccbSWilliam A. Kennington III constexpr bool operator==(in_addr lhs, in_addr rhs) noexcept
233bb0eaccbSWilliam A. Kennington III {
234bb0eaccbSWilliam A. Kennington III     return lhs.s_addr == rhs.s_addr;
235bb0eaccbSWilliam A. Kennington III }
236bb0eaccbSWilliam A. Kennington III 
237bb0eaccbSWilliam A. Kennington III constexpr bool operator==(in6_addr lhs, in6_addr rhs) noexcept
238bb0eaccbSWilliam A. Kennington III {
239bb0eaccbSWilliam A. Kennington III     return std::equal(lhs.s6_addr32, lhs.s6_addr32 + 4, rhs.s6_addr32);
240bb0eaccbSWilliam A. Kennington III }
241bb0eaccbSWilliam A. Kennington III 
242bb0eaccbSWilliam A. Kennington III template <typename T>
243bb0eaccbSWilliam A. Kennington III constexpr std::enable_if_t<!std::is_same_v<phosphor::network::InAddrAny, T>,
244bb0eaccbSWilliam A. Kennington III                            bool>
245bb0eaccbSWilliam A. Kennington III     operator==(phosphor::network::InAddrAny lhs, T rhs) noexcept
246bb0eaccbSWilliam A. Kennington III {
247bb0eaccbSWilliam A. Kennington III     return phosphor::network::detail::veq(rhs, lhs);
248bb0eaccbSWilliam A. Kennington III }
249bb0eaccbSWilliam A. Kennington III 
25086eb8b70SWilliam A. Kennington III auto& operator<<(auto& os, ether_addr v)
251bb0eaccbSWilliam A. Kennington III {
252bb0eaccbSWilliam A. Kennington III     return os << phosphor::network::detail::AddrBufMaker<ether_addr>{}(v);
253bb0eaccbSWilliam A. Kennington III }
254bb0eaccbSWilliam A. Kennington III 
25586eb8b70SWilliam A. Kennington III auto& operator<<(auto& os, in_addr v)
256bb0eaccbSWilliam A. Kennington III {
257bb0eaccbSWilliam A. Kennington III     return os << phosphor::network::detail::AddrBufMaker<in_addr>{}(v);
258bb0eaccbSWilliam A. Kennington III }
259bb0eaccbSWilliam A. Kennington III 
26086eb8b70SWilliam A. Kennington III auto& operator<<(auto& os, in6_addr v)
261bb0eaccbSWilliam A. Kennington III {
262bb0eaccbSWilliam A. Kennington III     return os << phosphor::network::detail::AddrBufMaker<in6_addr>{}(v);
263bb0eaccbSWilliam A. Kennington III }
264bb0eaccbSWilliam A. Kennington III 
26586eb8b70SWilliam A. Kennington III auto& operator<<(auto& os, phosphor::network::InAddrAny v)
266bb0eaccbSWilliam A. Kennington III {
267bb0eaccbSWilliam A. Kennington III     return os << std::visit(
268bb0eaccbSWilliam A. Kennington III                [](auto v) {
269bb0eaccbSWilliam A. Kennington III                    return phosphor::network::detail::AddrBufMaker<
270bb0eaccbSWilliam A. Kennington III                        decltype(v)>{}(v);
271bb0eaccbSWilliam A. Kennington III                },
272bb0eaccbSWilliam A. Kennington III                v);
273bb0eaccbSWilliam A. Kennington III }
274