blob: f68dd90cfb0e3a5de76a04f55289d55e33580fbe [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 III08505792019-01-30 16:00:04 -080018#include <string_view>
William A. Kennington IIId7946a72019-04-19 14:24:09 -070019#include <utility>
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070020#include <vector>
William A. Kennington III8e61ca92022-09-01 13:28:33 -070021#include <xyz/openbmc_project/Common/error.hpp>
William A. Kennington III08505792019-01-30 16:00:04 -080022
23namespace phosphor
24{
25namespace network
26{
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070027namespace detail
William A. Kennington III08505792019-01-30 16:00:04 -080028{
William A. Kennington III08505792019-01-30 16:00:04 -080029
William A. Kennington IIId7946a72019-04-19 14:24:09 -070030void parseNeighbor(const NeighborFilter& filter, const nlmsghdr& hdr,
31 std::string_view msg, std::vector<NeighborInfo>& neighbors)
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070032{
33 if (hdr.nlmsg_type != RTM_NEWNEIGH)
34 {
35 throw std::runtime_error("Not a neighbor msg");
36 }
William A. Kennington III12beaad2020-06-13 19:30:41 -070037 auto ndm = stdplus::raw::extract<ndmsg>(msg);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070038
William A. Kennington IIId7946a72019-04-19 14:24:09 -070039 // Filter out neighbors we don't care about
40 unsigned ifindex = ndm.ndm_ifindex;
41 if (filter.interface != 0 && filter.interface != ifindex)
William A. Kennington III08505792019-01-30 16:00:04 -080042 {
William A. Kennington IIId7946a72019-04-19 14:24:09 -070043 return;
William A. Kennington III08505792019-01-30 16:00:04 -080044 }
William A. Kennington IIId7946a72019-04-19 14:24:09 -070045 if ((ndm.ndm_state & filter.state) == 0)
46 {
47 return;
48 }
49
50 // Build the neighbor info for our valid neighbor
51 NeighborInfo neighbor;
52 neighbor.interface = ifindex;
53 neighbor.state = ndm.ndm_state;
William A. Kennington III08505792019-01-30 16:00:04 -080054 bool set_addr = false;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070055 while (!msg.empty())
William A. Kennington III08505792019-01-30 16:00:04 -080056 {
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070057 auto [hdr, data] = netlink::extractRtAttr(msg);
William A. Kennington III08505792019-01-30 16:00:04 -080058 if (hdr.rta_type == NDA_LLADDR)
59 {
William A. Kennington III12beaad2020-06-13 19:30:41 -070060 neighbor.mac = stdplus::raw::copyFrom<ether_addr>(data);
William A. Kennington III08505792019-01-30 16:00:04 -080061 }
62 else if (hdr.rta_type == NDA_DST)
63 {
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070064 neighbor.address = addrFromBuf(ndm.ndm_family, data);
William A. Kennington III08505792019-01-30 16:00:04 -080065 set_addr = true;
66 }
William A. Kennington III08505792019-01-30 16:00:04 -080067 }
68 if (!set_addr)
69 {
70 throw std::runtime_error("Missing address");
71 }
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070072 neighbors.push_back(std::move(neighbor));
William A. Kennington III08505792019-01-30 16:00:04 -080073}
74
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070075} // namespace detail
William A. Kennington III08505792019-01-30 16:00:04 -080076
William A. Kennington IIId7946a72019-04-19 14:24:09 -070077std::vector<NeighborInfo> getCurrentNeighbors(const NeighborFilter& filter)
William A. Kennington III08505792019-01-30 16:00:04 -080078{
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070079 std::vector<NeighborInfo> neighbors;
William A. Kennington IIId7946a72019-04-19 14:24:09 -070080 auto cb = [&filter, &neighbors](const nlmsghdr& hdr, std::string_view msg) {
81 detail::parseNeighbor(filter, hdr, msg, neighbors);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070082 };
William A. Kennington IIId7946a72019-04-19 14:24:09 -070083 ndmsg msg{};
84 msg.ndm_ifindex = filter.interface;
85 netlink::performRequest(NETLINK_ROUTE, RTM_GETNEIGH, NLM_F_DUMP, msg, cb);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070086 return neighbors;
William A. Kennington III08505792019-01-30 16:00:04 -080087}
88
Patrick Williamsc38b0712022-07-22 19:26:54 -050089Neighbor::Neighbor(sdbusplus::bus_t& bus, const char* objPath,
William A. Kennington III08505792019-01-30 16:00:04 -080090 EthernetInterface& parent, const std::string& ipAddress,
91 const std::string& macAddress, State state) :
Patrick Williams166b9592022-03-30 16:09:16 -050092 NeighborObj(bus, objPath, NeighborObj::action::defer_emit),
William A. Kennington III08505792019-01-30 16:00:04 -080093 parent(parent)
94{
William A. Kennington III19194622022-09-06 02:13:34 -070095 NeighborObj::ipAddress(ipAddress);
96 NeighborObj::macAddress(macAddress);
97 NeighborObj::state(state);
William A. Kennington III08505792019-01-30 16:00:04 -080098
99 // Emit deferred signal.
100 emit_object_added();
101}
102
103void Neighbor::delete_()
104{
Patrick Williams6aef7692021-05-01 06:39:41 -0500105 parent.deleteStaticNeighborObject(ipAddress());
William A. Kennington III08505792019-01-30 16:00:04 -0800106}
107
William A. Kennington III8e61ca92022-09-01 13:28:33 -0700108using sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
109using REASON =
110 phosphor::logging::xyz::openbmc_project::Common::NotAllowed::REASON;
111using phosphor::logging::elog;
112
113std::string Neighbor::ipAddress(std::string /*ipAddress*/)
114{
115 elog<NotAllowed>(REASON("Property update is not allowed"));
116}
117
118std::string Neighbor::macAddress(std::string /*macAddress*/)
119{
120 elog<NotAllowed>(REASON("Property update is not allowed"));
121}
122
123Neighbor::State Neighbor::state(State /*state*/)
124{
125 elog<NotAllowed>(REASON("Property update is not allowed"));
126}
127
William A. Kennington III08505792019-01-30 16:00:04 -0800128} // namespace network
129} // namespace phosphor