blob: 6aebc94ad01596f044f2ad84193d8c1ade19fdcb [file] [log] [blame]
Ratan Gupta2eff84f2017-04-20 19:19:15 +05301#include "ipaddress.hpp"
Patrick Venture189d44e2018-07-09 12:30:59 -07002
Ratan Gupta2eff84f2017-04-20 19:19:15 +05303#include "ethernet_interface.hpp"
William A. Kennington IIIc2e5e0e2019-04-22 01:26:06 -07004#include "netlink.hpp"
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -05005#include "util.hpp"
Ratan Gupta2eff84f2017-04-20 19:19:15 +05306
William A. Kennington IIIc2e5e0e2019-04-22 01:26:06 -07007#include <linux/netlink.h>
8#include <linux/rtnetlink.h>
9
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -050010#include <phosphor-logging/elog-errors.hpp>
Patrick Venture189d44e2018-07-09 12:30:59 -070011#include <phosphor-logging/log.hpp>
William A. Kennington IIIc2e5e0e2019-04-22 01:26:06 -070012#include <stdexcept>
13#include <stdplus/raw.hpp>
14#include <string>
15#include <string_view>
16#include <vector>
Patrick Venture189d44e2018-07-09 12:30:59 -070017#include <xyz/openbmc_project/Common/error.hpp>
William A. Kennington IIIc2e5e0e2019-04-22 01:26:06 -070018
Ratan Gupta2eff84f2017-04-20 19:19:15 +053019namespace phosphor
20{
21namespace network
22{
23
William A. Kennington IIIc2e5e0e2019-04-22 01:26:06 -070024std::vector<AddressInfo> getCurrentAddresses(const AddressFilter& filter)
25{
26 std::vector<AddressInfo> addresses;
27 auto cb = [&filter, &addresses](const nlmsghdr& hdr, std::string_view msg) {
28 detail::parseAddress(filter, hdr, msg, addresses);
29 };
30 ifaddrmsg msg{};
31 msg.ifa_index = filter.interface;
32 netlink::performRequest(NETLINK_ROUTE, RTM_GETADDR, NLM_F_DUMP, msg, cb);
33 return addresses;
34}
35
Ratan Gupta2eff84f2017-04-20 19:19:15 +053036using namespace phosphor::logging;
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -050037using namespace sdbusplus::xyz::openbmc_project::Common::Error;
William A. Kennington III5e72d082022-09-01 13:10:17 -070038using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
39using Reason = xyz::openbmc_project::Common::NotAllowed::REASON;
Ratan Gupta2eff84f2017-04-20 19:19:15 +053040
William A. Kennington IIIe25f8b42022-10-11 14:43:28 -070041IPAddress::IPAddress(sdbusplus::bus_t& bus, stdplus::const_zstring objPath,
Gunnar Mills57d9c502018-09-14 14:42:34 -050042 EthernetInterface& parent, IP::Protocol type,
William A. Kennington IIIe25f8b42022-10-11 14:43:28 -070043 std::string_view ipaddress, IP::AddressOrigin origin,
44 uint8_t prefixLength) :
45 IPIfaces(bus, objPath.c_str(), IPIfaces::action::defer_emit),
Gunnar Mills57d9c502018-09-14 14:42:34 -050046 parent(parent)
Ratan Gupta2eff84f2017-04-20 19:19:15 +053047{
Ravi Teja2fd2f7d2019-06-06 03:27:55 -050048
William A. Kennington IIIe25f8b42022-10-11 14:43:28 -070049 IP::address(std::string(ipaddress));
Ravi Teja2fd2f7d2019-06-06 03:27:55 -050050 IP::prefixLength(prefixLength);
Ravi Teja2fd2f7d2019-06-06 03:27:55 -050051 IP::type(type);
52 IP::origin(origin);
Ratan Gupta29b0e432017-05-25 12:51:40 +053053
Gunnar Mills57d9c502018-09-14 14:42:34 -050054 // Emit deferred signal.
55 emit_object_added();
Ratan Gupta2eff84f2017-04-20 19:19:15 +053056}
William A. Kennington III5e72d082022-09-01 13:10:17 -070057std::string IPAddress::address(std::string /*ipAddress*/)
58{
59 elog<NotAllowed>(Reason("Property update is not allowed"));
60}
61uint8_t IPAddress::prefixLength(uint8_t /*value*/)
62{
63 elog<NotAllowed>(Reason("Property update is not allowed"));
64}
65std::string IPAddress::gateway(std::string /*gateway*/)
66{
67 elog<NotAllowed>(Reason("Property update is not allowed"));
68}
69IP::Protocol IPAddress::type(IP::Protocol /*type*/)
70{
71 elog<NotAllowed>(Reason("Property update is not allowed"));
72}
73IP::AddressOrigin IPAddress::origin(IP::AddressOrigin /*origin*/)
74{
75 elog<NotAllowed>(Reason("Property update is not allowed"));
76}
Ratan Gupta2eff84f2017-04-20 19:19:15 +053077void IPAddress::delete_()
78{
William A. Kennington III2dae9692019-04-22 02:18:41 -070079 if (origin() != IP::AddressOrigin::Static)
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -050080 {
William A. Kennington III2dae9692019-04-22 02:18:41 -070081 log<level::ERR>("Tried to delete a non-static address"),
82 entry("ADDRESS=%s", address().c_str()),
83 entry("PREFIX=%" PRIu8, prefixLength()),
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -050084 entry("INTERFACE=%s", parent.interfaceName().c_str());
William A. Kennington III2dae9692019-04-22 02:18:41 -070085 elog<InternalFailure>();
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -050086 }
87
Ratan Gupta2eff84f2017-04-20 19:19:15 +053088 parent.deleteObject(address());
89}
90
William A. Kennington IIIc2e5e0e2019-04-22 01:26:06 -070091namespace detail
92{
93
94void parseAddress(const AddressFilter& filter, const nlmsghdr& hdr,
95 std::string_view msg, std::vector<AddressInfo>& addresses)
96{
97 if (hdr.nlmsg_type != RTM_NEWADDR)
98 {
99 throw std::runtime_error("Not an address msg");
100 }
101 auto ifaddr = stdplus::raw::extract<ifaddrmsg>(msg);
102
103 // Filter out addresses we don't care about
104 unsigned ifindex = ifaddr.ifa_index;
105 if (filter.interface != 0 && filter.interface != ifindex)
106 {
107 return;
108 }
109 if (filter.scope && *filter.scope != ifaddr.ifa_scope)
110 {
111 return;
112 }
113
114 // Build the info about the address we found
115 AddressInfo address;
116 address.interface = ifindex;
117 address.prefix = ifaddr.ifa_prefixlen;
118 address.flags = ifaddr.ifa_flags;
119 address.scope = ifaddr.ifa_scope;
120 bool set_addr = false;
121 while (!msg.empty())
122 {
123 auto [hdr, data] = netlink::extractRtAttr(msg);
124 if (hdr.rta_type == IFA_ADDRESS)
125 {
126 address.address = addrFromBuf(ifaddr.ifa_family, data);
127 set_addr = true;
128 }
129 else if (hdr.rta_type == IFA_FLAGS)
130 {
131 address.flags = stdplus::raw::extract<uint32_t>(data);
132 }
133 }
134 if (!set_addr)
135 {
136 throw std::runtime_error("Missing address");
137 }
138 addresses.push_back(std::move(address));
139}
140
141} // namespace detail
Gunnar Mills57d9c502018-09-14 14:42:34 -0500142} // namespace network
143} // namespace phosphor