blob: c9c1fc96ad5b17050045ca9def40928736e6b62a [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 III434a9432022-11-04 18:38:46 -07005#include "network_manager.hpp"
William A. Kennington III08505792019-01-30 16:00:04 -08006#include "util.hpp"
7
8#include <linux/neighbour.h>
9#include <linux/netlink.h>
10#include <linux/rtnetlink.h>
11#include <net/if.h>
12#include <sys/socket.h>
13#include <sys/types.h>
14
William A. Kennington III8e61ca92022-09-01 13:28:33 -070015#include <phosphor-logging/elog-errors.hpp>
16#include <phosphor-logging/elog.hpp>
William A. Kennington III08505792019-01-30 16:00:04 -080017#include <stdexcept>
William A. Kennington III12beaad2020-06-13 19:30:41 -070018#include <stdplus/raw.hpp>
William A. Kennington IIIbe3bd2f2022-10-11 14:11:27 -070019#include <string>
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 IIIf1289a02022-10-24 18:30:36 -070039 const auto& ndm = netlink::extractRtData<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
William A. Kennington III434a9432022-11-04 18:38:46 -070091static auto makeObjPath(std::string_view root, InAddrAny addr)
William A. Kennington III08505792019-01-30 16:00:04 -080092{
William A. Kennington III434a9432022-11-04 18:38:46 -070093 auto ret = sdbusplus::message::object_path(std::string(root));
94 ret /= std::to_string(addr);
95 return ret;
96}
97
98Neighbor::Neighbor(sdbusplus::bus_t& bus, std::string_view objRoot,
99 EthernetInterface& parent, InAddrAny addr, ether_addr lladdr,
100 State state) :
101 Neighbor(bus, makeObjPath(objRoot, addr), parent, addr, lladdr, state)
102{
103}
104
105Neighbor::Neighbor(sdbusplus::bus_t& bus,
106 sdbusplus::message::object_path objPath,
107 EthernetInterface& parent, InAddrAny addr, ether_addr lladdr,
108 State state) :
109 NeighborObj(bus, objPath.str.c_str(), NeighborObj::action::defer_emit),
110 parent(parent), objPath(std::move(objPath))
111{
112 NeighborObj::ipAddress(std::to_string(addr));
113 NeighborObj::macAddress(std::to_string(lladdr));
William A. Kennington III19194622022-09-06 02:13:34 -0700114 NeighborObj::state(state);
William A. Kennington III08505792019-01-30 16:00:04 -0800115
116 // Emit deferred signal.
117 emit_object_added();
118}
119
120void Neighbor::delete_()
121{
William A. Kennington III434a9432022-11-04 18:38:46 -0700122 auto& neighbors = parent.staticNeighbors;
123 std::unique_ptr<Neighbor> ptr;
124 for (auto it = neighbors.begin(); it != neighbors.end(); ++it)
125 {
126 if (it->second.get() == this)
127 {
128 ptr = std::move(it->second);
129 neighbors.erase(it);
130 break;
131 }
132 }
133
134 parent.writeConfigurationFile();
135 parent.manager.reloadConfigs();
William A. Kennington III08505792019-01-30 16:00:04 -0800136}
137
William A. Kennington III8e61ca92022-09-01 13:28:33 -0700138using sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
139using REASON =
140 phosphor::logging::xyz::openbmc_project::Common::NotAllowed::REASON;
141using phosphor::logging::elog;
142
143std::string Neighbor::ipAddress(std::string /*ipAddress*/)
144{
145 elog<NotAllowed>(REASON("Property update is not allowed"));
146}
147
148std::string Neighbor::macAddress(std::string /*macAddress*/)
149{
150 elog<NotAllowed>(REASON("Property update is not allowed"));
151}
152
153Neighbor::State Neighbor::state(State /*state*/)
154{
155 elog<NotAllowed>(REASON("Property update is not allowed"));
156}
157
William A. Kennington III08505792019-01-30 16:00:04 -0800158} // namespace network
159} // namespace phosphor