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