blob: 5b6c6249d97fcfc5b328632938c337ca9eee813c [file] [log] [blame]
Tomáš Pecka2d578c82021-02-23 19:01:35 +01001/*
2 * Copyright (C) 2021 CESNET, https://photonics.cesnet.cz/
3 *
4 * Written by Tomáš Pecka <tomas.pecka@cesnet.cz>
5 *
6 */
7
8#pragma once
9
10#include <functional>
11#include <mutex>
12#include <netlink/netlink.h>
Tomáš Pecka09729382021-03-08 19:36:50 +010013#include <netlink/route/addr.h>
Tomáš Pecka2d578c82021-02-23 19:01:35 +010014#include <netlink/route/link.h>
Tomáš Peckac017eab2021-03-10 12:26:05 +010015#include <netlink/route/neighbour.h>
Tomáš Pecka1ea7e312021-03-31 20:00:03 +020016#include <netlink/route/route.h>
Tomáš Pecka2d578c82021-02-23 19:01:35 +010017#include <stdexcept>
18#include <thread>
19#include "utils/log-fwd.h"
20
21namespace velia::system {
22
23namespace impl {
24class nlCacheMngrWatcher;
25}
26
27/** @brief Wrapper for monitoring changes in NETLINK_ROUTE */
28class Rtnetlink {
29public:
30 using nlCacheManager = std::shared_ptr<nl_cache_mngr>;
Tomáš Peckac017eab2021-03-10 12:26:05 +010031 using nlCache = std::unique_ptr<nl_cache, std::function<void(nl_cache*)>>;
32 using nlLink = std::unique_ptr<rtnl_link, std::function<void(rtnl_link*)>>;
Tomáš Peckaf9212c42021-03-10 11:45:05 +010033 using nlNeigh = std::unique_ptr<rtnl_neigh, std::function<void(rtnl_neigh*)>>;
Tomáš Pecka1ea7e312021-03-31 20:00:03 +020034 using nlRoute = std::unique_ptr<rtnl_route, std::function<void(rtnl_route*)>>;
Tomáš Peckac017eab2021-03-10 12:26:05 +010035
Tomáš Pecka2d578c82021-02-23 19:01:35 +010036 using LinkCB = std::function<void(rtnl_link* link, int cacheAction)>; /// cacheAction: NL_ACT_*
Tomáš Pecka09729382021-03-08 19:36:50 +010037 using AddrCB = std::function<void(rtnl_addr* addr, int cacheAction)>; /// cacheAction: NL_ACT_*
Tomáš Peckab29f36b2021-03-31 20:02:06 +020038 using RouteCB = std::function<void(rtnl_route* route, int cacheAction)>; /// cacheAction: NL_ACT_*
Tomáš Pecka2d578c82021-02-23 19:01:35 +010039
Tomáš Peckab29f36b2021-03-31 20:02:06 +020040 Rtnetlink(LinkCB cbLink, AddrCB cbAddr, RouteCB cbRoute);
Tomáš Pecka2d578c82021-02-23 19:01:35 +010041 ~Rtnetlink();
Tomáš Peckac017eab2021-03-10 12:26:05 +010042 std::vector<nlLink> getLinks();
Tomáš Pecka1ea7e312021-03-31 20:00:03 +020043 std::vector<nlRoute> getRoutes();
Tomáš Peckaf9212c42021-03-10 11:45:05 +010044 std::vector<std::pair<nlNeigh, nlLink>> getNeighbours();
Tomáš Pecka2d578c82021-02-23 19:01:35 +010045
Tomáš Pecka3d3cf612021-03-31 19:51:31 +020046 void invokeInitialCallbacks();
47
Tomáš Pecka2d578c82021-02-23 19:01:35 +010048private:
Tomáš Peckac017eab2021-03-10 12:26:05 +010049 void resyncCache(const nlCache& cache);
50
Tomáš Pecka2d578c82021-02-23 19:01:35 +010051 velia::Log m_log;
Tomáš Peckac017eab2021-03-10 12:26:05 +010052 std::unique_ptr<nl_sock, std::function<void(nl_sock*)>> m_nlSocket;
53 nlCacheManager m_nlCacheManager; // for updates
Tomáš Pecka3d3cf612021-03-31 19:51:31 +020054 nl_cache* m_nlManagedCacheLink;
55 nl_cache* m_nlManagedCacheAddr;
Tomáš Pecka1ea7e312021-03-31 20:00:03 +020056 nl_cache* m_nlManagedCacheRoute;
Tomáš Peckaf9212c42021-03-10 11:45:05 +010057 nlCache m_nlCacheLink; // for getLinks, getNeighbours
58 nlCache m_nlCacheNeighbour; // for getNeighbours
Tomáš Pecka1ea7e312021-03-31 20:00:03 +020059 nlCache m_nlCacheRoute; // for getRoutes
Tomáš Pecka09729382021-03-08 19:36:50 +010060 LinkCB m_cbLink;
61 AddrCB m_cbAddr;
Tomáš Peckab29f36b2021-03-31 20:02:06 +020062 RouteCB m_cbRoute;
Tomáš Pecka2d578c82021-02-23 19:01:35 +010063 std::unique_ptr<impl::nlCacheMngrWatcher> m_nlCacheMngrWatcher; // first to destroy, because the thread uses m_nlCacheManager and m_log
64};
65
66class RtnetlinkException : public std::runtime_error {
67public:
68 RtnetlinkException(const std::string& msg);
69 RtnetlinkException(const std::string& funcName, int error);
70};
71
72}