chiark / gitweb /
networkd: add address pool support
[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         r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
414         if (r < 0)
415                 return r;
416
417         r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
418         if (r < 0)
419                 return r;
420
421         r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
422         if (r < 0)
423                 return r;
424
425         r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &link_rtnl_process_address, m);
426         if (r < 0)
427                 return r;
428
429         r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &link_rtnl_process_address, m);
430         if (r < 0)
431                 return r;
432
433         return 0;
434 }
435
436 int manager_bus_listen(Manager *m) {
437         int r;
438
439         assert(m->event);
440
441         if (!m->bus) /* TODO: drop when we can rely on kdbus */
442                 return 0;
443
444         r = sd_bus_attach_event(m->bus, m->event, 0);
445         if (r < 0)
446                 return r;
447
448         return 0;
449 }
450
451 int manager_save(Manager *m) {
452         Link *link;
453         Iterator i;
454         _cleanup_free_ char *temp_path = NULL;
455         _cleanup_fclose_ FILE *f = NULL;
456         LinkOperationalState operstate = LINK_OPERSTATE_UNKNOWN;
457         const char *operstate_str;
458         int r;
459
460         assert(m);
461         assert(m->state_file);
462
463         HASHMAP_FOREACH(link, m->links, i) {
464                 if (link->flags & IFF_LOOPBACK)
465                         continue;
466
467                 if (link->operstate > operstate)
468                         operstate = link->operstate;
469         }
470
471         operstate_str = link_operstate_to_string(operstate);
472         assert(operstate_str);
473
474         r = fopen_temporary(m->state_file, &f, &temp_path);
475         if (r < 0)
476                 goto finish;
477
478         fchmod(fileno(f), 0644);
479
480         fprintf(f,
481                 "# This is private data. Do not parse.\n"
482                 "OPER_STATE=%s\n", operstate_str);
483
484         fflush(f);
485
486         if (ferror(f) || rename(temp_path, m->state_file) < 0) {
487                 r = -errno;
488                 unlink(m->state_file);
489                 unlink(temp_path);
490         }
491
492 finish:
493         if (r < 0)
494                 log_error("Failed to save network state to %s: %s", m->state_file, strerror(-r));
495
496         return r;
497 }
498
499 int manager_address_pool_acquire(Manager *m, unsigned family, unsigned prefixlen, union in_addr_union *found) {
500         AddressPool *p;
501         int r;
502
503         assert(m);
504         assert(prefixlen > 0);
505         assert(found);
506
507         LIST_FOREACH(address_pools, p, m->address_pools) {
508                 if (p->family != family)
509                         continue;
510
511                 r = address_pool_acquire(p, prefixlen, found);
512                 if (r != 0)
513                         return r;
514         }
515
516         return 0;
517 }