blob: 579a5a8242bb559ad6f69c34826d6cb7ecb0ea98 [file] [log] [blame]
William A. Kennington III08505792019-01-30 16:00:04 -08001#include "config.h"
2
3#include "neighbor.hpp"
4
5#include "ethernet_interface.hpp"
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -07006#include "netlink.hpp"
William A. Kennington III08505792019-01-30 16:00:04 -08007#include "util.hpp"
8
9#include <linux/neighbour.h>
10#include <linux/netlink.h>
11#include <linux/rtnetlink.h>
12#include <net/if.h>
13#include <sys/socket.h>
14#include <sys/types.h>
15
William A. Kennington III8e61ca92022-09-01 13:28:33 -070016#include <phosphor-logging/elog-errors.hpp>
17#include <phosphor-logging/elog.hpp>
William A. Kennington III08505792019-01-30 16:00:04 -080018#include <stdexcept>
William A. Kennington III12beaad2020-06-13 19:30:41 -070019#include <stdplus/raw.hpp>
William A. Kennington III08505792019-01-30 16:00:04 -080020#include <string_view>
William A. Kennington IIId7946a72019-04-19 14:24:09 -070021#include <utility>
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070022#include <vector>
William A. Kennington III8e61ca92022-09-01 13:28:33 -070023#include <xyz/openbmc_project/Common/error.hpp>
William A. Kennington III08505792019-01-30 16:00:04 -080024
25namespace phosphor
26{
27namespace network
28{
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070029namespace detail
William A. Kennington III08505792019-01-30 16:00:04 -080030{
William A. Kennington III08505792019-01-30 16:00:04 -080031
William A. Kennington IIId7946a72019-04-19 14:24:09 -070032void parseNeighbor(const NeighborFilter& filter, const nlmsghdr& hdr,
33 std::string_view msg, std::vector<NeighborInfo>& neighbors)
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070034{
35 if (hdr.nlmsg_type != RTM_NEWNEIGH)
36 {
37 throw std::runtime_error("Not a neighbor msg");
38 }
William A. Kennington III12beaad2020-06-13 19:30:41 -070039 auto ndm = stdplus::raw::extract<ndmsg>(msg);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070040
William A. Kennington IIId7946a72019-04-19 14:24:09 -070041 // Filter out neighbors we don't care about
42 unsigned ifindex = ndm.ndm_ifindex;
43 if (filter.interface != 0 && filter.interface != ifindex)
William A. Kennington III08505792019-01-30 16:00:04 -080044 {
William A. Kennington IIId7946a72019-04-19 14:24:09 -070045 return;
William A. Kennington III08505792019-01-30 16:00:04 -080046 }
William A. Kennington IIId7946a72019-04-19 14:24:09 -070047 if ((ndm.ndm_state & filter.state) == 0)
48 {
49 return;
50 }
51
52 // Build the neighbor info for our valid neighbor
53 NeighborInfo neighbor;
54 neighbor.interface = ifindex;
55 neighbor.state = ndm.ndm_state;
William A. Kennington III08505792019-01-30 16:00:04 -080056 bool set_addr = false;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070057 while (!msg.empty())
William A. Kennington III08505792019-01-30 16:00:04 -080058 {
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070059 auto [hdr, data] = netlink::extractRtAttr(msg);
William A. Kennington III08505792019-01-30 16:00:04 -080060 if (hdr.rta_type == NDA_LLADDR)
61 {
William A. Kennington III12beaad2020-06-13 19:30:41 -070062 neighbor.mac = stdplus::raw::copyFrom<ether_addr>(data);
William A. Kennington III08505792019-01-30 16:00:04 -080063 }
64 else if (hdr.rta_type == NDA_DST)
65 {
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070066 neighbor.address = addrFromBuf(ndm.ndm_family, data);
William A. Kennington III08505792019-01-30 16:00:04 -080067 set_addr = true;
68 }
William A. Kennington III08505792019-01-30 16:00:04 -080069 }
70 if (!set_addr)
71 {
72 throw std::runtime_error("Missing address");
73 }
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070074 neighbors.push_back(std::move(neighbor));
William A. Kennington III08505792019-01-30 16:00:04 -080075}
76
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070077} // namespace detail
William A. Kennington III08505792019-01-30 16:00:04 -080078
William A. Kennington IIId7946a72019-04-19 14:24:09 -070079std::vector<NeighborInfo> getCurrentNeighbors(const NeighborFilter& filter)
William A. Kennington III08505792019-01-30 16:00:04 -080080{
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070081 std::vector<NeighborInfo> neighbors;
William A. Kennington IIId7946a72019-04-19 14:24:09 -070082 auto cb = [&filter, &neighbors](const nlmsghdr& hdr, std::string_view msg) {
83 detail::parseNeighbor(filter, hdr, msg, neighbors);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070084 };
William A. Kennington IIId7946a72019-04-19 14:24:09 -070085 ndmsg msg{};
86 msg.ndm_ifindex = filter.interface;
87 netlink::performRequest(NETLINK_ROUTE, RTM_GETNEIGH, NLM_F_DUMP, msg, cb);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070088 return neighbors;
William A. Kennington III08505792019-01-30 16:00:04 -080089}
90
Patrick Williamsc38b0712022-07-22 19:26:54 -050091Neighbor::Neighbor(sdbusplus::bus_t& bus, const char* objPath,
William A. Kennington III08505792019-01-30 16:00:04 -080092 EthernetInterface& parent, const std::string& ipAddress,
93 const std::string& macAddress, State state) :
Patrick Williams166b9592022-03-30 16:09:16 -050094 NeighborObj(bus, objPath, NeighborObj::action::defer_emit),
William A. Kennington III08505792019-01-30 16:00:04 -080095 parent(parent)
96{
William A. Kennington III19194622022-09-06 02:13:34 -070097 NeighborObj::ipAddress(ipAddress);
98 NeighborObj::macAddress(macAddress);
99 NeighborObj::state(state);
William A. Kennington III08505792019-01-30 16:00:04 -0800100
101 // Emit deferred signal.
102 emit_object_added();
103}
104
105void Neighbor::delete_()
106{
Patrick Williams6aef7692021-05-01 06:39:41 -0500107 parent.deleteStaticNeighborObject(ipAddress());
William A. Kennington III08505792019-01-30 16:00:04 -0800108}
109
William A. Kennington III8e61ca92022-09-01 13:28:33 -0700110using sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
111using REASON =
112 phosphor::logging::xyz::openbmc_project::Common::NotAllowed::REASON;
113using phosphor::logging::elog;
114
115std::string Neighbor::ipAddress(std::string /*ipAddress*/)
116{
117 elog<NotAllowed>(REASON("Property update is not allowed"));
118}
119
120std::string Neighbor::macAddress(std::string /*macAddress*/)
121{
122 elog<NotAllowed>(REASON("Property update is not allowed"));
123}
124
125Neighbor::State Neighbor::state(State /*state*/)
126{
127 elog<NotAllowed>(REASON("Property update is not allowed"));
128}
129
William A. Kennington III08505792019-01-30 16:00:04 -0800130} // namespace network
131} // namespace phosphor