1 /* SPDX-License-Identifier: LGPL-2.1+ */
6 #include "sd-netlink.h"
8 #include "networkd-link-bus.h"
9 #include "networkd-link.h"
10 #include "networkd-manager.h"
11 #include "networkd-speed-meter.h"
13 static int process_message(Manager
*manager
, sd_netlink_message
*message
) {
18 r
= sd_netlink_message_get_type(message
, &type
);
22 if (type
!= RTM_NEWLINK
)
25 r
= sd_rtnl_message_link_get_ifindex(message
, &ifindex
);
29 link
= hashmap_get(manager
->links
, INT_TO_PTR(ifindex
));
33 link
->stats_old
= link
->stats_new
;
35 r
= sd_netlink_message_read(message
, IFLA_STATS64
, sizeof link
->stats_new
, &link
->stats_new
);
39 link
->stats_updated
= true;
44 static int speed_meter_handler(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
45 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
, *reply
= NULL
;
46 Manager
*manager
= userdata
;
47 sd_netlink_message
*i
;
55 r
= sd_event_now(sd_event_source_get_event(s
), CLOCK_MONOTONIC
, &usec_now
);
59 r
= sd_event_source_set_time(s
, usec_now
+ manager
->speed_meter_interval_usec
);
63 manager
->speed_meter_usec_old
= manager
->speed_meter_usec_new
;
64 manager
->speed_meter_usec_new
= usec_now
;
66 HASHMAP_FOREACH(link
, manager
->links
)
67 link
->stats_updated
= false;
69 r
= sd_rtnl_message_new_link(manager
->rtnl
, &req
, RTM_GETLINK
, 0);
71 log_warning_errno(r
, "Failed to allocate RTM_GETLINK netlink message, ignoring: %m");
75 r
= sd_netlink_message_request_dump(req
, true);
77 log_warning_errno(r
, "Failed to set dump flag, ignoring: %m");
81 r
= sd_netlink_call(manager
->rtnl
, req
, 0, &reply
);
83 log_warning_errno(r
, "Failed to call RTM_GETLINK, ignoring: %m");
87 for (i
= reply
; i
; i
= sd_netlink_message_next(i
))
88 (void) process_message(manager
, i
);
93 int manager_start_speed_meter(Manager
*manager
) {
94 _cleanup_(sd_event_source_unrefp
) sd_event_source
*s
= NULL
;
98 assert(manager
->event
);
100 if (!manager
->use_speed_meter
)
103 r
= sd_event_add_time(manager
->event
, &s
, CLOCK_MONOTONIC
, 0, 0, speed_meter_handler
, manager
);
107 r
= sd_event_source_set_enabled(s
, SD_EVENT_ON
);
111 manager
->speed_meter_event_source
= TAKE_PTR(s
);