chiark / gitweb /
networkd: introduce vxlan
[elogind.git] / src / network / networkd-netdev.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 <net/if.h>
23
24 #include "networkd.h"
25 #include "network-internal.h"
26 #include "path-util.h"
27 #include "conf-files.h"
28 #include "conf-parser.h"
29 #include "list.h"
30 #include "siphash24.h"
31
32 #define VLANID_MAX 4094
33
34 static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
35         [NETDEV_KIND_BRIDGE] = "bridge",
36         [NETDEV_KIND_BOND] = "bond",
37         [NETDEV_KIND_VLAN] = "vlan",
38         [NETDEV_KIND_MACVLAN] = "macvlan",
39         [NETDEV_KIND_VXLAN] = "vxlan",
40         [NETDEV_KIND_IPIP] = "ipip",
41         [NETDEV_KIND_GRE] = "gre",
42         [NETDEV_KIND_SIT] = "sit",
43         [NETDEV_KIND_VETH] = "veth",
44         [NETDEV_KIND_VTI] = "vti"
45 };
46
47 DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);
48 DEFINE_CONFIG_PARSE_ENUM(config_parse_netdev_kind, netdev_kind, NetDevKind, "Failed to parse netdev kind");
49
50 static const char* const macvlan_mode_table[_NETDEV_MACVLAN_MODE_MAX] = {
51         [NETDEV_MACVLAN_MODE_PRIVATE] = "private",
52         [NETDEV_MACVLAN_MODE_VEPA] = "vepa",
53         [NETDEV_MACVLAN_MODE_BRIDGE] = "bridge",
54         [NETDEV_MACVLAN_MODE_PASSTHRU] = "passthru",
55 };
56
57 DEFINE_STRING_TABLE_LOOKUP(macvlan_mode, MacVlanMode);
58 DEFINE_CONFIG_PARSE_ENUM(config_parse_macvlan_mode, macvlan_mode, MacVlanMode, "Failed to parse macvlan mode");
59
60 static void netdev_cancel_callbacks(NetDev *netdev) {
61         _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
62         netdev_enslave_callback *callback;
63
64         if (!netdev)
65                 return;
66
67         rtnl_message_new_synthetic_error(-ENODEV, 0, &m);
68
69         while ((callback = netdev->callbacks)) {
70                 if (m) {
71                         assert(callback->link);
72                         assert(callback->callback);
73                         assert(netdev->manager);
74                         assert(netdev->manager->rtnl);
75
76                         callback->callback(netdev->manager->rtnl, m, link);
77                 }
78
79                 LIST_REMOVE(callbacks, netdev->callbacks, callback);
80                 free(callback);
81         }
82 }
83
84 static void netdev_free(NetDev *netdev) {
85         if (!netdev)
86                 return;
87
88         netdev_cancel_callbacks(netdev);
89
90         if (netdev->ifname)
91                 hashmap_remove(netdev->manager->netdevs, netdev->ifname);
92
93         free(netdev->filename);
94
95         free(netdev->description);
96         free(netdev->ifname);
97         free(netdev->mac);
98         free(netdev->mac_peer);
99
100         condition_free_list(netdev->match_host);
101         condition_free_list(netdev->match_virt);
102         condition_free_list(netdev->match_kernel);
103         condition_free_list(netdev->match_arch);
104
105         free(netdev);
106 }
107
108 NetDev *netdev_unref(NetDev *netdev) {
109         if (netdev && (-- netdev->n_ref <= 0))
110                 netdev_free(netdev);
111
112         return NULL;
113 }
114
115 NetDev *netdev_ref(NetDev *netdev) {
116         if (netdev)
117                 assert_se(++ netdev->n_ref >= 2);
118
119         return netdev;
120 }
121
122 void netdev_drop(NetDev *netdev) {
123         if (!netdev || netdev->state == NETDEV_STATE_LINGER)
124                 return;
125
126         netdev->state = NETDEV_STATE_LINGER;
127
128         log_debug_netdev(netdev, "netdev removed");
129
130         netdev_cancel_callbacks(netdev);
131
132         netdev_unref(netdev);
133
134         return;
135 }
136
137 int netdev_get(Manager *manager, const char *name, NetDev **ret) {
138         NetDev *netdev;
139
140         assert(manager);
141         assert(name);
142         assert(ret);
143
144         netdev = hashmap_get(manager->netdevs, name);
145         if (!netdev) {
146                 *ret = NULL;
147                 return -ENOENT;
148         }
149
150         *ret = netdev;
151
152         return 0;
153 }
154
155 static int netdev_enter_failed(NetDev *netdev) {
156         netdev->state = NETDEV_STATE_FAILED;
157
158         return 0;
159 }
160
161 static int netdev_enslave_ready(NetDev *netdev, Link* link, sd_rtnl_message_handler_t callback) {
162         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
163         int r;
164
165         assert(netdev);
166         assert(netdev->state == NETDEV_STATE_READY);
167         assert(netdev->manager);
168         assert(netdev->manager->rtnl);
169         assert(link);
170         assert(callback);
171
172         r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req,
173                                      RTM_SETLINK, link->ifindex);
174         if (r < 0) {
175                 log_error_netdev(netdev,
176                                  "Could not allocate RTM_SETLINK message: %s",
177                                  strerror(-r));
178                 return r;
179         }
180
181         r = sd_rtnl_message_append_u32(req, IFLA_MASTER, netdev->ifindex);
182         if (r < 0) {
183                 log_error_netdev(netdev,
184                                  "Could not append IFLA_MASTER attribute: %s",
185                                  strerror(-r));
186                 return r;
187         }
188
189         r = sd_rtnl_call_async(netdev->manager->rtnl, req, callback, link, 0, NULL);
190         if (r < 0) {
191                 log_error_netdev(netdev,
192                                  "Could not send rtnetlink message: %s",
193                                  strerror(-r));
194                 return r;
195         }
196
197         log_debug_netdev(netdev, "enslaving link '%s'", link->ifname);
198
199         return 0;
200 }
201
202 static int netdev_enter_ready(NetDev *netdev) {
203         netdev_enslave_callback *callback;
204
205         assert(netdev);
206         assert(netdev->ifname);
207
208         if (netdev->state != NETDEV_STATE_CREATING)
209                 return 0;
210
211         netdev->state = NETDEV_STATE_READY;
212
213         log_info_netdev(netdev, "netdev ready");
214
215         LIST_FOREACH(callbacks, callback, netdev->callbacks) {
216                 /* enslave the links that were attempted to be enslaved before the
217                  * link was ready */
218                 netdev_enslave_ready(netdev, callback->link, callback->callback);
219         }
220
221         return 0;
222 }
223 static int netdev_create_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
224         NetDev *netdev = userdata;
225         int r;
226
227         assert(netdev->state != _NETDEV_STATE_INVALID);
228
229         r = sd_rtnl_message_get_errno(m);
230         if (r == -EEXIST)
231                 log_debug_netdev(netdev, "netdev exists, using existing");
232         else if (r < 0) {
233                 log_warning_netdev(netdev, "netdev could not be created: %s", strerror(-r));
234                 netdev_drop(netdev);
235
236                 return 1;
237         }
238
239         return 1;
240 }
241
242 int config_parse_tunnel_address(const char *unit,
243                                 const char *filename,
244                                 unsigned line,
245                                 const char *section,
246                                 unsigned section_line,
247                                 const char *lvalue,
248                                 int ltype,
249                                 const char *rvalue,
250                                 void *data,
251                                 void *userdata) {
252         NetDev *n = data;
253         unsigned char family = AF_INET;
254         int r;
255
256         assert(filename);
257         assert(lvalue);
258         assert(rvalue);
259         assert(data);
260
261         r = net_parse_inaddr(rvalue, &family, n);
262         if (r < 0) {
263                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
264                            "Tunnel address is invalid, ignoring assignment: %s", rvalue);
265                 return 0;
266         }
267        return 0;
268 }
269
270 static int netdev_create(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
271         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
272         const char *kind;
273         int r;
274
275         assert(netdev);
276         assert(!(netdev->kind == NETDEV_KIND_VLAN || netdev->kind == NETDEV_KIND_MACVLAN) ||
277                (link && callback));
278         assert(netdev->ifname);
279         assert(netdev->manager);
280         assert(netdev->manager->rtnl);
281
282         r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, RTM_NEWLINK, 0);
283         if (r < 0) {
284                 log_error_netdev(netdev,
285                                  "Could not allocate RTM_NEWLINK message: %s",
286                                  strerror(-r));
287                 return r;
288         }
289
290         if (link) {
291                 r = sd_rtnl_message_append_u32(req, IFLA_LINK, link->ifindex);
292                 if (r < 0) {
293                         log_error_netdev(netdev,
294                                          "Could not append IFLA_LINK attribute: %s",
295                                          strerror(-r));
296                         return r;
297                 }
298         }
299
300         r = sd_rtnl_message_append_string(req, IFLA_IFNAME, netdev->ifname);
301         if (r < 0) {
302                 log_error_netdev(netdev,
303                                  "Could not append IFLA_IFNAME attribute: %s",
304                                  strerror(-r));
305                 return r;
306         }
307
308         if (netdev->mtu) {
309                 r = sd_rtnl_message_append_u32(req, IFLA_MTU, netdev->mtu);
310                 if (r < 0) {
311                         log_error_netdev(netdev,
312                                          "Could not append IFLA_MTU attribute: %s",
313                                          strerror(-r));
314                         return r;
315                 }
316         }
317
318         if (netdev->mac) {
319                 r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, netdev->mac);
320                 if (r < 0) {
321                         log_error_netdev(netdev,
322                                          "Colud not append IFLA_ADDRESS attribute: %s",
323                                          strerror(-r));
324                     return r;
325                 }
326         }
327
328         r = sd_rtnl_message_open_container(req, IFLA_LINKINFO);
329         if (r < 0) {
330                 log_error_netdev(netdev,
331                                  "Could not open IFLA_LINKINFO container: %s",
332                                  strerror(-r));
333                 return r;
334         }
335
336         kind = netdev_kind_to_string(netdev->kind);
337         if (!kind) {
338                 log_error_netdev(netdev, "Invalid kind");
339                 return -EINVAL;
340         }
341
342         r = sd_rtnl_message_open_container_union(req, IFLA_INFO_DATA, kind);
343         if (r < 0) {
344                 log_error_netdev(netdev,
345                                  "Could not open IFLA_INFO_DATA container: %s",
346                                   strerror(-r));
347                 return r;
348         }
349
350         if (netdev->vlanid <= VLANID_MAX) {
351                 r = sd_rtnl_message_append_u16(req, IFLA_VLAN_ID, netdev->vlanid);
352                 if (r < 0) {
353                         log_error_netdev(netdev,
354                                          "Could not append IFLA_VLAN_ID attribute: %s",
355                                          strerror(-r));
356                         return r;
357                 }
358         }
359
360         if (netdev->macvlan_mode != _NETDEV_MACVLAN_MODE_INVALID) {
361         r = sd_rtnl_message_append_u32(req, IFLA_MACVLAN_MODE, netdev->macvlan_mode);
362         if (r < 0) {
363                 log_error_netdev(netdev,
364                                  "Could not append IFLA_MACVLAN_MODE attribute: %s",
365                                  strerror(-r));
366                         return r;
367                 }
368         }
369
370         r = sd_rtnl_message_close_container(req);
371         if (r < 0) {
372                 log_error_netdev(netdev,
373                                  "Could not close IFLA_INFO_DATA container %s",
374                                  strerror(-r));
375                 return r;
376         }
377
378         r = sd_rtnl_message_close_container(req);
379         if (r < 0) {
380                 log_error_netdev(netdev,
381                                  "Could not close IFLA_LINKINFO container %s",
382                                  strerror(-r));
383                 return r;
384         }
385
386         if (link)
387                 r = sd_rtnl_call_async(netdev->manager->rtnl, req, callback, link, 0, NULL);
388         else
389                 r = sd_rtnl_call_async(netdev->manager->rtnl, req, &netdev_create_handler, netdev, 0, NULL);
390         if (r < 0) {
391                 log_error_netdev(netdev,
392                                  "Could not send rtnetlink message: %s", strerror(-r));
393                 return r;
394         }
395
396         log_debug_netdev(netdev, "creating netdev");
397
398         netdev->state = NETDEV_STATE_CREATING;
399
400         return 0;
401 }
402
403 int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
404         int r;
405
406         switch(netdev->kind) {
407         case NETDEV_KIND_VLAN:
408         case NETDEV_KIND_MACVLAN:
409                 return netdev_create(netdev, link, callback);
410         case NETDEV_KIND_VXLAN:
411                 return netdev_create_vxlan(netdev, link, callback);
412         case NETDEV_KIND_IPIP:
413         case NETDEV_KIND_GRE:
414         case NETDEV_KIND_SIT:
415         case NETDEV_KIND_VTI:
416                 return netdev_create_tunnel(link, netdev_create_handler);
417         default:
418                 break;
419         }
420
421         if (netdev->state == NETDEV_STATE_READY) {
422                 r = netdev_enslave_ready(netdev, link, callback);
423                 if (r < 0)
424                         return r;
425         } else {
426                 /* the netdev is not yet read, save this request for when it is*/
427                 netdev_enslave_callback *cb;
428
429                 cb = new0(netdev_enslave_callback, 1);
430                 if (!cb)
431                         return log_oom();
432
433                 cb->callback = callback;
434                 cb->link = link;
435
436                 LIST_PREPEND(callbacks, netdev->callbacks, cb);
437         }
438
439         return 0;
440 }
441
442 int netdev_set_ifindex(NetDev *netdev, sd_rtnl_message *message) {
443         uint16_t type;
444         const char *kind;
445         char *received_kind;
446         char *received_name;
447         int r, ifindex;
448
449         assert(netdev);
450         assert(message);
451
452         r = sd_rtnl_message_get_type(message, &type);
453         if (r < 0) {
454                 log_error_netdev(netdev, "Could not get rtnl message type");
455                 return r;
456         }
457
458         if (type != RTM_NEWLINK) {
459                 log_error_netdev(netdev, "Can not set ifindex from unexpected rtnl message type");
460                 return -EINVAL;
461         }
462
463         r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
464         if (r < 0) {
465                 log_error_netdev(netdev, "Could not get ifindex: %s", strerror(-r));
466                 netdev_enter_failed(netdev);
467                 return r;
468         } else if (ifindex <= 0) {
469                 log_error_netdev(netdev, "Got invalid ifindex: %d", ifindex);
470                 netdev_enter_failed(netdev);
471                 return r;
472         }
473
474         if (netdev->ifindex > 0) {
475                 if (netdev->ifindex != ifindex) {
476                         log_error_netdev(netdev, "Could not set ifindex to %d, already set to %d",
477                                          ifindex, netdev->ifindex);
478                         netdev_enter_failed(netdev);
479                         return -EEXIST;
480                 } else
481                         /* ifindex already set to the same for this netdev */
482                         return 0;
483         }
484
485         r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &received_name);
486         if (r < 0) {
487                 log_error_netdev(netdev, "Could not get IFNAME");
488                 return r;
489         }
490
491         if (!streq(netdev->ifname, received_name)) {
492                 log_error_netdev(netdev, "Received newlink with wrong IFNAME %s",
493                                  received_name);
494                 netdev_enter_failed(netdev);
495                 return r;
496         }
497
498         r = sd_rtnl_message_enter_container(message, IFLA_LINKINFO);
499         if (r < 0) {
500                 log_error_netdev(netdev, "Could not get LINKINFO");
501                 return r;
502         }
503
504         r = sd_rtnl_message_read_string(message, IFLA_INFO_KIND, &received_kind);
505         if (r < 0) {
506                 log_error_netdev(netdev, "Could not get KIND");
507                 return r;
508         }
509
510         r = sd_rtnl_message_exit_container(message);
511         if (r < 0) {
512                 log_error_netdev(netdev, "Could not exit container");
513                 return r;
514         }
515
516         kind = netdev_kind_to_string(netdev->kind);
517         if (!kind) {
518                 log_error_netdev(netdev, "Could not get kind");
519                 netdev_enter_failed(netdev);
520                 return -EINVAL;
521         }
522
523         if (!streq(kind, received_kind)) {
524                 log_error_netdev(netdev, "Received newlink with wrong KIND %s, "
525                                  "expected %s", received_kind, kind);
526                 netdev_enter_failed(netdev);
527                 return r;
528         }
529
530         netdev->ifindex = ifindex;
531
532         log_debug_netdev(netdev, "netdev has index %d", netdev->ifindex);
533
534         netdev_enter_ready(netdev);
535
536         return 0;
537 }
538
539 #define HASH_KEY SD_ID128_MAKE(52,e1,45,bd,00,6f,29,96,21,c6,30,6d,83,71,04,48)
540
541 static int netdev_get_mac(const char *ifname, struct ether_addr **ret) {
542         _cleanup_free_ struct ether_addr *mac = NULL;
543         uint8_t result[8];
544         size_t l, sz;
545         uint8_t *v;
546         int r;
547
548         assert(ifname);
549         assert(ret);
550
551         mac = new0(struct ether_addr, 1);
552         if (!mac)
553                 return -ENOMEM;
554
555         l = strlen(ifname);
556         sz = sizeof(sd_id128_t) + l;
557         v = alloca(sz);
558
559         /* fetch some persistent data unique to the machine */
560         r = sd_id128_get_machine((sd_id128_t*) v);
561         if (r < 0)
562                 return r;
563
564         /* combine with some data unique (on this machine) to this
565          * netdev */
566         memcpy(v + sizeof(sd_id128_t), ifname, l);
567
568         /* Let's hash the host machine ID plus the container name. We
569          * use a fixed, but originally randomly created hash key here. */
570         siphash24(result, v, sz, HASH_KEY.bytes);
571
572         assert_cc(ETH_ALEN <= sizeof(result));
573         memcpy(mac->ether_addr_octet, result, ETH_ALEN);
574
575         /* see eth_random_addr in the kernel */
576         mac->ether_addr_octet[0] &= 0xfe;        /* clear multicast bit */
577         mac->ether_addr_octet[0] |= 0x02;        /* set local assignment bit (IEEE802) */
578
579         *ret = mac;
580         mac = NULL;
581
582         return 0;
583 }
584
585 static int netdev_load_one(Manager *manager, const char *filename) {
586         _cleanup_netdev_unref_ NetDev *netdev = NULL;
587         _cleanup_fclose_ FILE *file = NULL;
588         int r;
589
590         assert(manager);
591         assert(filename);
592
593         if (null_or_empty_path(filename)) {
594                 log_debug("skipping empty file: %s", filename);
595                 return 0;
596         }
597
598         file = fopen(filename, "re");
599         if (!file) {
600                 if (errno == ENOENT)
601                         return 0;
602                 else
603                         return -errno;
604         }
605
606         netdev = new0(NetDev, 1);
607         if (!netdev)
608                 return log_oom();
609
610         netdev->n_ref = 1;
611         netdev->manager = manager;
612         netdev->state = _NETDEV_STATE_INVALID;
613         netdev->kind = _NETDEV_KIND_INVALID;
614         netdev->macvlan_mode = _NETDEV_MACVLAN_MODE_INVALID;
615         netdev->vlanid = VLANID_MAX + 1;
616         netdev->vxlanid = VXLAN_VID_MAX + 1;
617         netdev->tunnel_pmtudisc = true;
618         netdev->learning = true;
619
620         r = config_parse(NULL, filename, file,
621                          "Match\0NetDev\0VLAN\0MACVLAN\0VXLAN\0Tunnel\0Peer\0",
622                          config_item_perf_lookup, (void*) network_netdev_gperf_lookup,
623                          false, false, netdev);
624         if (r < 0) {
625                 log_warning("Could not parse config file %s: %s", filename, strerror(-r));
626                 return r;
627         }
628
629         if (netdev->kind == _NETDEV_KIND_INVALID) {
630                 log_warning("NetDev without Kind configured in %s. Ignoring", filename);
631                 return 0;
632         }
633
634         if (!netdev->ifname) {
635                 log_warning("NetDev without Name configured in %s. Ignoring", filename);
636                 return 0;
637         }
638
639         if (netdev->kind == NETDEV_KIND_VLAN && netdev->vlanid > VLANID_MAX) {
640                 log_warning("VLAN without valid Id configured in %s. Ignoring", filename);
641                 return 0;
642         }
643
644         if (netdev->kind == NETDEV_KIND_VXLAN && netdev->vxlanid > VXLAN_VID_MAX) {
645                 log_warning("VXLAN without valid Id configured in %s. Ignoring", filename);
646                 return 0;
647         }
648
649         if (netdev->kind != NETDEV_KIND_VLAN && netdev->vlanid <= VLANID_MAX) {
650                 log_warning("VLAN Id configured for a %s in %s. Ignoring",
651                             netdev_kind_to_string(netdev->kind), filename);
652                 return 0;
653         }
654
655         if (netdev->kind != NETDEV_KIND_VXLAN && netdev->vlanid <= VXLAN_VID_MAX) {
656                 log_warning("VLAN Id configured for a %s in %s. Ignoring",
657                             netdev_kind_to_string(netdev->kind), filename);
658                 return 0;
659         }
660
661         if (netdev->kind != NETDEV_KIND_MACVLAN &&
662             netdev->macvlan_mode != _NETDEV_MACVLAN_MODE_INVALID) {
663                 log_warning("MACVLAN Mode configured for a %s in %s. Ignoring",
664                             netdev_kind_to_string(netdev->kind), filename);
665                 return 0;
666         }
667
668         netdev->filename = strdup(filename);
669         if (!netdev->filename)
670                 return log_oom();
671
672         if (net_match_config(NULL, NULL, NULL, NULL, NULL,
673                              netdev->match_host, netdev->match_virt,
674                              netdev->match_kernel, netdev->match_arch,
675                              NULL, NULL, NULL, NULL, NULL, NULL) <= 0)
676                 return 0;
677
678         if (!netdev->mac) {
679                 r = netdev_get_mac(netdev->ifname, &netdev->mac);
680                 if (r < 0) {
681                         log_error("Failed to generate predictable MAC address for %s",
682                                   netdev->ifname);
683                         return r;
684                 }
685         }
686
687         r = hashmap_put(netdev->manager->netdevs, netdev->ifname, netdev);
688         if (r < 0)
689                 return r;
690
691         LIST_HEAD_INIT(netdev->callbacks);
692
693         if(netdev->kind == NETDEV_KIND_VETH) {
694                 if (netdev->ifname_peer) {
695                         log_warning("Veth NetDev without Peer Name configured "
696                                     "in %s. Ignoring", filename);
697                         return 0;
698                 }
699
700                 if (!netdev->mac) {
701                         r = netdev_get_mac(netdev->ifname_peer, &netdev->mac_peer);
702                         if (r < 0) {
703                                 log_error("Failed to generate predictable MAC address for %s",
704                                           netdev->ifname_peer);
705                                 return r;
706                         }
707                 }
708
709                 return netdev_create_veth(netdev, netdev_create_handler);
710         }
711
712         if (netdev->kind != NETDEV_KIND_VLAN &&
713             netdev->kind != NETDEV_KIND_MACVLAN &&
714             netdev->kind != NETDEV_KIND_VXLAN &&
715             netdev->kind != NETDEV_KIND_IPIP &&
716             netdev->kind != NETDEV_KIND_GRE &&
717             netdev->kind != NETDEV_KIND_SIT &&
718             netdev->kind != NETDEV_KIND_VTI) {
719                 r = netdev_create(netdev, NULL, NULL);
720                 if (r < 0)
721                         return r;
722         }
723
724         log_debug_netdev(netdev, "loaded %s", netdev_kind_to_string(netdev->kind));
725
726         netdev = NULL;
727
728         return 0;
729 }
730
731 int netdev_load(Manager *manager) {
732         NetDev *netdev;
733         char **files, **f;
734         int r;
735
736         assert(manager);
737
738         while ((netdev = hashmap_first(manager->netdevs)))
739                 netdev_unref(netdev);
740
741         r = conf_files_list_strv(&files, ".netdev", NULL, network_dirs);
742         if (r < 0) {
743                 log_error("Failed to enumerate netdev files: %s", strerror(-r));
744                 return r;
745         }
746
747         STRV_FOREACH_BACKWARDS(f, files) {
748                 r = netdev_load_one(manager, *f);
749                 if (r < 0)
750                         return r;
751         }
752
753         strv_free(files);
754
755         return 0;
756 }