chiark / gitweb /
networkd: link - improve refcounting
[elogind.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 static int setup_default_address_pool(Manager *m) {
79         AddressPool *p;
80         int r;
81
82         assert(m);
83
84         /* Add in the well-known private address ranges. */
85
86         r = address_pool_new_from_string(m, &p, AF_INET6, "fc00::", 7);
87         if (r < 0)
88                 return r;
89
90         r = address_pool_new_from_string(m, &p, AF_INET, "192.168.0.0", 16);
91         if (r < 0)
92                 return r;
93
94         r = address_pool_new_from_string(m, &p, AF_INET, "172.16.0.0", 12);
95         if (r < 0)
96                 return r;
97
98         r = address_pool_new_from_string(m, &p, AF_INET, "10.0.0.0", 8);
99         if (r < 0)
100                 return r;
101
102         return 0;
103 }
104
105 int manager_new(Manager **ret) {
106         _cleanup_manager_free_ Manager *m = NULL;
107         int r;
108
109         m = new0(Manager, 1);
110         if (!m)
111                 return -ENOMEM;
112
113         m->state_file = strdup("/run/systemd/netif/state");
114         if (!m->state_file)
115                 return -ENOMEM;
116
117         r = sd_event_default(&m->event);
118         if (r < 0)
119                 return r;
120
121         sd_event_set_watchdog(m->event, true);
122
123         r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR,
124                          RTNLGRP_IPV6_IFADDR);
125         if (r < 0)
126                 return r;
127
128         r = sd_bus_default_system(&m->bus);
129         if (r < 0 && r != -ENOENT) /* TODO: drop when we can rely on kdbus */
130                 return r;
131
132         r = setup_signals(m);
133         if (r < 0)
134                 return r;
135
136         /* udev does not initialize devices inside containers,
137          * so we rely on them being already initialized before
138          * entering the container */
139         if (detect_container(NULL) <= 0) {
140                 m->udev = udev_new();
141                 if (!m->udev)
142                         return -ENOMEM;
143
144                 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
145                 if (!m->udev_monitor)
146                         return -ENOMEM;
147         }
148
149         m->links = hashmap_new(uint64_hash_func, uint64_compare_func);
150         if (!m->links)
151                 return -ENOMEM;
152
153         m->netdevs = hashmap_new(string_hash_func, string_compare_func);
154         if (!m->netdevs)
155                 return -ENOMEM;
156
157         LIST_HEAD_INIT(m->networks);
158
159         r = setup_default_address_pool(m);
160         if (r < 0)
161                 return r;
162
163         *ret = m;
164         m = NULL;
165
166         return 0;
167 }
168
169 void manager_free(Manager *m) {
170         Network *network;
171         NetDev *netdev;
172         Link *link;
173         AddressPool *pool;
174
175         if (!m)
176                 return;
177
178         free(m->state_file);
179
180         udev_monitor_unref(m->udev_monitor);
181         udev_unref(m->udev);
182         sd_bus_unref(m->bus);
183         sd_event_source_unref(m->udev_event_source);
184         sd_event_source_unref(m->sigterm_event_source);
185         sd_event_source_unref(m->sigint_event_source);
186         sd_event_unref(m->event);
187
188         while ((link = hashmap_first(m->links)))
189                 link_unref(link);
190         hashmap_free(m->links);
191
192         while ((network = m->networks))
193                 network_free(network);
194
195         while ((netdev = hashmap_first(m->netdevs)))
196                 netdev_unref(netdev);
197         hashmap_free(m->netdevs);
198
199         while ((pool = m->address_pools))
200                 address_pool_free(pool);
201
202         sd_rtnl_unref(m->rtnl);
203
204         free(m);
205 }
206
207 int manager_load_config(Manager *m) {
208         int r;
209
210         /* update timestamp */
211         paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
212
213         r = netdev_load(m);
214         if (r < 0)
215                 return r;
216
217         r = network_load(m);
218         if (r < 0)
219                 return r;
220
221         return 0;
222 }
223
224 bool manager_should_reload(Manager *m) {
225         return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
226 }
227
228 static int manager_udev_process_link(Manager *m, struct udev_device *device) {
229         Link *link = NULL;
230         int r, ifindex;
231
232         assert(m);
233         assert(device);
234
235         if (!streq_ptr(udev_device_get_action(device), "add"))
236                 return 0;
237
238         ifindex = udev_device_get_ifindex(device);
239         if (ifindex <= 0) {
240                 log_debug("ignoring udev ADD event for device with invalid ifindex");
241                 return 0;
242         }
243
244         r = link_get(m, ifindex, &link);
245         if (r == -ENODEV)
246                 return 0;
247         else if (r < 0)
248                 return r;
249
250         r = link_initialized(link, device);
251         if (r < 0)
252                 return r;
253
254         return 0;
255 }
256
257 static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
258         Manager *m = userdata;
259         Link *link = NULL;
260         NetDev *netdev = NULL;
261         uint16_t type;
262         char *name;
263         int r, ifindex;
264
265         assert(rtnl);
266         assert(message);
267         assert(m);
268
269         r = sd_rtnl_message_get_type(message, &type);
270         if (r < 0) {
271                 log_warning("rtnl: could not get message type");
272                 return 0;
273         }
274
275         r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
276         if (r < 0 || ifindex <= 0) {
277                 log_warning("rtnl: received link message without valid ifindex");
278                 return 0;
279         } else
280                 link_get(m, ifindex, &link);
281
282         r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name);
283         if (r < 0 || !name) {
284                 log_warning("rtnl: received link message without valid ifname");
285                 return 0;
286         } else
287                 netdev_get(m, name, &netdev);
288
289         switch (type) {
290         case RTM_NEWLINK:
291                 if (!link) {
292                         /* link is new, so add it */
293                         r = link_add(m, message, &link);
294                         if (r < 0) {
295                                 log_debug("could not add new link");
296                                 return 0;
297                         }
298                 }
299
300                 if (netdev) {
301                         /* netdev exists, so make sure the ifindex matches */
302                         r = netdev_set_ifindex(netdev, message);
303                         if (r < 0) {
304                                 log_debug("could not set ifindex on netdev");
305                                 return 0;
306                         }
307                 }
308
309                 r = link_update(link, message);
310                 if (r < 0)
311                         return 0;
312
313                 break;
314
315         case RTM_DELLINK:
316                 link_drop(link);
317                 netdev_drop(netdev);
318
319                 break;
320
321         default:
322                 assert_not_reached("Received invalid RTNL message type.");
323         }
324
325         return 1;
326 }
327
328 int manager_rtnl_enumerate_links(Manager *m) {
329         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
330         sd_rtnl_message *link;
331         int r, k;
332
333         assert(m);
334         assert(m->rtnl);
335
336         r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
337         if (r < 0)
338                 return r;
339
340         r = sd_rtnl_message_request_dump(req, true);
341         if (r < 0)
342                 return r;
343
344         r = sd_rtnl_call(m->rtnl, req, 0, &reply);
345         if (r < 0)
346                 return r;
347
348         for (link = reply; link; link = sd_rtnl_message_next(link)) {
349                 uint16_t type;
350
351                 k = sd_rtnl_message_get_type(link, &type);
352                 if (k < 0)
353                         return k;
354
355                 if (type != RTM_NEWLINK)
356                         continue;
357
358                 k = manager_rtnl_process_link(m->rtnl, link, m);
359                 if (k < 0)
360                         r = k;
361         }
362
363         return r;
364 }
365
366 static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
367         Manager *m = userdata;
368         struct udev_monitor *monitor = m->udev_monitor;
369         _cleanup_udev_device_unref_ struct udev_device *device = NULL;
370
371         device = udev_monitor_receive_device(monitor);
372         if (!device)
373                 return -ENOMEM;
374
375         manager_udev_process_link(m, device);
376         return 0;
377 }
378
379 int manager_udev_listen(Manager *m) {
380         int r;
381
382         if (detect_container(NULL) > 0)
383                 return 0;
384
385         assert(m->udev_monitor);
386
387         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL);
388         if (r < 0) {
389                 log_error("Could not add udev monitor filter: %s", strerror(-r));
390                 return r;
391         }
392
393         r = udev_monitor_enable_receiving(m->udev_monitor);
394         if (r < 0) {
395                 log_error("Could not enable udev monitor");
396                 return r;
397         }
398
399         r = sd_event_add_io(m->event,
400                         &m->udev_event_source,
401                         udev_monitor_get_fd(m->udev_monitor),
402                         EPOLLIN, manager_dispatch_link_udev,
403                         m);
404         if (r < 0)
405                 return r;
406
407         return 0;
408 }
409
410 int manager_rtnl_listen(Manager *m) {
411         int r;
412
413         assert(m);
414
415         r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
416         if (r < 0)
417                 return r;
418
419         r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
420         if (r < 0)
421                 return r;
422
423         r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
424         if (r < 0)
425                 return r;
426
427         r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &link_rtnl_process_address, m);
428         if (r < 0)
429                 return r;
430
431         r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &link_rtnl_process_address, m);
432         if (r < 0)
433                 return r;
434
435         return 0;
436 }
437
438 int manager_bus_listen(Manager *m) {
439         int r;
440
441         assert(m->event);
442
443         if (!m->bus) /* TODO: drop when we can rely on kdbus */
444                 return 0;
445
446         r = sd_bus_attach_event(m->bus, m->event, 0);
447         if (r < 0)
448                 return r;
449
450         return 0;
451 }
452
453 int manager_save(Manager *m) {
454         Link *link;
455         Iterator i;
456         _cleanup_free_ char *temp_path = NULL;
457         _cleanup_fclose_ FILE *f = NULL;
458         LinkOperationalState operstate = LINK_OPERSTATE_UNKNOWN;
459         const char *operstate_str;
460         int r;
461
462         assert(m);
463         assert(m->state_file);
464
465         HASHMAP_FOREACH(link, m->links, i) {
466                 if (link->flags & IFF_LOOPBACK)
467                         continue;
468
469                 if (link->operstate > operstate)
470                         operstate = link->operstate;
471         }
472
473         operstate_str = link_operstate_to_string(operstate);
474         assert(operstate_str);
475
476         r = fopen_temporary(m->state_file, &f, &temp_path);
477         if (r < 0)
478                 goto finish;
479
480         fchmod(fileno(f), 0644);
481
482         fprintf(f,
483                 "# This is private data. Do not parse.\n"
484                 "OPER_STATE=%s\n", operstate_str);
485
486         fflush(f);
487
488         if (ferror(f) || rename(temp_path, m->state_file) < 0) {
489                 r = -errno;
490                 unlink(m->state_file);
491                 unlink(temp_path);
492         }
493
494 finish:
495         if (r < 0)
496                 log_error("Failed to save network state to %s: %s", m->state_file, strerror(-r));
497
498         return r;
499 }
500
501 int manager_address_pool_acquire(Manager *m, unsigned family, unsigned prefixlen, union in_addr_union *found) {
502         AddressPool *p;
503         int r;
504
505         assert(m);
506         assert(prefixlen > 0);
507         assert(found);
508
509         LIST_FOREACH(address_pools, p, m->address_pools) {
510                 if (p->family != family)
511                         continue;
512
513                 r = address_pool_acquire(p, prefixlen, found);
514                 if (r != 0)
515                         return r;
516         }
517
518         return 0;
519 }