blob: 1260f8e1b0e5283a131d42d52eb4208f7755809a [file] [log] [blame]
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -07001#pragma once
2#include <linux/netlink.h>
3#include <linux/rtnetlink.h>
4
William A. Kennington III058f4cf2022-08-25 17:01:48 -07005#include <function2/function2.hpp>
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -07006#include <string_view>
7#include <tuple>
8#include <type_traits>
9
10namespace phosphor
11{
12namespace network
13{
14namespace netlink
15{
16
17/* @brief Called on each nlmsg received on the socket
18 */
William A. Kennington III058f4cf2022-08-25 17:01:48 -070019using ReceiveCallback =
20 fu2::function_view<void(const nlmsghdr&, std::string_view)>;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070021
22namespace detail
23{
24
William A. Kennington III058f4cf2022-08-25 17:01:48 -070025void processMsg(std::string_view& msgs, bool& done, ReceiveCallback cb);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070026
William A. Kennington III058f4cf2022-08-25 17:01:48 -070027void performRequest(int protocol, void* data, size_t size, ReceiveCallback cb);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070028
29} // namespace detail
30
William A. Kennington III5f165dc2022-10-24 15:58:55 -070031/** @brief Receives all outstanding messages on a netlink socket
32 *
33 * @param[in] sock - The socket to receive the messages on
34 * @param[in] cb - Called for each response message payload
35 */
36void receive(int sock, ReceiveCallback cb);
37
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070038/* @brief Call on a block of rtattrs to parse a single one out
39 * Updates the input to remove the attr parsed out.
40 *
41 * @param[in,out] attrs - The buffer holding rtattrs to parse
42 * @return A tuple of rtattr header + data buffer for the attr
43 */
44std::tuple<rtattr, std::string_view> extractRtAttr(std::string_view& data);
45
46/** @brief Performs a netlink request of the specified type with the given
47 * message Calls the callback upon receiving
48 *
49 * @param[in] protocol - The netlink protocol to use when opening the socket
50 * @param[in] type - The netlink message type
51 * @param[in] flags - Additional netlink flags for the request
52 * @param[in] msg - The message payload for the request
53 * @param[in] cb - Called for each response message payload
54 */
55template <typename T>
56void performRequest(int protocol, uint16_t type, uint16_t flags, const T& msg,
William A. Kennington III058f4cf2022-08-25 17:01:48 -070057 ReceiveCallback cb)
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070058{
59 static_assert(std::is_trivially_copyable_v<T>);
60
61 struct
62 {
63 nlmsghdr hdr;
64 T msg;
65 } data{};
66 data.hdr.nlmsg_len = sizeof(data);
67 data.hdr.nlmsg_type = type;
68 data.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
69 data.msg = msg;
70
71 detail::performRequest(protocol, &data, sizeof(data), cb);
72}
73
74} // namespace netlink
75} // namespace network
76} // namespace phosphor