1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 #include "alloc-util.h"
4 #include "bus-common-errors.h"
6 #include "networkd-link-bus.h"
7 #include "networkd-link.h"
8 #include "networkd-manager.h"
9 #include "parse-util.h"
12 BUS_DEFINE_PROPERTY_GET_ENUM(property_get_operational_state
, link_operstate
, LinkOperationalState
);
13 BUS_DEFINE_PROPERTY_GET_ENUM(property_get_carrier_state
, link_carrier_state
, LinkCarrierState
);
14 BUS_DEFINE_PROPERTY_GET_ENUM(property_get_address_state
, link_address_state
, LinkAddressState
);
15 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_administrative_state
, link_state
, LinkState
);
17 static int property_get_bit_rates(
20 const char *interface
,
22 sd_bus_message
*reply
,
24 sd_bus_error
*error
) {
26 Link
*link
= userdata
;
28 double tx
, rx
, interval_sec
;
34 manager
= link
->manager
;
36 if (!manager
->use_speed_meter
)
37 return sd_bus_error_set(error
, BUS_ERROR_SPEED_METER_INACTIVE
, "Speed meter is disabled.");
39 if (manager
->speed_meter_usec_old
== 0)
40 return sd_bus_error_set(error
, BUS_ERROR_SPEED_METER_INACTIVE
, "Speed meter is not active.");
42 if (!link
->stats_updated
)
43 return sd_bus_error_set(error
, BUS_ERROR_SPEED_METER_INACTIVE
, "Failed to measure bit-rates.");
45 assert(manager
->speed_meter_usec_new
> manager
->speed_meter_usec_old
);
46 interval_sec
= (double) (manager
->speed_meter_usec_new
- manager
->speed_meter_usec_old
) / USEC_PER_SEC
;
48 if (link
->stats_new
.tx_bytes
> link
->stats_old
.tx_bytes
)
49 tx
= (link
->stats_new
.tx_bytes
- link
->stats_old
.tx_bytes
) / interval_sec
;
51 tx
= (UINT64_MAX
- (link
->stats_old
.tx_bytes
- link
->stats_new
.tx_bytes
)) / interval_sec
;
53 if (link
->stats_new
.rx_bytes
> link
->stats_old
.rx_bytes
)
54 rx
= (link
->stats_new
.rx_bytes
- link
->stats_old
.rx_bytes
) / interval_sec
;
56 rx
= (UINT64_MAX
- (link
->stats_old
.rx_bytes
- link
->stats_new
.rx_bytes
)) / interval_sec
;
58 return sd_bus_message_append(reply
, "(dd)", tx
, rx
);
61 const sd_bus_vtable link_vtable
[] = {
62 SD_BUS_VTABLE_START(0),
64 SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state
, offsetof(Link
, operstate
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
65 SD_BUS_PROPERTY("CarrierState", "s", property_get_carrier_state
, offsetof(Link
, carrier_state
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
66 SD_BUS_PROPERTY("AddressState", "s", property_get_address_state
, offsetof(Link
, address_state
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
67 SD_BUS_PROPERTY("AdministrativeState", "s", property_get_administrative_state
, offsetof(Link
, state
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
68 SD_BUS_PROPERTY("BitRates", "(dd)", property_get_bit_rates
, 0, 0),
73 char *link_bus_path(Link
*link
) {
74 _cleanup_free_
char *ifindex
= NULL
;
79 assert(link
->ifindex
> 0);
81 if (asprintf(&ifindex
, "%d", link
->ifindex
) < 0)
84 r
= sd_bus_path_encode("/org/freedesktop/network1/link", ifindex
, &p
);
91 int link_node_enumerator(sd_bus
*bus
, const char *path
, void *userdata
, char ***nodes
, sd_bus_error
*error
) {
92 _cleanup_strv_free_
char **l
= NULL
;
93 Manager
*m
= userdata
;
103 l
= new0(char*, hashmap_size(m
->links
) + 1);
107 HASHMAP_FOREACH(link
, m
->links
, i
) {
110 p
= link_bus_path(link
);
118 *nodes
= TAKE_PTR(l
);
123 int link_object_find(sd_bus
*bus
, const char *path
, const char *interface
, void *userdata
, void **found
, sd_bus_error
*error
) {
124 _cleanup_free_
char *identifier
= NULL
;
125 Manager
*m
= userdata
;
135 r
= sd_bus_path_decode(path
, "/org/freedesktop/network1/link", &identifier
);
139 r
= parse_ifindex(identifier
, &ifindex
);
143 r
= link_get(m
, ifindex
, &link
);
152 int link_send_changed_strv(Link
*link
, char **properties
) {
153 _cleanup_free_
char *p
= NULL
;
156 assert(link
->manager
);
159 if (!link
->manager
->bus
)
162 p
= link_bus_path(link
);
166 return sd_bus_emit_properties_changed_strv(
169 "org.freedesktop.network1.Link",
173 int link_send_changed(Link
*link
, const char *property
, ...) {
176 properties
= strv_from_stdarg_alloca(property
);
178 return link_send_changed_strv(link
, properties
);