11bbe3d1eSWilliam A. Kennington III #include "config.h" 21bbe3d1eSWilliam A. Kennington III 31bbe3d1eSWilliam A. Kennington III #include "neighbor.hpp" 41bbe3d1eSWilliam A. Kennington III 51bbe3d1eSWilliam A. Kennington III #include "ethernet_interface.hpp" 61bbe3d1eSWilliam A. Kennington III #include "netlink.hpp" 71bbe3d1eSWilliam A. Kennington III #include "util.hpp" 81bbe3d1eSWilliam A. Kennington III 91bbe3d1eSWilliam A. Kennington III #include <linux/neighbour.h> 101bbe3d1eSWilliam A. Kennington III #include <linux/netlink.h> 111bbe3d1eSWilliam A. Kennington III #include <linux/rtnetlink.h> 121bbe3d1eSWilliam A. Kennington III #include <net/if.h> 131bbe3d1eSWilliam A. Kennington III #include <sys/socket.h> 141bbe3d1eSWilliam A. Kennington III #include <sys/types.h> 151bbe3d1eSWilliam A. Kennington III 161bbe3d1eSWilliam A. Kennington III #include <stdexcept> 171bbe3d1eSWilliam A. Kennington III #include <stdplus/raw.hpp> 181bbe3d1eSWilliam A. Kennington III #include <string_view> 191bbe3d1eSWilliam A. Kennington III #include <utility> 201bbe3d1eSWilliam A. Kennington III #include <vector> 211bbe3d1eSWilliam A. Kennington III 221bbe3d1eSWilliam A. Kennington III namespace phosphor 231bbe3d1eSWilliam A. Kennington III { 241bbe3d1eSWilliam A. Kennington III namespace network 251bbe3d1eSWilliam A. Kennington III { 261bbe3d1eSWilliam A. Kennington III namespace detail 271bbe3d1eSWilliam A. Kennington III { 281bbe3d1eSWilliam A. Kennington III 291bbe3d1eSWilliam A. Kennington III void parseNeighbor(const NeighborFilter& filter, const nlmsghdr& hdr, 301bbe3d1eSWilliam A. Kennington III std::string_view msg, std::vector<NeighborInfo>& neighbors) 311bbe3d1eSWilliam A. Kennington III { 321bbe3d1eSWilliam A. Kennington III if (hdr.nlmsg_type != RTM_NEWNEIGH) 331bbe3d1eSWilliam A. Kennington III { 341bbe3d1eSWilliam A. Kennington III throw std::runtime_error("Not a neighbor msg"); 351bbe3d1eSWilliam A. Kennington III } 361bbe3d1eSWilliam A. Kennington III auto ndm = stdplus::raw::extract<ndmsg>(msg); 371bbe3d1eSWilliam A. Kennington III 381bbe3d1eSWilliam A. Kennington III // Filter out neighbors we don't care about 391bbe3d1eSWilliam A. Kennington III unsigned ifindex = ndm.ndm_ifindex; 401bbe3d1eSWilliam A. Kennington III if (filter.interface != 0 && filter.interface != ifindex) 411bbe3d1eSWilliam A. Kennington III { 421bbe3d1eSWilliam A. Kennington III return; 431bbe3d1eSWilliam A. Kennington III } 441bbe3d1eSWilliam A. Kennington III if ((ndm.ndm_state & filter.state) == 0) 451bbe3d1eSWilliam A. Kennington III { 461bbe3d1eSWilliam A. Kennington III return; 471bbe3d1eSWilliam A. Kennington III } 481bbe3d1eSWilliam A. Kennington III 491bbe3d1eSWilliam A. Kennington III // Build the neighbor info for our valid neighbor 501bbe3d1eSWilliam A. Kennington III NeighborInfo neighbor; 511bbe3d1eSWilliam A. Kennington III neighbor.interface = ifindex; 521bbe3d1eSWilliam A. Kennington III neighbor.state = ndm.ndm_state; 531bbe3d1eSWilliam A. Kennington III bool set_addr = false; 541bbe3d1eSWilliam A. Kennington III while (!msg.empty()) 551bbe3d1eSWilliam A. Kennington III { 561bbe3d1eSWilliam A. Kennington III auto [hdr, data] = netlink::extractRtAttr(msg); 571bbe3d1eSWilliam A. Kennington III if (hdr.rta_type == NDA_LLADDR) 581bbe3d1eSWilliam A. Kennington III { 591bbe3d1eSWilliam A. Kennington III neighbor.mac = stdplus::raw::copyFrom<ether_addr>(data); 601bbe3d1eSWilliam A. Kennington III } 611bbe3d1eSWilliam A. Kennington III else if (hdr.rta_type == NDA_DST) 621bbe3d1eSWilliam A. Kennington III { 631bbe3d1eSWilliam A. Kennington III neighbor.address = addrFromBuf(ndm.ndm_family, data); 641bbe3d1eSWilliam A. Kennington III set_addr = true; 651bbe3d1eSWilliam A. Kennington III } 661bbe3d1eSWilliam A. Kennington III } 671bbe3d1eSWilliam A. Kennington III if (!set_addr) 681bbe3d1eSWilliam A. Kennington III { 691bbe3d1eSWilliam A. Kennington III throw std::runtime_error("Missing address"); 701bbe3d1eSWilliam A. Kennington III } 711bbe3d1eSWilliam A. Kennington III neighbors.push_back(std::move(neighbor)); 721bbe3d1eSWilliam A. Kennington III } 731bbe3d1eSWilliam A. Kennington III 741bbe3d1eSWilliam A. Kennington III } // namespace detail 751bbe3d1eSWilliam A. Kennington III 761bbe3d1eSWilliam A. Kennington III std::vector<NeighborInfo> getCurrentNeighbors(const NeighborFilter& filter) 771bbe3d1eSWilliam A. Kennington III { 781bbe3d1eSWilliam A. Kennington III std::vector<NeighborInfo> neighbors; 791bbe3d1eSWilliam A. Kennington III auto cb = [&filter, &neighbors](const nlmsghdr& hdr, std::string_view msg) { 801bbe3d1eSWilliam A. Kennington III detail::parseNeighbor(filter, hdr, msg, neighbors); 811bbe3d1eSWilliam A. Kennington III }; 821bbe3d1eSWilliam A. Kennington III ndmsg msg{}; 831bbe3d1eSWilliam A. Kennington III msg.ndm_ifindex = filter.interface; 841bbe3d1eSWilliam A. Kennington III netlink::performRequest(NETLINK_ROUTE, RTM_GETNEIGH, NLM_F_DUMP, msg, cb); 851bbe3d1eSWilliam A. Kennington III return neighbors; 861bbe3d1eSWilliam A. Kennington III } 871bbe3d1eSWilliam A. Kennington III 881bbe3d1eSWilliam A. Kennington III Neighbor::Neighbor(sdbusplus::bus::bus& bus, const char* objPath, 891bbe3d1eSWilliam A. Kennington III EthernetInterface& parent, const std::string& ipAddress, 901bbe3d1eSWilliam A. Kennington III const std::string& macAddress, State state) : 91*166b9598SPatrick Williams NeighborObj(bus, objPath, NeighborObj::action::defer_emit), 921bbe3d1eSWilliam A. Kennington III parent(parent) 931bbe3d1eSWilliam A. Kennington III { 941bbe3d1eSWilliam A. Kennington III this->ipAddress(ipAddress); 951bbe3d1eSWilliam A. Kennington III this->macAddress(macAddress); 961bbe3d1eSWilliam A. Kennington III this->state(state); 971bbe3d1eSWilliam A. Kennington III 981bbe3d1eSWilliam A. Kennington III // Emit deferred signal. 991bbe3d1eSWilliam A. Kennington III emit_object_added(); 1001bbe3d1eSWilliam A. Kennington III } 1011bbe3d1eSWilliam A. Kennington III 1021bbe3d1eSWilliam A. Kennington III void Neighbor::delete_() 1031bbe3d1eSWilliam A. Kennington III { 1041bbe3d1eSWilliam A. Kennington III parent.deleteStaticNeighborObject(ipAddress()); 1051bbe3d1eSWilliam A. Kennington III } 1061bbe3d1eSWilliam A. Kennington III 1071bbe3d1eSWilliam A. Kennington III } // namespace network 1081bbe3d1eSWilliam A. Kennington III } // namespace phosphor 109