]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-link-bus.c
Merge pull request #12753 from jrouleau/fix/hibernate-resume-timeout
[thirdparty/systemd.git] / src / network / networkd-link-bus.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
e331e246 2
b5efdb8a 3#include "alloc-util.h"
a879e1a4 4#include "bus-common-errors.h"
cf0fbc49 5#include "bus-util.h"
e331e246 6#include "networkd-link.h"
23f53b99 7#include "networkd-manager.h"
6bedfcbb 8#include "parse-util.h"
cf0fbc49 9#include "strv.h"
e331e246
TG
10
11static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_operational_state, link_operstate, LinkOperationalState);
12static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_administrative_state, link_state, LinkState);
13
a879e1a4
YW
14static int property_get_bit_rates(
15 sd_bus *bus,
16 const char *path,
17 const char *interface,
18 const char *property,
19 sd_bus_message *reply,
20 void *userdata,
21 sd_bus_error *error) {
22
23 Link *link = userdata;
24 Manager *manager;
25 double tx, rx, interval_sec;
26
27 assert(bus);
28 assert(reply);
29 assert(userdata);
30
31 manager = link->manager;
32
33 if (!manager->use_speed_meter)
34 return sd_bus_error_set(error, BUS_ERROR_SPEED_METER_INACTIVE, "Speed meter is disabled.");
35
36 if (manager->speed_meter_usec_old == 0)
37 return sd_bus_error_set(error, BUS_ERROR_SPEED_METER_INACTIVE, "Speed meter is not active.");
38
39 if (!link->stats_updated)
40 return sd_bus_error_set(error, BUS_ERROR_SPEED_METER_INACTIVE, "Failed to measure bit-rates.");
41
42 assert(manager->speed_meter_usec_new > manager->speed_meter_usec_old);
43 interval_sec = (double) (manager->speed_meter_usec_new - manager->speed_meter_usec_old) / USEC_PER_SEC;
44
45 if (link->stats_new.tx_bytes > link->stats_old.tx_bytes)
46 tx = (link->stats_new.tx_bytes - link->stats_old.tx_bytes) / interval_sec;
47 else
48 tx = (UINT64_MAX - (link->stats_old.tx_bytes - link->stats_new.tx_bytes)) / interval_sec;
49
50 if (link->stats_new.rx_bytes > link->stats_old.rx_bytes)
51 rx = (link->stats_new.rx_bytes - link->stats_old.rx_bytes) / interval_sec;
52 else
53 rx = (UINT64_MAX - (link->stats_old.rx_bytes - link->stats_new.rx_bytes)) / interval_sec;
54
55 return sd_bus_message_append(reply, "(dd)", tx, rx);
56}
57
e331e246
TG
58const sd_bus_vtable link_vtable[] = {
59 SD_BUS_VTABLE_START(0),
60
61 SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state, offsetof(Link, operstate), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
62 SD_BUS_PROPERTY("AdministrativeState", "s", property_get_administrative_state, offsetof(Link, state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
a879e1a4 63 SD_BUS_PROPERTY("BitRates", "(dd)", property_get_bit_rates, 0, 0),
e331e246
TG
64
65 SD_BUS_VTABLE_END
66};
67
68static char *link_bus_path(Link *link) {
c8f5edea 69 _cleanup_free_ char *ifindex = NULL;
e331e246 70 char *p;
c8f5edea 71 int r;
e331e246
TG
72
73 assert(link);
74 assert(link->ifindex > 0);
75
c8f5edea
TG
76 if (asprintf(&ifindex, "%d", link->ifindex) < 0)
77 return NULL;
78
79 r = sd_bus_path_encode("/org/freedesktop/network1/link", ifindex, &p);
80 if (r < 0)
02f50053 81 return NULL;
e331e246
TG
82
83 return p;
84}
85
86int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
87 _cleanup_strv_free_ char **l = NULL;
88 Manager *m = userdata;
fdb90ac6 89 unsigned c = 0;
e331e246
TG
90 Link *link;
91 Iterator i;
e331e246
TG
92
93 assert(bus);
94 assert(path);
95 assert(m);
96 assert(nodes);
97
fdb90ac6
LP
98 l = new0(char*, hashmap_size(m->links) + 1);
99 if (!l)
100 return -ENOMEM;
101
e331e246
TG
102 HASHMAP_FOREACH(link, m->links, i) {
103 char *p;
104
105 p = link_bus_path(link);
106 if (!p)
107 return -ENOMEM;
108
fdb90ac6 109 l[c++] = p;
e331e246
TG
110 }
111
fdb90ac6 112 l[c] = NULL;
ae2a15bc 113 *nodes = TAKE_PTR(l);
e331e246
TG
114
115 return 1;
116}
117
118int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
c8f5edea 119 _cleanup_free_ char *identifier = NULL;
e331e246
TG
120 Manager *m = userdata;
121 Link *link;
122 int ifindex, r;
123
124 assert(bus);
125 assert(path);
126 assert(interface);
127 assert(m);
128 assert(found);
129
c8f5edea 130 r = sd_bus_path_decode(path, "/org/freedesktop/network1/link", &identifier);
a7f6e7e8 131 if (r <= 0)
c8f5edea
TG
132 return 0;
133
6ad623a3 134 r = parse_ifindex(identifier, &ifindex);
1c111814 135 if (r < 0)
e331e246
TG
136 return 0;
137
138 r = link_get(m, ifindex, &link);
139 if (r < 0)
140 return 0;
141
142 *found = link;
143
144 return 1;
145}
146
147int link_send_changed(Link *link, const char *property, ...) {
148 _cleanup_free_ char *p = NULL;
149 char **l;
150
151 assert(link);
152 assert(link->manager);
153
4852e159
TG
154 if (!link->manager->bus)
155 return 0; /* replace with assert when we have kdbus */
156
e331e246
TG
157 l = strv_from_stdarg_alloca(property);
158
159 p = link_bus_path(link);
160 if (!p)
161 return -ENOMEM;
162
163 return sd_bus_emit_properties_changed_strv(
164 link->manager->bus,
165 p,
166 "org.freedesktop.network1.Link",
167 l);
168}