1 #pragma once 2 #include <linux/netlink.h> 3 #include <linux/rtnetlink.h> 4 5 #include <function2/function2.hpp> 6 #include <string_view> 7 #include <tuple> 8 #include <type_traits> 9 10 namespace phosphor 11 { 12 namespace network 13 { 14 namespace netlink 15 { 16 17 /* @brief Called on each nlmsg received on the socket 18 */ 19 using ReceiveCallback = 20 fu2::function_view<void(const nlmsghdr&, std::string_view)>; 21 22 namespace detail 23 { 24 25 void processMsg(std::string_view& msgs, bool& done, ReceiveCallback cb); 26 27 void performRequest(int protocol, void* data, size_t size, ReceiveCallback cb); 28 29 } // namespace detail 30 31 /* @brief Call on a block of rtattrs to parse a single one out 32 * Updates the input to remove the attr parsed out. 33 * 34 * @param[in,out] attrs - The buffer holding rtattrs to parse 35 * @return A tuple of rtattr header + data buffer for the attr 36 */ 37 std::tuple<rtattr, std::string_view> extractRtAttr(std::string_view& data); 38 39 /** @brief Performs a netlink request of the specified type with the given 40 * message Calls the callback upon receiving 41 * 42 * @param[in] protocol - The netlink protocol to use when opening the socket 43 * @param[in] type - The netlink message type 44 * @param[in] flags - Additional netlink flags for the request 45 * @param[in] msg - The message payload for the request 46 * @param[in] cb - Called for each response message payload 47 */ 48 template <typename T> 49 void performRequest(int protocol, uint16_t type, uint16_t flags, const T& msg, 50 ReceiveCallback cb) 51 { 52 static_assert(std::is_trivially_copyable_v<T>); 53 54 struct 55 { 56 nlmsghdr hdr; 57 T msg; 58 } data{}; 59 data.hdr.nlmsg_len = sizeof(data); 60 data.hdr.nlmsg_type = type; 61 data.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags; 62 data.msg = msg; 63 64 detail::performRequest(protocol, &data, sizeof(data), cb); 65 } 66 67 } // namespace netlink 68 } // namespace network 69 } // namespace phosphor 70