neighbor: Refactor out netlink code
This will allow us to re-use the generic netlink bits for other netlink
request operations.
Adds test coverage to the netlink message parsing routines for sanity
and regression prevention.
Tested:
Neighbor population still works when static neighbors are created on
the BMC.
Change-Id: I755e86eb76a8f6f825616c13279328134de87da9
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/util.hpp b/util.hpp
index 723c941..fe94444 100644
--- a/util.hpp
+++ b/util.hpp
@@ -200,6 +200,53 @@
} // namespace network
+/** @brief Copies data from a buffer into a copyable type
+ *
+ * @param[in] data - The data buffer being extracted from
+ * @param[in] emsg - The message to print if extraction fails
+ * @return The copyable type with data populated
+ */
+template <typename T>
+T copyFrom(std::string_view data, const char* emsg = "Extract Failed")
+{
+ static_assert(std::is_trivially_copyable_v<T>);
+ T ret;
+ if (data.size() < sizeof(ret))
+ {
+ throw std::runtime_error(emsg);
+ }
+ std::memcpy(&ret, data.data(), sizeof(ret));
+ return ret;
+}
+
+/** @brief Extracts data from a buffer into a copyable type
+ * Updates the data buffer to show that data was removed
+ *
+ * @param[in,out] data - The data buffer being extracted from
+ * @param[in] emsg - The message to print if extraction fails
+ * @return The copyable type with data populated
+ */
+template <typename T>
+T extract(std::string_view& data, const char* emsg = "Extract Failed")
+{
+ T ret = copyFrom<T>(data, emsg);
+ data.remove_prefix(sizeof(ret));
+ return ret;
+}
+
+/** @brief Compares two of the same trivially copyable types
+ *
+ * @param[in] a - The data buffer being extracted from
+ * @param[in] b - The message to print if extraction fails
+ * @return True if the parameters are bitwise identical
+ */
+template <typename T>
+bool equal(const T& a, const T& b)
+{
+ static_assert(std::is_trivially_copyable_v<T>);
+ return memcmp(&a, &b, sizeof(T)) == 0;
+}
+
class Descriptor
{
private: