blob: ffa123ec04db6c8482cf468d5c31013a165e0fe0 [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
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +05307#include <linux/netlink.h>
8#include <linux/rtnetlink.h>
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +05309
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +053010#include <memory>
William A. Kennington III71590bf2022-10-31 14:14:16 -070011#include <phosphor-logging/log.hpp>
William A. Kennington III32eef712022-01-24 17:03:03 -080012#include <stdplus/fd/create.hpp>
13#include <stdplus/fd/ops.hpp>
William A. Kennington III08505792019-01-30 16:00:04 -080014#include <string_view>
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +053015
16namespace phosphor
17{
18namespace network
19{
Ratan Guptaa54d8f82017-09-08 17:05:46 +053020
William A. Kennington III3a70fa22018-09-20 18:48:20 -070021extern std::unique_ptr<Timer> refreshObjectTimer;
Ratan Guptaa54d8f82017-09-08 17:05:46 +053022
William A. Kennington III5f165dc2022-10-24 15:58:55 -070023namespace netlink
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +053024{
25
William A. Kennington III71590bf2022-10-31 14:14:16 -070026using phosphor::logging::entry;
27using phosphor::logging::level;
28using phosphor::logging::log;
29
William A. Kennington IIIed5ff472022-11-12 16:24:02 -080030inline void rthandler(std::string_view data, auto&& cb)
William A. Kennington III71590bf2022-10-31 14:14:16 -070031{
William A. Kennington IIIed5ff472022-11-12 16:24:02 -080032 auto ret = gatewayFromRtm(data);
William A. Kennington III71590bf2022-10-31 14:14:16 -070033 if (!ret)
34 {
35 return;
36 }
William A. Kennington IIIed5ff472022-11-12 16:24:02 -080037 cb(std::get<unsigned>(*ret), std::get<InAddrAny>(*ret));
William A. Kennington IIIbc2502c2022-11-07 16:31:54 -080038}
39
William A. Kennington III71590bf2022-10-31 14:14:16 -070040static void handler(Manager& m, const nlmsghdr& hdr, std::string_view data)
William A. Kennington III5f165dc2022-10-24 15:58:55 -070041{
William A. Kennington IIIc0fdaaf2022-11-07 16:44:56 -080042 try
William A. Kennington III71590bf2022-10-31 14:14:16 -070043 {
William A. Kennington IIIc0fdaaf2022-11-07 16:44:56 -080044 switch (hdr.nlmsg_type)
45 {
William A. Kennington IIIef2b28e2022-11-13 18:33:10 -080046 case RTM_NEWLINK:
47 m.addInterface(intfFromRtm(data));
48 break;
49 case RTM_DELLINK:
50 m.removeInterface(intfFromRtm(data));
51 break;
William A. Kennington IIIc0fdaaf2022-11-07 16:44:56 -080052 case RTM_NEWROUTE:
William A. Kennington IIIed5ff472022-11-12 16:24:02 -080053 rthandler(data, [&](auto ifidx, auto addr) {
54 m.addDefGw(ifidx, addr);
55 });
William A. Kennington IIIc0fdaaf2022-11-07 16:44:56 -080056 break;
57 case RTM_DELROUTE:
William A. Kennington IIIed5ff472022-11-12 16:24:02 -080058 rthandler(data, [&](auto ifidx, auto addr) {
59 m.removeDefGw(ifidx, addr);
60 });
William A. Kennington IIIc0fdaaf2022-11-07 16:44:56 -080061 break;
62 case RTM_NEWADDR:
William A. Kennington IIIed5ff472022-11-12 16:24:02 -080063 m.addAddress(addrFromRtm(data));
William A. Kennington IIIc0fdaaf2022-11-07 16:44:56 -080064 break;
65 case RTM_DELADDR:
William A. Kennington IIIed5ff472022-11-12 16:24:02 -080066 m.removeAddress(addrFromRtm(data));
William A. Kennington IIIc0fdaaf2022-11-07 16:44:56 -080067 break;
68 case RTM_NEWNEIGH:
William A. Kennington IIIed5ff472022-11-12 16:24:02 -080069 m.addNeighbor(neighFromRtm(data));
William A. Kennington IIIc0fdaaf2022-11-07 16:44:56 -080070 break;
71 case RTM_DELNEIGH:
William A. Kennington IIIed5ff472022-11-12 16:24:02 -080072 m.removeNeighbor(neighFromRtm(data));
William A. Kennington IIIc0fdaaf2022-11-07 16:44:56 -080073 break;
74 }
75 }
76 catch (const std::exception& e)
77 {
William A. Kennington IIIed5ff472022-11-12 16:24:02 -080078 auto msg = fmt::format("Failed handling netlink event: {}", e.what());
79 log<level::ERR>(msg.c_str(), entry("ERROR=%s", e.what()));
William A. Kennington III71590bf2022-10-31 14:14:16 -070080 }
William A. Kennington III5f165dc2022-10-24 15:58:55 -070081}
82
William A. Kennington III71590bf2022-10-31 14:14:16 -070083static void eventHandler(Manager& m, sdeventplus::source::IO&, int fd, uint32_t)
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +053084{
William A. Kennington III71590bf2022-10-31 14:14:16 -070085 auto cb = [&](auto&&... args) {
86 return handler(m, std::forward<decltype(args)>(args)...);
87 };
88 while (receive(fd, cb) > 0)
William A. Kennington III29418ef2022-11-07 22:59:47 -080089 ;
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +053090}
91
William A. Kennington III32eef712022-01-24 17:03:03 -080092static stdplus::ManagedFd makeSock()
93{
94 using namespace stdplus::fd;
95
96 auto sock = socket(SocketDomain::Netlink, SocketType::Raw,
97 static_cast<stdplus::fd::SocketProto>(NETLINK_ROUTE));
98
99 sock.fcntlSetfl(sock.fcntlGetfl().set(FileFlag::NonBlock));
100
101 sockaddr_nl local{};
102 local.nl_family = AF_NETLINK;
William A. Kennington III226cada2022-10-28 16:33:11 -0700103 local.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR |
William A. Kennington III32eef712022-01-24 17:03:03 -0800104 RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_NEIGH;
105 bind(sock, local);
106
107 return sock;
108}
109
William A. Kennington III71590bf2022-10-31 14:14:16 -0700110Server::Server(sdeventplus::Event& event, Manager& manager) :
111 sock(makeSock()),
112 io(event, sock.get(), EPOLLIN | EPOLLET, [&](auto&&... args) {
113 return eventHandler(manager, std::forward<decltype(args)>(args)...);
114 })
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +0530115{
William A. Kennington IIIe1b50d52022-11-14 17:14:04 -0800116 auto cb = [&](const nlmsghdr& hdr, std::string_view data) {
117 handler(manager, hdr, data);
118 };
119 performRequest(NETLINK_ROUTE, RTM_GETLINK, NLM_F_DUMP, ifinfomsg{}, cb);
120 performRequest(NETLINK_ROUTE, RTM_GETADDR, NLM_F_DUMP, ifaddrmsg{}, cb);
121 performRequest(NETLINK_ROUTE, RTM_GETROUTE, NLM_F_DUMP, rtmsg{}, cb);
122 performRequest(NETLINK_ROUTE, RTM_GETNEIGH, NLM_F_DUMP, ndmsg{}, cb);
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +0530123}
124
William A. Kennington III5f165dc2022-10-24 15:58:55 -0700125} // namespace netlink
Gunnar Mills57d9c502018-09-14 14:42:34 -0500126} // namespace network
127} // namespace phosphor