chiark / gitweb /
update NEWS
[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 "networkd-link.h"
30 #include "network-internal.h"
31 #include "libudev-private.h"
32 #include "udev-util.h"
33 #include "rtnl-util.h"
34 #include "mkdir.h"
35 #include "virt.h"
36
37 #include "sd-rtnl.h"
38
39 const char* const network_dirs[] = {
40         "/etc/systemd/network",
41         "/run/systemd/network",
42         "/usr/lib/systemd/network",
43 #ifdef HAVE_SPLIT_USR
44         "/lib/systemd/network",
45 #endif
46         NULL};
47
48 static int setup_default_address_pool(Manager *m) {
49         AddressPool *p;
50         int r;
51
52         assert(m);
53
54         /* Add in the well-known private address ranges. */
55
56         r = address_pool_new_from_string(m, &p, AF_INET6, "fc00::", 7);
57         if (r < 0)
58                 return r;
59
60         r = address_pool_new_from_string(m, &p, AF_INET, "192.168.0.0", 16);
61         if (r < 0)
62                 return r;
63
64         r = address_pool_new_from_string(m, &p, AF_INET, "172.16.0.0", 12);
65         if (r < 0)
66                 return r;
67
68         r = address_pool_new_from_string(m, &p, AF_INET, "10.0.0.0", 8);
69         if (r < 0)
70                 return r;
71
72         return 0;
73 }
74
75 int manager_new(Manager **ret) {
76         _cleanup_manager_free_ Manager *m = NULL;
77         int r;
78
79         m = new0(Manager, 1);
80         if (!m)
81                 return -ENOMEM;
82
83         m->state_file = strdup("/run/systemd/netif/state");
84         if (!m->state_file)
85                 return -ENOMEM;
86
87         r = sd_event_default(&m->event);
88         if (r < 0)
89                 return r;
90
91         sd_event_set_watchdog(m->event, true);
92
93         sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
94         sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
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         /* udev does not initialize devices inside containers,
106          * so we rely on them being already initialized before
107          * entering the container */
108         if (detect_container(NULL) <= 0) {
109                 m->udev = udev_new();
110                 if (!m->udev)
111                         return -ENOMEM;
112
113                 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
114                 if (!m->udev_monitor)
115                         return -ENOMEM;
116         }
117
118         m->netdevs = hashmap_new(&string_hash_ops);
119         if (!m->netdevs)
120                 return -ENOMEM;
121
122         LIST_HEAD_INIT(m->networks);
123
124         r = setup_default_address_pool(m);
125         if (r < 0)
126                 return r;
127
128         *ret = m;
129         m = NULL;
130
131         return 0;
132 }
133
134 void manager_free(Manager *m) {
135         Network *network;
136         NetDev *netdev;
137         Link *link;
138         AddressPool *pool;
139
140         if (!m)
141                 return;
142
143         free(m->state_file);
144
145         udev_monitor_unref(m->udev_monitor);
146         udev_unref(m->udev);
147         sd_bus_unref(m->bus);
148         sd_event_source_unref(m->udev_event_source);
149         sd_event_unref(m->event);
150
151         while ((link = hashmap_first(m->links)))
152                 link_unref(link);
153         hashmap_free(m->links);
154
155         while ((network = m->networks))
156                 network_free(network);
157
158         while ((netdev = hashmap_first(m->netdevs)))
159                 netdev_unref(netdev);
160         hashmap_free(m->netdevs);
161
162         while ((pool = m->address_pools))
163                 address_pool_free(pool);
164
165         sd_rtnl_unref(m->rtnl);
166
167         free(m);
168 }
169
170 int manager_load_config(Manager *m) {
171         int r;
172
173         /* update timestamp */
174         paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true);
175
176         r = netdev_load(m);
177         if (r < 0)
178                 return r;
179
180         r = network_load(m);
181         if (r < 0)
182                 return r;
183
184         return 0;
185 }
186
187 bool manager_should_reload(Manager *m) {
188         return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false);
189 }
190
191 static int manager_udev_process_link(Manager *m, struct udev_device *device) {
192         Link *link = NULL;
193         int r, ifindex;
194
195         assert(m);
196         assert(device);
197
198         if (!streq_ptr(udev_device_get_action(device), "add"))
199                 return 0;
200
201         ifindex = udev_device_get_ifindex(device);
202         if (ifindex <= 0) {
203                 log_debug("ignoring udev ADD event for device with invalid ifindex");
204                 return 0;
205         }
206
207         r = link_get(m, ifindex, &link);
208         if (r == -ENODEV)
209                 return 0;
210         else if (r < 0)
211                 return r;
212
213         r = link_initialized(link, device);
214         if (r < 0)
215                 return r;
216
217         return 0;
218 }
219
220 static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
221         Manager *m = userdata;
222         Link *link = NULL;
223         NetDev *netdev = NULL;
224         uint16_t type;
225         const char *name;
226         int r, ifindex;
227
228         assert(rtnl);
229         assert(message);
230         assert(m);
231
232         r = sd_rtnl_message_get_type(message, &type);
233         if (r < 0) {
234                 log_warning("rtnl: could not get message type");
235                 return 0;
236         }
237
238         r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
239         if (r < 0 || ifindex <= 0) {
240                 log_warning("rtnl: received link message without valid ifindex");
241                 return 0;
242         } else
243                 link_get(m, ifindex, &link);
244
245         r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name);
246         if (r < 0 || !name) {
247                 log_warning("rtnl: received link message without valid ifname");
248                 return 0;
249         } else
250                 netdev_get(m, name, &netdev);
251
252         switch (type) {
253         case RTM_NEWLINK:
254                 if (!link) {
255                         /* link is new, so add it */
256                         r = link_add(m, message, &link);
257                         if (r < 0) {
258                                 log_debug("could not add new link: %s",
259                                            strerror(-r));
260                                 return 0;
261                         }
262                 }
263
264                 if (netdev) {
265                         /* netdev exists, so make sure the ifindex matches */
266                         r = netdev_set_ifindex(netdev, message);
267                         if (r < 0) {
268                                 log_debug("could not set ifindex on netdev");
269                                 return 0;
270                         }
271                 }
272
273                 r = link_update(link, message);
274                 if (r < 0)
275                         return 0;
276
277                 break;
278
279         case RTM_DELLINK:
280                 link_drop(link);
281                 netdev_drop(netdev);
282
283                 break;
284
285         default:
286                 assert_not_reached("Received invalid RTNL message type.");
287         }
288
289         return 1;
290 }
291
292 int manager_rtnl_enumerate_links(Manager *m) {
293         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
294         sd_rtnl_message *link;
295         int r, k;
296
297         assert(m);
298         assert(m->rtnl);
299
300         r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
301         if (r < 0)
302                 return r;
303
304         r = sd_rtnl_message_request_dump(req, true);
305         if (r < 0)
306                 return r;
307
308         r = sd_rtnl_call(m->rtnl, req, 0, &reply);
309         if (r < 0)
310                 return r;
311
312         for (link = reply; link; link = sd_rtnl_message_next(link)) {
313                 uint16_t type;
314
315                 k = sd_rtnl_message_get_type(link, &type);
316                 if (k < 0)
317                         return k;
318
319                 if (type != RTM_NEWLINK)
320                         continue;
321
322                 k = manager_rtnl_process_link(m->rtnl, link, m);
323                 if (k < 0)
324                         r = k;
325         }
326
327         return r;
328 }
329
330 static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
331         Manager *m = userdata;
332         struct udev_monitor *monitor = m->udev_monitor;
333         _cleanup_udev_device_unref_ struct udev_device *device = NULL;
334
335         device = udev_monitor_receive_device(monitor);
336         if (!device)
337                 return -ENOMEM;
338
339         manager_udev_process_link(m, device);
340         return 0;
341 }
342
343 int manager_udev_listen(Manager *m) {
344         int r;
345
346         if (detect_container(NULL) > 0)
347                 return 0;
348
349         assert(m->udev_monitor);
350
351         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL);
352         if (r < 0) {
353                 log_error("Could not add udev monitor filter: %s", strerror(-r));
354                 return r;
355         }
356
357         r = udev_monitor_enable_receiving(m->udev_monitor);
358         if (r < 0) {
359                 log_error("Could not enable udev monitor");
360                 return r;
361         }
362
363         r = sd_event_add_io(m->event,
364                         &m->udev_event_source,
365                         udev_monitor_get_fd(m->udev_monitor),
366                         EPOLLIN, manager_dispatch_link_udev,
367                         m);
368         if (r < 0)
369                 return r;
370
371         r = sd_event_source_set_name(m->udev_event_source, "networkd-udev");
372         if (r < 0)
373                 return r;
374
375         return 0;
376 }
377
378 int manager_rtnl_listen(Manager *m) {
379         int r;
380
381         assert(m);
382
383         r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
384         if (r < 0)
385                 return r;
386
387         r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
388         if (r < 0)
389                 return r;
390
391         r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
392         if (r < 0)
393                 return r;
394
395         r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &link_rtnl_process_address, m);
396         if (r < 0)
397                 return r;
398
399         r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &link_rtnl_process_address, m);
400         if (r < 0)
401                 return r;
402
403         return 0;
404 }
405
406 int manager_bus_listen(Manager *m) {
407         int r;
408
409         assert(m->event);
410
411         if (!m->bus) /* TODO: drop when we can rely on kdbus */
412                 return 0;
413
414         r = sd_bus_attach_event(m->bus, m->event, 0);
415         if (r < 0)
416                 return r;
417
418         return 0;
419 }
420
421 static int set_put_in_addr(Set *s, const struct in_addr *address) {
422         char *p;
423         int r;
424
425         assert(s);
426
427         r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
428         if (r < 0)
429                 return r;
430
431         r = set_consume(s, p);
432         if (r == -EEXIST)
433                 return 0;
434
435         return r;
436 }
437
438 static int set_put_in_addrv(Set *s, const struct in_addr *addresses, int n) {
439         int r, i, c = 0;
440
441         assert(s);
442         assert(n <= 0 || addresses);
443
444         for (i = 0; i < n; i++) {
445                 r = set_put_in_addr(s, addresses+i);
446                 if (r < 0)
447                         return r;
448
449                 c += r;
450         }
451
452         return c;
453 }
454
455 static void print_string_set(FILE *f, const char *field, Set *s) {
456         bool space = false;
457         Iterator i;
458         char *p;
459
460         if (set_isempty(s))
461                 return;
462
463         fputs(field, f);
464
465         SET_FOREACH(p, s, i) {
466                 if (space)
467                         fputc(' ', f);
468                 fputs(p, f);
469                 space = true;
470         }
471         fputc('\n', f);
472 }
473
474 int manager_save(Manager *m) {
475         _cleanup_set_free_free_ Set *dns = NULL, *ntp = NULL, *domains = NULL;
476         Link *link;
477         Iterator i;
478         _cleanup_free_ char *temp_path = NULL;
479         _cleanup_fclose_ FILE *f = NULL;
480         LinkOperationalState operstate = LINK_OPERSTATE_OFF;
481         const char *operstate_str;
482         int r;
483
484         assert(m);
485         assert(m->state_file);
486
487         /* We add all NTP and DNS server to a set, to filter out duplicates */
488         dns = set_new(&string_hash_ops);
489         if (!dns)
490                 return -ENOMEM;
491
492         ntp = set_new(&string_hash_ops);
493         if (!ntp)
494                 return -ENOMEM;
495
496         domains = set_new(&string_hash_ops);
497         if (!domains)
498                 return -ENOMEM;
499
500         HASHMAP_FOREACH(link, m->links, i) {
501                 if (link->flags & IFF_LOOPBACK)
502                         continue;
503
504                 if (link->operstate > operstate)
505                         operstate = link->operstate;
506
507                 if (!link->network)
508                         continue;
509
510                 /* First add the static configured entries */
511                 r = set_put_strdupv(dns, link->network->dns);
512                 if (r < 0)
513                         return r;
514
515                 r = set_put_strdupv(ntp, link->network->ntp);
516                 if (r < 0)
517                         return r;
518
519                 r = set_put_strdupv(domains, link->network->domains);
520                 if (r < 0)
521                         return r;
522
523                 if (!link->dhcp_lease)
524                         continue;
525
526                 /* Secondly, add the entries acquired via DHCP */
527                 if (link->network->dhcp_dns) {
528                         const struct in_addr *addresses;
529
530                         r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
531                         if (r > 0) {
532                                 r = set_put_in_addrv(dns, addresses, r);
533                                 if (r < 0)
534                                         return r;
535                         } else if (r < 0 && r != -ENOENT)
536                                 return r;
537                 }
538
539                 if (link->network->dhcp_ntp) {
540                         const struct in_addr *addresses;
541
542                         r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
543                         if (r > 0) {
544                                 r = set_put_in_addrv(ntp, addresses, r);
545                                 if (r < 0)
546                                         return r;
547                         } else if (r < 0 && r != -ENOENT)
548                                 return r;
549                 }
550
551                 if (link->network->dhcp_domains) {
552                         const char *domainname;
553
554                         r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
555                         if (r >= 0) {
556                                 r = set_put_strdup(domains, domainname);
557                                 if (r < 0)
558                                         return r;
559                         } else if (r != -ENOENT)
560                                 return r;
561                 }
562         }
563
564         operstate_str = link_operstate_to_string(operstate);
565         assert(operstate_str);
566
567         r = fopen_temporary(m->state_file, &f, &temp_path);
568         if (r < 0)
569                 return r;
570
571         fchmod(fileno(f), 0644);
572
573         fprintf(f,
574                 "# This is private data. Do not parse.\n"
575                 "OPER_STATE=%s\n", operstate_str);
576
577         print_string_set(f, "DNS=", dns);
578         print_string_set(f, "NTP=", ntp);
579         print_string_set(f, "DOMAINS=", domains);
580
581         r = fflush_and_check(f);
582         if (r < 0)
583                 goto fail;
584
585         if (rename(temp_path, m->state_file) < 0) {
586                 r = -errno;
587                 goto fail;
588         }
589
590         return 0;
591
592 fail:
593         log_error("Failed to save network state to %s: %s", m->state_file, strerror(-r));
594         unlink(m->state_file);
595         unlink(temp_path);
596         return r;
597 }
598
599 int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
600         AddressPool *p;
601         int r;
602
603         assert(m);
604         assert(prefixlen > 0);
605         assert(found);
606
607         LIST_FOREACH(address_pools, p, m->address_pools) {
608                 if (p->family != family)
609                         continue;
610
611                 r = address_pool_acquire(p, prefixlen, found);
612                 if (r != 0)
613                         return r;
614         }
615
616         return 0;
617 }