blob: 85e5bca32270c21044b15057d79fc0a86e9935e7 [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;
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 IIIa809f922022-08-25 15:21:49 -070058
Ratan Gupta2eff84f2017-04-20 19:19:15 +053059void IPAddress::delete_()
60{
William A. Kennington III2dae9692019-04-22 02:18:41 -070061 if (origin() != IP::AddressOrigin::Static)
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -050062 {
William A. Kennington III2dae9692019-04-22 02:18:41 -070063 log<level::ERR>("Tried to delete a non-static address"),
64 entry("ADDRESS=%s", address().c_str()),
65 entry("PREFIX=%" PRIu8, prefixLength()),
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -050066 entry("INTERFACE=%s", parent.interfaceName().c_str());
William A. Kennington III2dae9692019-04-22 02:18:41 -070067 elog<InternalFailure>();
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -050068 }
69
Ratan Gupta2eff84f2017-04-20 19:19:15 +053070 parent.deleteObject(address());
71}
72
William A. Kennington IIIc2e5e0e2019-04-22 01:26:06 -070073namespace detail
74{
75
76void parseAddress(const AddressFilter& filter, const nlmsghdr& hdr,
77 std::string_view msg, std::vector<AddressInfo>& addresses)
78{
79 if (hdr.nlmsg_type != RTM_NEWADDR)
80 {
81 throw std::runtime_error("Not an address msg");
82 }
83 auto ifaddr = stdplus::raw::extract<ifaddrmsg>(msg);
84
85 // Filter out addresses we don't care about
86 unsigned ifindex = ifaddr.ifa_index;
87 if (filter.interface != 0 && filter.interface != ifindex)
88 {
89 return;
90 }
91 if (filter.scope && *filter.scope != ifaddr.ifa_scope)
92 {
93 return;
94 }
95
96 // Build the info about the address we found
97 AddressInfo address;
98 address.interface = ifindex;
99 address.prefix = ifaddr.ifa_prefixlen;
100 address.flags = ifaddr.ifa_flags;
101 address.scope = ifaddr.ifa_scope;
102 bool set_addr = false;
103 while (!msg.empty())
104 {
105 auto [hdr, data] = netlink::extractRtAttr(msg);
106 if (hdr.rta_type == IFA_ADDRESS)
107 {
108 address.address = addrFromBuf(ifaddr.ifa_family, data);
109 set_addr = true;
110 }
111 else if (hdr.rta_type == IFA_FLAGS)
112 {
113 address.flags = stdplus::raw::extract<uint32_t>(data);
114 }
115 }
116 if (!set_addr)
117 {
118 throw std::runtime_error("Missing address");
119 }
120 addresses.push_back(std::move(address));
121}
122
123} // namespace detail
Gunnar Mills57d9c502018-09-14 14:42:34 -0500124} // namespace network
125} // namespace phosphor