chiark / gitweb /
8a0ed5ea2b4f38966cd07562eaa8c6bf4636a40a
[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 int manager_save(Manager *m) {
419         Link *link;
420         Iterator i;
421         _cleanup_free_ char *temp_path = NULL;
422         _cleanup_fclose_ FILE *f = NULL;
423         LinkOperationalState operstate = LINK_OPERSTATE_UNKNOWN;
424         const char *operstate_str;
425         int r;
426
427         assert(m);
428         assert(m->state_file);
429
430         HASHMAP_FOREACH(link, m->links, i) {
431                 if (link->flags & IFF_LOOPBACK)
432                         continue;
433
434                 if (link->operstate > operstate)
435                         operstate = link->operstate;
436         }
437
438         operstate_str = link_operstate_to_string(operstate);
439         assert(operstate_str);
440
441         r = fopen_temporary(m->state_file, &f, &temp_path);
442         if (r < 0)
443                 return r;
444
445         fchmod(fileno(f), 0644);
446
447         fprintf(f,
448                 "# This is private data. Do not parse.\n"
449                 "OPER_STATE=%s\n", operstate_str);
450
451         r = fflush_and_check(f);
452         if (r < 0)
453                 goto fail;
454
455         if (rename(temp_path, m->state_file) < 0) {
456                 r = -errno;
457                 goto fail;
458         }
459
460         return 0;
461
462 fail:
463         log_error("Failed to save network state to %s: %s", m->state_file, strerror(-r));
464         unlink(m->state_file);
465         unlink(temp_path);
466         return r;
467 }
468
469 int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
470         AddressPool *p;
471         int r;
472
473         assert(m);
474         assert(prefixlen > 0);
475         assert(found);
476
477         LIST_FOREACH(address_pools, p, m->address_pools) {
478                 if (p->family != family)
479                         continue;
480
481                 r = address_pool_acquire(p, prefixlen, found);
482                 if (r != 0)
483                         return r;
484         }
485
486         return 0;
487 }