blob: ac9c0b0e320cdcf71a711a1edccfd9c0616f9ec2 [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
Patrick Williamsc38b0712022-07-22 19:26:54 -050041IPAddress::IPAddress(sdbusplus::bus_t& bus, const char* objPath,
Gunnar Mills57d9c502018-09-14 14:42:34 -050042 EthernetInterface& parent, IP::Protocol type,
43 const std::string& ipaddress, IP::AddressOrigin origin,
44 uint8_t prefixLength, const std::string& gateway) :
Patrick Williams166b9592022-03-30 16:09:16 -050045 IPIfaces(bus, objPath, 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
49 IP::address(ipaddress);
50 IP::prefixLength(prefixLength);
51 IP::gateway(gateway);
52 IP::type(type);
53 IP::origin(origin);
Ratan Gupta29b0e432017-05-25 12:51:40 +053054
Gunnar Mills57d9c502018-09-14 14:42:34 -050055 // Emit deferred signal.
56 emit_object_added();
Ratan Gupta2eff84f2017-04-20 19:19:15 +053057}
William A. Kennington III5e72d082022-09-01 13:10:17 -070058std::string IPAddress::address(std::string /*ipAddress*/)
59{
60 elog<NotAllowed>(Reason("Property update is not allowed"));
61}
62uint8_t IPAddress::prefixLength(uint8_t /*value*/)
63{
64 elog<NotAllowed>(Reason("Property update is not allowed"));
65}
66std::string IPAddress::gateway(std::string /*gateway*/)
67{
68 elog<NotAllowed>(Reason("Property update is not allowed"));
69}
70IP::Protocol IPAddress::type(IP::Protocol /*type*/)
71{
72 elog<NotAllowed>(Reason("Property update is not allowed"));
73}
74IP::AddressOrigin IPAddress::origin(IP::AddressOrigin /*origin*/)
75{
76 elog<NotAllowed>(Reason("Property update is not allowed"));
77}
Ratan Gupta2eff84f2017-04-20 19:19:15 +053078void IPAddress::delete_()
79{
William A. Kennington III2dae9692019-04-22 02:18:41 -070080 if (origin() != IP::AddressOrigin::Static)
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -050081 {
William A. Kennington III2dae9692019-04-22 02:18:41 -070082 log<level::ERR>("Tried to delete a non-static address"),
83 entry("ADDRESS=%s", address().c_str()),
84 entry("PREFIX=%" PRIu8, prefixLength()),
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -050085 entry("INTERFACE=%s", parent.interfaceName().c_str());
William A. Kennington III2dae9692019-04-22 02:18:41 -070086 elog<InternalFailure>();
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -050087 }
88
Ratan Gupta2eff84f2017-04-20 19:19:15 +053089 parent.deleteObject(address());
90}
91
William A. Kennington IIIc2e5e0e2019-04-22 01:26:06 -070092namespace detail
93{
94
95void parseAddress(const AddressFilter& filter, const nlmsghdr& hdr,
96 std::string_view msg, std::vector<AddressInfo>& addresses)
97{
98 if (hdr.nlmsg_type != RTM_NEWADDR)
99 {
100 throw std::runtime_error("Not an address msg");
101 }
102 auto ifaddr = stdplus::raw::extract<ifaddrmsg>(msg);
103
104 // Filter out addresses we don't care about
105 unsigned ifindex = ifaddr.ifa_index;
106 if (filter.interface != 0 && filter.interface != ifindex)
107 {
108 return;
109 }
110 if (filter.scope && *filter.scope != ifaddr.ifa_scope)
111 {
112 return;
113 }
114
115 // Build the info about the address we found
116 AddressInfo address;
117 address.interface = ifindex;
118 address.prefix = ifaddr.ifa_prefixlen;
119 address.flags = ifaddr.ifa_flags;
120 address.scope = ifaddr.ifa_scope;
121 bool set_addr = false;
122 while (!msg.empty())
123 {
124 auto [hdr, data] = netlink::extractRtAttr(msg);
125 if (hdr.rta_type == IFA_ADDRESS)
126 {
127 address.address = addrFromBuf(ifaddr.ifa_family, data);
128 set_addr = true;
129 }
130 else if (hdr.rta_type == IFA_FLAGS)
131 {
132 address.flags = stdplus::raw::extract<uint32_t>(data);
133 }
134 }
135 if (!set_addr)
136 {
137 throw std::runtime_error("Missing address");
138 }
139 addresses.push_back(std::move(address));
140}
141
142} // namespace detail
Gunnar Mills57d9c502018-09-14 14:42:34 -0500143} // namespace network
144} // namespace phosphor