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