blob: becb5b3b52fa5d2bb6a53f17014ababbdedeada0 [file] [log] [blame]
Gunnar Mills57d9c502018-09-14 14:42:34 -05001#include "config.h"
2
Ratan Gupta2eff84f2017-04-20 19:19:15 +05303#include "ipaddress.hpp"
Patrick Venture189d44e2018-07-09 12:30:59 -07004
Ratan Gupta2eff84f2017-04-20 19:19:15 +05305#include "ethernet_interface.hpp"
William A. Kennington IIIc2e5e0e2019-04-22 01:26:06 -07006#include "netlink.hpp"
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -05007#include "util.hpp"
Ratan Gupta2eff84f2017-04-20 19:19:15 +05308
William A. Kennington IIIc2e5e0e2019-04-22 01:26:06 -07009#include <linux/netlink.h>
10#include <linux/rtnetlink.h>
11
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -050012#include <phosphor-logging/elog-errors.hpp>
Patrick Venture189d44e2018-07-09 12:30:59 -070013#include <phosphor-logging/log.hpp>
William A. Kennington IIIc2e5e0e2019-04-22 01:26:06 -070014#include <stdexcept>
15#include <stdplus/raw.hpp>
16#include <string>
17#include <string_view>
18#include <vector>
Patrick Venture189d44e2018-07-09 12:30:59 -070019#include <xyz/openbmc_project/Common/error.hpp>
William A. Kennington IIIc2e5e0e2019-04-22 01:26:06 -070020
Ratan Gupta2eff84f2017-04-20 19:19:15 +053021namespace phosphor
22{
23namespace network
24{
25
William A. Kennington IIIc2e5e0e2019-04-22 01:26:06 -070026std::vector<AddressInfo> getCurrentAddresses(const AddressFilter& filter)
27{
28 std::vector<AddressInfo> addresses;
29 auto cb = [&filter, &addresses](const nlmsghdr& hdr, std::string_view msg) {
30 detail::parseAddress(filter, hdr, msg, addresses);
31 };
32 ifaddrmsg msg{};
33 msg.ifa_index = filter.interface;
34 netlink::performRequest(NETLINK_ROUTE, RTM_GETADDR, NLM_F_DUMP, msg, cb);
35 return addresses;
36}
37
Ratan Gupta2eff84f2017-04-20 19:19:15 +053038using namespace phosphor::logging;
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -050039using namespace sdbusplus::xyz::openbmc_project::Common::Error;
William A. Kennington III5e72d082022-09-01 13:10:17 -070040using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
41using Reason = xyz::openbmc_project::Common::NotAllowed::REASON;
Ratan Gupta2eff84f2017-04-20 19:19:15 +053042
Patrick Williamsc38b0712022-07-22 19:26:54 -050043IPAddress::IPAddress(sdbusplus::bus_t& bus, const char* objPath,
Gunnar Mills57d9c502018-09-14 14:42:34 -050044 EthernetInterface& parent, IP::Protocol type,
45 const std::string& ipaddress, IP::AddressOrigin origin,
46 uint8_t prefixLength, const std::string& gateway) :
Patrick Williams166b9592022-03-30 16:09:16 -050047 IPIfaces(bus, objPath, IPIfaces::action::defer_emit),
Gunnar Mills57d9c502018-09-14 14:42:34 -050048 parent(parent)
Ratan Gupta2eff84f2017-04-20 19:19:15 +053049{
Ravi Teja2fd2f7d2019-06-06 03:27:55 -050050
51 IP::address(ipaddress);
52 IP::prefixLength(prefixLength);
53 IP::gateway(gateway);
54 IP::type(type);
55 IP::origin(origin);
Ratan Gupta29b0e432017-05-25 12:51:40 +053056
Gunnar Mills57d9c502018-09-14 14:42:34 -050057 // Emit deferred signal.
58 emit_object_added();
Ratan Gupta2eff84f2017-04-20 19:19:15 +053059}
William A. Kennington III5e72d082022-09-01 13:10:17 -070060std::string IPAddress::address(std::string /*ipAddress*/)
61{
62 elog<NotAllowed>(Reason("Property update is not allowed"));
63}
64uint8_t IPAddress::prefixLength(uint8_t /*value*/)
65{
66 elog<NotAllowed>(Reason("Property update is not allowed"));
67}
68std::string IPAddress::gateway(std::string /*gateway*/)
69{
70 elog<NotAllowed>(Reason("Property update is not allowed"));
71}
72IP::Protocol IPAddress::type(IP::Protocol /*type*/)
73{
74 elog<NotAllowed>(Reason("Property update is not allowed"));
75}
76IP::AddressOrigin IPAddress::origin(IP::AddressOrigin /*origin*/)
77{
78 elog<NotAllowed>(Reason("Property update is not allowed"));
79}
Ratan Gupta2eff84f2017-04-20 19:19:15 +053080void IPAddress::delete_()
81{
William A. Kennington III2dae9692019-04-22 02:18:41 -070082 if (origin() != IP::AddressOrigin::Static)
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -050083 {
William A. Kennington III2dae9692019-04-22 02:18:41 -070084 log<level::ERR>("Tried to delete a non-static address"),
85 entry("ADDRESS=%s", address().c_str()),
86 entry("PREFIX=%" PRIu8, prefixLength()),
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -050087 entry("INTERFACE=%s", parent.interfaceName().c_str());
William A. Kennington III2dae9692019-04-22 02:18:41 -070088 elog<InternalFailure>();
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -050089 }
90
Ratan Gupta2eff84f2017-04-20 19:19:15 +053091 parent.deleteObject(address());
92}
93
William A. Kennington IIIc2e5e0e2019-04-22 01:26:06 -070094namespace detail
95{
96
97void parseAddress(const AddressFilter& filter, const nlmsghdr& hdr,
98 std::string_view msg, std::vector<AddressInfo>& addresses)
99{
100 if (hdr.nlmsg_type != RTM_NEWADDR)
101 {
102 throw std::runtime_error("Not an address msg");
103 }
104 auto ifaddr = stdplus::raw::extract<ifaddrmsg>(msg);
105
106 // Filter out addresses we don't care about
107 unsigned ifindex = ifaddr.ifa_index;
108 if (filter.interface != 0 && filter.interface != ifindex)
109 {
110 return;
111 }
112 if (filter.scope && *filter.scope != ifaddr.ifa_scope)
113 {
114 return;
115 }
116
117 // Build the info about the address we found
118 AddressInfo address;
119 address.interface = ifindex;
120 address.prefix = ifaddr.ifa_prefixlen;
121 address.flags = ifaddr.ifa_flags;
122 address.scope = ifaddr.ifa_scope;
123 bool set_addr = false;
124 while (!msg.empty())
125 {
126 auto [hdr, data] = netlink::extractRtAttr(msg);
127 if (hdr.rta_type == IFA_ADDRESS)
128 {
129 address.address = addrFromBuf(ifaddr.ifa_family, data);
130 set_addr = true;
131 }
132 else if (hdr.rta_type == IFA_FLAGS)
133 {
134 address.flags = stdplus::raw::extract<uint32_t>(data);
135 }
136 }
137 if (!set_addr)
138 {
139 throw std::runtime_error("Missing address");
140 }
141 addresses.push_back(std::move(address));
142}
143
144} // namespace detail
Gunnar Mills57d9c502018-09-14 14:42:34 -0500145} // namespace network
146} // namespace phosphor