Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : :
3 : : #include <errno.h>
4 : :
5 : : #include "sd-event.h"
6 : : #include "sd-netlink.h"
7 : :
8 : : #include "networkd-link-bus.h"
9 : : #include "networkd-link.h"
10 : : #include "networkd-manager.h"
11 : : #include "networkd-speed-meter.h"
12 : :
13 : 0 : static int process_message(Manager *manager, sd_netlink_message *message) {
14 : : uint16_t type;
15 : : int ifindex, r;
16 : : Link *link;
17 : :
18 : 0 : r = sd_netlink_message_get_type(message, &type);
19 [ # # ]: 0 : if (r < 0)
20 : 0 : return r;
21 : :
22 [ # # ]: 0 : if (type != RTM_NEWLINK)
23 : 0 : return 0;
24 : :
25 : 0 : r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
26 [ # # ]: 0 : if (r < 0)
27 : 0 : return r;
28 : :
29 : 0 : link = hashmap_get(manager->links, INT_TO_PTR(ifindex));
30 [ # # ]: 0 : if (!link)
31 : 0 : return -ENODEV;
32 : :
33 : 0 : link->stats_old = link->stats_new;
34 : :
35 : 0 : r = sd_netlink_message_read(message, IFLA_STATS64, sizeof link->stats_new, &link->stats_new);
36 [ # # ]: 0 : if (r < 0)
37 : 0 : return r;
38 : :
39 : 0 : link->stats_updated = true;
40 : :
41 : 0 : return 0;
42 : : }
43 : :
44 : 0 : static int speed_meter_handler(sd_event_source *s, uint64_t usec, void *userdata) {
45 : 0 : _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
46 : 0 : Manager *manager = userdata;
47 : : sd_netlink_message *i;
48 : : usec_t usec_now;
49 : : Iterator j;
50 : : Link *link;
51 : : int r;
52 : :
53 [ # # ]: 0 : assert(s);
54 [ # # ]: 0 : assert(userdata);
55 : :
56 : 0 : r = sd_event_now(sd_event_source_get_event(s), CLOCK_MONOTONIC, &usec_now);
57 [ # # ]: 0 : if (r < 0)
58 : 0 : return r;
59 : :
60 : 0 : r = sd_event_source_set_time(s, usec_now + manager->speed_meter_interval_usec);
61 [ # # ]: 0 : if (r < 0)
62 : 0 : return r;
63 : :
64 : 0 : manager->speed_meter_usec_old = manager->speed_meter_usec_new;
65 : 0 : manager->speed_meter_usec_new = usec_now;
66 : :
67 [ # # ]: 0 : HASHMAP_FOREACH(link, manager->links, j)
68 : 0 : link->stats_updated = false;
69 : :
70 : 0 : r = sd_rtnl_message_new_link(manager->rtnl, &req, RTM_GETLINK, 0);
71 [ # # ]: 0 : if (r < 0) {
72 [ # # ]: 0 : log_warning_errno(r, "Failed to allocate RTM_GETLINK netlink message, ignoring: %m");
73 : 0 : return 0;
74 : : }
75 : :
76 : 0 : r = sd_netlink_message_request_dump(req, true);
77 [ # # ]: 0 : if (r < 0) {
78 [ # # ]: 0 : log_warning_errno(r, "Failed to set dump flag, ignoring: %m");
79 : 0 : return 0;
80 : : }
81 : :
82 : 0 : r = sd_netlink_call(manager->rtnl, req, 0, &reply);
83 [ # # ]: 0 : if (r < 0) {
84 [ # # ]: 0 : log_warning_errno(r, "Failed to call RTM_GETLINK, ignoring: %m");
85 : 0 : return 0;
86 : : }
87 : :
88 [ # # ]: 0 : for (i = reply; i; i = sd_netlink_message_next(i))
89 : 0 : (void) process_message(manager, i);
90 : :
91 : 0 : return 0;
92 : : }
93 : :
94 : 0 : int manager_start_speed_meter(Manager *manager) {
95 : 0 : _cleanup_(sd_event_source_unrefp) sd_event_source *s = NULL;
96 : : int r;
97 : :
98 [ # # ]: 0 : assert(manager);
99 [ # # ]: 0 : assert(manager->event);
100 : :
101 [ # # ]: 0 : if (!manager->use_speed_meter)
102 : 0 : return 0;
103 : :
104 : 0 : r = sd_event_add_time(manager->event, &s, CLOCK_MONOTONIC, 0, 0, speed_meter_handler, manager);
105 [ # # ]: 0 : if (r < 0)
106 : 0 : return r;
107 : :
108 : 0 : r = sd_event_source_set_enabled(s, SD_EVENT_ON);
109 [ # # ]: 0 : if (r < 0)
110 : 0 : return r;
111 : :
112 : 0 : manager->speed_meter_event_source = TAKE_PTR(s);
113 : 0 : return 0;
114 : : }
|