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