blob: bed1f702aaac8123850e9e3696803971e4d2c5db [file] [log] [blame]
Ratan Gupta233524c2017-05-27 11:47:31 +05301#include "routing_table.hpp"
Patrick Venture189d44e2018-07-09 12:30:59 -07002
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -07003#include "netlink.hpp"
Ratan Gupta233524c2017-05-27 11:47:31 +05304
William A. Kennington IIId81a0982019-02-01 21:10:27 -08005#include <optional>
Patrick Venture189d44e2018-07-09 12:30:59 -07006#include <phosphor-logging/elog-errors.hpp>
7#include <phosphor-logging/log.hpp>
Ratan Gupta233524c2017-05-27 11:47:31 +05308#include <stdexcept>
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -07009#include <stdplus/raw.hpp>
William A. Kennington IIId81a0982019-02-01 21:10:27 -080010#include <string_view>
Patrick Venture189d44e2018-07-09 12:30:59 -070011#include <xyz/openbmc_project/Common/error.hpp>
Ratan Gupta233524c2017-05-27 11:47:31 +053012
13namespace phosphor
14{
15namespace network
16{
17namespace route
18{
19
20using namespace phosphor::logging;
21using namespace sdbusplus::xyz::openbmc_project::Common::Error;
22
William A. Kennington III2bd35d62022-10-26 19:20:29 -070023template <typename Addr>
24static void parse(auto& gws, std::string_view msg)
25{
26 std::optional<unsigned> ifIdx;
27 std::optional<Addr> gw;
28 while (!msg.empty())
29 {
30 auto [hdr, data] = netlink::extractRtAttr(msg);
31 switch (hdr.rta_type)
32 {
33 case RTA_OIF:
34 ifIdx.emplace(stdplus::raw::copyFrom<int>(data));
35 break;
36 case RTA_GATEWAY:
37 gw.emplace(stdplus::raw::copyFrom<Addr>(data));
38 break;
39 }
40 }
41 if (ifIdx && gw)
42 {
43 gws.emplace(*ifIdx, *gw);
44 }
45}
46
47static void parseRoute(auto& gws4, auto& gws6, const nlmsghdr& hdr,
48 std::string_view msg)
49{
50 if (hdr.nlmsg_type != RTM_NEWROUTE)
51 {
52 throw std::runtime_error("Not a route msg");
53 }
54 const auto& rtm = netlink::extractRtData<rtmsg>(msg);
55
56 if (rtm.rtm_table != RT_TABLE_MAIN || rtm.rtm_dst_len != 0)
57 {
58 return;
59 }
60
61 switch (rtm.rtm_family)
62 {
63 case AF_INET:
64 return parse<in_addr>(gws4, msg);
65 case AF_INET6:
66 return parse<in6_addr>(gws6, msg);
67 }
68}
69
William A. Kennington IIIe0564842021-10-23 16:02:22 -070070void Table::refresh()
Ratan Gupta233524c2017-05-27 11:47:31 +053071{
William A. Kennington III2bd35d62022-10-26 19:20:29 -070072 gws4.clear();
73 gws6.clear();
Ratan Gupta233524c2017-05-27 11:47:31 +053074 try
75 {
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -070076 rtmsg msg{};
77 netlink::performRequest(NETLINK_ROUTE, RTM_GETROUTE, NLM_F_DUMP, msg,
78 [&](const nlmsghdr& hdr, std::string_view msg) {
William A. Kennington III2bd35d62022-10-26 19:20:29 -070079 parseRoute(gws4, gws6, hdr, msg);
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -070080 });
Ratan Gupta233524c2017-05-27 11:47:31 +053081 }
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -070082 catch (const std::exception& e)
Ratan Gupta233524c2017-05-27 11:47:31 +053083 {
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -070084 log<level::ERR>("Reading routes failed", entry("ERROR=%s", e.what()));
Ratan Gupta233524c2017-05-27 11:47:31 +053085 commit<InternalFailure>();
86 }
Ratan Gupta233524c2017-05-27 11:47:31 +053087}
Gunnar Mills57d9c502018-09-14 14:42:34 -050088} // namespace route
89} // namespace network
90} // namespace phosphor