chiark / gitweb /
28d72617dd7bf8384dac2a2a42635690131a6d1a
[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 "networkd-netdev.h"
29 #include "network-internal.h"
30 #include "libudev-private.h"
31 #include "udev-util.h"
32 #include "rtnl-util.h"
33 #include "mkdir.h"
34 #include "virt.h"
35
36 #include "sd-rtnl.h"
37
38 const char* const network_dirs[] = {
39         "/etc/systemd/network",
40         "/run/systemd/network",
41         "/usr/lib/systemd/network",
42 #ifdef HAVE_SPLIT_USR
43         "/lib/systemd/network",
44 #endif
45         NULL};
46
47 static int setup_default_address_pool(Manager *m) {
48         AddressPool *p;
49         int r;
50
51         assert(m);
52
53         /* Add in the well-known private address ranges. */
54
55         r = address_pool_new_from_string(m, &p, AF_INET6, "fc00::", 7);
56         if (r < 0)
57                 return r;
58
59         r = address_pool_new_from_string(m, &p, AF_INET, "192.168.0.0", 16);
60         if (r < 0)
61                 return r;
62
63         r = address_pool_new_from_string(m, &p, AF_INET, "172.16.0.0", 12);
64         if (r < 0)
65                 return r;
66
67         r = address_pool_new_from_string(m, &p, AF_INET, "10.0.0.0", 8);
68         if (r < 0)
69                 return r;
70
71         return 0;
72 }
73
74 int manager_new(Manager **ret) {
75         _cleanup_manager_free_ Manager *m = NULL;
76         int r;
77
78         m = new0(Manager, 1);
79         if (!m)
80                 return -ENOMEM;
81
82         m->state_file = strdup("/run/systemd/netif/state");
83         if (!m->state_file)
84                 return -ENOMEM;
85
86         r = sd_event_default(&m->event);
87         if (r < 0)
88                 return r;
89
90         sd_event_set_watchdog(m->event, true);
91
92         sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
93         sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
94
95         r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR,
96                          RTNLGRP_IPV6_IFADDR);
97         if (r < 0)
98                 return r;
99
100         r = sd_bus_default_system(&m->bus);
101         if (r < 0 && r != -ENOENT) /* TODO: drop when we can rely on kdbus */
102                 return r;
103
104         /* udev does not initialize devices inside containers,
105          * so we rely on them being already initialized before
106          * entering the container */
107         if (detect_container(NULL) <= 0) {
108                 m->udev = udev_new();
109                 if (!m->udev)
110                         return -ENOMEM;
111
112                 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
113                 if (!m->udev_monitor)
114                         return -ENOMEM;
115         }
116
117         m->netdevs = hashmap_new(string_hash_func, string_compare_func);
118         if (!m->netdevs)
119                 return -ENOMEM;
120
121         LIST_HEAD_INIT(m->networks);
122
123         r = setup_default_address_pool(m);
124         if (r < 0)
125                 return r;
126
127         *ret = m;
128         m = NULL;
129
130         return 0;
131 }
132
133 void manager_free(Manager *m) {
134         Network *network;
135         NetDev *netdev;
136         Link *link;
137         AddressPool *pool;
138
139         if (!m)
140                 return;
141
142         free(m->state_file);
143
144         udev_monitor_unref(m->udev_monitor);
145         udev_unref(m->udev);
146         sd_bus_unref(m->bus);
147         sd_event_source_unref(m->udev_event_source);
148         sd_event_source_unref(m->sigterm_event_source);
149         sd_event_source_unref(m->sigint_event_source);
150         sd_event_unref(m->event);
151
152         while ((link = hashmap_first(m->links)))
153                 link_unref(link);
154         hashmap_free(m->links);
155
156         while ((network = m->networks))
157                 network_free(network);
158
159         while ((netdev = hashmap_first(m->netdevs)))
160                 netdev_unref(netdev);
161         hashmap_free(m->netdevs);
162
163         while ((pool = m->address_pools))
164                 address_pool_free(pool);
165
166         sd_rtnl_unref(m->rtnl);
167
168         free(m);
169 }
170
171 int manager_load_config(Manager *m) {
172         int r;
173
174         /* update timestamp */
175         paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
176
177         r = netdev_load(m);
178         if (r < 0)
179                 return r;
180
181         r = network_load(m);
182         if (r < 0)
183                 return r;
184
185         return 0;
186 }
187
188 bool manager_should_reload(Manager *m) {
189         return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
190 }
191
192 static int manager_udev_process_link(Manager *m, struct udev_device *device) {
193         Link *link = NULL;
194         int r, ifindex;
195
196         assert(m);
197         assert(device);
198
199         if (!streq_ptr(udev_device_get_action(device), "add"))
200                 return 0;
201
202         ifindex = udev_device_get_ifindex(device);
203         if (ifindex <= 0) {
204                 log_debug("ignoring udev ADD event for device with invalid ifindex");
205                 return 0;
206         }
207
208         r = link_get(m, ifindex, &link);
209         if (r == -ENODEV)
210                 return 0;
211         else if (r < 0)
212                 return r;
213
214         r = link_initialized(link, device);
215         if (r < 0)
216                 return r;
217
218         return 0;
219 }
220
221 static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
222         Manager *m = userdata;
223         Link *link = NULL;
224         NetDev *netdev = NULL;
225         uint16_t type;
226         const char *name;
227         int r, ifindex;
228
229         assert(rtnl);
230         assert(message);
231         assert(m);
232
233         r = sd_rtnl_message_get_type(message, &type);
234         if (r < 0) {
235                 log_warning("rtnl: could not get message type");
236                 return 0;
237         }
238
239         r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
240         if (r < 0 || ifindex <= 0) {
241                 log_warning("rtnl: received link message without valid ifindex");
242                 return 0;
243         } else
244                 link_get(m, ifindex, &link);
245
246         r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name);
247         if (r < 0 || !name) {
248                 log_warning("rtnl: received link message without valid ifname");
249                 return 0;
250         } else
251                 netdev_get(m, name, &netdev);
252
253         switch (type) {
254         case RTM_NEWLINK:
255                 if (!link) {
256                         /* link is new, so add it */
257                         r = link_add(m, message, &link);
258                         if (r < 0) {
259                                 log_debug("could not add new link: %s",
260                                            strerror(-r));
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         assert(m);
379
380         r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
381         if (r < 0)
382                 return r;
383
384         r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
385         if (r < 0)
386                 return r;
387
388         r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
389         if (r < 0)
390                 return r;
391
392         r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &link_rtnl_process_address, m);
393         if (r < 0)
394                 return r;
395
396         r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &link_rtnl_process_address, m);
397         if (r < 0)
398                 return r;
399
400         return 0;
401 }
402
403 int manager_bus_listen(Manager *m) {
404         int r;
405
406         assert(m->event);
407
408         if (!m->bus) /* TODO: drop when we can rely on kdbus */
409                 return 0;
410
411         r = sd_bus_attach_event(m->bus, m->event, 0);
412         if (r < 0)
413                 return r;
414
415         return 0;
416 }
417
418 static int set_put_in_addr(Set *s, const struct in_addr *address) {
419         char *p;
420         int r;
421
422         assert(s);
423
424         r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
425         if (r < 0)
426                 return r;
427
428         r = set_consume(s, p);
429         if (r == -EEXIST)
430                 return 0;
431
432         return r;
433 }
434
435 static int set_put_in_addrv(Set *s, const struct in_addr *addresses, int n) {
436         int r, i, c = 0;
437
438         assert(s);
439         assert(n <= 0 || addresses);
440
441         for (i = 0; i < n; i++) {
442                 r = set_put_in_addr(s, addresses+i);
443                 if (r < 0)
444                         return r;
445
446                 c += r;
447         }
448
449         return c;
450 }
451
452 int manager_save(Manager *m) {
453         _cleanup_set_free_free_ Set *dns = NULL, *ntp = NULL;
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         /* We add all NTP and DNS server to a set, to filter out duplicates */
466         dns = set_new(string_hash_func, string_compare_func);
467         if (!dns)
468                 return -ENOMEM;
469
470         ntp = set_new(string_hash_func, string_compare_func);
471         if (!ntp)
472                 return -ENOMEM;
473
474         HASHMAP_FOREACH(link, m->links, i) {
475                 if (link->flags & IFF_LOOPBACK)
476                         continue;
477
478                 if (link->operstate > operstate)
479                         operstate = link->operstate;
480
481                 if (!link->network)
482                         continue;
483
484                 /* First add the static configured entries */
485                 r = set_put_strdupv(dns, link->network->dns);
486                 if (r < 0)
487                         return r;
488
489                 r = set_put_strdupv(ntp, link->network->ntp);
490                 if (r < 0)
491                         return r;
492
493                 if (!link->dhcp_lease)
494                         continue;
495
496                 /* Secondly, add the entries acquired via DHCP */
497                 if (link->network->dhcp_dns) {
498                         const struct in_addr *addresses;
499
500                         r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
501                         if (r > 0) {
502                                 r = set_put_in_addrv(dns, addresses, r);
503                                 if (r < 0)
504                                         return r;
505                         } else if (r != -ENOENT)
506                                 return r;
507                 }
508
509                 if (link->network->dhcp_ntp) {
510                         const struct in_addr *addresses;
511
512                         r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
513                         if (r > 0) {
514                                 r = set_put_in_addrv(ntp, addresses, r);
515                                 if (r < 0)
516                                         return r;
517                         } else if (r != -ENOENT)
518                                 return r;
519                 }
520         }
521
522         operstate_str = link_operstate_to_string(operstate);
523         assert(operstate_str);
524
525         r = fopen_temporary(m->state_file, &f, &temp_path);
526         if (r < 0)
527                 return r;
528
529         fchmod(fileno(f), 0644);
530
531         fprintf(f,
532                 "# This is private data. Do not parse.\n"
533                 "OPER_STATE=%s\n", operstate_str);
534
535         if (!set_isempty(dns)) {
536                 bool space = false;
537                 char *p;
538
539                 fputs("DNS=", f);
540                 SET_FOREACH(p, dns, i) {
541                         if (space)
542                                 fputc(' ', f);
543                         fputs(p, f);
544                         space = true;
545                 }
546                 fputc('\n', f);
547         }
548
549         if (!set_isempty(ntp)) {
550                 bool space = false;
551                 char *p;
552
553                 fputs("NTP=", f);
554                 SET_FOREACH(p, ntp, i) {
555                         if (space)
556                                 fputc(' ', f);
557                         fputs(p, f);
558                         space = true;
559                 }
560                 fputc('\n', f);
561         }
562
563         r = fflush_and_check(f);
564         if (r < 0)
565                 goto fail;
566
567         if (rename(temp_path, m->state_file) < 0) {
568                 r = -errno;
569                 goto fail;
570         }
571
572         return 0;
573
574 fail:
575         log_error("Failed to save network state to %s: %s", m->state_file, strerror(-r));
576         unlink(m->state_file);
577         unlink(temp_path);
578         return r;
579 }
580
581 int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
582         AddressPool *p;
583         int r;
584
585         assert(m);
586         assert(prefixlen > 0);
587         assert(found);
588
589         LIST_FOREACH(address_pools, p, m->address_pools) {
590                 if (p->family != family)
591                         continue;
592
593                 r = address_pool_acquire(p, prefixlen, found);
594                 if (r != 0)
595                         return r;
596         }
597
598         return 0;
599 }