blob: cfa8e600d5c42981eb7711c02109ae803d0ecf0c [file] [log] [blame]
William A. Kennington III08505792019-01-30 16:00:04 -08001#include "neighbor.hpp"
2
3#include "ethernet_interface.hpp"
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -07004#include "netlink.hpp"
William A. Kennington III08505792019-01-30 16:00:04 -08005#include "util.hpp"
6
7#include <linux/neighbour.h>
8#include <linux/netlink.h>
9#include <linux/rtnetlink.h>
10#include <net/if.h>
11#include <sys/socket.h>
12#include <sys/types.h>
13
William A. Kennington III8e61ca92022-09-01 13:28:33 -070014#include <phosphor-logging/elog-errors.hpp>
15#include <phosphor-logging/elog.hpp>
William A. Kennington III08505792019-01-30 16:00:04 -080016#include <stdexcept>
William A. Kennington III12beaad2020-06-13 19:30:41 -070017#include <stdplus/raw.hpp>
William A. Kennington IIIbe3bd2f2022-10-11 14:11:27 -070018#include <string>
William A. Kennington III08505792019-01-30 16:00:04 -080019#include <string_view>
William A. Kennington IIId7946a72019-04-19 14:24:09 -070020#include <utility>
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070021#include <vector>
William A. Kennington III8e61ca92022-09-01 13:28:33 -070022#include <xyz/openbmc_project/Common/error.hpp>
William A. Kennington III08505792019-01-30 16:00:04 -080023
24namespace phosphor
25{
26namespace network
27{
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070028namespace detail
William A. Kennington III08505792019-01-30 16:00:04 -080029{
William A. Kennington III08505792019-01-30 16:00:04 -080030
William A. Kennington IIId7946a72019-04-19 14:24:09 -070031void parseNeighbor(const NeighborFilter& filter, const nlmsghdr& hdr,
32 std::string_view msg, std::vector<NeighborInfo>& neighbors)
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070033{
34 if (hdr.nlmsg_type != RTM_NEWNEIGH)
35 {
36 throw std::runtime_error("Not a neighbor msg");
37 }
William A. Kennington III12beaad2020-06-13 19:30:41 -070038 auto ndm = stdplus::raw::extract<ndmsg>(msg);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070039
William A. Kennington IIId7946a72019-04-19 14:24:09 -070040 // Filter out neighbors we don't care about
41 unsigned ifindex = ndm.ndm_ifindex;
42 if (filter.interface != 0 && filter.interface != ifindex)
William A. Kennington III08505792019-01-30 16:00:04 -080043 {
William A. Kennington IIId7946a72019-04-19 14:24:09 -070044 return;
William A. Kennington III08505792019-01-30 16:00:04 -080045 }
William A. Kennington IIId7946a72019-04-19 14:24:09 -070046 if ((ndm.ndm_state & filter.state) == 0)
47 {
48 return;
49 }
50
51 // Build the neighbor info for our valid neighbor
52 NeighborInfo neighbor;
53 neighbor.interface = ifindex;
54 neighbor.state = ndm.ndm_state;
William A. Kennington III08505792019-01-30 16:00:04 -080055 bool set_addr = false;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070056 while (!msg.empty())
William A. Kennington III08505792019-01-30 16:00:04 -080057 {
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070058 auto [hdr, data] = netlink::extractRtAttr(msg);
William A. Kennington III08505792019-01-30 16:00:04 -080059 if (hdr.rta_type == NDA_LLADDR)
60 {
William A. Kennington III12beaad2020-06-13 19:30:41 -070061 neighbor.mac = stdplus::raw::copyFrom<ether_addr>(data);
William A. Kennington III08505792019-01-30 16:00:04 -080062 }
63 else if (hdr.rta_type == NDA_DST)
64 {
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070065 neighbor.address = addrFromBuf(ndm.ndm_family, data);
William A. Kennington III08505792019-01-30 16:00:04 -080066 set_addr = true;
67 }
William A. Kennington III08505792019-01-30 16:00:04 -080068 }
69 if (!set_addr)
70 {
71 throw std::runtime_error("Missing address");
72 }
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070073 neighbors.push_back(std::move(neighbor));
William A. Kennington III08505792019-01-30 16:00:04 -080074}
75
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070076} // namespace detail
William A. Kennington III08505792019-01-30 16:00:04 -080077
William A. Kennington IIId7946a72019-04-19 14:24:09 -070078std::vector<NeighborInfo> getCurrentNeighbors(const NeighborFilter& filter)
William A. Kennington III08505792019-01-30 16:00:04 -080079{
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070080 std::vector<NeighborInfo> neighbors;
William A. Kennington IIId7946a72019-04-19 14:24:09 -070081 auto cb = [&filter, &neighbors](const nlmsghdr& hdr, std::string_view msg) {
82 detail::parseNeighbor(filter, hdr, msg, neighbors);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070083 };
William A. Kennington IIId7946a72019-04-19 14:24:09 -070084 ndmsg msg{};
85 msg.ndm_ifindex = filter.interface;
86 netlink::performRequest(NETLINK_ROUTE, RTM_GETNEIGH, NLM_F_DUMP, msg, cb);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070087 return neighbors;
William A. Kennington III08505792019-01-30 16:00:04 -080088}
89
William A. Kennington IIIbe3bd2f2022-10-11 14:11:27 -070090Neighbor::Neighbor(sdbusplus::bus_t& bus, stdplus::const_zstring objPath,
91 EthernetInterface& parent, std::string_view ipAddress,
92 std::string_view macAddress, State state) :
93 NeighborObj(bus, objPath.c_str(), NeighborObj::action::defer_emit),
William A. Kennington III08505792019-01-30 16:00:04 -080094 parent(parent)
95{
William A. Kennington IIIbe3bd2f2022-10-11 14:11:27 -070096 NeighborObj::ipAddress(std::string(ipAddress));
97 NeighborObj::macAddress(std::string(macAddress));
William A. Kennington III19194622022-09-06 02:13:34 -070098 NeighborObj::state(state);
William A. Kennington III08505792019-01-30 16:00:04 -080099
100 // Emit deferred signal.
101 emit_object_added();
102}
103
104void Neighbor::delete_()
105{
Patrick Williams6aef7692021-05-01 06:39:41 -0500106 parent.deleteStaticNeighborObject(ipAddress());
William A. Kennington III08505792019-01-30 16:00:04 -0800107}
108
William A. Kennington III8e61ca92022-09-01 13:28:33 -0700109using sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
110using REASON =
111 phosphor::logging::xyz::openbmc_project::Common::NotAllowed::REASON;
112using phosphor::logging::elog;
113
114std::string Neighbor::ipAddress(std::string /*ipAddress*/)
115{
116 elog<NotAllowed>(REASON("Property update is not allowed"));
117}
118
119std::string Neighbor::macAddress(std::string /*macAddress*/)
120{
121 elog<NotAllowed>(REASON("Property update is not allowed"));
122}
123
124Neighbor::State Neighbor::state(State /*state*/)
125{
126 elog<NotAllowed>(REASON("Property update is not allowed"));
127}
128
William A. Kennington III08505792019-01-30 16:00:04 -0800129} // namespace network
130} // namespace phosphor