| Ed Tanous | 6d481b5 | 2025-09-29 10:47:58 -0700 | [diff] [blame] | 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 |  | 
 | 35 |     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 |  | 
 | 45 |     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: | 
 | 56 |     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 | }; |