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
;
35 manager
= link
->manager
;
37 if (!manager
->use_speed_meter
)
38 return sd_bus_error_set(error
, BUS_ERROR_SPEED_METER_INACTIVE
, "Speed meter is disabled.");
40 if (manager
->speed_meter_usec_old
== 0)
41 return sd_bus_error_set(error
, BUS_ERROR_SPEED_METER_INACTIVE
, "Speed meter is not active.");
43 if (!link
->stats_updated
)
44 return sd_bus_error_set(error
, BUS_ERROR_SPEED_METER_INACTIVE
, "Failed to measure bit-rates.");
46 assert(manager
->speed_meter_usec_new
> manager
->speed_meter_usec_old
);
47 interval_sec
= (manager
->speed_meter_usec_new
- manager
->speed_meter_usec_old
) / USEC_PER_SEC
;
49 if (link
->stats_new
.tx_bytes
> link
->stats_old
.tx_bytes
)
50 tx
= (uint64_t) ((link
->stats_new
.tx_bytes
- link
->stats_old
.tx_bytes
) / interval_sec
);
52 tx
= (uint64_t) ((UINT64_MAX
- (link
->stats_old
.tx_bytes
- link
->stats_new
.tx_bytes
)) / interval_sec
);
54 if (link
->stats_new
.rx_bytes
> link
->stats_old
.rx_bytes
)
55 rx
= (uint64_t) ((link
->stats_new
.rx_bytes
- link
->stats_old
.rx_bytes
) / interval_sec
);
57 rx
= (uint64_t) ((UINT64_MAX
- (link
->stats_old
.rx_bytes
- link
->stats_new
.rx_bytes
)) / interval_sec
);
59 return sd_bus_message_append(reply
, "(tt)", tx
, rx
);
62 const sd_bus_vtable link_vtable
[] = {
63 SD_BUS_VTABLE_START(0),
65 SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state
, offsetof(Link
, operstate
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
66 SD_BUS_PROPERTY("CarrierState", "s", property_get_carrier_state
, offsetof(Link
, carrier_state
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
67 SD_BUS_PROPERTY("AddressState", "s", property_get_address_state
, offsetof(Link
, address_state
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
68 SD_BUS_PROPERTY("AdministrativeState", "s", property_get_administrative_state
, offsetof(Link
, state
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
69 SD_BUS_PROPERTY("BitRates", "(tt)", property_get_bit_rates
, 0, 0),
74 char *link_bus_path(Link
*link
) {
75 _cleanup_free_
char *ifindex
= NULL
;
80 assert(link
->ifindex
> 0);
82 if (asprintf(&ifindex
, "%d", link
->ifindex
) < 0)
85 r
= sd_bus_path_encode("/org/freedesktop/network1/link", ifindex
, &p
);
92 int link_node_enumerator(sd_bus
*bus
, const char *path
, void *userdata
, char ***nodes
, sd_bus_error
*error
) {
93 _cleanup_strv_free_
char **l
= NULL
;
94 Manager
*m
= userdata
;
104 l
= new0(char*, hashmap_size(m
->links
) + 1);
108 HASHMAP_FOREACH(link
, m
->links
, i
) {
111 p
= link_bus_path(link
);
119 *nodes
= TAKE_PTR(l
);
124 int link_object_find(sd_bus
*bus
, const char *path
, const char *interface
, void *userdata
, void **found
, sd_bus_error
*error
) {
125 _cleanup_free_
char *identifier
= NULL
;
126 Manager
*m
= userdata
;
136 r
= sd_bus_path_decode(path
, "/org/freedesktop/network1/link", &identifier
);
140 r
= parse_ifindex(identifier
, &ifindex
);
144 r
= link_get(m
, ifindex
, &link
);
153 int link_send_changed_strv(Link
*link
, char **properties
) {
154 _cleanup_free_
char *p
= NULL
;
157 assert(link
->manager
);
160 if (!link
->manager
->bus
)
163 p
= link_bus_path(link
);
167 return sd_bus_emit_properties_changed_strv(
170 "org.freedesktop.network1.Link",
174 int link_send_changed(Link
*link
, const char *property
, ...) {
177 properties
= strv_from_stdarg_alloca(property
);
179 return link_send_changed_strv(link
, properties
);