chiark / gitweb /
sd-dhcp-client/net-util: make netmask_to_prefixlen generic
[elogind.git] / src / network / networkd-link.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 <netinet/ether.h>
23 #include <linux/if.h>
24
25 #include "networkd.h"
26 #include "libudev-private.h"
27 #include "util.h"
28 #include "bus-util.h"
29 #include "net-util.h"
30
31 int link_new(Manager *manager, struct udev_device *device, Link **ret) {
32         _cleanup_link_free_ Link *link = NULL;
33         const char *mac;
34         struct ether_addr *mac_addr;
35         const char *ifname;
36         int r;
37
38         assert(device);
39         assert(ret);
40
41         link = new0(Link, 1);
42         if (!link)
43                 return -ENOMEM;
44
45         link->manager = manager;
46         link->state = _LINK_STATE_INVALID;
47
48         link->ifindex = udev_device_get_ifindex(device);
49         if (link->ifindex <= 0)
50                 return -EINVAL;
51
52         mac = udev_device_get_sysattr_value(device, "address");
53         if (mac) {
54                 mac_addr = ether_aton(mac);
55                 if (mac_addr)
56                         memcpy(&link->mac, mac_addr, sizeof(struct ether_addr));
57         }
58
59         ifname = udev_device_get_sysname(device);
60         link->ifname = strdup(ifname);
61
62         r = hashmap_put(manager->links, &link->ifindex, link);
63         if (r < 0)
64                 return r;
65
66         *ret = link;
67         link = NULL;
68
69         return 0;
70 }
71
72 void link_free(Link *link) {
73         if (!link)
74                 return;
75
76         assert(link->manager);
77
78         if (link->dhcp)
79                 sd_dhcp_client_free(link->dhcp);
80
81         route_free(link->dhcp_route);
82         link->dhcp_route = NULL;
83
84         address_free(link->dhcp_address);
85         link->dhcp_address = NULL;
86
87         hashmap_remove(link->manager->links, &link->ifindex);
88
89         free(link->ifname);
90
91         free(link);
92 }
93
94 int link_add(Manager *m, struct udev_device *device, Link **ret) {
95         Link *link;
96         Network *network;
97         int r;
98         uint64_t ifindex;
99         NetdevKind kind;
100
101         assert(m);
102         assert(device);
103
104         ifindex = udev_device_get_ifindex(device);
105         link = hashmap_get(m->links, &ifindex);
106         if (link) {
107                 *ret = link;
108                 return -EEXIST;
109         }
110
111         r = link_new(m, device, &link);
112         if (r < 0)
113                 return r;
114
115         *ret = link;
116
117         kind = netdev_kind_from_string(udev_device_get_devtype(device));
118         if (kind != _NETDEV_KIND_INVALID) {
119                 r = netdev_set_link(m, kind, link);
120                 if (r < 0 && r != -ENOENT)
121                         return r;
122         }
123
124         r = network_get(m, device, &network);
125         if (r < 0)
126                 return r == -ENOENT ? 0 : r;
127
128         r = network_apply(m, network, link);
129         if (r < 0)
130                 return r;
131
132         return 0;
133 }
134
135 static int link_enter_configured(Link *link) {
136         assert(link);
137         assert(link->state == LINK_STATE_SETTING_ROUTES);
138
139         log_info_link(link, "link configured");
140
141         link->state = LINK_STATE_CONFIGURED;
142
143         return 0;
144 }
145
146 static void link_enter_failed(Link *link) {
147         assert(link);
148
149         log_warning_link(link, "failed");
150
151         link->state = LINK_STATE_FAILED;
152 }
153
154 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
155         Link *link = userdata;
156         int r;
157
158         assert(link->route_messages > 0);
159         assert(link->state == LINK_STATE_SETTING_ADDRESSES ||
160                link->state == LINK_STATE_SETTING_ROUTES ||
161                link->state == LINK_STATE_FAILED);
162
163         link->route_messages --;
164
165         if (link->state == LINK_STATE_FAILED)
166                 return 1;
167
168         r = sd_rtnl_message_get_errno(m);
169         if (r < 0 && r != -EEXIST)
170                 log_struct_link(LOG_WARNING, link,
171                                 "MESSAGE=%s: could not set route: %s",
172                                 link->ifname, strerror(-r),
173                                 "ERRNO=%d", -r,
174                                 NULL);
175
176         /* we might have received an old reply after moving back to SETTING_ADDRESSES,
177          * ignore it */
178         if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
179                 log_debug_link(link, "routes set");
180                 link_enter_configured(link);
181         }
182
183         return 1;
184 }
185
186 static int link_enter_set_routes(Link *link) {
187         Route *route;
188         int r;
189
190         assert(link);
191         assert(link->network);
192         assert(link->state == LINK_STATE_SETTING_ADDRESSES);
193
194         link->state = LINK_STATE_SETTING_ROUTES;
195
196         if (!link->network->static_routes && !link->dhcp_route)
197                 return link_enter_configured(link);
198
199         log_debug_link(link, "setting routes");
200
201         LIST_FOREACH(static_routes, route, link->network->static_routes) {
202                 r = route_configure(route, link, &route_handler);
203                 if (r < 0) {
204                         log_warning_link(link,
205                                          "could not set routes: %s", strerror(-r));
206                         link_enter_failed(link);
207                         return r;
208                 }
209
210                 link->route_messages ++;
211         }
212
213         if (link->dhcp_route) {
214                 r = route_configure(link->dhcp_route, link, &route_handler);
215                 if (r < 0) {
216                         log_warning_link(link,
217                                          "could not set routes: %s", strerror(-r));
218                         link_enter_failed(link);
219                         return r;
220                 }
221
222                 link->route_messages ++;
223         }
224
225         return 0;
226 }
227
228 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
229         Link *link = userdata;
230         int r;
231
232         assert(m);
233         assert(link);
234         assert(link->ifname);
235         assert(link->addr_messages > 0);
236         assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
237
238         link->addr_messages --;
239
240         if (link->state == LINK_STATE_FAILED)
241                 return 1;
242
243         r = sd_rtnl_message_get_errno(m);
244         if (r < 0 && r != -EEXIST)
245                 log_struct_link(LOG_WARNING, link,
246                                 "MESSAGE=%s: could not set address: %s",
247                                 link->ifname, strerror(-r),
248                                 "ERRNO=%d", -r,
249                                 NULL);
250
251         if (link->addr_messages == 0) {
252                 log_debug_link(link, "addresses set");
253                 link_enter_set_routes(link);
254         }
255
256         return 1;
257 }
258
259 static int link_enter_set_addresses(Link *link) {
260         Address *address;
261         int r;
262
263         assert(link);
264         assert(link->network);
265         assert(link->state != _LINK_STATE_INVALID);
266
267         link->state = LINK_STATE_SETTING_ADDRESSES;
268
269         if (!link->network->static_addresses && !link->dhcp_address)
270                 return link_enter_set_routes(link);
271
272         log_debug_link(link, "setting addresses");
273
274         LIST_FOREACH(static_addresses, address, link->network->static_addresses) {
275                 r = address_configure(address, link, &address_handler);
276                 if (r < 0) {
277                         log_warning_link(link,
278                                          "could not set addresses: %s", strerror(-r));
279                         link_enter_failed(link);
280                         return r;
281                 }
282
283                 link->addr_messages ++;
284         }
285
286         if (link->dhcp_address) {
287                 r = address_configure(link->dhcp_address, link, &address_handler);
288                 if (r < 0) {
289                         log_warning_link(link,
290                                          "could not set addresses: %s", strerror(-r));
291                         link_enter_failed(link);
292                         return r;
293                 }
294
295                 link->addr_messages ++;
296         }
297
298         return 0;
299 }
300
301 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
302         Link *link = userdata;
303         int r;
304
305         assert(m);
306         assert(link);
307         assert(link->ifname);
308
309         if (link->state == LINK_STATE_FAILED)
310                 return 1;
311
312         r = sd_rtnl_message_get_errno(m);
313         if (r < 0 && r != -ENOENT)
314                 log_struct_link(LOG_WARNING, link,
315                                 "MESSAGE=%s: could not drop address: %s",
316                                 link->ifname, strerror(-r),
317                                 "ERRNO=%d", -r,
318                                 NULL);
319
320         return 1;
321 }
322
323 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
324         int r;
325
326         r = sd_bus_message_get_errno(m);
327         if (r < 0)
328                 log_warning("Could not set hostname: %s", strerror(-r));
329
330         return 1;
331 }
332
333 static int set_hostname(sd_bus *bus, const char *hostname) {
334         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
335         int r = 0;
336
337         assert(hostname);
338
339         log_debug("Setting transient hostname: '%s'", hostname);
340
341         if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
342                 log_info("Not connected to system bus, ignoring transient hostname.");
343                 return 0;
344         }
345
346         r = sd_bus_message_new_method_call(
347                         bus,
348                         "org.freedesktop.hostname1",
349                         "/org/freedesktop/hostname1",
350                         "org.freedesktop.hostname1",
351                         "SetHostname",
352                         &m);
353         if (r < 0)
354                 return r;
355
356         r = sd_bus_message_append(m, "sb", hostname, false);
357         if (r < 0)
358                 return r;
359
360         r = sd_bus_call_async(bus, m, set_hostname_handler, NULL, 0, NULL);
361         if (r < 0)
362                 log_error("Could not set transient hostname: %s", strerror(-r));
363
364         return r;
365 }
366
367 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
368         Link *link = userdata;
369         int r;
370
371         assert(m);
372         assert(link);
373         assert(link->ifname);
374
375         if (link->state == LINK_STATE_FAILED)
376                 return 1;
377
378         r = sd_rtnl_message_get_errno(m);
379         if (r < 0)
380                 log_struct_link(LOG_WARNING, link,
381                                 "MESSAGE=%s: could not set MTU: %s",
382                                 link->ifname, strerror(-r),
383                                 "ERRNO=%d", -r,
384                                 NULL);
385
386         return 1;
387 }
388
389 static int link_set_mtu(Link *link, uint32_t mtu) {
390         _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
391         int r;
392
393         assert(link);
394         assert(link->manager);
395         assert(link->manager->rtnl);
396
397         log_debug_link(link, "setting MTU: %" PRIu32, mtu);
398
399         r = sd_rtnl_message_link_new(RTM_SETLINK, link->ifindex, &req);
400         if (r < 0) {
401                 log_error_link(link, "Could not allocate RTM_SETLINK message");
402                 return r;
403         }
404
405         r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
406         if (r < 0) {
407                 log_error_link(link, "Could not append MTU: %s", strerror(-r));
408                 return r;
409         }
410
411         r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
412         if (r < 0) {
413                 log_error_link(link,
414                                "Could not send rtnetlink message: %s", strerror(-r));
415                 return r;
416         }
417
418         return 0;
419 }
420
421 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
422         Link *link = userdata;
423         struct in_addr address;
424         struct in_addr netmask;
425         struct in_addr gateway;
426         unsigned prefixlen;
427         int r;
428
429         assert(link);
430         assert(link->network);
431         assert(link->manager);
432
433         if (link->state == LINK_STATE_FAILED)
434                 return;
435
436         if (event < 0) {
437                 log_warning_link(link, "DHCP error: %s", strerror(-event));
438                 link_enter_failed(link);
439                 return;
440         }
441
442         if (event == DHCP_EVENT_NO_LEASE)
443                 log_debug_link(link, "IP address in use.");
444
445         if (event == DHCP_EVENT_IP_CHANGE || event == DHCP_EVENT_EXPIRED ||
446             event == DHCP_EVENT_STOP) {
447                 if (link->network->dhcp_critical) {
448                         log_warning_link(link, "DHCPv4 connection considered system critical, "
449                                          "ignoring request to reconfigure it down.");
450                         return;
451                 }
452
453                 if (link->dhcp_address) {
454                         address_drop(link->dhcp_address, link, address_drop_handler);
455
456                         address_free(link->dhcp_address);
457                         link->dhcp_address = NULL;
458                 }
459
460                 if (link->dhcp_route) {
461                         route_free(link->dhcp_route);
462                         link->dhcp_route = NULL;
463                 }
464
465                 if (link->network->dhcp_mtu) {
466                         uint16_t mtu;
467
468                         r = sd_dhcp_client_get_mtu(client, &mtu);
469                         if (r >= 0 && link->original_mtu != mtu) {
470                                 r = link_set_mtu(link, link->original_mtu);
471                                 if (r < 0) {
472                                         log_warning_link(link, "DHCP error: could not reset MTU");
473                                         link_enter_failed(link);
474                                         return;
475                                 }
476                         }
477                 }
478
479                 if (link->network->dhcp_hostname) {
480                         r = set_hostname(link->manager->bus, "");
481                         if (r < 0)
482                                 log_error("Failed to reset transient hostname");
483                 }
484         }
485
486         r = sd_dhcp_client_get_address(client, &address);
487         if (r < 0) {
488                 log_warning_link(link, "DHCP error: no address");
489                 link_enter_failed(link);
490                 return;
491         }
492
493         r = sd_dhcp_client_get_netmask(client, &netmask);
494         if (r < 0) {
495                 log_warning_link(link, "DHCP error: no netmask");
496                 link_enter_failed(link);
497                 return;
498         }
499
500         prefixlen = net_netmask_to_prefixlen(&netmask);
501
502         r = sd_dhcp_client_get_router(client, &gateway);
503         if (r < 0) {
504                 log_warning_link(link, "DHCP error: no router");
505                 link_enter_failed(link);
506                 return;
507         }
508
509         if (event == DHCP_EVENT_IP_CHANGE || event == DHCP_EVENT_IP_ACQUIRE) {
510                 _cleanup_address_free_ Address *addr = NULL;
511                 _cleanup_route_free_ Route *rt = NULL;
512                 struct in_addr *nameservers;
513                 size_t nameservers_size;
514
515                 log_struct_link(LOG_INFO, link,
516                                 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
517                                 link->ifname,
518                                 ADDRESS_FMT_VAL(address),
519                                 prefixlen,
520                                 ADDRESS_FMT_VAL(gateway),
521                                 "ADDRESS=%u.%u.%u.%u",
522                                 ADDRESS_FMT_VAL(address),
523                                 "PREFIXLEN=%u",
524                                 prefixlen,
525                                 "GATEWAY=%u.%u.%u.%u",
526                                 ADDRESS_FMT_VAL(gateway),
527                                 NULL);
528
529                 r = address_new_dynamic(&addr);
530                 if (r < 0) {
531                         log_error_link(link, "Could not allocate address");
532                         link_enter_failed(link);
533                         return;
534                 }
535
536                 addr->family = AF_INET;
537                 addr->in_addr.in = address;
538                 addr->prefixlen = prefixlen;
539                 addr->broadcast.s_addr = address.s_addr | ~netmask.s_addr;
540
541                 r = route_new_dynamic(&rt);
542                 if (r < 0) {
543                         log_error_link(link, "Could not allocate route");
544                         link_enter_failed(link);
545                         return;
546                 }
547
548                 rt->family = AF_INET;
549                 rt->in_addr.in = gateway;
550
551                 link->dhcp_address = addr;
552                 link->dhcp_route = rt;
553                 addr = NULL;
554                 rt = NULL;
555
556                 if (link->network->dhcp_dns) {
557                         r = sd_dhcp_client_get_dns(client, &nameservers, &nameservers_size);
558                         if (r >= 0) {
559                                 r = manager_update_resolv_conf(link->manager);
560                                 if (r < 0)
561                                         log_error("Failed to update resolv.conf");
562                         }
563                 }
564
565                 if (link->network->dhcp_mtu) {
566                         uint16_t mtu;
567
568                         r = sd_dhcp_client_get_mtu(client, &mtu);
569                         if (r >= 0) {
570                                 r = link_set_mtu(link, mtu);
571                                 if (r < 0)
572                                         log_error_link(link, "Failed to set MTU "
573                                                              "to %" PRIu16, mtu);
574                         }
575                 }
576
577                 if (link->network->dhcp_hostname) {
578                         const char *hostname;
579
580                         r = sd_dhcp_client_get_hostname(client, &hostname);
581                         if (r >= 0) {
582                                 r = set_hostname(link->manager->bus, hostname);
583                                 if (r < 0)
584                                         log_error("Failed to set transient hostname "
585                                                   "to '%s'", hostname);
586                         }
587                 }
588
589                 link_enter_set_addresses(link);
590         }
591
592         return;
593 }
594
595 static int link_acquire_conf(Link *link) {
596         int r;
597
598         assert(link);
599         assert(link->network);
600         assert(link->network->dhcp);
601         assert(link->manager);
602         assert(link->manager->event);
603
604         if (!link->dhcp) {
605                 r = sd_dhcp_client_new(&link->dhcp);
606                 if (r < 0)
607                         return r;
608
609                 r = sd_dhcp_client_attach_event(link->dhcp, NULL, 0);
610                 if (r < 0)
611                         return r;
612
613                 r = sd_dhcp_client_set_index(link->dhcp, link->ifindex);
614                 if (r < 0)
615                         return r;
616
617                 r = sd_dhcp_client_set_mac(link->dhcp, &link->mac);
618                 if (r < 0)
619                         return r;
620
621                 r = sd_dhcp_client_set_callback(link->dhcp, dhcp_handler, link);
622                 if (r < 0)
623                         return r;
624
625                 if (link->network->dhcp_mtu) {
626                         r = sd_dhcp_client_set_request_option(link->dhcp, 26);
627                         if (r < 0)
628                                 return r;
629                 }
630         }
631
632         log_debug_link(link, "acquiring DHCPv4 lease");
633
634         r = sd_dhcp_client_start(link->dhcp);
635         if (r < 0)
636                 return r;
637
638         return 0;
639 }
640
641 static int link_update_flags(Link *link, unsigned flags) {
642         int r;
643
644         assert(link);
645         assert(link->network);
646
647         if (link->state == LINK_STATE_FAILED)
648                 return 0;
649
650         if (link->flags == flags) {
651                 log_debug_link(link, "link status unchanged: %#.8x", flags);
652                 return 0;
653         }
654
655         if ((link->flags & IFF_UP) != (flags & IFF_UP))
656                 log_info_link(link,
657                               "link is %s", flags & IFF_UP ? "up": "down");
658
659         if ((link->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
660                 if (flags & IFF_LOWER_UP) {
661                         log_info_link(link, "carrier on");
662
663                         if (link->network->dhcp) {
664                                 r = link_acquire_conf(link);
665                                 if (r < 0) {
666                                         log_warning_link(link, "Could not acquire DHCPv4 lease: %s", strerror(-r));
667                                         link_enter_failed(link);
668                                         return r;
669                                 }
670                         }
671                 } else {
672                         log_info_link(link, "carrier off");
673
674                         if (link->network->dhcp) {
675                                 r = sd_dhcp_client_stop(link->dhcp);
676                                 if (r < 0) {
677                                         log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
678                                         link_enter_failed(link);
679                                         return r;
680                                 }
681                         }
682                 }
683         }
684
685         log_debug_link(link,
686                        "link status updated: %#.8x -> %#.8x", link->flags, flags);
687
688         link->flags = flags;
689
690         return 0;
691 }
692
693 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
694         Link *link = userdata;
695         int r;
696
697         assert(link);
698
699         if (link->state == LINK_STATE_FAILED)
700                 return 1;
701
702         r = sd_rtnl_message_get_errno(m);
703         if (r < 0) {
704                 log_struct_link(LOG_ERR, link,
705                                 "MESSAGE=%s: could not bring up interface: %s",
706                                 link->ifname, strerror(-r),
707                                 "ERRNO=%d", -r,
708                                 NULL);
709                 link_enter_failed(link);
710                 return 1;
711         }
712
713         link_update_flags(link, link->flags | IFF_UP);
714
715         return 1;
716 }
717
718 static int link_up(Link *link) {
719         _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
720         int r;
721
722         assert(link);
723         assert(link->manager);
724         assert(link->manager->rtnl);
725
726         log_debug_link(link, "bringing link up");
727
728         r = sd_rtnl_message_link_new(RTM_SETLINK, link->ifindex, &req);
729         if (r < 0) {
730                 log_error_link(link, "Could not allocate RTM_SETLINK message");
731                 return r;
732         }
733
734         r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
735         if (r < 0) {
736                 log_error_link(link, "Could not set link flags: %s", strerror(-r));
737                 return r;
738         }
739
740         r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
741         if (r < 0) {
742                 log_error_link(link,
743                                "Could not send rtnetlink message: %s", strerror(-r));
744                 return r;
745         }
746
747         return 0;
748 }
749
750 static int link_enslaved(Link *link) {
751         int r;
752
753         assert(link);
754         assert(link->state == LINK_STATE_ENSLAVING);
755         assert(link->network);
756
757         r = link_up(link);
758         if (r < 0) {
759                 link_enter_failed(link);
760                 return r;
761         }
762
763         if (!link->network->dhcp)
764                 return link_enter_set_addresses(link);
765
766         return 0;
767 }
768
769 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
770         Link *link = userdata;
771         int r;
772
773         assert(link);
774         assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
775         assert(link->network);
776
777         link->enslaving --;
778
779         if (link->state == LINK_STATE_FAILED)
780                 return 1;
781
782         r = sd_rtnl_message_get_errno(m);
783         if (r < 0) {
784                 log_struct_link(LOG_ERR, link,
785                                 "MESSAGE=%s: could not enslave: %s",
786                                 link->ifname, strerror(-r),
787                                 "ERRNO=%d", -r,
788                                 NULL);
789                 link_enter_failed(link);
790                 return 1;
791         }
792
793         log_debug_link(link, "enslaved");
794
795         if (link->enslaving == 0)
796                 link_enslaved(link);
797
798         return 1;
799 }
800
801 static int link_enter_enslave(Link *link) {
802         int r;
803
804         assert(link);
805         assert(link->network);
806         assert(link->state == _LINK_STATE_INVALID);
807
808         link->state = LINK_STATE_ENSLAVING;
809
810         if (!link->network->bridge && !link->network->bond && !link->network->vlan)
811                 return link_enslaved(link);
812
813         if (link->network->bridge) {
814                 log_struct_link(LOG_DEBUG, link,
815                                 "MESSAGE=%s: enslaving by '%s'",
816                                 link->ifname, link->network->bridge->name,
817                                 NETDEV(link->network->bridge),
818                                 NULL);
819
820                 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
821                 if (r < 0) {
822                         log_struct_link(LOG_WARNING, link,
823                                         "MESSAGE=%s: could not enslave by '%s': %s",
824                                         link->ifname, link->network->bridge->name, strerror(-r),
825                                         NETDEV(link->network->bridge),
826                                         NULL);
827                         link_enter_failed(link);
828                         return r;
829                 }
830
831                 link->enslaving ++;
832         }
833
834         if (link->network->vlan) {
835                 log_struct_link(LOG_DEBUG, link,
836                                 "MESSAGE=%s: enslaving by '%s'",
837                                 link->ifname, link->network->vlan->name,
838                                 NETDEV(link->network->vlan),
839                                 NULL);
840
841                 r = netdev_enslave(link->network->vlan, link, &enslave_handler);
842                 if (r < 0) {
843                         log_struct_link(LOG_WARNING, link,
844                                         "MESSAGE=%s: could not enslave by '%s': %s",
845                                         link->ifname, link->network->vlan->name,
846                                         strerror(-r), NETDEV(link->network->vlan),
847                                         NULL);
848                         link_enter_failed(link);
849                         return r;
850                 }
851
852                 link->enslaving ++;
853         }
854
855         return 0;
856 }
857
858 static int link_get_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
859         Link *link = userdata;
860         int r;
861
862         assert(link);
863
864         if (link->state == LINK_STATE_FAILED)
865                 return 1;
866
867         r = sd_rtnl_message_get_errno(m);
868         if (r < 0) {
869                 log_struct_link(LOG_ERR, link,
870                                 "MESSAGE=%s: could not get state: %s",
871                                 link->ifname, strerror(-r),
872                                 "ERRNO=%d", -r,
873                                 NULL);
874                 link_enter_failed(link);
875                 return 1;
876         }
877
878         log_debug_link(link, "got link state");
879
880         link_update(link, m);
881
882         return 1;
883 }
884
885 static int link_get(Link *link) {
886         _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
887         int r;
888
889         assert(link);
890         assert(link->manager);
891         assert(link->manager->rtnl);
892
893         log_debug_link(link, "requesting link status");
894
895         r = sd_rtnl_message_link_new(RTM_GETLINK, link->ifindex, &req);
896         if (r < 0) {
897                 log_error_link(link, "Could not allocate RTM_GETLINK message");
898                 return r;
899         }
900
901         r = sd_rtnl_call_async(link->manager->rtnl, req, link_get_handler, link, 0, NULL);
902         if (r < 0) {
903                 log_error_link(link,
904                                "Could not send rtnetlink message: %s", strerror(-r));
905                 return r;
906         }
907
908         return 0;
909 }
910
911 int link_configure(Link *link) {
912         int r;
913
914         assert(link);
915         assert(link->network);
916         assert(link->state == _LINK_STATE_INVALID);
917
918         r = link_get(link);
919         if (r < 0) {
920                 link_enter_failed(link);
921                 return r;
922         }
923
924         return link_enter_enslave(link);
925 }
926
927 int link_update(Link *link, sd_rtnl_message *m) {
928         unsigned flags;
929         void *data;
930         uint16_t type;
931         int r;
932
933         assert(link);
934         assert(m);
935
936         if (link->state == LINK_STATE_FAILED)
937                 return 0;
938
939         r = sd_rtnl_message_link_get_flags(m, &flags);
940         if (r < 0) {
941                 log_warning_link(link, "Could not get link flags");
942                 return r;
943         }
944
945         while (sd_rtnl_message_read(m, &type, &data) > 0) {
946                 if (type == IFLA_MTU && link->network->dhcp &&
947                     link->network->dhcp_mtu && !link->original_mtu) {
948                         link->original_mtu = *(uint16_t *) data;
949                         log_debug_link(link, "saved original MTU: %" PRIu16,
950                                        link->original_mtu);
951                 }
952         }
953
954         return link_update_flags(link, flags);
955 }