#include "config.h" #include "neighbor.hpp" #include "ethernet_interface.hpp" #include "netlink.hpp" #include "util.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace phosphor { namespace network { namespace detail { void parseNeighbor(const NeighborFilter& filter, const nlmsghdr& hdr, std::string_view msg, std::vector& neighbors) { if (hdr.nlmsg_type != RTM_NEWNEIGH) { throw std::runtime_error("Not a neighbor msg"); } auto ndm = stdplus::raw::extract(msg); // Filter out neighbors we don't care about unsigned ifindex = ndm.ndm_ifindex; if (filter.interface != 0 && filter.interface != ifindex) { return; } if ((ndm.ndm_state & filter.state) == 0) { return; } // Build the neighbor info for our valid neighbor NeighborInfo neighbor; neighbor.interface = ifindex; neighbor.state = ndm.ndm_state; bool set_addr = false; while (!msg.empty()) { auto [hdr, data] = netlink::extractRtAttr(msg); if (hdr.rta_type == NDA_LLADDR) { neighbor.mac = stdplus::raw::copyFrom(data); } else if (hdr.rta_type == NDA_DST) { neighbor.address = addrFromBuf(ndm.ndm_family, data); set_addr = true; } } if (!set_addr) { throw std::runtime_error("Missing address"); } neighbors.push_back(std::move(neighbor)); } } // namespace detail std::vector getCurrentNeighbors(const NeighborFilter& filter) { std::vector neighbors; auto cb = [&filter, &neighbors](const nlmsghdr& hdr, std::string_view msg) { detail::parseNeighbor(filter, hdr, msg, neighbors); }; ndmsg msg{}; msg.ndm_ifindex = filter.interface; netlink::performRequest(NETLINK_ROUTE, RTM_GETNEIGH, NLM_F_DUMP, msg, cb); return neighbors; } Neighbor::Neighbor(sdbusplus::bus_t& bus, const char* objPath, EthernetInterface& parent, const std::string& ipAddress, const std::string& macAddress, State state) : NeighborObj(bus, objPath, NeighborObj::action::defer_emit), parent(parent) { NeighborObj::ipAddress(ipAddress); NeighborObj::macAddress(macAddress); NeighborObj::state(state); // Emit deferred signal. emit_object_added(); } void Neighbor::delete_() { parent.deleteStaticNeighborObject(ipAddress()); } using sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed; using REASON = phosphor::logging::xyz::openbmc_project::Common::NotAllowed::REASON; using phosphor::logging::elog; std::string Neighbor::ipAddress(std::string /*ipAddress*/) { elog(REASON("Property update is not allowed")); } std::string Neighbor::macAddress(std::string /*macAddress*/) { elog(REASON("Property update is not allowed")); } Neighbor::State Neighbor::state(State /*state*/) { elog(REASON("Property update is not allowed")); } } // namespace network } // namespace phosphor