chiark / gitweb /
7f815382a4a643c4f9c5cba74930fc3f8c11df40
[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 "network-internal.h"
30
31 #include "dhcp-lease-internal.h"
32
33 static int ipv4ll_address_update(Link *link, bool deprecate);
34 static bool ipv4ll_is_bound(sd_ipv4ll *ll);
35
36 int link_new(Manager *manager, struct udev_device *device, Link **ret) {
37         _cleanup_link_free_ Link *link = NULL;
38         const char *ifname;
39         int r;
40
41         assert(manager);
42         assert(manager->links);
43         assert(device);
44         assert(ret);
45
46         link = new0(Link, 1);
47         if (!link)
48                 return -ENOMEM;
49
50         link->manager = manager;
51         link->state = _LINK_STATE_INVALID;
52
53         link->ifindex = udev_device_get_ifindex(device);
54         if (link->ifindex <= 0)
55                 return -EINVAL;
56
57         r = asprintf(&link->state_file, "/run/systemd/network/links/%"PRIu64,
58                      link->ifindex);
59         if (r < 0)
60                 return -ENOMEM;
61
62         ifname = udev_device_get_sysname(device);
63         link->ifname = strdup(ifname);
64
65         r = hashmap_put(manager->links, &link->ifindex, link);
66         if (r < 0)
67                 return r;
68
69         link->udev_device = udev_device_ref(device);
70
71         *ret = link;
72         link = NULL;
73
74         return 0;
75 }
76
77 void link_free(Link *link) {
78         if (!link)
79                 return;
80
81         assert(link->manager);
82
83         sd_dhcp_client_unref(link->dhcp_client);
84         sd_dhcp_lease_unref(link->dhcp_lease);
85
86         sd_ipv4ll_unref(link->ipv4ll);
87
88         hashmap_remove(link->manager->links, &link->ifindex);
89
90         free(link->ifname);
91         free(link->state_file);
92
93         udev_device_unref(link->udev_device);
94
95         free(link);
96 }
97
98 int link_get(Manager *m, int ifindex, Link **ret) {
99         Link *link;
100         uint64_t ifindex_64;
101
102         assert(m);
103         assert(m->links);
104         assert(ifindex);
105         assert(ret);
106
107         ifindex_64 = ifindex;
108         link = hashmap_get(m->links, &ifindex_64);
109         if (!link)
110                 return -ENODEV;
111
112         *ret = link;
113
114         return 0;
115 }
116
117 static int link_enter_configured(Link *link) {
118         assert(link);
119         assert(link->state == LINK_STATE_SETTING_ROUTES);
120
121         log_info_link(link, "link configured");
122
123         link->state = LINK_STATE_CONFIGURED;
124
125         link_save(link);
126
127         return 0;
128 }
129
130 static void link_enter_failed(Link *link) {
131         assert(link);
132
133         log_warning_link(link, "failed");
134
135         link->state = LINK_STATE_FAILED;
136
137         link_save(link);
138 }
139
140 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
141         Link *link = userdata;
142         int r;
143
144         assert(link->route_messages > 0);
145         assert(link->state == LINK_STATE_SETTING_ADDRESSES ||
146                link->state == LINK_STATE_SETTING_ROUTES ||
147                link->state == LINK_STATE_FAILED);
148
149         link->route_messages --;
150
151         if (link->state == LINK_STATE_FAILED)
152                 return 1;
153
154         r = sd_rtnl_message_get_errno(m);
155         if (r < 0 && r != -EEXIST)
156                 log_struct_link(LOG_WARNING, link,
157                                 "MESSAGE=%s: could not set route: %s",
158                                 link->ifname, strerror(-r),
159                                 "ERRNO=%d", -r,
160                                 NULL);
161
162         /* we might have received an old reply after moving back to SETTING_ADDRESSES,
163          * ignore it */
164         if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
165                 log_debug_link(link, "routes set");
166                 link_enter_configured(link);
167         }
168
169         return 1;
170 }
171
172 static int link_enter_set_routes(Link *link) {
173         Route *rt;
174         int r;
175
176         assert(link);
177         assert(link->network);
178         assert(link->state == LINK_STATE_SETTING_ADDRESSES);
179
180         link->state = LINK_STATE_SETTING_ROUTES;
181
182         if (!link->network->static_routes && !link->dhcp_lease &&
183                 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
184                 return link_enter_configured(link);
185
186         log_debug_link(link, "setting routes");
187
188         LIST_FOREACH(static_routes, rt, link->network->static_routes) {
189                 r = route_configure(rt, link, &route_handler);
190                 if (r < 0) {
191                         log_warning_link(link,
192                                          "could not set routes: %s", strerror(-r));
193                         link_enter_failed(link);
194                         return r;
195                 }
196
197                 link->route_messages ++;
198         }
199
200         if (link->ipv4ll && !link->dhcp_lease) {
201                 _cleanup_route_free_ Route *route = NULL;
202                 struct in_addr addr;
203
204                 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
205                 if (r < 0 && r != -ENOENT) {
206                         log_warning_link(link, "IPV4LL error: no address: %s",
207                                         strerror(-r));
208                         return r;
209                 }
210
211                 if (r != -ENOENT) {
212                         r = route_new_dynamic(&route);
213                         if (r < 0) {
214                                 log_error_link(link, "Could not allocate route: %s",
215                                                strerror(-r));
216                                 return r;
217                         }
218
219                         route->family = AF_INET;
220                         route->scope = RT_SCOPE_LINK;
221                         route->metrics = 99;
222
223                         r = route_configure(route, link, &route_handler);
224                         if (r < 0) {
225                                 log_warning_link(link,
226                                                  "could not set routes: %s", strerror(-r));
227                                 link_enter_failed(link);
228                                 return r;
229                         }
230
231                         link->route_messages ++;
232                 }
233         }
234
235         if (link->dhcp_lease) {
236                 _cleanup_route_free_ Route *route = NULL;
237                 _cleanup_route_free_ Route *route_gw = NULL;
238                 struct in_addr gateway;
239
240                 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
241                 if (r < 0) {
242                         log_warning_link(link, "DHCP error: no router: %s",
243                                          strerror(-r));
244                         return r;
245                 }
246
247                 r = route_new_dynamic(&route);
248                 if (r < 0) {
249                         log_error_link(link, "Could not allocate route: %s",
250                                        strerror(-r));
251                         return r;
252                 }
253
254                 r = route_new_dynamic(&route_gw);
255                 if (r < 0) {
256                         log_error_link(link, "Could not allocate route: %s",
257                                        strerror(-r));
258                         return r;
259                 }
260
261                 /* The dhcp netmask may mask out the gateway. Add an explicit
262                  * route for the gw host so that we can route no matter the
263                  * netmask or existing kernel route tables. */
264                 route_gw->family = AF_INET;
265                 route_gw->dst_addr.in = gateway;
266                 route_gw->dst_prefixlen = 32;
267                 route_gw->scope = RT_SCOPE_LINK;
268
269                 r = route_configure(route_gw, link, &route_handler);
270                 if (r < 0) {
271                         log_warning_link(link,
272                                          "could not set host route: %s", strerror(-r));
273                         return r;
274                 }
275
276                 link->route_messages ++;
277
278                 route->family = AF_INET;
279                 route->in_addr.in = gateway;
280
281                 r = route_configure(route, link, &route_handler);
282                 if (r < 0) {
283                         log_warning_link(link,
284                                          "could not set routes: %s", strerror(-r));
285                         link_enter_failed(link);
286                         return r;
287                 }
288
289                 link->route_messages ++;
290         }
291
292         return 0;
293 }
294
295 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
296         Link *link = userdata;
297         int r;
298
299         assert(m);
300         assert(link);
301         assert(link->ifname);
302
303         if (link->state == LINK_STATE_FAILED)
304                 return 1;
305
306         r = sd_rtnl_message_get_errno(m);
307         if (r < 0 && r != -ENOENT)
308                 log_struct_link(LOG_WARNING, link,
309                                 "MESSAGE=%s: could not drop route: %s",
310                                 link->ifname, strerror(-r),
311                                 "ERRNO=%d", -r,
312                                 NULL);
313
314         return 0;
315 }
316
317 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
318         Link *link = userdata;
319         int r;
320
321         assert(m);
322         assert(link);
323         assert(link->ifname);
324         assert(link->addr_messages > 0);
325         assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
326
327         link->addr_messages --;
328
329         if (link->state == LINK_STATE_FAILED)
330                 return 1;
331
332         r = sd_rtnl_message_get_errno(m);
333         if (r < 0 && r != -EEXIST)
334                 log_struct_link(LOG_WARNING, link,
335                                 "MESSAGE=%s: could not set address: %s",
336                                 link->ifname, strerror(-r),
337                                 "ERRNO=%d", -r,
338                                 NULL);
339
340         if (link->addr_messages == 0) {
341                 log_debug_link(link, "addresses set");
342                 link_enter_set_routes(link);
343         }
344
345         return 1;
346 }
347
348 static int link_enter_set_addresses(Link *link) {
349         Address *ad;
350         int r;
351
352         assert(link);
353         assert(link->network);
354         assert(link->state != _LINK_STATE_INVALID);
355
356         link->state = LINK_STATE_SETTING_ADDRESSES;
357
358         if (!link->network->static_addresses && !link->dhcp_lease &&
359                 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
360                 return link_enter_set_routes(link);
361
362         log_debug_link(link, "setting addresses");
363
364         LIST_FOREACH(static_addresses, ad, link->network->static_addresses) {
365                 r = address_configure(ad, link, &address_handler);
366                 if (r < 0) {
367                         log_warning_link(link,
368                                          "could not set addresses: %s", strerror(-r));
369                         link_enter_failed(link);
370                         return r;
371                 }
372
373                 link->addr_messages ++;
374         }
375
376         if (link->ipv4ll && !link->dhcp_lease) {
377                 _cleanup_address_free_ Address *ll_addr = NULL;
378                 struct in_addr addr;
379
380                 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
381                 if (r < 0 && r != -ENOENT) {
382                         log_warning_link(link, "IPV4LL error: no address: %s",
383                                         strerror(-r));
384                         return r;
385                 }
386
387                 if (r != -ENOENT) {
388                         r = address_new_dynamic(&ll_addr);
389                         if (r < 0) {
390                                 log_error_link(link, "Could not allocate address: %s", strerror(-r));
391                                 return r;
392                         }
393
394                         ll_addr->family = AF_INET;
395                         ll_addr->in_addr.in = addr;
396                         ll_addr->prefixlen = 16;
397                         ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
398                         ll_addr->scope = RT_SCOPE_LINK;
399
400                         r = address_configure(ll_addr, link, &address_handler);
401                         if (r < 0) {
402                                 log_warning_link(link,
403                                          "could not set addresses: %s", strerror(-r));
404                                 link_enter_failed(link);
405                                 return r;
406                         }
407
408                         link->addr_messages ++;
409                 }
410         }
411
412         if (link->dhcp_lease) {
413                 _cleanup_address_free_ Address *address = NULL;
414                 struct in_addr addr;
415                 struct in_addr netmask;
416                 unsigned prefixlen;
417
418                 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
419                 if (r < 0) {
420                         log_warning_link(link, "DHCP error: no address: %s",
421                                          strerror(-r));
422                         return r;
423                 }
424
425                 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
426                 if (r < 0) {
427                         log_warning_link(link, "DHCP error: no netmask: %s",
428                                          strerror(-r));
429                         return r;
430                 }
431
432                 prefixlen = net_netmask_to_prefixlen(&netmask);
433
434                 r = address_new_dynamic(&address);
435                 if (r < 0) {
436                         log_error_link(link, "Could not allocate address: %s",
437                                        strerror(-r));
438                         return r;
439                 }
440
441                 address->family = AF_INET;
442                 address->in_addr.in = addr;
443                 address->prefixlen = prefixlen;
444                 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
445
446                 r = address_configure(address, link, &address_handler);
447                 if (r < 0) {
448                         log_warning_link(link,
449                                          "could not set addresses: %s", strerror(-r));
450                         link_enter_failed(link);
451                         return r;
452                 }
453
454                 link->addr_messages ++;
455         }
456
457         return 0;
458 }
459
460 static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
461         Link *link = userdata;
462         int r;
463
464         assert(m);
465         assert(link);
466         assert(link->ifname);
467
468         if (link->state == LINK_STATE_FAILED)
469                 return 1;
470
471         r = sd_rtnl_message_get_errno(m);
472         if (r < 0 && r != -ENOENT)
473                 log_struct_link(LOG_WARNING, link,
474                                 "MESSAGE=%s: could not update address: %s",
475                                 link->ifname, strerror(-r),
476                                 "ERRNO=%d", -r,
477                                 NULL);
478
479         return 0;
480 }
481
482 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
483         Link *link = userdata;
484         int r;
485
486         assert(m);
487         assert(link);
488         assert(link->ifname);
489
490         if (link->state == LINK_STATE_FAILED)
491                 return 1;
492
493         r = sd_rtnl_message_get_errno(m);
494         if (r < 0 && r != -ENOENT)
495                 log_struct_link(LOG_WARNING, link,
496                                 "MESSAGE=%s: could not drop address: %s",
497                                 link->ifname, strerror(-r),
498                                 "ERRNO=%d", -r,
499                                 NULL);
500
501         return 0;
502 }
503
504 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
505         int r;
506
507         r = sd_bus_message_get_errno(m);
508         if (r < 0)
509                 log_warning("Could not set hostname: %s", strerror(-r));
510
511         return 1;
512 }
513
514 static int set_hostname(sd_bus *bus, const char *hostname) {
515         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
516         int r = 0;
517
518         assert(hostname);
519
520         log_debug("Setting transient hostname: '%s'", hostname);
521
522         if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
523                 log_info("Not connected to system bus, ignoring transient hostname.");
524                 return 0;
525         }
526
527         r = sd_bus_message_new_method_call(
528                         bus,
529                         &m,
530                         "org.freedesktop.hostname1",
531                         "/org/freedesktop/hostname1",
532                         "org.freedesktop.hostname1",
533                         "SetHostname");
534         if (r < 0)
535                 return r;
536
537         r = sd_bus_message_append(m, "sb", hostname, false);
538         if (r < 0)
539                 return r;
540
541         r = sd_bus_call_async(bus, m, set_hostname_handler, NULL, 0, NULL);
542         if (r < 0)
543                 log_error("Could not set transient hostname: %s", strerror(-r));
544
545         return r;
546 }
547
548 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
549         Link *link = userdata;
550         int r;
551
552         assert(m);
553         assert(link);
554         assert(link->ifname);
555
556         if (link->state == LINK_STATE_FAILED)
557                 return 1;
558
559         r = sd_rtnl_message_get_errno(m);
560         if (r < 0)
561                 log_struct_link(LOG_WARNING, link,
562                                 "MESSAGE=%s: could not set MTU: %s",
563                                 link->ifname, strerror(-r),
564                                 "ERRNO=%d", -r,
565                                 NULL);
566
567         return 1;
568 }
569
570 static int link_set_mtu(Link *link, uint32_t mtu) {
571         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
572         int r;
573
574         assert(link);
575         assert(link->manager);
576         assert(link->manager->rtnl);
577
578         log_debug_link(link, "setting MTU: %" PRIu32, mtu);
579
580         r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
581                                      RTM_SETLINK, link->ifindex);
582         if (r < 0) {
583                 log_error_link(link, "Could not allocate RTM_SETLINK message");
584                 return r;
585         }
586
587         r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
588         if (r < 0) {
589                 log_error_link(link, "Could not append MTU: %s", strerror(-r));
590                 return r;
591         }
592
593         r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
594         if (r < 0) {
595                 log_error_link(link,
596                                "Could not send rtnetlink message: %s", strerror(-r));
597                 return r;
598         }
599
600         return 0;
601 }
602
603 static int dhcp_lease_lost(Link *link) {
604         _cleanup_address_free_ Address *address = NULL;
605         _cleanup_route_free_ Route *route_gw = NULL;
606         _cleanup_route_free_ Route *route = NULL;
607         struct in_addr addr;
608         struct in_addr netmask;
609         struct in_addr gateway;
610         unsigned prefixlen;
611         int r;
612
613         assert(link);
614         assert(link->dhcp_lease);
615
616         log_warning_link(link, "DHCP lease lost");
617
618         r = address_new_dynamic(&address);
619         if (r >= 0) {
620                 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
621                 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
622                 sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
623                 prefixlen = net_netmask_to_prefixlen(&netmask);
624
625                 r = route_new_dynamic(&route_gw);
626                 if (r >= 0) {
627                         route_gw->family = AF_INET;
628                         route_gw->dst_addr.in = gateway;
629                         route_gw->dst_prefixlen = 32;
630                         route_gw->scope = RT_SCOPE_LINK;
631
632                         route_drop(route_gw, link, &route_drop_handler);
633                 }
634
635                 r = route_new_dynamic(&route);
636                 if (r >= 0) {
637                         route->family = AF_INET;
638                         route->in_addr.in = gateway;
639
640                         route_drop(route, link, &route_drop_handler);
641                 }
642
643                 address->family = AF_INET;
644                 address->in_addr.in = addr;
645                 address->prefixlen = prefixlen;
646
647                 address_drop(address, link, &address_drop_handler);
648         }
649
650         if (link->network->dhcp_mtu) {
651                 uint16_t mtu;
652
653                 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
654                 if (r >= 0 && link->original_mtu != mtu) {
655                         r = link_set_mtu(link, link->original_mtu);
656                         if (r < 0) {
657                                 log_warning_link(link, "DHCP error: could not reset MTU");
658                                 link_enter_failed(link);
659                                 return r;
660                         }
661                 }
662         }
663
664         if (link->network->dhcp_hostname) {
665                 const char *hostname = NULL;
666
667                 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
668                 if (r >= 0 && hostname) {
669                         r = set_hostname(link->manager->bus, "");
670                         if (r < 0)
671                                 log_error("Failed to reset transient hostname");
672                 }
673         }
674
675         link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
676
677         return 0;
678 }
679
680 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
681         sd_dhcp_lease *lease;
682         struct in_addr address;
683         struct in_addr netmask;
684         struct in_addr gateway;
685         unsigned prefixlen;
686         struct in_addr *nameservers;
687         size_t nameservers_size;
688         int r;
689
690         assert(client);
691         assert(link);
692
693         r = sd_dhcp_client_get_lease(client, &lease);
694         if (r < 0) {
695                 log_warning_link(link, "DHCP error: no lease: %s",
696                                  strerror(-r));
697                 return r;
698         }
699
700         r = sd_dhcp_lease_get_address(lease, &address);
701         if (r < 0) {
702                 log_warning_link(link, "DHCP error: no address: %s",
703                                  strerror(-r));
704                 return r;
705         }
706
707         r = sd_dhcp_lease_get_netmask(lease, &netmask);
708         if (r < 0) {
709                 log_warning_link(link, "DHCP error: no netmask: %s",
710                                  strerror(-r));
711                 return r;
712         }
713
714         prefixlen = net_netmask_to_prefixlen(&netmask);
715
716         r = sd_dhcp_lease_get_router(lease, &gateway);
717         if (r < 0) {
718                 log_warning_link(link, "DHCP error: no router: %s",
719                                  strerror(-r));
720                 return r;
721         }
722
723         log_struct_link(LOG_INFO, link,
724                         "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
725                          link->ifname,
726                          ADDRESS_FMT_VAL(address),
727                          prefixlen,
728                          ADDRESS_FMT_VAL(gateway),
729                          "ADDRESS=%u.%u.%u.%u",
730                          ADDRESS_FMT_VAL(address),
731                          "PREFIXLEN=%u",
732                          prefixlen,
733                          "GATEWAY=%u.%u.%u.%u",
734                          ADDRESS_FMT_VAL(gateway),
735                          NULL);
736
737         link->dhcp_lease = lease;
738
739         if (link->network->dhcp_dns) {
740                 r = sd_dhcp_lease_get_dns(lease, &nameservers, &nameservers_size);
741                 if (r >= 0) {
742                         r = manager_update_resolv_conf(link->manager);
743                         if (r < 0)
744                                 log_error("Failed to update resolv.conf");
745                 }
746         }
747
748         if (link->network->dhcp_mtu) {
749                 uint16_t mtu;
750
751                 r = sd_dhcp_lease_get_mtu(lease, &mtu);
752                 if (r >= 0) {
753                         r = link_set_mtu(link, mtu);
754                         if (r < 0)
755                                 log_error_link(link, "Failed to set MTU "
756                                                "to %" PRIu16, mtu);
757                 }
758         }
759
760         if (link->network->dhcp_hostname) {
761                 const char *hostname;
762
763                 r = sd_dhcp_lease_get_hostname(lease, &hostname);
764                 if (r >= 0) {
765                         r = set_hostname(link->manager->bus, hostname);
766                         if (r < 0)
767                                 log_error("Failed to set transient hostname "
768                                           "to '%s'", hostname);
769                 }
770         }
771
772         link_enter_set_addresses(link);
773
774         return 0;
775 }
776
777 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
778         Link *link = userdata;
779         int r = 0;
780
781         assert(link);
782         assert(link->network);
783         assert(link->manager);
784
785         if (link->state == LINK_STATE_FAILED)
786                 return;
787
788         switch (event) {
789                 case DHCP_EVENT_NO_LEASE:
790                         log_debug_link(link, "IP address in use.");
791                         break;
792                 case DHCP_EVENT_EXPIRED:
793                 case DHCP_EVENT_STOP:
794                 case DHCP_EVENT_IP_CHANGE:
795                         if (link->network->dhcp_critical) {
796                                 log_error_link(link, "DHCPv4 connection considered system critical, "
797                                                "ignoring request to reconfigure it.");
798                                 return;
799                         }
800
801                         if (link->dhcp_lease) {
802                                 r = dhcp_lease_lost(link);
803                                 if (r < 0) {
804                                         link_enter_failed(link);
805                                         return;
806                                 }
807                         }
808
809                         if (event == DHCP_EVENT_IP_CHANGE) {
810                                 r = dhcp_lease_acquired(client, link);
811                                 if (r < 0) {
812                                         link_enter_failed(link);
813                                         return;
814                                 }
815                         }
816
817                         if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
818                                 if (!sd_ipv4ll_is_running(link->ipv4ll))
819                                         r = sd_ipv4ll_start(link->ipv4ll);
820                                 else if (ipv4ll_is_bound(link->ipv4ll))
821                                         r = ipv4ll_address_update(link, false);
822                                 if (r < 0) {
823                                         link_enter_failed(link);
824                                         return;
825                                 }
826                         }
827
828                         break;
829                 case DHCP_EVENT_IP_ACQUIRE:
830                         r = dhcp_lease_acquired(client, link);
831                         if (r < 0) {
832                                 link_enter_failed(link);
833                                 return;
834                         }
835                         if (link->ipv4ll) {
836                                 if (ipv4ll_is_bound(link->ipv4ll))
837                                         r = ipv4ll_address_update(link, true);
838                                 else
839                                         r = sd_ipv4ll_stop(link->ipv4ll);
840                                 if (r < 0) {
841                                         link_enter_failed(link);
842                                         return;
843                                 }
844                         }
845                         break;
846                 default:
847                         if (event < 0)
848                                 log_warning_link(link, "DHCP error: %s", strerror(-event));
849                         else
850                                 log_warning_link(link, "DHCP unknown event: %d", event);
851                         break;
852         }
853
854         return;
855 }
856
857 static int ipv4ll_address_update(Link *link, bool deprecate) {
858         int r;
859         struct in_addr addr;
860
861         assert(link);
862
863         r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
864         if (r >= 0) {
865                 _cleanup_address_free_ Address *address = NULL;
866
867                 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
868                                deprecate ? "deprecate" : "approve",
869                                ADDRESS_FMT_VAL(addr));
870
871                 r = address_new_dynamic(&address);
872                 if (r < 0) {
873                         log_error_link(link, "Could not allocate address: %s", strerror(-r));
874                         return r;
875                 }
876
877                 address->family = AF_INET;
878                 address->in_addr.in = addr;
879                 address->prefixlen = 16;
880                 address->scope = RT_SCOPE_LINK;
881                 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
882                 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
883
884                 address_update(address, link, &address_update_handler);
885         }
886
887         return 0;
888
889 }
890
891 static int ipv4ll_address_lost(Link *link) {
892         int r;
893         struct in_addr addr;
894
895         assert(link);
896
897         r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
898         if (r >= 0) {
899                 _cleanup_address_free_ Address *address = NULL;
900                 _cleanup_route_free_ Route *route = NULL;
901
902                 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
903                                 ADDRESS_FMT_VAL(addr));
904
905                 r = address_new_dynamic(&address);
906                 if (r < 0) {
907                         log_error_link(link, "Could not allocate address: %s", strerror(-r));
908                         return r;
909                 }
910
911                 address->family = AF_INET;
912                 address->in_addr.in = addr;
913                 address->prefixlen = 16;
914                 address->scope = RT_SCOPE_LINK;
915
916                 address_drop(address, link, &address_drop_handler);
917
918                 r = route_new_dynamic(&route);
919                 if (r < 0) {
920                         log_error_link(link, "Could not allocate route: %s",
921                                        strerror(-r));
922                         return r;
923                 }
924
925                 route->family = AF_INET;
926                 route->scope = RT_SCOPE_LINK;
927                 route->metrics = 99;
928
929                 route_drop(route, link, &route_drop_handler);
930         }
931
932         return 0;
933 }
934
935 static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
936         int r;
937         struct in_addr addr;
938
939         assert(ll);
940
941         r = sd_ipv4ll_get_address(ll, &addr);
942         if (r < 0)
943                 return false;
944         return true;
945 }
946
947 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
948         struct in_addr address;
949         int r;
950
951         assert(ll);
952         assert(link);
953
954         r = sd_ipv4ll_get_address(ll, &address);
955         if (r < 0)
956                 return r;
957
958         log_struct_link(LOG_INFO, link,
959                         "MESSAGE=%s: IPv4 link-local address %u.%u.%u.%u",
960                         link->ifname,
961                         ADDRESS_FMT_VAL(address),
962                         NULL);
963
964        link_enter_set_addresses(link);
965
966        return 0;
967 }
968
969 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
970         Link *link = userdata;
971         int r;
972
973         assert(link);
974         assert(link->network);
975         assert(link->manager);
976
977         switch(event) {
978                 case IPV4LL_EVENT_STOP:
979                 case IPV4LL_EVENT_CONFLICT:
980                         r = ipv4ll_address_lost(link);
981                         if (r < 0) {
982                                 link_enter_failed(link);
983                                 return;
984                         }
985                         break;
986                 case IPV4LL_EVENT_BIND:
987                         r = ipv4ll_address_claimed(ll, link);
988                         if (r < 0) {
989                                 link_enter_failed(link);
990                                 return;
991                         }
992                         break;
993                 default:
994                         if (event < 0)
995                                 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
996                         else
997                                 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
998                         break;
999         }
1000 }
1001
1002 static int link_acquire_conf(Link *link) {
1003         int r;
1004
1005         assert(link);
1006         assert(link->network);
1007         assert(link->manager);
1008         assert(link->manager->event);
1009
1010         if (link->network->ipv4ll) {
1011                 assert(link->ipv4ll);
1012
1013                 log_debug_link(link, "acquiring IPv4 link-local address");
1014
1015                 r = sd_ipv4ll_start(link->ipv4ll);
1016                 if (r < 0)
1017                         return r;
1018         }
1019
1020         if (link->network->dhcp) {
1021                 assert(link->dhcp_client);
1022
1023                 log_debug_link(link, "acquiring DHCPv4 lease");
1024
1025                 r = sd_dhcp_client_start(link->dhcp_client);
1026                 if (r < 0)
1027                         return r;
1028         }
1029
1030         return 0;
1031 }
1032
1033 static int link_update_flags(Link *link, unsigned flags) {
1034         unsigned flags_added, flags_removed, generic_flags;
1035         bool carrier_gained, carrier_lost;
1036         int r;
1037
1038         assert(link);
1039         assert(link->network);
1040
1041         if (link->state == LINK_STATE_FAILED)
1042                 return 0;
1043
1044         if (link->flags == flags)
1045                 return 0;
1046
1047         flags_added = (link->flags ^ flags) & flags;
1048         flags_removed = (link->flags ^ flags) & link->flags;
1049         generic_flags = ~(IFF_UP | IFF_LOWER_UP | IFF_RUNNING);
1050
1051         /* consider link to have carrier when both RUNNING and LOWER_UP, as RUNNING
1052            may mean that the oper state is unknown, in which case we should fall back to
1053            simply trust LOWER_UP, even thought that is less reliable
1054          */
1055         carrier_gained = ((flags_added & IFF_LOWER_UP) && (flags & IFF_RUNNING)) ||
1056                          ((flags_added & IFF_RUNNING) && (flags & IFF_LOWER_UP));
1057         carrier_lost = ((link->flags & (IFF_RUNNING | IFF_LOWER_UP)) ==
1058                         (IFF_RUNNING | IFF_LOWER_UP)) &&
1059                        (flags_removed & (IFF_LOWER_UP | IFF_RUNNING));
1060
1061         link->flags = flags;
1062
1063         if (flags_added & generic_flags)
1064                 log_debug_link(link, "link flags gained: %#.8x",
1065                                flags_added & generic_flags);
1066
1067         if (flags_removed & generic_flags)
1068                 log_debug_link(link, "link flags lost: %#.8x",
1069                                 flags_removed & generic_flags);
1070
1071         if (flags_added & IFF_UP)
1072                 log_info_link(link, "link is up");
1073         else if (flags_removed & IFF_UP)
1074                 log_info_link(link, "link is down");
1075
1076         if (flags_added & IFF_LOWER_UP)
1077                 log_info_link(link, "link is lower up");
1078         else if (flags_removed & IFF_LOWER_UP)
1079                 log_info_link(link, "link is lower down");
1080
1081         if (flags_added & IFF_RUNNING)
1082                 log_info_link(link, "link is running");
1083         else if (flags_removed & IFF_RUNNING)
1084                 log_info_link(link, "link is not running");
1085
1086         if (carrier_gained) {
1087                 log_info_link(link, "gained carrier");
1088
1089                 if (link->network->dhcp || link->network->ipv4ll) {
1090                         r = link_acquire_conf(link);
1091                         if (r < 0) {
1092                                 log_warning_link(link, "Could not acquire configuration: %s", strerror(-r));
1093                                 link_enter_failed(link);
1094                                 return r;
1095                         }
1096                 }
1097         } else if (carrier_lost) {
1098                 log_info_link(link, "lost carrier");
1099
1100                 if (link->network->dhcp) {
1101                         r = sd_dhcp_client_stop(link->dhcp_client);
1102                         if (r < 0) {
1103                                 log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
1104                                 link_enter_failed(link);
1105                                 return r;
1106                         }
1107                 }
1108
1109                 if (link->network->ipv4ll) {
1110                         r = sd_ipv4ll_stop(link->ipv4ll);
1111                         if (r < 0) {
1112                                 log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
1113                                 link_enter_failed(link);
1114                                 return r;
1115                         }
1116                 }
1117         }
1118
1119         return 0;
1120 }
1121
1122 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1123         Link *link = userdata;
1124         int r;
1125
1126         assert(link);
1127
1128         if (link->state == LINK_STATE_FAILED)
1129                 return 1;
1130
1131         r = sd_rtnl_message_get_errno(m);
1132         if (r >= 0)
1133                 link_update_flags(link, link->flags | IFF_UP);
1134         else
1135                 log_struct_link(LOG_WARNING, link,
1136                                 "MESSAGE=%s: could not bring up interface: %s",
1137                                 link->ifname, strerror(-r),
1138                                 "ERRNO=%d", -r,
1139                                 NULL);
1140         return 1;
1141 }
1142
1143 static int link_up(Link *link) {
1144         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1145         int r;
1146
1147         assert(link);
1148         assert(link->manager);
1149         assert(link->manager->rtnl);
1150
1151         log_debug_link(link, "bringing link up");
1152
1153         r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1154                                      RTM_SETLINK, link->ifindex);
1155         if (r < 0) {
1156                 log_error_link(link, "Could not allocate RTM_SETLINK message");
1157                 return r;
1158         }
1159
1160         r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1161         if (r < 0) {
1162                 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1163                 return r;
1164         }
1165
1166         r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1167         if (r < 0) {
1168                 log_error_link(link,
1169                                "Could not send rtnetlink message: %s", strerror(-r));
1170                 return r;
1171         }
1172
1173         return 0;
1174 }
1175
1176 static int link_enslaved(Link *link) {
1177         int r;
1178
1179         assert(link);
1180         assert(link->state == LINK_STATE_ENSLAVING);
1181         assert(link->network);
1182
1183         r = link_up(link);
1184         if (r < 0) {
1185                 link_enter_failed(link);
1186                 return r;
1187         }
1188
1189         if (!link->network->dhcp && !link->network->ipv4ll)
1190                 return link_enter_set_addresses(link);
1191
1192         return 0;
1193 }
1194
1195 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1196         Link *link = userdata;
1197         int r;
1198
1199         assert(link);
1200         assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
1201         assert(link->network);
1202
1203         link->enslaving --;
1204
1205         if (link->state == LINK_STATE_FAILED)
1206                 return 1;
1207
1208         r = sd_rtnl_message_get_errno(m);
1209         if (r < 0) {
1210                 log_struct_link(LOG_ERR, link,
1211                                 "MESSAGE=%s: could not enslave: %s",
1212                                 link->ifname, strerror(-r),
1213                                 "ERRNO=%d", -r,
1214                                 NULL);
1215                 link_enter_failed(link);
1216                 return 1;
1217         }
1218
1219         log_debug_link(link, "enslaved");
1220
1221         if (link->enslaving == 0)
1222                 link_enslaved(link);
1223
1224         return 1;
1225 }
1226
1227 static int link_enter_enslave(Link *link) {
1228         NetDev *vlan, *macvlan;
1229         Iterator i;
1230         int r;
1231
1232         assert(link);
1233         assert(link->network);
1234         assert(link->state == _LINK_STATE_INVALID);
1235
1236         link->state = LINK_STATE_ENSLAVING;
1237
1238         link_save(link);
1239
1240         if (!link->network->bridge && !link->network->bond &&
1241             hashmap_isempty(link->network->vlans) &&
1242             hashmap_isempty(link->network->macvlans))
1243                 return link_enslaved(link);
1244
1245         if (link->network->bridge) {
1246                 log_struct_link(LOG_DEBUG, link,
1247                                 "MESSAGE=%s: enslaving by '%s'",
1248                                 link->ifname, link->network->bridge->name,
1249                                 NETDEV(link->network->bridge),
1250                                 NULL);
1251
1252                 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1253                 if (r < 0) {
1254                         log_struct_link(LOG_WARNING, link,
1255                                         "MESSAGE=%s: could not enslave by '%s': %s",
1256                                         link->ifname, link->network->bridge->name, strerror(-r),
1257                                         NETDEV(link->network->bridge),
1258                                         NULL);
1259                         link_enter_failed(link);
1260                         return r;
1261                 }
1262
1263                 link->enslaving ++;
1264         }
1265
1266         if (link->network->bond) {
1267                 log_struct_link(LOG_DEBUG, link,
1268                                 "MESSAGE=%s: enslaving by '%s'",
1269                                 link->ifname, link->network->bond->name,
1270                                 NETDEV(link->network->bond),
1271                                 NULL);
1272
1273                 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1274                 if (r < 0) {
1275                         log_struct_link(LOG_WARNING, link,
1276                                         "MESSAGE=%s: could not enslave by '%s': %s",
1277                                         link->ifname, link->network->bond->name, strerror(-r),
1278                                         NETDEV(link->network->bond),
1279                                         NULL);
1280                         link_enter_failed(link);
1281                         return r;
1282                 }
1283
1284                 link->enslaving ++;
1285         }
1286
1287         HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1288                 log_struct_link(LOG_DEBUG, link,
1289                                 "MESSAGE=%s: enslaving by '%s'",
1290                                 link->ifname, vlan->name, NETDEV(vlan), NULL);
1291
1292                 r = netdev_enslave(vlan, link, &enslave_handler);
1293                 if (r < 0) {
1294                         log_struct_link(LOG_WARNING, link,
1295                                         "MESSAGE=%s: could not enslave by '%s': %s",
1296                                         link->ifname, vlan->name, strerror(-r),
1297                                         NETDEV(vlan), NULL);
1298                         link_enter_failed(link);
1299                         return r;
1300                 }
1301
1302                 link->enslaving ++;
1303         }
1304
1305         HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1306                 log_struct_link(LOG_DEBUG, link,
1307                                 "MESSAGE=%s: enslaving by '%s'",
1308                                 link->ifname, macvlan->name, NETDEV(macvlan), NULL);
1309
1310                 r = netdev_enslave(macvlan, link, &enslave_handler);
1311                 if (r < 0) {
1312                         log_struct_link(LOG_WARNING, link,
1313                                         "MESSAGE=%s: could not enslave by '%s': %s",
1314                                         link->ifname, macvlan->name, strerror(-r),
1315                                         NETDEV(macvlan), NULL);
1316                         link_enter_failed(link);
1317                         return r;
1318                 }
1319
1320                 link->enslaving ++;
1321         }
1322
1323         return 0;
1324 }
1325
1326 static int link_getlink_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
1327                                 void *userdata) {
1328         Link *link = userdata;
1329         int r;
1330
1331         assert(link);
1332         assert(link->ifname);
1333
1334         if (link->state == LINK_STATE_FAILED)
1335                 return 1;
1336
1337         r = sd_rtnl_message_get_errno(m);
1338         if (r < 0) {
1339                 log_struct_link(LOG_ERR, link,
1340                                 "MESSAGE=%s: could not get state: %s",
1341                                 link->ifname, strerror(-r),
1342                                 "ERRNO=%d", -r,
1343                                 NULL);
1344                 link_enter_failed(link);
1345                 return 1;
1346         }
1347
1348         link_update(link, m);
1349
1350         return 1;
1351 }
1352
1353 static int link_getlink(Link *link) {
1354         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1355         int r;
1356
1357         assert(link);
1358         assert(link->manager);
1359         assert(link->manager->rtnl);
1360
1361         log_debug_link(link, "requesting link status");
1362
1363         r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1364                                      RTM_GETLINK, link->ifindex);
1365         if (r < 0) {
1366                 log_error_link(link, "Could not allocate RTM_GETLINK message");
1367                 return r;
1368         }
1369
1370         r = sd_rtnl_call_async(link->manager->rtnl, req, link_getlink_handler,
1371                                link, 0, NULL);
1372         if (r < 0) {
1373                 log_error_link(link,
1374                                "Could not send rtnetlink message: %s", strerror(-r));
1375                 return r;
1376         }
1377
1378         return 0;
1379 }
1380
1381 static int link_configure(Link *link) {
1382         int r;
1383
1384         assert(link);
1385         assert(link->state == _LINK_STATE_INVALID);
1386
1387         r = link_getlink(link);
1388         if (r < 0)
1389                 return r;
1390
1391         return link_enter_enslave(link);
1392 }
1393
1394 int link_add(Manager *m, struct udev_device *device, Link **ret) {
1395         Link *link = NULL;
1396         Network *network;
1397         int r;
1398
1399         assert(m);
1400         assert(device);
1401
1402         r = link_new(m, device, &link);
1403         if (r < 0)
1404                 return r;
1405
1406         *ret = link;
1407
1408         r = network_get(m, device, &network);
1409         if (r < 0)
1410                 return r == -ENOENT ? 0 : r;
1411
1412         r = network_apply(m, network, link);
1413         if (r < 0)
1414                 return r;
1415
1416         if (link->network->ipv4ll) {
1417                 uint8_t seed[8];
1418                 r = sd_ipv4ll_new(&link->ipv4ll);
1419                 if (r < 0)
1420                         return r;
1421
1422                 r = net_get_unique_predictable_data(link->udev_device, seed);
1423                 if (r >= 0) {
1424                         r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1425                         if (r < 0)
1426                                 return r;
1427                 }
1428
1429                 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1430                 if (r < 0)
1431                         return r;
1432
1433                 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1434                 if (r < 0)
1435                         return r;
1436
1437                 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1438                 if (r < 0)
1439                         return r;
1440         }
1441
1442         if (link->network->dhcp) {
1443                 r = sd_dhcp_client_new(&link->dhcp_client);
1444                 if (r < 0)
1445                         return r;
1446
1447                 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1448                 if (r < 0)
1449                         return r;
1450
1451                 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1452                 if (r < 0)
1453                         return r;
1454
1455                 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1456                 if (r < 0)
1457                         return r;
1458
1459                 if (link->network->dhcp_mtu) {
1460                         r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1461                         if (r < 0)
1462                                 return r;
1463                 }
1464         }
1465
1466         r = link_configure(link);
1467         if (r < 0)
1468                 return r;
1469
1470         return 0;
1471 }
1472
1473 int link_update(Link *link, sd_rtnl_message *m) {
1474         unsigned flags;
1475         struct ether_addr mac;
1476         int r;
1477
1478         assert(link);
1479         assert(link->network);
1480         assert(m);
1481
1482         if (link->state == LINK_STATE_FAILED)
1483                 return 0;
1484
1485         if (link->network->dhcp && link->network->dhcp_mtu &&
1486             !link->original_mtu) {
1487                 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
1488                 if (r >= 0)
1489                         log_debug_link(link, "saved original MTU: %"
1490                                        PRIu16, link->original_mtu);
1491         }
1492
1493         r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1494         if (r < 0)
1495                 log_debug_link(link, "Could not get MAC address: %s", strerror(-r));
1496         else {
1497                 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
1498
1499                         memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
1500
1501                         log_debug_link(link, "MAC address: "
1502                                        "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1503                                        mac.ether_addr_octet[0],
1504                                        mac.ether_addr_octet[1],
1505                                        mac.ether_addr_octet[2],
1506                                        mac.ether_addr_octet[3],
1507                                        mac.ether_addr_octet[4],
1508                                        mac.ether_addr_octet[5]);
1509
1510                         if (link->ipv4ll) {
1511                                 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1512                                 if (r < 0) {
1513                                         log_warning_link(link, "Could not update MAC "
1514                                                          "address in IPv4LL client: %s",
1515                                                          strerror(-r));
1516                                         return r;
1517                                 }
1518                         }
1519
1520                         if (link->dhcp_client) {
1521                                 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1522                                 if (r < 0) {
1523                                         log_warning_link(link, "Could not update MAC "
1524                                                          "address in DHCP client: %s",
1525                                                          strerror(-r));
1526                                         return r;
1527                                 }
1528                         }
1529                 }
1530         }
1531
1532         r = sd_rtnl_message_link_get_flags(m, &flags);
1533         if (r < 0) {
1534                 log_warning_link(link, "Could not get link flags");
1535                 return r;
1536         }
1537
1538         return link_update_flags(link, flags);
1539 }
1540
1541 int link_save(Link *link) {
1542         _cleanup_free_ char *temp_path = NULL;
1543         _cleanup_fclose_ FILE *f = NULL;
1544         const char *state;
1545         int r;
1546
1547         assert(link);
1548         assert(link->state_file);
1549
1550         state = link_state_to_string(link->state);
1551         assert(state);
1552
1553         r = fopen_temporary(link->state_file, &f, &temp_path);
1554         if (r < 0)
1555                 goto finish;
1556
1557         fchmod(fileno(f), 0644);
1558
1559         fprintf(f,
1560                 "# This is private data. Do not parse.\n"
1561                 "STATE=%s\n", state);
1562
1563         if (link->dhcp_lease) {
1564                 _cleanup_free_ char *lease_file = NULL;
1565
1566                 r = asprintf(&lease_file, "/run/systemd/network/leases/%"PRIu64,
1567                              link->ifindex);
1568                 if (r < 0)
1569                         return -ENOMEM;
1570
1571                 r = dhcp_lease_save(link->dhcp_lease, lease_file);
1572                 if (r < 0)
1573                         goto finish;
1574
1575                 fprintf(f, "DHCP_LEASE=%s\n", lease_file);
1576         }
1577
1578         fflush(f);
1579
1580         if (ferror(f) || rename(temp_path, link->state_file) < 0) {
1581                 r = -errno;
1582                 unlink(link->state_file);
1583                 unlink(temp_path);
1584         }
1585
1586 finish:
1587         if (r < 0)
1588                 log_error("Failed to save link data %s: %s", link->state_file, strerror(-r));
1589
1590         return r;
1591 }
1592
1593 static const char* const link_state_table[_LINK_STATE_MAX] = {
1594         [LINK_STATE_ENSLAVING] = "configuring",
1595         [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1596         [LINK_STATE_SETTING_ROUTES] = "configuring",
1597         [LINK_STATE_CONFIGURED] = "configured",
1598         [LINK_STATE_FAILED] = "failed",
1599 };
1600
1601 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);