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