blob: 880eba1ed47bc61968f39e3ad552d316214fba3f [file] [log] [blame]
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +05301#include "rtnetlink_server.hpp"
Patrick Venture189d44e2018-07-09 12:30:59 -07002
William A. Kennington III5f165dc2022-10-24 15:58:55 -07003#include "netlink.hpp"
William A. Kennington III71590bf2022-10-31 14:14:16 -07004#include "network_manager.hpp"
5#include "rtnetlink.hpp"
William A. Kennington III217bb3f2022-09-29 13:43:13 -07006#include "types.hpp"
7
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +05308#include <linux/netlink.h>
9#include <linux/rtnetlink.h>
Patrick Venture189d44e2018-07-09 12:30:59 -070010#include <netinet/in.h>
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +053011
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +053012#include <memory>
William A. Kennington III71590bf2022-10-31 14:14:16 -070013#include <phosphor-logging/log.hpp>
William A. Kennington III32eef712022-01-24 17:03:03 -080014#include <stdplus/fd/create.hpp>
15#include <stdplus/fd/ops.hpp>
William A. Kennington III08505792019-01-30 16:00:04 -080016#include <string_view>
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +053017
18namespace phosphor
19{
20namespace network
21{
Ratan Guptaa54d8f82017-09-08 17:05:46 +053022
William A. Kennington III3a70fa22018-09-20 18:48:20 -070023extern std::unique_ptr<Timer> refreshObjectTimer;
Ratan Guptaa54d8f82017-09-08 17:05:46 +053024
William A. Kennington III5f165dc2022-10-24 15:58:55 -070025namespace netlink
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +053026{
27
William A. Kennington III71590bf2022-10-31 14:14:16 -070028using phosphor::logging::entry;
29using phosphor::logging::level;
30using phosphor::logging::log;
31
William A. Kennington III5f165dc2022-10-24 15:58:55 -070032static bool shouldRefresh(const struct nlmsghdr& hdr,
33 std::string_view data) noexcept
William A. Kennington IIId2d05942019-01-30 16:04:11 -080034{
35 switch (hdr.nlmsg_type)
36 {
William A. Kennington III226cada2022-10-28 16:33:11 -070037 case RTM_NEWLINK:
38 case RTM_DELLINK:
William A. Kennington IIId2d05942019-01-30 16:04:11 -080039 case RTM_NEWADDR:
40 case RTM_DELADDR:
William A. Kennington IIId2d05942019-01-30 16:04:11 -080041 return true;
William A. Kennington III08505792019-01-30 16:00:04 -080042 case RTM_NEWNEIGH:
43 case RTM_DELNEIGH:
44 {
William A. Kennington IIIc8e992f2022-10-24 16:15:32 -070045 if (data.size() < sizeof(ndmsg))
William A. Kennington III08505792019-01-30 16:00:04 -080046 {
47 return false;
48 }
William A. Kennington IIIc8e992f2022-10-24 16:15:32 -070049 const auto& ndm = *reinterpret_cast<const ndmsg*>(data.data());
William A. Kennington III08505792019-01-30 16:00:04 -080050 // We only want to refresh for static neighbors
51 return ndm.ndm_state & NUD_PERMANENT;
52 }
William A. Kennington IIId2d05942019-01-30 16:04:11 -080053 }
William A. Kennington IIId2d05942019-01-30 16:04:11 -080054 return false;
55}
56
William A. Kennington III71590bf2022-10-31 14:14:16 -070057static void rthandler(Manager& m, bool n, std::string_view data)
58{
59 auto ret = netlink::gatewayFromRtm(data);
60 if (!ret)
61 {
62 return;
63 }
64 auto ifIdx = std::get<unsigned>(*ret);
65 auto it = m.interfacesByIdx.find(ifIdx);
66 if (it == m.interfacesByIdx.end())
67 {
68 auto msg = fmt::format("Interface `{}` not found for route", ifIdx);
69 log<level::ERR>(msg.c_str(), entry("IFIDX=%u", ifIdx));
70 return;
71 }
72 std::visit(
73 [&](auto addr) {
74 if constexpr (std::is_same_v<in_addr, decltype(addr)>)
75 {
76 if (n)
77 {
78 it->second->EthernetInterfaceIntf::defaultGateway(
79 std::to_string(addr));
80 }
81 else if (it->second->defaultGateway() == std::to_string(addr))
82 {
83 it->second->EthernetInterfaceIntf::defaultGateway("");
84 }
85 }
86 else if constexpr (std::is_same_v<in6_addr, decltype(addr)>)
87 {
88 if (n)
89 {
90 it->second->EthernetInterfaceIntf::defaultGateway6(
91 std::to_string(addr));
92 }
93 else if (it->second->defaultGateway6() == std::to_string(addr))
94 {
95 it->second->EthernetInterfaceIntf::defaultGateway6("");
96 }
97 }
98 else
99 {
100 static_assert(!std::is_same_v<void, decltype(addr)>);
101 }
102 },
103 std::get<InAddrAny>(*ret));
104}
105
106static void handler(Manager& m, const nlmsghdr& hdr, std::string_view data)
William A. Kennington III5f165dc2022-10-24 15:58:55 -0700107{
108 if (shouldRefresh(hdr, data) && !refreshObjectTimer->isEnabled())
109 {
110 refreshObjectTimer->restartOnce(refreshTimeout);
111 }
William A. Kennington III71590bf2022-10-31 14:14:16 -0700112 switch (hdr.nlmsg_type)
113 {
114 case RTM_NEWROUTE:
115 rthandler(m, true, data);
116 break;
117 case RTM_DELROUTE:
118 rthandler(m, false, data);
119 break;
120 }
William A. Kennington III5f165dc2022-10-24 15:58:55 -0700121}
122
William A. Kennington III71590bf2022-10-31 14:14:16 -0700123static void eventHandler(Manager& m, sdeventplus::source::IO&, int fd, uint32_t)
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +0530124{
William A. Kennington III71590bf2022-10-31 14:14:16 -0700125 auto cb = [&](auto&&... args) {
126 return handler(m, std::forward<decltype(args)>(args)...);
127 };
128 while (receive(fd, cb) > 0)
William A. Kennington III29418ef2022-11-07 22:59:47 -0800129 ;
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +0530130}
131
William A. Kennington III32eef712022-01-24 17:03:03 -0800132static stdplus::ManagedFd makeSock()
133{
134 using namespace stdplus::fd;
135
136 auto sock = socket(SocketDomain::Netlink, SocketType::Raw,
137 static_cast<stdplus::fd::SocketProto>(NETLINK_ROUTE));
138
139 sock.fcntlSetfl(sock.fcntlGetfl().set(FileFlag::NonBlock));
140
141 sockaddr_nl local{};
142 local.nl_family = AF_NETLINK;
William A. Kennington III226cada2022-10-28 16:33:11 -0700143 local.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR |
William A. Kennington III32eef712022-01-24 17:03:03 -0800144 RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_NEIGH;
145 bind(sock, local);
146
147 return sock;
148}
149
William A. Kennington III71590bf2022-10-31 14:14:16 -0700150Server::Server(sdeventplus::Event& event, Manager& manager) :
151 sock(makeSock()),
152 io(event, sock.get(), EPOLLIN | EPOLLET, [&](auto&&... args) {
153 return eventHandler(manager, std::forward<decltype(args)>(args)...);
154 })
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +0530155{
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +0530156}
157
William A. Kennington III5f165dc2022-10-24 15:58:55 -0700158} // namespace netlink
Gunnar Mills57d9c502018-09-14 14:42:34 -0500159} // namespace network
160} // namespace phosphor