]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-manager.c
networkd: drop CAP_SYS_MODULE
[thirdparty/systemd.git] / src / network / networkd-manager.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2013 Tom Gundersen <teg@jklm.no>
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <sys/socket.h>
23 #include <linux/if.h>
24
25 #include "conf-parser.h"
26 #include "path-util.h"
27 #include "networkd.h"
28 #include "network-internal.h"
29 #include "libudev-private.h"
30 #include "udev-util.h"
31 #include "rtnl-util.h"
32 #include "mkdir.h"
33 #include "virt.h"
34
35 #include "sd-rtnl.h"
36
37 const char* const network_dirs[] = {
38 "/etc/systemd/network",
39 "/run/systemd/network",
40 "/usr/lib/systemd/network",
41 #ifdef HAVE_SPLIT_USR
42 "/lib/systemd/network",
43 #endif
44 NULL};
45
46 static int dispatch_sigterm(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
47 Manager *m = userdata;
48
49 assert(m);
50
51 log_received_signal(LOG_INFO, si);
52
53 sd_event_exit(m->event, 0);
54 return 0;
55 }
56
57 static int setup_signals(Manager *m) {
58 sigset_t mask;
59 int r;
60
61 assert(m);
62
63 assert_se(sigemptyset(&mask) == 0);
64 sigset_add_many(&mask, SIGINT, SIGTERM, -1);
65 assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
66
67 r = sd_event_add_signal(m->event, &m->sigterm_event_source, SIGTERM, dispatch_sigterm, m);
68 if (r < 0)
69 return r;
70
71 r = sd_event_add_signal(m->event, &m->sigint_event_source, SIGINT, dispatch_sigterm, m);
72 if (r < 0)
73 return r;
74
75 return 0;
76 }
77
78 int manager_new(Manager **ret) {
79 _cleanup_manager_free_ Manager *m = NULL;
80 int r;
81
82 m = new0(Manager, 1);
83 if (!m)
84 return -ENOMEM;
85
86 m->state_file = strdup("/run/systemd/network/state");
87 if (!m->state_file)
88 return -ENOMEM;
89
90 r = sd_event_default(&m->event);
91 if (r < 0)
92 return r;
93
94 sd_event_set_watchdog(m->event, true);
95
96 r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR,
97 RTNLGRP_IPV6_IFADDR);
98 if (r < 0)
99 return r;
100
101 r = sd_bus_default_system(&m->bus);
102 if (r < 0 && r != -ENOENT) /* TODO: drop when we can rely on kdbus */
103 return r;
104
105 r = setup_signals(m);
106 if (r < 0)
107 return r;
108
109 /* udev does not initialize devices inside containers,
110 * so we rely on them being already initialized before
111 * entering the container */
112 if (detect_container(NULL) <= 0) {
113 m->udev = udev_new();
114 if (!m->udev)
115 return -ENOMEM;
116
117 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
118 if (!m->udev_monitor)
119 return -ENOMEM;
120 }
121
122 m->links = hashmap_new(uint64_hash_func, uint64_compare_func);
123 if (!m->links)
124 return -ENOMEM;
125
126 m->netdevs = hashmap_new(string_hash_func, string_compare_func);
127 if (!m->netdevs)
128 return -ENOMEM;
129
130 LIST_HEAD_INIT(m->networks);
131
132 *ret = m;
133 m = NULL;
134
135 return 0;
136 }
137
138 void manager_free(Manager *m) {
139 Network *network;
140 NetDev *netdev;
141 Link *link;
142
143 if (!m)
144 return;
145
146 free(m->state_file);
147
148 udev_monitor_unref(m->udev_monitor);
149 udev_unref(m->udev);
150 sd_bus_unref(m->bus);
151 sd_event_source_unref(m->udev_event_source);
152 sd_event_source_unref(m->sigterm_event_source);
153 sd_event_source_unref(m->sigint_event_source);
154 sd_event_unref(m->event);
155
156 while ((link = hashmap_first(m->links)))
157 link_unref(link);
158 hashmap_free(m->links);
159
160 while ((network = m->networks))
161 network_free(network);
162
163 while ((netdev = hashmap_first(m->netdevs)))
164 netdev_unref(netdev);
165 hashmap_free(m->netdevs);
166
167 sd_rtnl_unref(m->rtnl);
168
169 free(m);
170 }
171
172 int manager_load_config(Manager *m) {
173 int r;
174
175 /* update timestamp */
176 paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
177
178 r = netdev_load(m);
179 if (r < 0)
180 return r;
181
182 r = network_load(m);
183 if (r < 0)
184 return r;
185
186 return 0;
187 }
188
189 bool manager_should_reload(Manager *m) {
190 return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
191 }
192
193 static int manager_udev_process_link(Manager *m, struct udev_device *device) {
194 Link *link = NULL;
195 int r, ifindex;
196
197 assert(m);
198 assert(device);
199
200 if (!streq_ptr(udev_device_get_action(device), "add"))
201 return 0;
202
203 ifindex = udev_device_get_ifindex(device);
204 if (ifindex <= 0) {
205 log_debug("ignoring udev ADD event for device with invalid ifindex");
206 return 0;
207 }
208
209 r = link_get(m, ifindex, &link);
210 if (r == -ENODEV)
211 return 0;
212 else if (r < 0)
213 return r;
214
215 r = link_initialized(link, device);
216 if (r < 0)
217 return r;
218
219 return 0;
220 }
221
222 static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
223 Manager *m = userdata;
224 Link *link = NULL;
225 NetDev *netdev = NULL;
226 uint16_t type;
227 char *name;
228 int r, ifindex;
229
230 assert(rtnl);
231 assert(message);
232 assert(m);
233
234 r = sd_rtnl_message_get_type(message, &type);
235 if (r < 0) {
236 log_warning("rtnl: could not get message type");
237 return 0;
238 }
239
240 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
241 if (r < 0 || ifindex <= 0) {
242 log_warning("rtnl: received link message without valid ifindex");
243 return 0;
244 } else
245 link_get(m, ifindex, &link);
246
247 r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name);
248 if (r < 0 || !name) {
249 log_warning("rtnl: received link message without valid ifname");
250 return 0;
251 } else
252 netdev_get(m, name, &netdev);
253
254 switch (type) {
255 case RTM_NEWLINK:
256 if (!link) {
257 /* link is new, so add it */
258 r = link_add(m, message, &link);
259 if (r < 0) {
260 log_debug("could not add new link");
261 return 0;
262 }
263 }
264
265 if (netdev) {
266 /* netdev exists, so make sure the ifindex matches */
267 r = netdev_set_ifindex(netdev, message);
268 if (r < 0) {
269 log_debug("could not set ifindex on netdev");
270 return 0;
271 }
272 }
273
274 r = link_update(link, message);
275 if (r < 0)
276 return 0;
277
278 break;
279
280 case RTM_DELLINK:
281 link_drop(link);
282 netdev_drop(netdev);
283
284 break;
285
286 default:
287 assert_not_reached("Received invalid RTNL message type.");
288 }
289
290 return 1;
291 }
292
293 int manager_rtnl_enumerate_links(Manager *m) {
294 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
295 sd_rtnl_message *link;
296 int r, k;
297
298 assert(m);
299 assert(m->rtnl);
300
301 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
302 if (r < 0)
303 return r;
304
305 r = sd_rtnl_message_request_dump(req, true);
306 if (r < 0)
307 return r;
308
309 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
310 if (r < 0)
311 return r;
312
313 for (link = reply; link; link = sd_rtnl_message_next(link)) {
314 uint16_t type;
315
316 k = sd_rtnl_message_get_type(link, &type);
317 if (k < 0)
318 return k;
319
320 if (type != RTM_NEWLINK)
321 continue;
322
323 k = manager_rtnl_process_link(m->rtnl, link, m);
324 if (k < 0)
325 r = k;
326 }
327
328 return r;
329 }
330
331 static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
332 Manager *m = userdata;
333 struct udev_monitor *monitor = m->udev_monitor;
334 _cleanup_udev_device_unref_ struct udev_device *device = NULL;
335
336 device = udev_monitor_receive_device(monitor);
337 if (!device)
338 return -ENOMEM;
339
340 manager_udev_process_link(m, device);
341 return 0;
342 }
343
344 int manager_udev_listen(Manager *m) {
345 int r;
346
347 if (detect_container(NULL) > 0)
348 return 0;
349
350 assert(m->udev_monitor);
351
352 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL);
353 if (r < 0) {
354 log_error("Could not add udev monitor filter: %s", strerror(-r));
355 return r;
356 }
357
358 r = udev_monitor_enable_receiving(m->udev_monitor);
359 if (r < 0) {
360 log_error("Could not enable udev monitor");
361 return r;
362 }
363
364 r = sd_event_add_io(m->event,
365 &m->udev_event_source,
366 udev_monitor_get_fd(m->udev_monitor),
367 EPOLLIN, manager_dispatch_link_udev,
368 m);
369 if (r < 0)
370 return r;
371
372 return 0;
373 }
374
375 int manager_rtnl_listen(Manager *m) {
376 int r;
377
378 r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
379 if (r < 0)
380 return r;
381
382 r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
383 if (r < 0)
384 return r;
385
386 r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
387 if (r < 0)
388 return r;
389
390 r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &link_rtnl_process_address, m);
391 if (r < 0)
392 return r;
393
394 r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &link_rtnl_process_address, m);
395 if (r < 0)
396 return r;
397
398 return 0;
399 }
400
401 int manager_bus_listen(Manager *m) {
402 int r;
403
404 assert(m->event);
405
406 if (!m->bus) /* TODO: drop when we can rely on kdbus */
407 return 0;
408
409 r = sd_bus_attach_event(m->bus, m->event, 0);
410 if (r < 0)
411 return r;
412
413 return 0;
414 }
415
416 int manager_save(Manager *m) {
417 Link *link;
418 Iterator i;
419 _cleanup_free_ char *temp_path = NULL;
420 _cleanup_fclose_ FILE *f = NULL;
421 LinkOperationalState operstate = LINK_OPERSTATE_UNKNOWN;
422 const char *operstate_str;
423 int r;
424
425 assert(m);
426 assert(m->state_file);
427
428 HASHMAP_FOREACH(link, m->links, i) {
429 if (link->flags & IFF_LOOPBACK)
430 continue;
431
432 if (link->operstate > operstate)
433 operstate = link->operstate;
434 }
435
436 operstate_str = link_operstate_to_string(operstate);
437 assert(operstate_str);
438
439 r = fopen_temporary(m->state_file, &f, &temp_path);
440 if (r < 0)
441 goto finish;
442
443 fchmod(fileno(f), 0644);
444
445 fprintf(f,
446 "# This is private data. Do not parse.\n"
447 "OPER_STATE=%s\n", operstate_str);
448
449 fflush(f);
450
451 if (ferror(f) || rename(temp_path, m->state_file) < 0) {
452 r = -errno;
453 unlink(m->state_file);
454 unlink(temp_path);
455 }
456
457 finish:
458 if (r < 0)
459 log_error("Failed to save network state to %s: %s", m->state_file, strerror(-r));
460
461 return r;
462 }