chiark / gitweb /
networkd: link - save link flags when the link is added
[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_func, string_compare_func);
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_source_unref(m->sigterm_event_source);
150         sd_event_source_unref(m->sigint_event_source);
151         sd_event_unref(m->event);
152
153         while ((link = hashmap_first(m->links)))
154                 link_unref(link);
155         hashmap_free(m->links);
156
157         while ((network = m->networks))
158                 network_free(network);
159
160         while ((netdev = hashmap_first(m->netdevs)))
161                 netdev_unref(netdev);
162         hashmap_free(m->netdevs);
163
164         while ((pool = m->address_pools))
165                 address_pool_free(pool);
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         const 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: %s",
261                                            strerror(-r));
262                                 return 0;
263                         }
264                 }
265
266                 if (netdev) {
267                         /* netdev exists, so make sure the ifindex matches */
268                         r = netdev_set_ifindex(netdev, message);
269                         if (r < 0) {
270                                 log_debug("could not set ifindex on netdev");
271                                 return 0;
272                         }
273                 }
274
275                 r = link_update(link, message);
276                 if (r < 0)
277                         return 0;
278
279                 break;
280
281         case RTM_DELLINK:
282                 link_drop(link);
283                 netdev_drop(netdev);
284
285                 break;
286
287         default:
288                 assert_not_reached("Received invalid RTNL message type.");
289         }
290
291         return 1;
292 }
293
294 int manager_rtnl_enumerate_links(Manager *m) {
295         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
296         sd_rtnl_message *link;
297         int r, k;
298
299         assert(m);
300         assert(m->rtnl);
301
302         r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
303         if (r < 0)
304                 return r;
305
306         r = sd_rtnl_message_request_dump(req, true);
307         if (r < 0)
308                 return r;
309
310         r = sd_rtnl_call(m->rtnl, req, 0, &reply);
311         if (r < 0)
312                 return r;
313
314         for (link = reply; link; link = sd_rtnl_message_next(link)) {
315                 uint16_t type;
316
317                 k = sd_rtnl_message_get_type(link, &type);
318                 if (k < 0)
319                         return k;
320
321                 if (type != RTM_NEWLINK)
322                         continue;
323
324                 k = manager_rtnl_process_link(m->rtnl, link, m);
325                 if (k < 0)
326                         r = k;
327         }
328
329         return r;
330 }
331
332 static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
333         Manager *m = userdata;
334         struct udev_monitor *monitor = m->udev_monitor;
335         _cleanup_udev_device_unref_ struct udev_device *device = NULL;
336
337         device = udev_monitor_receive_device(monitor);
338         if (!device)
339                 return -ENOMEM;
340
341         manager_udev_process_link(m, device);
342         return 0;
343 }
344
345 int manager_udev_listen(Manager *m) {
346         int r;
347
348         if (detect_container(NULL) > 0)
349                 return 0;
350
351         assert(m->udev_monitor);
352
353         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL);
354         if (r < 0) {
355                 log_error("Could not add udev monitor filter: %s", strerror(-r));
356                 return r;
357         }
358
359         r = udev_monitor_enable_receiving(m->udev_monitor);
360         if (r < 0) {
361                 log_error("Could not enable udev monitor");
362                 return r;
363         }
364
365         r = sd_event_add_io(m->event,
366                         &m->udev_event_source,
367                         udev_monitor_get_fd(m->udev_monitor),
368                         EPOLLIN, manager_dispatch_link_udev,
369                         m);
370         if (r < 0)
371                 return r;
372
373         r = sd_event_source_set_name(m->udev_event_source, "networkd-udev");
374         if (r < 0)
375                 return r;
376
377         return 0;
378 }
379
380 int manager_rtnl_listen(Manager *m) {
381         int r;
382
383         assert(m);
384
385         r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
386         if (r < 0)
387                 return r;
388
389         r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m);
390         if (r < 0)
391                 return r;
392
393         r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, &manager_rtnl_process_link, m);
394         if (r < 0)
395                 return r;
396
397         r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, &link_rtnl_process_address, m);
398         if (r < 0)
399                 return r;
400
401         r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, &link_rtnl_process_address, m);
402         if (r < 0)
403                 return r;
404
405         return 0;
406 }
407
408 int manager_bus_listen(Manager *m) {
409         int r;
410
411         assert(m->event);
412
413         if (!m->bus) /* TODO: drop when we can rely on kdbus */
414                 return 0;
415
416         r = sd_bus_attach_event(m->bus, m->event, 0);
417         if (r < 0)
418                 return r;
419
420         return 0;
421 }
422
423 static int set_put_in_addr(Set *s, const struct in_addr *address) {
424         char *p;
425         int r;
426
427         assert(s);
428
429         r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
430         if (r < 0)
431                 return r;
432
433         r = set_consume(s, p);
434         if (r == -EEXIST)
435                 return 0;
436
437         return r;
438 }
439
440 static int set_put_in_addrv(Set *s, const struct in_addr *addresses, int n) {
441         int r, i, c = 0;
442
443         assert(s);
444         assert(n <= 0 || addresses);
445
446         for (i = 0; i < n; i++) {
447                 r = set_put_in_addr(s, addresses+i);
448                 if (r < 0)
449                         return r;
450
451                 c += r;
452         }
453
454         return c;
455 }
456
457 static void print_string_set(FILE *f, const char *field, Set *s) {
458         bool space = false;
459         Iterator i;
460         char *p;
461
462         if (set_isempty(s))
463                 return;
464
465         fputs(field, f);
466
467         SET_FOREACH(p, s, i) {
468                 if (space)
469                         fputc(' ', f);
470                 fputs(p, f);
471                 space = true;
472         }
473         fputc('\n', f);
474 }
475
476 int manager_save(Manager *m) {
477         _cleanup_set_free_free_ Set *dns = NULL, *ntp = NULL, *domains = NULL;
478         Link *link;
479         Iterator i;
480         _cleanup_free_ char *temp_path = NULL;
481         _cleanup_fclose_ FILE *f = NULL;
482         LinkOperationalState operstate = LINK_OPERSTATE_OFF;
483         const char *operstate_str;
484         int r;
485
486         assert(m);
487         assert(m->state_file);
488
489         /* We add all NTP and DNS server to a set, to filter out duplicates */
490         dns = set_new(string_hash_func, string_compare_func);
491         if (!dns)
492                 return -ENOMEM;
493
494         ntp = set_new(string_hash_func, string_compare_func);
495         if (!ntp)
496                 return -ENOMEM;
497
498         domains = set_new(string_hash_func, string_compare_func);
499         if (!domains)
500                 return -ENOMEM;
501
502         HASHMAP_FOREACH(link, m->links, i) {
503                 if (link->flags & IFF_LOOPBACK)
504                         continue;
505
506                 if (link->operstate > operstate)
507                         operstate = link->operstate;
508
509                 if (!link->network)
510                         continue;
511
512                 /* First add the static configured entries */
513                 r = set_put_strdupv(dns, link->network->dns);
514                 if (r < 0)
515                         return r;
516
517                 r = set_put_strdupv(ntp, link->network->ntp);
518                 if (r < 0)
519                         return r;
520
521                 r = set_put_strdupv(domains, link->network->domains);
522                 if (r < 0)
523                         return r;
524
525                 if (!link->dhcp_lease)
526                         continue;
527
528                 /* Secondly, add the entries acquired via DHCP */
529                 if (link->network->dhcp_dns) {
530                         const struct in_addr *addresses;
531
532                         r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
533                         if (r > 0) {
534                                 r = set_put_in_addrv(dns, addresses, r);
535                                 if (r < 0)
536                                         return r;
537                         } else if (r < 0 && r != -ENOENT)
538                                 return r;
539                 }
540
541                 if (link->network->dhcp_ntp) {
542                         const struct in_addr *addresses;
543
544                         r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
545                         if (r > 0) {
546                                 r = set_put_in_addrv(ntp, addresses, r);
547                                 if (r < 0)
548                                         return r;
549                         } else if (r < 0 && r != -ENOENT)
550                                 return r;
551                 }
552
553                 if (link->network->dhcp_domains) {
554                         const char *domainname;
555
556                         r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
557                         if (r >= 0) {
558                                 r = set_put_strdup(domains, domainname);
559                                 if (r < 0)
560                                         return r;
561                         } else if (r != -ENOENT)
562                                 return r;
563                 }
564         }
565
566         operstate_str = link_operstate_to_string(operstate);
567         assert(operstate_str);
568
569         r = fopen_temporary(m->state_file, &f, &temp_path);
570         if (r < 0)
571                 return r;
572
573         fchmod(fileno(f), 0644);
574
575         fprintf(f,
576                 "# This is private data. Do not parse.\n"
577                 "OPER_STATE=%s\n", operstate_str);
578
579         print_string_set(f, "DNS=", dns);
580         print_string_set(f, "NTP=", ntp);
581         print_string_set(f, "DOMAINS=", domains);
582
583         r = fflush_and_check(f);
584         if (r < 0)
585                 goto fail;
586
587         if (rename(temp_path, m->state_file) < 0) {
588                 r = -errno;
589                 goto fail;
590         }
591
592         return 0;
593
594 fail:
595         log_error("Failed to save network state to %s: %s", m->state_file, strerror(-r));
596         unlink(m->state_file);
597         unlink(temp_path);
598         return r;
599 }
600
601 int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
602         AddressPool *p;
603         int r;
604
605         assert(m);
606         assert(prefixlen > 0);
607         assert(found);
608
609         LIST_FOREACH(address_pools, p, m->address_pools) {
610                 if (p->family != family)
611                         continue;
612
613                 r = address_pool_acquire(p, prefixlen, found);
614                 if (r != 0)
615                         return r;
616         }
617
618         return 0;
619 }