| #pragma once |
| #include <linux/netlink.h> |
| #include <linux/rtnetlink.h> |
| |
| #include <stdplus/function_view.hpp> |
| #include <stdplus/raw.hpp> |
| |
| #include <string_view> |
| #include <tuple> |
| #include <type_traits> |
| |
| namespace phosphor |
| { |
| namespace network |
| { |
| namespace netlink |
| { |
| |
| /* @brief Called on each nlmsg received on the socket |
| */ |
| using ReceiveCallback = |
| stdplus::function_view<void(const nlmsghdr&, std::string_view)>; |
| |
| namespace detail |
| { |
| |
| void processMsg(std::string_view& msgs, bool& done, ReceiveCallback cb); |
| |
| void performRequest(int protocol, void* data, size_t size, ReceiveCallback cb); |
| |
| } // namespace detail |
| |
| /** @brief Receives all outstanding messages on a netlink socket |
| * |
| * @param[in] sock - The socket to receive the messages on |
| * @param[in] cb - Called for each response message payload |
| */ |
| size_t receive(int sock, ReceiveCallback cb); |
| |
| /* @brief Call on an rtnetlink payload |
| * Updates the input to remove the attr parsed out. |
| * |
| * @param[in,out] data - The buffer holding rtpayload to parse |
| * @return The payload for the rt msg |
| */ |
| template <typename T> |
| constexpr const T& extractRtData(std::string_view& data) |
| { |
| const T& ret = stdplus::raw::refFrom<T, stdplus::raw::Aligned>(data); |
| data.remove_prefix(NLMSG_ALIGN(sizeof(T))); |
| return ret; |
| } |
| |
| /* @brief Call on a block of rtattrs to parse a single one out |
| * Updates the input to remove the attr parsed out. |
| * |
| * @param[in,out] attrs - The buffer holding rtattrs to parse |
| * @return A tuple of rtattr header + data buffer for the attr |
| */ |
| std::tuple<rtattr, std::string_view> extractRtAttr(std::string_view& data); |
| |
| /** @brief Performs a netlink request of the specified type with the given |
| * message Calls the callback upon receiving |
| * |
| * @param[in] protocol - The netlink protocol to use when opening the socket |
| * @param[in] type - The netlink message type |
| * @param[in] flags - Additional netlink flags for the request |
| * @param[in] msg - The message payload for the request |
| * @param[in] cb - Called for each response message payload |
| */ |
| template <typename T> |
| void performRequest(int protocol, uint16_t type, uint16_t flags, const T& msg, |
| ReceiveCallback cb) |
| { |
| static_assert(std::is_trivially_copyable_v<T>); |
| |
| struct |
| { |
| nlmsghdr hdr; |
| T msg; |
| } data{}; |
| data.hdr.nlmsg_len = sizeof(data); |
| data.hdr.nlmsg_type = type; |
| data.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags; |
| data.msg = msg; |
| |
| detail::performRequest(protocol, &data, sizeof(data), cb); |
| } |
| |
| } // namespace netlink |
| } // namespace network |
| } // namespace phosphor |