xref: /openbmc/dbus-sensors/src/MctpAsioEndpoint.hpp (revision 6d481b5d0636dc3adaa00c2292ac92fc8840fd94)
1 #pragma once
2 
3 #include <boost/asio/generic/datagram_protocol.hpp>
4 #include <phosphor-logging/lg2.hpp>
5 
6 #include <optional>
7 #include <utility>
8 
9 // Becuase of issues with glibc not matching linux, we need to make sure these
10 // are included AFTER the system headers, which are implictly included by boost.
11 // These show up as errors like
12 // /usr/include/net/if.h:44:14: error: ‘IFF_UP’ conflicts with a previous
13 // declaration
14 // The bugs below are other projects working around similar issues
15 // https://bugzilla.redhat.com/show_bug.cgi?id=1300256
16 // https://github.com/systemd/systemd/commit/08ce521fb2546921f2642bef067d2cc02158b121
17 // https://github.com/systemd/systemd/issues/2864
18 // clang-format off
19 #include <linux/mctp.h>
20 #include <sys/socket.h>
21 // clang-format on
22 
23 // Wrapper around boost::asio::generic::datagram_protocol::endpoint to provide
24 // MCTP specific APIs that are available to the kernel
25 struct MctpAsioEndpoint
26 {
27     MctpAsioEndpoint() = default;
28     MctpAsioEndpoint(const MctpAsioEndpoint&) = delete;
29     MctpAsioEndpoint(MctpAsioEndpoint&&) = delete;
30     MctpAsioEndpoint& operator=(const MctpAsioEndpoint&) = delete;
31     MctpAsioEndpoint& operator=(MctpAsioEndpoint&&) = delete;
32 
33     boost::asio::generic::datagram_protocol::endpoint endpoint;
34 
eidMctpAsioEndpoint35     std::optional<uint8_t> eid() const
36     {
37         const struct sockaddr_mctp* sock = getSockAddr();
38         if (sock == nullptr)
39         {
40             return std::nullopt;
41         }
42         return sock->smctp_addr.s_addr;
43     }
44 
typeMctpAsioEndpoint45     std::optional<uint8_t> type() const
46     {
47         const struct sockaddr_mctp* sock = getSockAddr();
48         if (sock == nullptr)
49         {
50             return std::nullopt;
51         }
52         return sock->smctp_type;
53     }
54 
55   private:
getSockAddrMctpAsioEndpoint56     const struct sockaddr_mctp* getSockAddr() const
57     {
58         if (endpoint.size() < sizeof(struct sockaddr_mctp))
59         {
60             lg2::error("MctpRequester: Received endpoint is too small?");
61             return nullptr;
62         }
63 
64         return std::bit_cast<struct sockaddr_mctp*>(endpoint.data());
65     }
66 };
67