]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
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" |
e331e246 | 9 | #include "bus-util.h" |
e7bdadb5 | 10 | #include "netlink-util.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" |
51517f9e | 16 | #include "strv.h" |
7f06b3e1 | 17 | #include "user-util.h" |
e331e246 | 18 | |
37d577c8 YW |
19 | static int method_list_links(sd_bus_message *message, void *userdata, sd_bus_error *error) { |
20 | _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; | |
21 | Manager *manager = userdata; | |
22 | Iterator i; | |
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 | ||
34 | HASHMAP_FOREACH(link, manager->links, i) { | |
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 | ||
69 | index = if_nametoindex(name); | |
e7bdadb5 | 70 | if (index <= 0) { |
231d9de1 ZJS |
71 | index = rtnl_resolve_link_alternative_name(&manager->rtnl, name); |
72 | if (index < 0) | |
e7bdadb5 YW |
73 | return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_LINK, "Link %s not known", name); |
74 | } | |
071712b2 YW |
75 | |
76 | link = hashmap_get(manager->links, INT_TO_PTR(index)); | |
77 | if (!link) | |
78 | return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_LINK, "Link %s not known", name); | |
79 | ||
80 | r = sd_bus_message_new_method_return(message, &reply); | |
81 | if (r < 0) | |
82 | return r; | |
83 | ||
84 | path = link_bus_path(link); | |
85 | if (!path) | |
86 | return -ENOMEM; | |
87 | ||
88 | r = sd_bus_message_append(reply, "io", link->ifindex, empty_to_root(path)); | |
89 | if (r < 0) | |
90 | return r; | |
91 | ||
92 | return sd_bus_send(NULL, reply, NULL); | |
93 | } | |
94 | ||
95 | static int method_get_link_by_index(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
96 | _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; | |
97 | _cleanup_free_ char *path = NULL; | |
98 | Manager *manager = userdata; | |
99 | int32_t index; | |
100 | Link *link; | |
101 | int r; | |
102 | ||
103 | r = sd_bus_message_read(message, "i", &index); | |
104 | if (r < 0) | |
105 | return r; | |
106 | ||
107 | link = hashmap_get(manager->links, INT_TO_PTR((int) index)); | |
108 | if (!link) | |
109 | return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_LINK, "Link %" PRIi32 " not known", index); | |
110 | ||
111 | r = sd_bus_message_new_method_return(message, &reply); | |
112 | if (r < 0) | |
113 | return r; | |
114 | ||
115 | path = link_bus_path(link); | |
116 | if (!path) | |
117 | return -ENOMEM; | |
118 | ||
119 | r = sd_bus_message_append(reply, "so", link->ifname, empty_to_root(path)); | |
120 | if (r < 0) | |
121 | return r; | |
122 | ||
123 | return sd_bus_send(NULL, reply, NULL); | |
124 | } | |
125 | ||
15761549 YW |
126 | static int call_link_method(Manager *m, sd_bus_message *message, sd_bus_message_handler_t handler, sd_bus_error *error) { |
127 | int ifindex, r; | |
128 | Link *l; | |
129 | ||
130 | assert(m); | |
131 | assert(message); | |
132 | assert(handler); | |
133 | ||
134 | assert_cc(sizeof(int) == sizeof(int32_t)); | |
135 | r = sd_bus_message_read(message, "i", &ifindex); | |
136 | if (r < 0) | |
137 | return r; | |
138 | ||
139 | if (ifindex <= 0) | |
140 | return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index"); | |
141 | ||
142 | l = hashmap_get(m->links, INT_TO_PTR(ifindex)); | |
143 | if (!l) | |
144 | return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_LINK, "Link %i not known", ifindex); | |
145 | ||
146 | return handler(message, l, error); | |
147 | } | |
148 | ||
149 | static int bus_method_set_link_ntp_servers(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
150 | return call_link_method(userdata, message, bus_link_method_set_ntp_servers, error); | |
151 | } | |
152 | ||
153 | static int bus_method_set_link_dns_servers(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
154 | return call_link_method(userdata, message, bus_link_method_set_dns_servers, error); | |
155 | } | |
156 | ||
157 | static int bus_method_set_link_domains(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
158 | return call_link_method(userdata, message, bus_link_method_set_domains, error); | |
159 | } | |
160 | ||
161 | static int bus_method_set_link_default_route(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
162 | return call_link_method(userdata, message, bus_link_method_set_default_route, error); | |
163 | } | |
164 | ||
165 | static int bus_method_set_link_llmnr(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
166 | return call_link_method(userdata, message, bus_link_method_set_llmnr, error); | |
167 | } | |
168 | ||
169 | static int bus_method_set_link_mdns(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
170 | return call_link_method(userdata, message, bus_link_method_set_mdns, error); | |
171 | } | |
172 | ||
173 | static int bus_method_set_link_dns_over_tls(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
174 | return call_link_method(userdata, message, bus_link_method_set_dns_over_tls, error); | |
175 | } | |
176 | ||
177 | static int bus_method_set_link_dnssec(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
178 | return call_link_method(userdata, message, bus_link_method_set_dnssec, error); | |
179 | } | |
180 | ||
181 | static int bus_method_set_link_dnssec_negative_trust_anchors(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
182 | return call_link_method(userdata, message, bus_link_method_set_dnssec_negative_trust_anchors, error); | |
183 | } | |
184 | ||
185 | static int bus_method_revert_link_ntp(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
186 | return call_link_method(userdata, message, bus_link_method_revert_ntp, error); | |
187 | } | |
188 | ||
189 | static int bus_method_revert_link_dns(sd_bus_message *message, void *userdata, sd_bus_error *error) { | |
190 | return call_link_method(userdata, message, bus_link_method_revert_dns, error); | |
191 | } | |
192 | ||
ae65d7db YW |
193 | static int bus_method_renew_link(sd_bus_message *message, void *userdata, sd_bus_error *error) { |
194 | return call_link_method(userdata, message, bus_link_method_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; | |
203 | Iterator i; | |
204 | Link *link; | |
205 | int r; | |
206 | ||
207 | r = bus_verify_polkit_async(message, CAP_NET_ADMIN, | |
208 | "org.freedesktop.network1.reload", | |
209 | NULL, true, UID_INVALID, | |
210 | &manager->polkit_registry, error); | |
211 | if (r < 0) | |
212 | return r; | |
213 | if (r == 0) | |
214 | return 1; /* Polkit will call us back */ | |
215 | ||
e272b621 YW |
216 | r = netdev_load(manager, true); |
217 | if (r < 0) | |
218 | return r; | |
219 | ||
7f06b3e1 YW |
220 | r = network_reload(manager); |
221 | if (r < 0) | |
222 | return r; | |
223 | ||
224 | HASHMAP_FOREACH(link, manager->links, i) { | |
99b8517c | 225 | r = link_reconfigure(link, false); |
7f06b3e1 YW |
226 | if (r < 0) |
227 | return r; | |
228 | } | |
229 | ||
230 | return sd_bus_reply_method_return(message, NULL); | |
231 | } | |
232 | ||
e331e246 TG |
233 | const sd_bus_vtable manager_vtable[] = { |
234 | SD_BUS_VTABLE_START(0), | |
235 | ||
236 | SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state, offsetof(Manager, operational_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), | |
7f3c07ad YW |
237 | SD_BUS_PROPERTY("CarrierState", "s", property_get_carrier_state, offsetof(Manager, carrier_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), |
238 | SD_BUS_PROPERTY("AddressState", "s", property_get_address_state, offsetof(Manager, address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), | |
e331e246 | 239 | |
37d577c8 | 240 | SD_BUS_METHOD("ListLinks", NULL, "a(iso)", method_list_links, SD_BUS_VTABLE_UNPRIVILEGED), |
071712b2 YW |
241 | SD_BUS_METHOD("GetLinkByName", "s", "io", method_get_link_by_name, SD_BUS_VTABLE_UNPRIVILEGED), |
242 | SD_BUS_METHOD("GetLinkByIndex", "i", "so", method_get_link_by_index, SD_BUS_VTABLE_UNPRIVILEGED), | |
15761549 YW |
243 | SD_BUS_METHOD("SetLinkNTP", "ias", NULL, bus_method_set_link_ntp_servers, SD_BUS_VTABLE_UNPRIVILEGED), |
244 | SD_BUS_METHOD("SetLinkDNS", "ia(iay)", NULL, bus_method_set_link_dns_servers, SD_BUS_VTABLE_UNPRIVILEGED), | |
245 | SD_BUS_METHOD("SetLinkDomains", "ia(sb)", NULL, bus_method_set_link_domains, SD_BUS_VTABLE_UNPRIVILEGED), | |
246 | SD_BUS_METHOD("SetLinkDefaultRoute", "ib", NULL, bus_method_set_link_default_route, SD_BUS_VTABLE_UNPRIVILEGED), | |
247 | SD_BUS_METHOD("SetLinkLLMNR", "is", NULL, bus_method_set_link_llmnr, SD_BUS_VTABLE_UNPRIVILEGED), | |
248 | SD_BUS_METHOD("SetLinkMulticastDNS", "is", NULL, bus_method_set_link_mdns, SD_BUS_VTABLE_UNPRIVILEGED), | |
249 | SD_BUS_METHOD("SetLinkDNSOverTLS", "is", NULL, bus_method_set_link_dns_over_tls, SD_BUS_VTABLE_UNPRIVILEGED), | |
250 | SD_BUS_METHOD("SetLinkDNSSEC", "is", NULL, bus_method_set_link_dnssec, SD_BUS_VTABLE_UNPRIVILEGED), | |
251 | SD_BUS_METHOD("SetLinkDNSSECNegativeTrustAnchors", "ias", NULL, bus_method_set_link_dnssec_negative_trust_anchors, SD_BUS_VTABLE_UNPRIVILEGED), | |
252 | SD_BUS_METHOD("RevertLinkNTP", "i", NULL, bus_method_revert_link_ntp, SD_BUS_VTABLE_UNPRIVILEGED), | |
253 | SD_BUS_METHOD("RevertLinkDNS", "i", NULL, bus_method_revert_link_dns, SD_BUS_VTABLE_UNPRIVILEGED), | |
ae65d7db | 254 | SD_BUS_METHOD("RenewLink", "i", NULL, bus_method_renew_link, SD_BUS_VTABLE_UNPRIVILEGED), |
99b8517c | 255 | SD_BUS_METHOD("ReconfigureLink", "i", NULL, bus_method_reconfigure_link, SD_BUS_VTABLE_UNPRIVILEGED), |
7f06b3e1 | 256 | SD_BUS_METHOD("Reload", NULL, NULL, bus_method_reload, SD_BUS_VTABLE_UNPRIVILEGED), |
37d577c8 | 257 | |
e331e246 TG |
258 | SD_BUS_VTABLE_END |
259 | }; | |
260 | ||
46606fdd | 261 | int manager_send_changed_strv(Manager *manager, char **properties) { |
e331e246 | 262 | assert(manager); |
46606fdd | 263 | assert(properties); |
e331e246 | 264 | |
4852e159 | 265 | if (!manager->bus) |
46606fdd | 266 | return 0; |
e331e246 TG |
267 | |
268 | return sd_bus_emit_properties_changed_strv( | |
269 | manager->bus, | |
270 | "/org/freedesktop/network1", | |
271 | "org.freedesktop.network1.Manager", | |
46606fdd YW |
272 | properties); |
273 | } |