blob: 356338ef73ce8764a62567fc98b6c30cde6f3edf [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#include "util.hpp"
Ratan Gupta233524c2017-05-27 11:47:31 +05305
Patrick Venture189d44e2018-07-09 12:30:59 -07006#include <net/if.h>
Ratan Gupta233524c2017-05-27 11:47:31 +05307
William A. Kennington IIId81a0982019-02-01 21:10:27 -08008#include <optional>
Patrick Venture189d44e2018-07-09 12:30:59 -07009#include <phosphor-logging/elog-errors.hpp>
10#include <phosphor-logging/log.hpp>
Ratan Gupta233524c2017-05-27 11:47:31 +053011#include <stdexcept>
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -070012#include <stdplus/raw.hpp>
William A. Kennington IIId81a0982019-02-01 21:10:27 -080013#include <string_view>
Patrick Venture189d44e2018-07-09 12:30:59 -070014#include <xyz/openbmc_project/Common/error.hpp>
Ratan Gupta233524c2017-05-27 11:47:31 +053015
16namespace phosphor
17{
18namespace network
19{
20namespace route
21{
22
23using namespace phosphor::logging;
24using namespace sdbusplus::xyz::openbmc_project::Common::Error;
25
26Table::Table()
27{
28 try
29 {
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -070030 rtmsg msg{};
31 netlink::performRequest(NETLINK_ROUTE, RTM_GETROUTE, NLM_F_DUMP, msg,
32 [&](const nlmsghdr& hdr, std::string_view msg) {
33 this->parseRoutes(hdr, msg);
34 });
Ratan Gupta233524c2017-05-27 11:47:31 +053035 }
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -070036 catch (const std::exception& e)
Ratan Gupta233524c2017-05-27 11:47:31 +053037 {
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -070038 log<level::ERR>("Reading routes failed", entry("ERROR=%s", e.what()));
Ratan Gupta233524c2017-05-27 11:47:31 +053039 commit<InternalFailure>();
40 }
Ratan Gupta233524c2017-05-27 11:47:31 +053041}
42
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -070043void Table::parseRoutes(const nlmsghdr& hdr, std::string_view msg)
Ratan Gupta233524c2017-05-27 11:47:31 +053044{
William A. Kennington IIId81a0982019-02-01 21:10:27 -080045 std::optional<InAddrAny> dstAddr;
46 std::optional<InAddrAny> gateWayAddr;
Ratan Gupta233524c2017-05-27 11:47:31 +053047 char ifName[IF_NAMESIZE] = {};
48
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -070049 if (hdr.nlmsg_type != RTM_NEWROUTE)
50 {
51 throw std::runtime_error("Not a route msg");
52 }
53 auto rtm = stdplus::raw::extract<rtmsg>(msg);
Ratan Gupta233524c2017-05-27 11:47:31 +053054
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -070055 if ((rtm.rtm_family != AF_INET && rtm.rtm_family != AF_INET6) ||
56 rtm.rtm_table != RT_TABLE_MAIN)
Ratan Gupta233524c2017-05-27 11:47:31 +053057 {
58 return;
59 }
60
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -070061 while (!msg.empty())
Ratan Gupta233524c2017-05-27 11:47:31 +053062 {
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -070063 auto [hdr, data] = netlink::extractRtAttr(msg);
64 switch (hdr.rta_type)
Ratan Gupta233524c2017-05-27 11:47:31 +053065 {
66 case RTA_OIF:
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -070067 if_indextoname(stdplus::raw::copyFrom<int>(data), ifName);
Ratan Gupta233524c2017-05-27 11:47:31 +053068 break;
69 case RTA_GATEWAY:
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -070070 gateWayAddr = addrFromBuf(rtm.rtm_family, data);
Ratan Gupta233524c2017-05-27 11:47:31 +053071 break;
72 case RTA_DST:
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -070073 dstAddr = addrFromBuf(rtm.rtm_family, data);
Ratan Gupta233524c2017-05-27 11:47:31 +053074 break;
75 }
76 }
77
78 std::string dstStr;
William A. Kennington IIId81a0982019-02-01 21:10:27 -080079 if (dstAddr)
Ratan Gupta233524c2017-05-27 11:47:31 +053080 {
William A. Kennington IIId81a0982019-02-01 21:10:27 -080081 dstStr = toString(*dstAddr);
Ratan Gupta233524c2017-05-27 11:47:31 +053082 }
William A. Kennington IIId81a0982019-02-01 21:10:27 -080083 std::string gatewayStr;
84 if (gateWayAddr)
85 {
86 gatewayStr = toString(*gateWayAddr);
87 }
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -070088 if (rtm.rtm_dst_len == 0 && gateWayAddr)
William A. Kennington IIId81a0982019-02-01 21:10:27 -080089 {
Ravi Tejaa5a09442020-07-17 00:57:33 -050090 std::string ifNameStr(ifName);
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -070091 if (rtm.rtm_family == AF_INET)
William A. Kennington IIId81a0982019-02-01 21:10:27 -080092 {
Ravi Tejaa5a09442020-07-17 00:57:33 -050093 defaultGateway[ifNameStr] = gatewayStr;
William A. Kennington IIId81a0982019-02-01 21:10:27 -080094 }
William A. Kennington IIIe0b8fd62021-10-23 14:35:08 -070095 else if (rtm.rtm_family == AF_INET6)
William A. Kennington IIId3c249c2019-02-01 21:12:02 -080096 {
Ravi Tejaa5a09442020-07-17 00:57:33 -050097 defaultGateway6[ifNameStr] = gatewayStr;
William A. Kennington IIId3c249c2019-02-01 21:12:02 -080098 }
William A. Kennington IIId81a0982019-02-01 21:10:27 -080099 }
Ratan Gupta233524c2017-05-27 11:47:31 +0530100 Entry route(dstStr, gatewayStr, ifName);
Ratan Gupta4a5f08a2018-05-04 17:23:16 +0530101 // if there is already existing route for this network
102 // then ignore the next one as it would not be used by the
103 // routing policy
104 // So don't update the route entry for the network for which
105 // there is already a route exist.
106 if (routeList.find(dstStr) == routeList.end())
107 {
108 routeList.emplace(std::make_pair(dstStr, std::move(route)));
109 }
Ratan Gupta233524c2017-05-27 11:47:31 +0530110}
111
Gunnar Mills57d9c502018-09-14 14:42:34 -0500112} // namespace route
113} // namespace network
114} // namespace phosphor