]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
e331e246 | 2 | |
071712b2 | 3 | #include <net/if.h> |
f39dbf28 | 4 | #include <netinet/in.h> |
7f06b3e1 | 5 | #include <sys/capability.h> |
071712b2 | 6 | |
b5efdb8a | 7 | #include "alloc-util.h" |
071712b2 | 8 | #include "bus-common-errors.h" |
7695e2cb | 9 | #include "bus-message-util.h" |
269e4d2d | 10 | #include "bus-polkit.h" |
7f3c07ad | 11 | #include "networkd-link-bus.h" |
37d577c8 | 12 | #include "networkd-link.h" |
79a59fa5 | 13 | #include "networkd-manager-bus.h" |
23f53b99 | 14 | #include "networkd-manager.h" |
37d577c8 | 15 | #include "path-util.h" |
fc2ea97a | 16 | #include "socket-netlink.h" |
51517f9e | 17 | #include "strv.h" |
7f06b3e1 | 18 | #include "user-util.h" |
e331e246 | 19 | |
37d577c8 YW |
20 | static int method_list_links(sd_bus_message *message, void *userdata, sd_bus_error *error) { |
21 | _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; | |
22 | Manager *manager = userdata; | |
37d577c8 YW |
23 | Link *link; |
24 | int r; | |
25 | ||
26 | r = sd_bus_message_new_method_return(message, &reply); | |
27 | if (r < 0) | |
28 | return r; | |
29 | ||
30 | r = sd_bus_message_open_container(reply, 'a', "(iso)"); | |
31 | if (r < 0) | |
32 | return r; | |
33 | ||
90e74a66 | 34 | HASHMAP_FOREACH(link, manager->links) { |
37d577c8 YW |
35 | _cleanup_free_ char *path = NULL; |
36 | ||
37 | path = link_bus_path(link); | |
38 | if (!path) | |
39 | return -ENOMEM; | |
40 | ||
41 | r = sd_bus_message_append( | |
42 | reply, "(iso)", | |
43 | link->ifindex, | |
44 | link->ifname, | |
45 | empty_to_root(path)); | |
46 | if (r < 0) | |
47 | return r; | |
48 | } | |
49 | ||
50 | r = sd_bus_message_close_container(reply); | |
51 | if (r < 0) | |
52 | return r; | |
53 | ||
54 | return sd_bus_send(NULL, reply, NULL); | |
55 | } | |
56 | ||
071712b2 YW |
57 | static int method_get_link_by_name(sd_bus_message *message, void *userdata, sd_bus_error *error) { |
58 | _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; | |
59 | _cleanup_free_ char *path = NULL; | |
60 | Manager *manager = userdata; | |
61 | const char *name; | |
62 | int index, r; | |
63 | Link *link; | |
64 | ||
65 | r = sd_bus_message_read(message, "s", &name); | |
66 | if (r < 0) | |
67 | return r; | |
68 | ||
fc2ea97a ZJS |
69 | index = resolve_ifname(&manager->rtnl, name); |
70 | if (index < 0) | |
71 | return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_LINK, "Link %s cannot be resolved", name); | |
071712b2 YW |
72 | |
73 | link = hashmap_get(manager->links, INT_TO_PTR(index)); | |
74 | if (!link) | |
75 | return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_LINK, "Link %s not known", name); | |
76 | ||
77 | r = sd_bus_message_new_method_return(message, &reply); | |
78 | if (r < 0) | |
79 | return r; | |
80 | ||
81 | path = link_bus_path(link); | |
82 | if (!path) | |
83 | return -ENOMEM; | |
84 | ||
85 | r = sd_bus_message_append(reply, "io", link->ifindex, empty_to_root(path)); | |
86 | if (r < 0) | |
87 | return r; | |
88 | ||
89 | return sd_bus_send(NULL, reply, NULL); | |
90 | } | |
91 | ||
92 | static int method_get_link_by_index(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
93 | _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; | |
94 | _cleanup_free_ char *path = NULL; | |
95 | Manager *manager = userdata; | |
7695e2cb | 96 | int ifindex, r; |
071712b2 | 97 | Link *link; |
071712b2 | 98 | |
7695e2cb | 99 | r = bus_message_read_ifindex(message, error, &ifindex); |
071712b2 YW |
100 | if (r < 0) |
101 | return r; | |
102 | ||
7695e2cb | 103 | link = hashmap_get(manager->links, INT_TO_PTR(ifindex)); |
071712b2 | 104 | if (!link) |
7695e2cb | 105 | return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_LINK, "Link %i not known", ifindex); |
071712b2 YW |
106 | |
107 | r = sd_bus_message_new_method_return(message, &reply); | |
108 | if (r < 0) | |
109 | return r; | |
110 | ||
111 | path = link_bus_path(link); | |
112 | if (!path) | |
113 | return -ENOMEM; | |
114 | ||
115 | r = sd_bus_message_append(reply, "so", link->ifname, empty_to_root(path)); | |
116 | if (r < 0) | |
117 | return r; | |
118 | ||
119 | return sd_bus_send(NULL, reply, NULL); | |
120 | } | |
121 | ||
15761549 YW |
122 | static int call_link_method(Manager *m, sd_bus_message *message, sd_bus_message_handler_t handler, sd_bus_error *error) { |
123 | int ifindex, r; | |
124 | Link *l; | |
125 | ||
126 | assert(m); | |
127 | assert(message); | |
128 | assert(handler); | |
129 | ||
7695e2cb | 130 | r = bus_message_read_ifindex(message, error, &ifindex); |
15761549 YW |
131 | if (r < 0) |
132 | return r; | |
133 | ||
15761549 YW |
134 | l = hashmap_get(m->links, INT_TO_PTR(ifindex)); |
135 | if (!l) | |
136 | return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_LINK, "Link %i not known", ifindex); | |
137 | ||
138 | return handler(message, l, error); | |
139 | } | |
140 | ||
141 | static int bus_method_set_link_ntp_servers(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
142 | return call_link_method(userdata, message, bus_link_method_set_ntp_servers, error); | |
143 | } | |
144 | ||
145 | static int bus_method_set_link_dns_servers(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
146 | return call_link_method(userdata, message, bus_link_method_set_dns_servers, error); | |
147 | } | |
148 | ||
4e11ddfd YW |
149 | static int bus_method_set_link_dns_servers_ex(sd_bus_message *message, void *userdata, sd_bus_error *error) { |
150 | return call_link_method(userdata, message, bus_link_method_set_dns_servers_ex, error); | |
151 | } | |
152 | ||
15761549 YW |
153 | static int bus_method_set_link_domains(sd_bus_message *message, void *userdata, sd_bus_error *error) { |
154 | return call_link_method(userdata, message, bus_link_method_set_domains, error); | |
155 | } | |
156 | ||
157 | static int bus_method_set_link_default_route(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
158 | return call_link_method(userdata, message, bus_link_method_set_default_route, error); | |
159 | } | |
160 | ||
161 | static int bus_method_set_link_llmnr(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
162 | return call_link_method(userdata, message, bus_link_method_set_llmnr, error); | |
163 | } | |
164 | ||
165 | static int bus_method_set_link_mdns(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
166 | return call_link_method(userdata, message, bus_link_method_set_mdns, error); | |
167 | } | |
168 | ||
169 | static int bus_method_set_link_dns_over_tls(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
170 | return call_link_method(userdata, message, bus_link_method_set_dns_over_tls, error); | |
171 | } | |
172 | ||
173 | static int bus_method_set_link_dnssec(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
174 | return call_link_method(userdata, message, bus_link_method_set_dnssec, error); | |
175 | } | |
176 | ||
177 | static int bus_method_set_link_dnssec_negative_trust_anchors(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
178 | return call_link_method(userdata, message, bus_link_method_set_dnssec_negative_trust_anchors, error); | |
179 | } | |
180 | ||
181 | static int bus_method_revert_link_ntp(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
182 | return call_link_method(userdata, message, bus_link_method_revert_ntp, error); | |
183 | } | |
184 | ||
185 | static int bus_method_revert_link_dns(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
186 | return call_link_method(userdata, message, bus_link_method_revert_dns, error); | |
187 | } | |
188 | ||
ae65d7db YW |
189 | static int bus_method_renew_link(sd_bus_message *message, void *userdata, sd_bus_error *error) { |
190 | return call_link_method(userdata, message, bus_link_method_renew, error); | |
191 | } | |
192 | ||
90867f6a SS |
193 | static int bus_method_force_renew_link(sd_bus_message *message, void *userdata, sd_bus_error *error) { |
194 | return call_link_method(userdata, message, bus_link_method_force_renew, error); | |
195 | } | |
196 | ||
99b8517c YW |
197 | static int bus_method_reconfigure_link(sd_bus_message *message, void *userdata, sd_bus_error *error) { |
198 | return call_link_method(userdata, message, bus_link_method_reconfigure, error); | |
199 | } | |
200 | ||
7f06b3e1 YW |
201 | static int bus_method_reload(sd_bus_message *message, void *userdata, sd_bus_error *error) { |
202 | Manager *manager = userdata; | |
7f06b3e1 YW |
203 | Link *link; |
204 | int r; | |
205 | ||
206 | r = bus_verify_polkit_async(message, CAP_NET_ADMIN, | |
207 | "org.freedesktop.network1.reload", | |
208 | NULL, true, UID_INVALID, | |
209 | &manager->polkit_registry, error); | |
210 | if (r < 0) | |
211 | return r; | |
212 | if (r == 0) | |
213 | return 1; /* Polkit will call us back */ | |
214 | ||
e272b621 YW |
215 | r = netdev_load(manager, true); |
216 | if (r < 0) | |
217 | return r; | |
218 | ||
7f06b3e1 YW |
219 | r = network_reload(manager); |
220 | if (r < 0) | |
221 | return r; | |
222 | ||
90e74a66 | 223 | HASHMAP_FOREACH(link, manager->links) { |
99b8517c | 224 | r = link_reconfigure(link, false); |
7f06b3e1 YW |
225 | if (r < 0) |
226 | return r; | |
227 | } | |
228 | ||
229 | return sd_bus_reply_method_return(message, NULL); | |
230 | } | |
231 | ||
e331e246 TG |
232 | const sd_bus_vtable manager_vtable[] = { |
233 | SD_BUS_VTABLE_START(0), | |
234 | ||
235 | SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state, offsetof(Manager, operational_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), | |
7f3c07ad YW |
236 | SD_BUS_PROPERTY("CarrierState", "s", property_get_carrier_state, offsetof(Manager, carrier_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), |
237 | SD_BUS_PROPERTY("AddressState", "s", property_get_address_state, offsetof(Manager, address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), | |
8430841b L |
238 | SD_BUS_PROPERTY("IPv4AddressState", "s", property_get_address_state, offsetof(Manager, ipv4_address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), |
239 | SD_BUS_PROPERTY("IPv6AddressState", "s", property_get_address_state, offsetof(Manager, ipv6_address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), | |
e331e246 | 240 | |
23c32ff8 YW |
241 | SD_BUS_METHOD_WITH_ARGS("ListLinks", |
242 | SD_BUS_NO_ARGS, | |
243 | SD_BUS_RESULT("a(iso)", links), | |
244 | method_list_links, | |
245 | SD_BUS_VTABLE_UNPRIVILEGED), | |
246 | SD_BUS_METHOD_WITH_ARGS("GetLinkByName", | |
247 | SD_BUS_ARGS("s", name), | |
248 | SD_BUS_RESULT("i", ifindex, "o", path), | |
249 | method_get_link_by_name, | |
250 | SD_BUS_VTABLE_UNPRIVILEGED), | |
251 | SD_BUS_METHOD_WITH_ARGS("GetLinkByIndex", | |
252 | SD_BUS_ARGS("i", ifindex), | |
253 | SD_BUS_RESULT("s", name, "o", path), | |
254 | method_get_link_by_index, | |
255 | SD_BUS_VTABLE_UNPRIVILEGED), | |
256 | SD_BUS_METHOD_WITH_ARGS("SetLinkNTP", | |
257 | SD_BUS_ARGS("i", ifindex, "as", servers), | |
258 | SD_BUS_NO_RESULT, | |
259 | bus_method_set_link_ntp_servers, | |
260 | SD_BUS_VTABLE_UNPRIVILEGED), | |
261 | SD_BUS_METHOD_WITH_ARGS("SetLinkDNS", | |
262 | SD_BUS_ARGS("i", ifindex, "a(iay)", addresses), | |
263 | SD_BUS_NO_RESULT, | |
264 | bus_method_set_link_dns_servers, | |
265 | SD_BUS_VTABLE_UNPRIVILEGED), | |
266 | SD_BUS_METHOD_WITH_ARGS("SetLinkDNSEx", | |
267 | SD_BUS_ARGS("i", ifindex, "a(iayqs)", addresses), | |
268 | SD_BUS_NO_RESULT, | |
269 | bus_method_set_link_dns_servers_ex, | |
270 | SD_BUS_VTABLE_UNPRIVILEGED), | |
271 | SD_BUS_METHOD_WITH_ARGS("SetLinkDomains", | |
272 | SD_BUS_ARGS("i", ifindex, "a(sb)", domains), | |
273 | SD_BUS_NO_RESULT, | |
274 | bus_method_set_link_domains, | |
275 | SD_BUS_VTABLE_UNPRIVILEGED), | |
276 | SD_BUS_METHOD_WITH_ARGS("SetLinkDefaultRoute", | |
277 | SD_BUS_ARGS("i", ifindex, "b", enable), | |
278 | SD_BUS_NO_RESULT, | |
279 | bus_method_set_link_default_route, | |
280 | SD_BUS_VTABLE_UNPRIVILEGED), | |
281 | SD_BUS_METHOD_WITH_ARGS("SetLinkLLMNR", | |
282 | SD_BUS_ARGS("i", ifindex, "s", mode), | |
283 | SD_BUS_NO_RESULT, | |
284 | bus_method_set_link_llmnr, | |
285 | SD_BUS_VTABLE_UNPRIVILEGED), | |
286 | SD_BUS_METHOD_WITH_ARGS("SetLinkMulticastDNS", | |
287 | SD_BUS_ARGS("i", ifindex, "s", mode), | |
288 | SD_BUS_NO_RESULT, | |
289 | bus_method_set_link_mdns, | |
290 | SD_BUS_VTABLE_UNPRIVILEGED), | |
291 | SD_BUS_METHOD_WITH_ARGS("SetLinkDNSOverTLS", | |
292 | SD_BUS_ARGS("i", ifindex, "s", mode), | |
293 | SD_BUS_NO_RESULT, | |
294 | bus_method_set_link_dns_over_tls, | |
295 | SD_BUS_VTABLE_UNPRIVILEGED), | |
296 | SD_BUS_METHOD_WITH_ARGS("SetLinkDNSSEC", | |
297 | SD_BUS_ARGS("i", ifindex, "s", mode), | |
298 | SD_BUS_NO_RESULT, | |
299 | bus_method_set_link_dnssec, | |
300 | SD_BUS_VTABLE_UNPRIVILEGED), | |
301 | SD_BUS_METHOD_WITH_ARGS("SetLinkDNSSECNegativeTrustAnchors", | |
302 | SD_BUS_ARGS("i", ifindex, "as", names), | |
303 | SD_BUS_NO_RESULT, | |
304 | bus_method_set_link_dnssec_negative_trust_anchors, | |
305 | SD_BUS_VTABLE_UNPRIVILEGED), | |
306 | SD_BUS_METHOD_WITH_ARGS("RevertLinkNTP", | |
307 | SD_BUS_ARGS("i", ifindex), | |
308 | SD_BUS_NO_RESULT, | |
309 | bus_method_revert_link_ntp, | |
310 | SD_BUS_VTABLE_UNPRIVILEGED), | |
311 | SD_BUS_METHOD_WITH_ARGS("RevertLinkDNS", | |
312 | SD_BUS_ARGS("i", ifindex), | |
313 | SD_BUS_NO_RESULT, | |
314 | bus_method_revert_link_dns, | |
315 | SD_BUS_VTABLE_UNPRIVILEGED), | |
316 | SD_BUS_METHOD_WITH_ARGS("RenewLink", | |
317 | SD_BUS_ARGS("i", ifindex), | |
318 | SD_BUS_NO_RESULT, | |
319 | bus_method_renew_link, | |
320 | SD_BUS_VTABLE_UNPRIVILEGED), | |
321 | SD_BUS_METHOD_WITH_ARGS("ForceRenewLink", | |
322 | SD_BUS_ARGS("i", ifindex), | |
323 | SD_BUS_NO_RESULT, | |
324 | bus_method_force_renew_link, | |
325 | SD_BUS_VTABLE_UNPRIVILEGED), | |
326 | SD_BUS_METHOD_WITH_ARGS("ReconfigureLink", | |
327 | SD_BUS_ARGS("i", ifindex), | |
328 | SD_BUS_NO_RESULT, | |
329 | bus_method_reconfigure_link, | |
330 | SD_BUS_VTABLE_UNPRIVILEGED), | |
331 | SD_BUS_METHOD_WITH_ARGS("Reload", | |
332 | SD_BUS_NO_ARGS, | |
333 | SD_BUS_NO_RESULT, | |
334 | bus_method_reload, | |
335 | SD_BUS_VTABLE_UNPRIVILEGED), | |
37d577c8 | 336 | |
e331e246 TG |
337 | SD_BUS_VTABLE_END |
338 | }; | |
339 | ||
46606fdd | 340 | int manager_send_changed_strv(Manager *manager, char **properties) { |
e331e246 | 341 | assert(manager); |
46606fdd | 342 | assert(properties); |
e331e246 | 343 | |
5dbec9bd | 344 | if (sd_bus_is_ready(manager->bus) <= 0) |
46606fdd | 345 | return 0; |
e331e246 TG |
346 | |
347 | return sd_bus_emit_properties_changed_strv( | |
348 | manager->bus, | |
349 | "/org/freedesktop/network1", | |
350 | "org.freedesktop.network1.Manager", | |
46606fdd YW |
351 | properties); |
352 | } |