blob: e1a82538ae1f380c8d1a94b7006786d54fafb125 [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
5#include <functional>
6#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 */
19using ReceiveCallback = std::function<void(const nlmsghdr&, std::string_view)>;
20
21namespace detail
22{
23
24void processMsg(std::string_view& msgs, bool& done, const ReceiveCallback& cb);
25
26void performRequest(int protocol, void* data, size_t size,
27 const 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 */
37std::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 */
48template <typename T>
49void performRequest(int protocol, uint16_t type, uint16_t flags, const T& msg,
50 const 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