types: Add a type for interface addresses
This will be used to uniquely identify them.
Change-Id: Iabd43520ae5060e4f5dfe18e549f96f6b910b3c1
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/types.hpp b/src/types.hpp
index 75db6a4..f1f2179 100644
--- a/src/types.hpp
+++ b/src/types.hpp
@@ -32,6 +32,46 @@
// Byte representations for common address types in network byte order
using InAddrAny = std::variant<in_addr, in6_addr>;
+class IfAddr
+{
+ private:
+ InAddrAny addr;
+ uint8_t pfx;
+
+ static void invalidPfx(uint8_t pfx);
+
+ public:
+ constexpr IfAddr() : addr({}), pfx(0)
+ {
+ }
+
+ constexpr IfAddr(InAddrAny addr, uint8_t pfx) : addr(addr), pfx(pfx)
+ {
+ std::visit(
+ [pfx](auto v) {
+ if (sizeof(v) * 8 < pfx)
+ {
+ invalidPfx(pfx);
+ }
+ },
+ addr);
+ }
+
+ constexpr auto getAddr() const
+ {
+ return addr;
+ }
+
+ constexpr auto getPfx() const
+ {
+ return pfx;
+ }
+
+ constexpr bool operator==(phosphor::network::IfAddr rhs) const noexcept
+ {
+ return addr == rhs.addr && pfx == rhs.pfx;
+ }
+};
using Timer = sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>;
@@ -254,6 +294,12 @@
std::size_t operator()(in6_addr addr) const noexcept;
};
+template <>
+struct std::hash<phosphor::network::IfAddr>
+{
+ std::size_t operator()(phosphor::network::IfAddr addr) const noexcept;
+};
+
namespace fmt
{
template <>
@@ -299,6 +345,29 @@
v);
}
};
+template <>
+struct formatter<phosphor::network::IfAddr>
+{
+ private:
+ fmt::formatter<phosphor::network::InAddrAny> addrF;
+ fmt::formatter<char> strF;
+ fmt::formatter<uint8_t> numF;
+
+ public:
+ template <typename ParseContext>
+ constexpr auto parse(ParseContext& ctx)
+ {
+ return ctx.begin();
+ }
+
+ template <typename FormatContext>
+ auto format(auto v, FormatContext& ctx) const
+ {
+ addrF.format(v.getAddr(), ctx);
+ strF.format('/', ctx);
+ return numF.format(v.getPfx(), ctx);
+ }
+};
} // namespace fmt
namespace std
@@ -307,6 +376,7 @@
string to_string(in_addr value);
string to_string(in6_addr value);
string to_string(phosphor::network::InAddrAny value);
+string to_string(phosphor::network::IfAddr value);
} // namespace std
constexpr bool operator==(ether_addr lhs, ether_addr rhs) noexcept
@@ -357,3 +427,8 @@
},
v);
}
+
+auto& operator<<(auto& os, phosphor::network::IfAddr v)
+{
+ return os << v.getAddr() << "/" << std::dec << int{v.getPfx()};
+}