chiark / gitweb /
networkd: configure dhcp server range only after successfully setting an IP address...
[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 "udev-util.h"
28 #include "util.h"
29 #include "virt.h"
30 #include "bus-util.h"
31 #include "network-internal.h"
32
33 #include "network-util.h"
34 #include "dhcp-lease-internal.h"
35
36 static int ipv4ll_address_update(Link *link, bool deprecate);
37 static bool ipv4ll_is_bound(sd_ipv4ll *ll);
38
39 static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
40         _cleanup_link_unref_ Link *link = NULL;
41         uint16_t type;
42         char *ifname;
43         int r, ifindex;
44
45         assert(manager);
46         assert(manager->links);
47         assert(message);
48         assert(ret);
49
50         r = sd_rtnl_message_get_type(message, &type);
51         if (r < 0)
52                 return r;
53         else if (type != RTM_NEWLINK)
54                 return -EINVAL;
55
56         r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
57         if (r < 0)
58                 return r;
59         else if (ifindex <= 0)
60                 return -EINVAL;
61
62         r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname);
63         if (r < 0)
64                 return r;
65
66         link = new0(Link, 1);
67         if (!link)
68                 return -ENOMEM;
69
70         link->n_ref = 1;
71         link->manager = manager;
72         link->state = LINK_STATE_INITIALIZING;
73         link->ifindex = ifindex;
74         link->ifname = strdup(ifname);
75         if (!link->ifname)
76                 return -ENOMEM;
77
78         r = sd_rtnl_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
79         if (r < 0)
80                 return r;
81
82         r = asprintf(&link->state_file, "/run/systemd/netif/links/%"PRIu64,
83                      link->ifindex);
84         if (r < 0)
85                 return -ENOMEM;
86
87         r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%"PRIu64,
88                      link->ifindex);
89         if (r < 0)
90                 return -ENOMEM;
91
92         r = hashmap_put(manager->links, &link->ifindex, link);
93         if (r < 0)
94                 return r;
95
96         *ret = link;
97         link = NULL;
98
99         return 0;
100 }
101
102 static void link_free(Link *link) {
103         Address *address;
104
105         if (!link)
106                 return;
107
108         assert(link->manager);
109
110         while ((address = link->addresses)) {
111                 LIST_REMOVE(addresses, link->addresses, address);
112                 address_free(address);
113         }
114
115         while ((address = link->pool_addresses)) {
116                 LIST_REMOVE(addresses, link->pool_addresses, address);
117                 address_free(address);
118         }
119
120         sd_dhcp_client_unref(link->dhcp_client);
121         sd_dhcp_lease_unref(link->dhcp_lease);
122
123         unlink(link->lease_file);
124         free(link->lease_file);
125
126         sd_ipv4ll_unref(link->ipv4ll);
127
128         hashmap_remove(link->manager->links, &link->ifindex);
129
130         free(link->ifname);
131
132         unlink(link->state_file);
133         free(link->state_file);
134
135         udev_device_unref(link->udev_device);
136
137         free(link);
138 }
139
140 Link *link_unref(Link *link) {
141         if (link && (-- link->n_ref <= 0))
142                 link_free(link);
143
144         return NULL;
145 }
146
147 Link *link_ref(Link *link) {
148         if (link)
149                 assert_se(++ link->n_ref >= 2);
150
151         return link;
152 }
153
154 int link_get(Manager *m, int ifindex, Link **ret) {
155         Link *link;
156         uint64_t ifindex_64;
157
158         assert(m);
159         assert(m->links);
160         assert(ifindex);
161         assert(ret);
162
163         ifindex_64 = ifindex;
164         link = hashmap_get(m->links, &ifindex_64);
165         if (!link)
166                 return -ENODEV;
167
168         *ret = link;
169
170         return 0;
171 }
172
173 void link_drop(Link *link) {
174         if (!link || link->state == LINK_STATE_LINGER)
175                 return;
176
177         link->state = LINK_STATE_LINGER;
178
179         log_debug_link(link, "link removed");
180
181         link_unref(link);
182
183         return;
184 }
185
186 static void link_enter_unmanaged(Link *link) {
187         assert(link);
188
189         log_debug_link(link, "unmanaged");
190
191         link->state = LINK_STATE_UNMANAGED;
192
193         link_save(link);
194 }
195
196 static int link_stop_clients(Link *link) {
197         int r = 0, k;
198
199         assert(link);
200         assert(link->manager);
201         assert(link->manager->event);
202
203         if (!link->network)
204                 return 0;
205
206         if (link->network->dhcp) {
207                 assert(link->dhcp_client);
208
209                 k = sd_dhcp_client_stop(link->dhcp_client);
210                 if (k < 0) {
211                         log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
212                         r = k;
213                 }
214         }
215
216         if (link->network->ipv4ll) {
217                 assert(link->ipv4ll);
218
219                 k = sd_ipv4ll_stop(link->ipv4ll);
220                 if (k < 0) {
221                         log_warning_link(link, "Could not stop IPv4 link-local: %s", strerror(-r));
222                         r = k;
223                 }
224         }
225
226         if (link->network->dhcp_server) {
227                 assert(link->dhcp_server);
228
229                 k = sd_dhcp_server_stop(link->dhcp_server);
230                 if (k < 0) {
231                         log_warning_link(link, "Could not stop DHCPv4 server: %s", strerror(-r));
232                         r = k;
233                 }
234         }
235
236         return r;
237 }
238
239 static void link_enter_failed(Link *link) {
240         assert(link);
241
242         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
243                 return;
244
245         log_warning_link(link, "failed");
246
247         link->state = LINK_STATE_FAILED;
248
249         link_stop_clients(link);
250
251         link_save(link);
252 }
253
254 static Address* link_find_dhcp_server_address(Link *link) {
255         Address *address;
256
257         assert(link);
258         assert(link->network);
259
260         /* The the first statically configured address if there is any */
261         LIST_FOREACH(addresses, address, link->network->static_addresses) {
262
263                 if (address->family != AF_INET)
264                         continue;
265
266                 if (in_addr_null(address->family, &address->in_addr))
267                         continue;
268
269                 return address;
270         }
271
272         /* If that didn't work, find a suitable address we got from the pool */
273         LIST_FOREACH(addresses, address, link->pool_addresses) {
274                 if (address->family != AF_INET)
275                         continue;
276
277                 return address;
278         }
279
280         return NULL;
281 }
282
283 static int link_enter_configured(Link *link) {
284         int r;
285
286         assert(link);
287         assert(link->network);
288         assert(link->state == LINK_STATE_SETTING_ROUTES);
289
290         if (link->network->dhcp_server) {
291                 struct in_addr pool_start;
292                 Address *address;
293
294                 address = link_find_dhcp_server_address(link);
295                 if (!address) {
296                         log_warning_link(link, "Failed to find suitable address for DHCPv4 server instance.");
297                         link_enter_failed(link);
298                         return 0;
299                 }
300
301                 log_debug_link(link, "offering DHCPv4 leases");
302
303                 r = sd_dhcp_server_set_address(link->dhcp_server, &address->in_addr.in);
304                 if (r < 0)
305                         return r;
306
307                 /* offer 32 addresses starting from the address following the server address */
308                 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
309                 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
310                                                   &pool_start, 32);
311                 if (r < 0)
312                         return r;
313
314                 /* TODO:
315                 r = sd_dhcp_server_set_router(link->dhcp_server,
316                                               &main_address->in_addr.in);
317                 if (r < 0)
318                         return r;
319
320                 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
321                                                  main_address->prefixlen);
322                 if (r < 0)
323                         return r;
324                 */
325
326                 r = sd_dhcp_server_start(link->dhcp_server);
327                 if (r < 0) {
328                         log_warning_link(link, "could not start DHCPv4 server "
329                                          "instance: %s", strerror(-r));
330
331                         link_enter_failed(link);
332
333                         return 0;
334                 }
335         }
336
337         log_info_link(link, "link configured");
338
339         link->state = LINK_STATE_CONFIGURED;
340
341         link_save(link);
342
343         return 0;
344 }
345
346 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
347         Link *link = userdata;
348         int r;
349
350         assert(link->route_messages > 0);
351         assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
352                       LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
353                       LINK_STATE_LINGER));
354
355         link->route_messages --;
356
357         if (IN_SET(LINK_STATE_FAILED, LINK_STATE_LINGER)) {
358                 link_unref(link);
359                 return 1;
360         }
361
362         r = sd_rtnl_message_get_errno(m);
363         if (r < 0 && r != -EEXIST)
364                 log_struct_link(LOG_WARNING, link,
365                                 "MESSAGE=%-*s: could not set route: %s",
366                                 IFNAMSIZ,
367                                 link->ifname, strerror(-r),
368                                 "ERRNO=%d", -r,
369                                 NULL);
370
371         /* we might have received an old reply after moving back to SETTING_ADDRESSES,
372          * ignore it */
373         if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
374                 log_debug_link(link, "routes set");
375                 link_enter_configured(link);
376         }
377
378         link_unref(link);
379
380         return 1;
381 }
382
383 static int link_enter_set_routes(Link *link) {
384         Route *rt;
385         int r;
386
387         assert(link);
388         assert(link->network);
389         assert(link->state == LINK_STATE_SETTING_ADDRESSES);
390
391         link->state = LINK_STATE_SETTING_ROUTES;
392
393         if (!link->network->static_routes && !link->dhcp_lease &&
394             (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
395                 return link_enter_configured(link);
396
397         log_debug_link(link, "setting routes");
398
399         LIST_FOREACH(routes, rt, link->network->static_routes) {
400                 r = route_configure(rt, link, &route_handler);
401                 if (r < 0) {
402                         log_warning_link(link,
403                                          "could not set routes: %s", strerror(-r));
404                         link_enter_failed(link);
405                         return r;
406                 }
407
408                 link_ref(link);
409                 link->route_messages ++;
410         }
411
412         if (link->ipv4ll && !link->dhcp_lease) {
413                 _cleanup_route_free_ Route *route = NULL;
414                 struct in_addr addr;
415
416                 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
417                 if (r < 0 && r != -ENOENT) {
418                         log_warning_link(link, "IPV4LL error: no address: %s",
419                                         strerror(-r));
420                         return r;
421                 }
422
423                 if (r != -ENOENT) {
424                         r = route_new_dynamic(&route);
425                         if (r < 0) {
426                                 log_error_link(link, "Could not allocate route: %s",
427                                                strerror(-r));
428                                 return r;
429                         }
430
431                         route->family = AF_INET;
432                         route->scope = RT_SCOPE_LINK;
433                         route->metrics = 99;
434
435                         r = route_configure(route, link, &route_handler);
436                         if (r < 0) {
437                                 log_warning_link(link,
438                                                  "could not set routes: %s", strerror(-r));
439                                 link_enter_failed(link);
440                                 return r;
441                         }
442
443                         link_ref(link);
444                         link->route_messages ++;
445                 }
446         }
447
448         if (link->dhcp_lease) {
449                 _cleanup_route_free_ Route *route = NULL;
450                 _cleanup_route_free_ Route *route_gw = NULL;
451                 struct in_addr gateway;
452
453                 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
454                 if (r < 0 && r != -ENOENT) {
455                         log_warning_link(link, "DHCP error: %s", strerror(-r));
456                         return r;
457                 }
458
459                 if (r >= 0) {
460                         r = route_new_dynamic(&route);
461                         if (r < 0) {
462                                 log_error_link(link, "Could not allocate route: %s",
463                                                strerror(-r));
464                                 return r;
465                         }
466
467                         r = route_new_dynamic(&route_gw);
468                         if (r < 0) {
469                                 log_error_link(link, "Could not allocate route: %s",
470                                                strerror(-r));
471                                 return r;
472                         }
473
474                         /* The dhcp netmask may mask out the gateway. Add an explicit
475                          * route for the gw host so that we can route no matter the
476                          * netmask or existing kernel route tables. */
477                         route_gw->family = AF_INET;
478                         route_gw->dst_addr.in = gateway;
479                         route_gw->dst_prefixlen = 32;
480                         route_gw->scope = RT_SCOPE_LINK;
481
482                         r = route_configure(route_gw, link, &route_handler);
483                         if (r < 0) {
484                                 log_warning_link(link,
485                                                  "could not set host route: %s", strerror(-r));
486                                 return r;
487                         }
488
489                         link_ref(link);
490                         link->route_messages ++;
491
492                         route->family = AF_INET;
493                         route->in_addr.in = gateway;
494
495                         r = route_configure(route, link, &route_handler);
496                         if (r < 0) {
497                                 log_warning_link(link,
498                                                  "could not set routes: %s", strerror(-r));
499                                 link_enter_failed(link);
500                                 return r;
501                         }
502
503                         link_ref(link);
504                         link->route_messages ++;
505                 }
506         }
507
508         if (link->route_messages == 0) {
509                 link_enter_configured(link);
510         }
511
512         return 0;
513 }
514
515 static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
516         Link *link = userdata;
517         int r;
518
519         assert(m);
520         assert(link);
521         assert(link->ifname);
522
523         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
524                 link_unref(link);
525                 return 1;
526         }
527
528         r = sd_rtnl_message_get_errno(m);
529         if (r < 0 && r != -ESRCH)
530                 log_struct_link(LOG_WARNING, link,
531                                 "MESSAGE=%-*s: could not drop route: %s",
532                                 IFNAMSIZ,
533                                 link->ifname, strerror(-r),
534                                 "ERRNO=%d", -r,
535                                 NULL);
536
537         link_unref(link);
538
539         return 0;
540 }
541
542 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
543         Link *link = userdata;
544         int r;
545
546         assert(m);
547         assert(link);
548         assert(link->ifname);
549         assert(link->addr_messages > 0);
550         assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
551                LINK_STATE_FAILED, LINK_STATE_LINGER));
552
553         link->addr_messages --;
554
555         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
556                 link_unref(link);
557                 return 1;
558         }
559
560         r = sd_rtnl_message_get_errno(m);
561         if (r < 0 && r != -EEXIST)
562                 log_struct_link(LOG_WARNING, link,
563                                 "MESSAGE=%-*s: could not set address: %s",
564                                 IFNAMSIZ,
565                                 link->ifname, strerror(-r),
566                                 "ERRNO=%d", -r,
567                                 NULL);
568
569         if (link->addr_messages == 0) {
570                 log_debug_link(link, "addresses set");
571                 link_enter_set_routes(link);
572         }
573
574         link_unref(link);
575
576         return 1;
577 }
578
579 static int link_enter_set_addresses(Link *link) {
580         Address *ad;
581         int r;
582
583         assert(link);
584         assert(link->network);
585         assert(link->state != _LINK_STATE_INVALID);
586
587         link->state = LINK_STATE_SETTING_ADDRESSES;
588
589         if (!link->network->static_addresses && !link->dhcp_lease &&
590                 (!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
591                 return link_enter_set_routes(link);
592
593         log_debug_link(link, "setting addresses");
594
595         LIST_FOREACH(addresses, ad, link->network->static_addresses) {
596                 r = address_configure(ad, link, &address_handler);
597                 if (r < 0) {
598                         log_warning_link(link,
599                                          "could not set addresses: %s", strerror(-r));
600                         link_enter_failed(link);
601                         return r;
602                 }
603
604                 link_ref(link);
605                 link->addr_messages ++;
606         }
607
608         if (link->ipv4ll && !link->dhcp_lease) {
609                 _cleanup_address_free_ Address *ll_addr = NULL;
610                 struct in_addr addr;
611
612                 r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
613                 if (r < 0 && r != -ENOENT) {
614                         log_warning_link(link, "IPV4LL error: no address: %s",
615                                         strerror(-r));
616                         return r;
617                 }
618
619                 if (r != -ENOENT) {
620                         r = address_new_dynamic(&ll_addr);
621                         if (r < 0) {
622                                 log_error_link(link, "Could not allocate address: %s", strerror(-r));
623                                 return r;
624                         }
625
626                         ll_addr->family = AF_INET;
627                         ll_addr->in_addr.in = addr;
628                         ll_addr->prefixlen = 16;
629                         ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
630                         ll_addr->scope = RT_SCOPE_LINK;
631
632                         r = address_configure(ll_addr, link, &address_handler);
633                         if (r < 0) {
634                                 log_warning_link(link,
635                                          "could not set addresses: %s", strerror(-r));
636                                 link_enter_failed(link);
637                                 return r;
638                         }
639
640                         link_ref(link);
641                         link->addr_messages ++;
642                 }
643         }
644
645         if (link->dhcp_lease) {
646                 _cleanup_address_free_ Address *address = NULL;
647                 struct in_addr addr;
648                 struct in_addr netmask;
649                 unsigned prefixlen;
650
651                 r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
652                 if (r < 0) {
653                         log_warning_link(link, "DHCP error: no address: %s",
654                                          strerror(-r));
655                         return r;
656                 }
657
658                 r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
659                 if (r < 0) {
660                         log_warning_link(link, "DHCP error: no netmask: %s",
661                                          strerror(-r));
662                         return r;
663                 }
664
665                 prefixlen = net_netmask_to_prefixlen(&netmask);
666
667                 r = address_new_dynamic(&address);
668                 if (r < 0) {
669                         log_error_link(link, "Could not allocate address: %s",
670                                        strerror(-r));
671                         return r;
672                 }
673
674                 address->family = AF_INET;
675                 address->in_addr.in = addr;
676                 address->prefixlen = prefixlen;
677                 address->broadcast.s_addr = addr.s_addr | ~netmask.s_addr;
678
679                 r = address_configure(address, link, &address_handler);
680                 if (r < 0) {
681                         log_warning_link(link,
682                                          "could not set addresses: %s", strerror(-r));
683                         link_enter_failed(link);
684                         return r;
685                 }
686
687                 link_ref(link);
688                 link->addr_messages ++;
689         }
690
691         return 0;
692 }
693
694 static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
695         Link *link = userdata;
696         int r;
697
698         assert(m);
699         assert(link);
700         assert(link->ifname);
701
702         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
703                 link_unref(link);
704                 return 1;
705         }
706
707         r = sd_rtnl_message_get_errno(m);
708         if (r < 0 && r != -ENOENT)
709                 log_struct_link(LOG_WARNING, link,
710                                 "MESSAGE=%-*s: could not update address: %s",
711                                 IFNAMSIZ,
712                                 link->ifname, strerror(-r),
713                                 "ERRNO=%d", -r,
714                                 NULL);
715
716         link_unref(link);
717
718         return 0;
719 }
720
721 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
722         Link *link = userdata;
723         int r;
724
725         assert(m);
726         assert(link);
727         assert(link->ifname);
728
729         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
730                 link_unref(link);
731                 return 1;
732         }
733
734         r = sd_rtnl_message_get_errno(m);
735         if (r < 0 && r != -EADDRNOTAVAIL)
736                 log_struct_link(LOG_WARNING, link,
737                                 "MESSAGE=%-*s: could not drop address: %s",
738                                 IFNAMSIZ,
739                                 link->ifname, strerror(-r),
740                                 "ERRNO=%d", -r,
741                                 NULL);
742
743         link_unref(link);
744
745         return 0;
746 }
747
748 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
749         Link *link = userdata;
750         int r;
751
752         assert(link);
753
754         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
755                 link_unref(link);
756                 return 1;
757         }
758
759         r = sd_bus_message_get_errno(m);
760         if (r < 0)
761                 log_warning_link(link, "Could not set hostname: %s", strerror(-r));
762
763         link_unref(link);
764
765         return 1;
766 }
767
768 static int link_set_hostname(Link *link, const char *hostname) {
769         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
770         int r = 0;
771
772         assert(link);
773         assert(link->manager);
774         assert(hostname);
775
776         log_debug_link(link, "Setting transient hostname: '%s'", hostname);
777
778         if (!link->manager->bus) { /* TODO: replace by assert when we can rely on kdbus */
779                 log_info_link(link, "Not connected to system bus, ignoring transient hostname.");
780                 return 0;
781         }
782
783         r = sd_bus_message_new_method_call(
784                         link->manager->bus,
785                         &m,
786                         "org.freedesktop.hostname1",
787                         "/org/freedesktop/hostname1",
788                         "org.freedesktop.hostname1",
789                         "SetHostname");
790         if (r < 0)
791                 return r;
792
793         r = sd_bus_message_append(m, "sb", hostname, false);
794         if (r < 0)
795                 return r;
796
797         r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler, link, 0);
798         if (r < 0)
799                 log_error_link(link, "Could not set transient hostname: %s", strerror(-r));
800
801         link_ref(link);
802
803         return r;
804 }
805
806 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
807         Link *link = userdata;
808         int r;
809
810         assert(m);
811         assert(link);
812         assert(link->ifname);
813
814         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
815                 link_unref(link);
816                 return 1;
817         }
818
819         r = sd_rtnl_message_get_errno(m);
820         if (r < 0)
821                 log_struct_link(LOG_WARNING, link,
822                                 "MESSAGE=%-*s: could not set MTU: %s",
823                                 IFNAMSIZ, link->ifname, strerror(-r),
824                                 "ERRNO=%d", -r,
825                                 NULL);
826
827         link_unref(link);
828
829         return 1;
830 }
831
832 static int link_set_mtu(Link *link, uint32_t mtu) {
833         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
834         int r;
835
836         assert(link);
837         assert(link->manager);
838         assert(link->manager->rtnl);
839
840         log_debug_link(link, "setting MTU: %" PRIu32, mtu);
841
842         r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
843                                      RTM_SETLINK, link->ifindex);
844         if (r < 0) {
845                 log_error_link(link, "Could not allocate RTM_SETLINK message");
846                 return r;
847         }
848
849         r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
850         if (r < 0) {
851                 log_error_link(link, "Could not append MTU: %s", strerror(-r));
852                 return r;
853         }
854
855         r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
856         if (r < 0) {
857                 log_error_link(link,
858                                "Could not send rtnetlink message: %s", strerror(-r));
859                 return r;
860         }
861
862         link_unref(link);
863
864         return 0;
865 }
866
867 static int dhcp_lease_lost(Link *link) {
868         _cleanup_address_free_ Address *address = NULL;
869         _cleanup_route_free_ Route *route_gw = NULL;
870         _cleanup_route_free_ Route *route = NULL;
871         struct in_addr addr;
872         struct in_addr netmask;
873         struct in_addr gateway;
874         unsigned prefixlen;
875         int r;
876
877         assert(link);
878         assert(link->dhcp_lease);
879
880         log_warning_link(link, "DHCP lease lost");
881
882         r = address_new_dynamic(&address);
883         if (r >= 0) {
884                 r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
885                 if (r >= 0) {
886                         r = route_new_dynamic(&route_gw);
887                         if (r >= 0) {
888                                 route_gw->family = AF_INET;
889                                 route_gw->dst_addr.in = gateway;
890                                 route_gw->dst_prefixlen = 32;
891                                 route_gw->scope = RT_SCOPE_LINK;
892
893                                 route_drop(route_gw, link, &route_drop_handler);
894                                 link_ref(link);
895                         }
896
897                         r = route_new_dynamic(&route);
898                         if (r >= 0) {
899                                 route->family = AF_INET;
900                                 route->in_addr.in = gateway;
901
902                                 route_drop(route, link, &route_drop_handler);
903                                 link_ref(link);
904                         }
905                 }
906
907                 sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
908                 sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask);
909                 prefixlen = net_netmask_to_prefixlen(&netmask);
910
911                 address->family = AF_INET;
912                 address->in_addr.in = addr;
913                 address->prefixlen = prefixlen;
914
915                 address_drop(address, link, &address_drop_handler);
916                 link_ref(link);
917         }
918
919         if (link->network->dhcp_mtu) {
920                 uint16_t mtu;
921
922                 r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
923                 if (r >= 0 && link->original_mtu != mtu) {
924                         r = link_set_mtu(link, link->original_mtu);
925                         if (r < 0) {
926                                 log_warning_link(link, "DHCP error: could not reset MTU");
927                                 link_enter_failed(link);
928                                 return r;
929                         }
930                 }
931         }
932
933         if (link->network->dhcp_hostname) {
934                 const char *hostname = NULL;
935
936                 r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname);
937                 if (r >= 0 && hostname) {
938                         r = link_set_hostname(link, "");
939                         if (r < 0)
940                                 log_error_link(link, "Failed to reset transient hostname");
941                 }
942         }
943
944         link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
945
946         return 0;
947 }
948
949 static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
950         sd_dhcp_lease *lease;
951         struct in_addr address;
952         struct in_addr netmask;
953         struct in_addr gateway;
954         unsigned prefixlen;
955         int r;
956
957         assert(client);
958         assert(link);
959
960         r = sd_dhcp_client_get_lease(client, &lease);
961         if (r < 0) {
962                 log_warning_link(link, "DHCP error: no lease: %s",
963                                  strerror(-r));
964                 return r;
965         }
966
967         r = sd_dhcp_lease_get_address(lease, &address);
968         if (r < 0) {
969                 log_warning_link(link, "DHCP error: no address: %s",
970                                  strerror(-r));
971                 return r;
972         }
973
974         r = sd_dhcp_lease_get_netmask(lease, &netmask);
975         if (r < 0) {
976                 log_warning_link(link, "DHCP error: no netmask: %s",
977                                  strerror(-r));
978                 return r;
979         }
980
981         prefixlen = net_netmask_to_prefixlen(&netmask);
982
983         r = sd_dhcp_lease_get_router(lease, &gateway);
984         if (r < 0 && r != -ENOENT) {
985                 log_warning_link(link, "DHCP error: %s", strerror(-r));
986                 return r;
987         }
988
989         if (r >= 0)
990                 log_struct_link(LOG_INFO, link,
991                                 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
992                                  IFNAMSIZ,
993                                  link->ifname,
994                                  ADDRESS_FMT_VAL(address),
995                                  prefixlen,
996                                  ADDRESS_FMT_VAL(gateway),
997                                  "ADDRESS=%u.%u.%u.%u",
998                                  ADDRESS_FMT_VAL(address),
999                                  "PREFIXLEN=%u",
1000                                  prefixlen,
1001                                  "GATEWAY=%u.%u.%u.%u",
1002                                  ADDRESS_FMT_VAL(gateway),
1003                                  NULL);
1004         else
1005                 log_struct_link(LOG_INFO, link,
1006                                 "MESSAGE=%-*s: DHCPv4 address %u.%u.%u.%u/%u",
1007                                  IFNAMSIZ,
1008                                  link->ifname,
1009                                  ADDRESS_FMT_VAL(address),
1010                                  prefixlen,
1011                                  "ADDRESS=%u.%u.%u.%u",
1012                                  ADDRESS_FMT_VAL(address),
1013                                  "PREFIXLEN=%u",
1014                                  prefixlen,
1015                                  NULL);
1016
1017         link->dhcp_lease = lease;
1018
1019         if (link->network->dhcp_mtu) {
1020                 uint16_t mtu;
1021
1022                 r = sd_dhcp_lease_get_mtu(lease, &mtu);
1023                 if (r >= 0) {
1024                         r = link_set_mtu(link, mtu);
1025                         if (r < 0)
1026                                 log_error_link(link, "Failed to set MTU "
1027                                                "to %" PRIu16, mtu);
1028                 }
1029         }
1030
1031         if (link->network->dhcp_hostname) {
1032                 const char *hostname;
1033
1034                 r = sd_dhcp_lease_get_hostname(lease, &hostname);
1035                 if (r >= 0) {
1036                         r = link_set_hostname(link, hostname);
1037                         if (r < 0)
1038                                 log_error_link(link, "Failed to set transient hostname "
1039                                           "to '%s'", hostname);
1040                 }
1041         }
1042
1043         link_enter_set_addresses(link);
1044
1045         return 0;
1046 }
1047
1048 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
1049         Link *link = userdata;
1050         int r = 0;
1051
1052         assert(link);
1053         assert(link->network);
1054         assert(link->manager);
1055
1056         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1057                 return;
1058
1059         switch (event) {
1060                 case DHCP_EVENT_NO_LEASE:
1061                         log_debug_link(link, "IP address in use.");
1062                         break;
1063                 case DHCP_EVENT_EXPIRED:
1064                 case DHCP_EVENT_STOP:
1065                 case DHCP_EVENT_IP_CHANGE:
1066                         if (link->network->dhcp_critical) {
1067                                 log_error_link(link, "DHCPv4 connection considered system critical, "
1068                                                "ignoring request to reconfigure it.");
1069                                 return;
1070                         }
1071
1072                         if (link->dhcp_lease) {
1073                                 r = dhcp_lease_lost(link);
1074                                 if (r < 0) {
1075                                         link_enter_failed(link);
1076                                         return;
1077                                 }
1078                         }
1079
1080                         if (event == DHCP_EVENT_IP_CHANGE) {
1081                                 r = dhcp_lease_acquired(client, link);
1082                                 if (r < 0) {
1083                                         link_enter_failed(link);
1084                                         return;
1085                                 }
1086                         }
1087
1088                         if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
1089                                 if (!sd_ipv4ll_is_running(link->ipv4ll))
1090                                         r = sd_ipv4ll_start(link->ipv4ll);
1091                                 else if (ipv4ll_is_bound(link->ipv4ll))
1092                                         r = ipv4ll_address_update(link, false);
1093                                 if (r < 0) {
1094                                         link_enter_failed(link);
1095                                         return;
1096                                 }
1097                         }
1098
1099                         break;
1100                 case DHCP_EVENT_IP_ACQUIRE:
1101                         r = dhcp_lease_acquired(client, link);
1102                         if (r < 0) {
1103                                 link_enter_failed(link);
1104                                 return;
1105                         }
1106                         if (link->ipv4ll) {
1107                                 if (ipv4ll_is_bound(link->ipv4ll))
1108                                         r = ipv4ll_address_update(link, true);
1109                                 else
1110                                         r = sd_ipv4ll_stop(link->ipv4ll);
1111                                 if (r < 0) {
1112                                         link_enter_failed(link);
1113                                         return;
1114                                 }
1115                         }
1116                         break;
1117                 default:
1118                         if (event < 0)
1119                                 log_warning_link(link, "DHCP error: %s", strerror(-event));
1120                         else
1121                                 log_warning_link(link, "DHCP unknown event: %d", event);
1122                         break;
1123         }
1124
1125         return;
1126 }
1127
1128 static int ipv4ll_address_update(Link *link, bool deprecate) {
1129         int r;
1130         struct in_addr addr;
1131
1132         assert(link);
1133
1134         r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1135         if (r >= 0) {
1136                 _cleanup_address_free_ Address *address = NULL;
1137
1138                 log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
1139                                deprecate ? "deprecate" : "approve",
1140                                ADDRESS_FMT_VAL(addr));
1141
1142                 r = address_new_dynamic(&address);
1143                 if (r < 0) {
1144                         log_error_link(link, "Could not allocate address: %s", strerror(-r));
1145                         return r;
1146                 }
1147
1148                 address->family = AF_INET;
1149                 address->in_addr.in = addr;
1150                 address->prefixlen = 16;
1151                 address->scope = RT_SCOPE_LINK;
1152                 address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
1153                 address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
1154
1155                 address_update(address, link, &address_update_handler);
1156                 link_ref(link);
1157         }
1158
1159         return 0;
1160
1161 }
1162
1163 static int ipv4ll_address_lost(Link *link) {
1164         int r;
1165         struct in_addr addr;
1166
1167         assert(link);
1168
1169         r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
1170         if (r >= 0) {
1171                 _cleanup_address_free_ Address *address = NULL;
1172                 _cleanup_route_free_ Route *route = NULL;
1173
1174                 log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
1175                                 ADDRESS_FMT_VAL(addr));
1176
1177                 r = address_new_dynamic(&address);
1178                 if (r < 0) {
1179                         log_error_link(link, "Could not allocate address: %s", strerror(-r));
1180                         return r;
1181                 }
1182
1183                 address->family = AF_INET;
1184                 address->in_addr.in = addr;
1185                 address->prefixlen = 16;
1186                 address->scope = RT_SCOPE_LINK;
1187
1188                 address_drop(address, link, &address_drop_handler);
1189                 link_ref(link);
1190
1191                 r = route_new_dynamic(&route);
1192                 if (r < 0) {
1193                         log_error_link(link, "Could not allocate route: %s",
1194                                        strerror(-r));
1195                         return r;
1196                 }
1197
1198                 route->family = AF_INET;
1199                 route->scope = RT_SCOPE_LINK;
1200                 route->metrics = 99;
1201
1202                 route_drop(route, link, &route_drop_handler);
1203                 link_ref(link);
1204         }
1205
1206         return 0;
1207 }
1208
1209 static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
1210         int r;
1211         struct in_addr addr;
1212
1213         assert(ll);
1214
1215         r = sd_ipv4ll_get_address(ll, &addr);
1216         if (r < 0)
1217                 return false;
1218         return true;
1219 }
1220
1221 static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
1222         struct in_addr address;
1223         int r;
1224
1225         assert(ll);
1226         assert(link);
1227
1228         r = sd_ipv4ll_get_address(ll, &address);
1229         if (r < 0)
1230                 return r;
1231
1232         log_struct_link(LOG_INFO, link,
1233                         "MESSAGE=%-*s: IPv4 link-local address %u.%u.%u.%u",
1234                         IFNAMSIZ,
1235                         link->ifname,
1236                         ADDRESS_FMT_VAL(address),
1237                         NULL);
1238
1239        link_enter_set_addresses(link);
1240
1241        return 0;
1242 }
1243
1244 static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
1245         Link *link = userdata;
1246         int r;
1247
1248         assert(link);
1249         assert(link->network);
1250         assert(link->manager);
1251
1252         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1253                 return;
1254
1255         switch(event) {
1256                 case IPV4LL_EVENT_STOP:
1257                 case IPV4LL_EVENT_CONFLICT:
1258                         r = ipv4ll_address_lost(link);
1259                         if (r < 0) {
1260                                 link_enter_failed(link);
1261                                 return;
1262                         }
1263                         break;
1264                 case IPV4LL_EVENT_BIND:
1265                         r = ipv4ll_address_claimed(ll, link);
1266                         if (r < 0) {
1267                                 link_enter_failed(link);
1268                                 return;
1269                         }
1270                         break;
1271                 default:
1272                         if (event < 0)
1273                                 log_warning_link(link, "IPv4 link-local error: %s", strerror(-event));
1274                         else
1275                                 log_warning_link(link, "IPv4 link-local unknown event: %d", event);
1276                         break;
1277         }
1278 }
1279
1280 static int link_acquire_conf(Link *link) {
1281         int r;
1282
1283         assert(link);
1284         assert(link->network);
1285         assert(link->manager);
1286         assert(link->manager->event);
1287
1288         if (link->network->ipv4ll) {
1289                 assert(link->ipv4ll);
1290
1291                 log_debug_link(link, "acquiring IPv4 link-local address");
1292
1293                 r = sd_ipv4ll_start(link->ipv4ll);
1294                 if (r < 0) {
1295                         log_warning_link(link, "could not acquire IPv4 "
1296                                          "link-local address");
1297                         return r;
1298                 }
1299         }
1300
1301         if (link->network->dhcp) {
1302                 assert(link->dhcp_client);
1303
1304                 log_debug_link(link, "acquiring DHCPv4 lease");
1305
1306                 r = sd_dhcp_client_start(link->dhcp_client);
1307                 if (r < 0) {
1308                         log_warning_link(link, "could not acquire DHCPv4 "
1309                                          "lease");
1310                         return r;
1311                 }
1312         }
1313
1314         return 0;
1315 }
1316
1317 bool link_has_carrier(unsigned flags, uint8_t operstate) {
1318         /* see Documentation/networking/operstates.txt in the kernel sources */
1319
1320         if (operstate == IF_OPER_UP)
1321                 return true;
1322
1323         if (operstate == IF_OPER_UNKNOWN)
1324                 /* operstate may not be implemented, so fall back to flags */
1325                 if ((flags & IFF_LOWER_UP) && !(flags & IFF_DORMANT))
1326                         return true;
1327
1328         return false;
1329 }
1330
1331 #define FLAG_STRING(string, flag, old, new) \
1332         (((old ^ new) & flag) \
1333                 ? ((old & flag) ? (" -" string) : (" +" string)) \
1334                 : "")
1335
1336 static int link_update_flags(Link *link, sd_rtnl_message *m) {
1337         unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
1338         uint8_t operstate;
1339         bool carrier_gained = false, carrier_lost = false;
1340         int r;
1341
1342         assert(link);
1343
1344         r = sd_rtnl_message_link_get_flags(m, &flags);
1345         if (r < 0) {
1346                 log_warning_link(link, "Could not get link flags");
1347                 return r;
1348         }
1349
1350         r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
1351         if (r < 0)
1352                 /* if we got a message without operstate, take it to mean
1353                    the state was unchanged */
1354                 operstate = link->kernel_operstate;
1355
1356         if ((link->flags == flags) && (link->kernel_operstate == operstate))
1357                 return 0;
1358
1359         if (link->flags != flags) {
1360                 log_debug_link(link, "flags change:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
1361                                FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
1362                                FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
1363                                FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
1364                                FLAG_STRING("UP", IFF_UP, link->flags, flags),
1365                                FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
1366                                FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
1367                                FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
1368                                FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
1369                                FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
1370                                FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
1371                                FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
1372                                FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
1373                                FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
1374                                FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
1375                                FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
1376                                FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
1377                                FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
1378                                FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
1379                                FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
1380
1381                 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
1382                                   IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
1383                                   IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
1384                                   IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
1385                                   IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
1386                                   IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
1387                 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
1388                 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
1389
1390                 /* link flags are currently at most 18 bits, let's align to printing 20 */
1391                 if (unknown_flags_added)
1392                         log_debug_link(link, "unknown link flags gained: %#.5x (ignoring)",
1393                                        unknown_flags_added);
1394
1395                 if (unknown_flags_removed)
1396                         log_debug_link(link, "unknown link flags lost: %#.5x (ignoring)",
1397                                        unknown_flags_removed);
1398         }
1399
1400         carrier_gained = !link_has_carrier(link->flags, link->kernel_operstate) &&
1401                        link_has_carrier(flags, operstate);
1402         carrier_lost = link_has_carrier(link->flags, link->kernel_operstate) &&
1403                          !link_has_carrier(flags, operstate);
1404
1405         link->flags = flags;
1406         link->kernel_operstate = operstate;
1407
1408         link_save(link);
1409
1410         if (link->state == LINK_STATE_FAILED ||
1411             link->state == LINK_STATE_UNMANAGED)
1412                 return 0;
1413
1414         if (carrier_gained) {
1415                 log_info_link(link, "gained carrier");
1416
1417                 if (link->network) {
1418                         r = link_acquire_conf(link);
1419                         if (r < 0) {
1420                                 link_enter_failed(link);
1421                                 return r;
1422                         }
1423                 }
1424         } else if (carrier_lost) {
1425                 log_info_link(link, "lost carrier");
1426
1427                 r = link_stop_clients(link);
1428                 if (r < 0) {
1429                         link_enter_failed(link);
1430                         return r;
1431                 }
1432         }
1433
1434         return 0;
1435 }
1436
1437 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1438         Link *link = userdata;
1439         int r;
1440
1441         assert(link);
1442
1443         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
1444                 link_unref(link);
1445                 return 1;
1446         }
1447
1448         r = sd_rtnl_message_get_errno(m);
1449         if (r < 0) {
1450                 /* we warn but don't fail the link, as it may
1451                    be brought up later */
1452                 log_struct_link(LOG_WARNING, link,
1453                                 "MESSAGE=%-*s: could not bring up interface: %s",
1454                                 IFNAMSIZ,
1455                                 link->ifname, strerror(-r),
1456                                 "ERRNO=%d", -r,
1457                                 NULL);
1458         }
1459
1460         link_unref(link);
1461
1462         return 1;
1463 }
1464
1465 static int link_up(Link *link) {
1466         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1467         int r;
1468
1469         assert(link);
1470         assert(link->manager);
1471         assert(link->manager->rtnl);
1472
1473         log_debug_link(link, "bringing link up");
1474
1475         r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1476                                      RTM_SETLINK, link->ifindex);
1477         if (r < 0) {
1478                 log_error_link(link, "Could not allocate RTM_SETLINK message");
1479                 return r;
1480         }
1481
1482         r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1483         if (r < 0) {
1484                 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1485                 return r;
1486         }
1487
1488         r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1489         if (r < 0) {
1490                 log_error_link(link,
1491                                "Could not send rtnetlink message: %s", strerror(-r));
1492                 return r;
1493         }
1494
1495         link_ref(link);
1496
1497         return 0;
1498 }
1499
1500 static int link_enslaved(Link *link) {
1501         int r;
1502
1503         assert(link);
1504         assert(link->state == LINK_STATE_ENSLAVING);
1505         assert(link->network);
1506
1507         if (!(link->flags & IFF_UP)) {
1508                 r = link_up(link);
1509                 if (r < 0) {
1510                         link_enter_failed(link);
1511                         return r;
1512                 }
1513         }
1514
1515         if (!link->network->dhcp && !link->network->ipv4ll)
1516                 return link_enter_set_addresses(link);
1517
1518         return 0;
1519 }
1520
1521 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1522         Link *link = userdata;
1523         int r;
1524
1525         assert(link);
1526         assert(IN_SET(link->state, LINK_STATE_ENSLAVING, LINK_STATE_FAILED,
1527                       LINK_STATE_LINGER));
1528         assert(link->network);
1529
1530         link->enslaving --;
1531
1532         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) {
1533                 link_unref(link);
1534                 return 1;
1535         }
1536
1537         r = sd_rtnl_message_get_errno(m);
1538         if (r < 0) {
1539                 log_struct_link(LOG_ERR, link,
1540                                 "MESSAGE=%-*s: could not enslave: %s",
1541                                 IFNAMSIZ,
1542                                 link->ifname, strerror(-r),
1543                                 "ERRNO=%d", -r,
1544                                 NULL);
1545                 link_enter_failed(link);
1546                 link_unref(link);
1547                 return 1;
1548         }
1549
1550         log_debug_link(link, "enslaved");
1551
1552         if (link->enslaving == 0)
1553                 link_enslaved(link);
1554
1555         link_unref(link);
1556
1557         return 1;
1558 }
1559
1560 static int link_enter_enslave(Link *link) {
1561         NetDev *vlan, *macvlan, *vxlan;
1562         Iterator i;
1563         int r;
1564
1565         assert(link);
1566         assert(link->network);
1567         assert(link->state == LINK_STATE_INITIALIZING);
1568
1569         link->state = LINK_STATE_ENSLAVING;
1570
1571         link_save(link);
1572
1573         if (!link->network->bridge &&
1574             !link->network->bond &&
1575             !link->network->tunnel &&
1576             hashmap_isempty(link->network->vlans) &&
1577             hashmap_isempty(link->network->macvlans) &&
1578             hashmap_isempty(link->network->vxlans))
1579                 return link_enslaved(link);
1580
1581         if (link->network->bond) {
1582                 log_struct_link(LOG_DEBUG, link,
1583                                 "MESSAGE=%-*s: enslaving by '%s'",
1584                                 IFNAMSIZ,
1585                                 link->ifname, link->network->bond->ifname,
1586                                 NETDEV(link->network->bond),
1587                                 NULL);
1588
1589                 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1590                 if (r < 0) {
1591                         log_struct_link(LOG_WARNING, link,
1592                                         "MESSAGE=%-*s: could not enslave by '%s': %s",
1593                                         IFNAMSIZ,
1594                                         link->ifname, link->network->bond->ifname, strerror(-r),
1595                                         NETDEV(link->network->bond),
1596                                         NULL);
1597                         link_enter_failed(link);
1598                         return r;
1599                 }
1600
1601                 link_ref(link);
1602                 link->enslaving ++;
1603         }
1604
1605         if (link->network->bridge) {
1606                 log_struct_link(LOG_DEBUG, link,
1607                                 "MESSAGE=%-*s: enslaving by '%s'",
1608                                 IFNAMSIZ,
1609                                 link->ifname, link->network->bridge->ifname,
1610                                 NETDEV(link->network->bridge),
1611                                 NULL);
1612
1613                 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1614                 if (r < 0) {
1615                         log_struct_link(LOG_WARNING, link,
1616                                         "MESSAGE=%-*s: could not enslave by '%s': %s",
1617                                         IFNAMSIZ,
1618                                         link->ifname, link->network->bridge->ifname, strerror(-r),
1619                                         NETDEV(link->network->bridge),
1620                                         NULL);
1621                         link_enter_failed(link);
1622                         return r;
1623                 }
1624
1625                 link_ref(link);
1626                 link->enslaving ++;
1627         }
1628
1629         if (link->network->tunnel) {
1630                 log_struct_link(LOG_DEBUG, link,
1631                                 "MESSAGE=%-*s: enslaving by '%s'",
1632                                 IFNAMSIZ,
1633                                 link->ifname, link->network->tunnel->ifname,
1634                                 NETDEV(link->network->tunnel),
1635                                 NULL);
1636
1637                 r = netdev_enslave(link->network->tunnel, link, &enslave_handler);
1638                 if (r < 0) {
1639                         log_struct_link(LOG_WARNING, link,
1640                                         "MESSAGE=%-*s: could not enslave by '%s': %s",
1641                                         IFNAMSIZ,
1642                                         link->ifname, link->network->tunnel->ifname, strerror(-r),
1643                                         NETDEV(link->network->tunnel),
1644                                         NULL);
1645                         link_enter_failed(link);
1646                         return r;
1647                 }
1648
1649                 link_ref(link);
1650                 link->enslaving ++;
1651         }
1652
1653         HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1654                 log_struct_link(LOG_DEBUG, link,
1655                                 "MESSAGE=%-*s: enslaving by '%s'",
1656                                 IFNAMSIZ,
1657                                 link->ifname, vlan->ifname, NETDEV(vlan), NULL);
1658
1659                 r = netdev_enslave(vlan, link, &enslave_handler);
1660                 if (r < 0) {
1661                         log_struct_link(LOG_WARNING, link,
1662                                         "MESSAGE=%-*s: could not enslave by '%s': %s",
1663                                         IFNAMSIZ,
1664                                         link->ifname, vlan->ifname, strerror(-r),
1665                                         NETDEV(vlan), NULL);
1666                         link_enter_failed(link);
1667                         return r;
1668                 }
1669
1670                 link_ref(link);
1671                 link->enslaving ++;
1672         }
1673
1674         HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1675                 log_struct_link(LOG_DEBUG, link,
1676                                 "MESSAGE=%-*s: enslaving by '%s'",
1677                                 IFNAMSIZ,
1678                                 link->ifname, macvlan->ifname, NETDEV(macvlan), NULL);
1679
1680                 r = netdev_enslave(macvlan, link, &enslave_handler);
1681                 if (r < 0) {
1682                         log_struct_link(LOG_WARNING, link,
1683                                         "MESSAGE=%-*s: could not enslave by '%s': %s",
1684                                         IFNAMSIZ,
1685                                         link->ifname, macvlan->ifname, strerror(-r),
1686                                         NETDEV(macvlan), NULL);
1687                         link_enter_failed(link);
1688                         return r;
1689                 }
1690
1691                 link_ref(link);
1692                 link->enslaving ++;
1693         }
1694
1695         HASHMAP_FOREACH(vxlan, link->network->vxlans, i) {
1696                 log_struct_link(LOG_DEBUG, link,
1697                                 "MESSAGE=%*s: enslaving by '%s'",
1698                                 IFNAMSIZ,
1699                                 link->ifname, vxlan->ifname, NETDEV(vxlan), NULL);
1700
1701                 r = netdev_enslave(vxlan, link, &enslave_handler);
1702                 if (r < 0) {
1703                         log_struct_link(LOG_WARNING, link,
1704                                         "MESSAGE=%*s: could not enslave by '%s': %s",
1705                                         IFNAMSIZ,
1706                                         link->ifname, vxlan->ifname, strerror(-r),
1707                                         NETDEV(vxlan), NULL);
1708                         link_enter_failed(link);
1709                         return r;
1710                 }
1711
1712                 link_ref(link);
1713                 link->enslaving ++;
1714         }
1715
1716         return 0;
1717 }
1718
1719 static int link_configure(Link *link) {
1720         int r;
1721
1722         assert(link);
1723         assert(link->state == LINK_STATE_INITIALIZING);
1724
1725         if (link->network->ipv4ll) {
1726                 uint8_t seed[8];
1727
1728                 r = sd_ipv4ll_new(&link->ipv4ll);
1729                 if (r < 0)
1730                         return r;
1731
1732                 if (link->udev_device) {
1733                         r = net_get_unique_predictable_data(link->udev_device, seed);
1734                         if (r >= 0) {
1735                                 r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed);
1736                                 if (r < 0)
1737                                         return r;
1738                         }
1739                 }
1740
1741                 r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0);
1742                 if (r < 0)
1743                         return r;
1744
1745                 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1746                 if (r < 0)
1747                         return r;
1748
1749                 r = sd_ipv4ll_set_index(link->ipv4ll, link->ifindex);
1750                 if (r < 0)
1751                         return r;
1752
1753                 r = sd_ipv4ll_set_callback(link->ipv4ll, ipv4ll_handler, link);
1754                 if (r < 0)
1755                         return r;
1756         }
1757
1758         if (link->network->dhcp) {
1759                 r = sd_dhcp_client_new(&link->dhcp_client);
1760                 if (r < 0)
1761                         return r;
1762
1763                 r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
1764                 if (r < 0)
1765                         return r;
1766
1767                 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
1768                 if (r < 0)
1769                         return r;
1770
1771                 r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
1772                 if (r < 0)
1773                         return r;
1774
1775                 r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp_handler, link);
1776                 if (r < 0)
1777                         return r;
1778
1779                 if (link->network->dhcp_mtu) {
1780                         r = sd_dhcp_client_set_request_option(link->dhcp_client, 26);
1781                         if (r < 0)
1782                                 return r;
1783                 }
1784         }
1785
1786         if (link->network->dhcp_server) {
1787                 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1788                 if (r < 0)
1789                         return r;
1790
1791                 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1792                 if (r < 0)
1793                         return r;
1794         }
1795
1796         if (link_has_carrier(link->flags, link->kernel_operstate)) {
1797                 r = link_acquire_conf(link);
1798                 if (r < 0)
1799                         return r;
1800         }
1801
1802         return link_enter_enslave(link);
1803 }
1804
1805 static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1806         Link *link = userdata;
1807         Network *network;
1808         int r;
1809
1810         assert(link);
1811         assert(link->ifname);
1812         assert(link->manager);
1813
1814         if (link->state != LINK_STATE_INITIALIZING)
1815                 return 0;
1816
1817         log_debug_link(link, "link state is up-to-date");
1818
1819         r = network_get(link->manager, link->udev_device, link->ifname, &link->mac, &network);
1820         if (r == -ENOENT) {
1821                 link_enter_unmanaged(link);
1822                 return 0;
1823         } else if (r < 0)
1824                 return r;
1825
1826         r = network_apply(link->manager, network, link);
1827         if (r < 0)
1828                 return r;
1829
1830         r = link_configure(link);
1831         if (r < 0)
1832                 return r;
1833
1834         return 0;
1835 }
1836
1837 int link_initialized(Link *link, struct udev_device *device) {
1838         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1839         int r;
1840
1841         assert(link);
1842         assert(link->manager);
1843         assert(link->manager->rtnl);
1844         assert(device);
1845
1846         if (link->state != LINK_STATE_INITIALIZING)
1847                 return 0;
1848
1849         log_debug_link(link, "udev initialized link");
1850
1851         link->udev_device = udev_device_ref(device);
1852
1853         /* udev has initialized the link, but we don't know if we have yet processed
1854            the NEWLINK messages with the latest state. Do a GETLINK, when it returns
1855            we know that the pending NEWLINKs have already been processed and that we
1856            are up-to-date */
1857
1858         r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK, link->ifindex);
1859         if (r < 0)
1860                 return r;
1861
1862         r = sd_rtnl_call_async(link->manager->rtnl, req, link_initialized_and_synced, link, 0, NULL);
1863         if (r < 0)
1864                 return r;
1865
1866         return 0;
1867 }
1868
1869 int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
1870         Manager *m = userdata;
1871         Link *link = NULL;
1872         uint16_t type;
1873         _cleanup_address_free_ Address *address = NULL;
1874         Address *ad;
1875         char buf[INET6_ADDRSTRLEN];
1876         bool address_dropped = false;
1877         int r, ifindex;
1878
1879         assert(rtnl);
1880         assert(message);
1881         assert(m);
1882
1883         r = sd_rtnl_message_get_type(message, &type);
1884         if (r < 0) {
1885                 log_warning("rtnl: could not get message type");
1886                 return 0;
1887         }
1888
1889         r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
1890         if (r < 0 || ifindex <= 0) {
1891                 log_warning("rtnl: received address message without valid ifindex, ignoring");
1892                 return 0;
1893         } else {
1894                 r = link_get(m, ifindex, &link);
1895                 if (r < 0 || !link) {
1896                         log_warning("rtnl: received address for a nonexistent link, ignoring");
1897                         return 0;
1898                 }
1899         }
1900
1901         r = address_new_dynamic(&address);
1902         if (r < 0)
1903                 return 0;
1904
1905         r = sd_rtnl_message_addr_get_family(message, &address->family);
1906         if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
1907                 log_warning_link(link, "rtnl: received address with invalid family, ignoring");
1908                 return 0;
1909         }
1910
1911         r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
1912         if (r < 0) {
1913                 log_warning_link(link, "rtnl: received address with invalid prefixlen, ignoring");
1914                 return 0;
1915         }
1916
1917         r = sd_rtnl_message_addr_get_scope(message, &address->scope);
1918         if (r < 0) {
1919                 log_warning_link(link, "rtnl: received address with invalid scope, ignoring");
1920                 return 0;
1921         }
1922
1923         switch (address->family) {
1924         case AF_INET:
1925                 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL, &address->in_addr.in);
1926                 if (r < 0) {
1927                         log_warning_link(link, "rtnl: received address without valid address, ignoring");
1928                         return 0;
1929                 }
1930
1931                 break;
1932
1933         case AF_INET6:
1934                 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS, &address->in_addr.in6);
1935                 if (r < 0) {
1936                         log_warning_link(link, "rtnl: received address without valid address, ignoring");
1937                         return 0;
1938                 }
1939
1940                 break;
1941
1942         default:
1943                 assert_not_reached("invalid address family");
1944         }
1945
1946         if (!inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN)) {
1947                 log_warning_link(link, "could not print address");
1948                 return 0;
1949         }
1950
1951         LIST_FOREACH(addresses, ad, link->addresses) {
1952                 if (address_equal(ad, address)) {
1953                         LIST_REMOVE(addresses, link->addresses, ad);
1954
1955                         address_free(ad);
1956
1957                         address_dropped = true;
1958
1959                         break;
1960                 }
1961         }
1962
1963         switch (type) {
1964         case RTM_NEWADDR:
1965                 if (!address_dropped)
1966                         log_debug_link(link, "added address: %s/%u", buf,
1967                                       address->prefixlen);
1968
1969                 LIST_PREPEND(addresses, link->addresses, address);
1970                 address = NULL;
1971
1972                 link_save(link);
1973
1974                 break;
1975         case RTM_DELADDR:
1976                 if (address_dropped) {
1977                         log_debug_link(link, "removed address: %s/%u", buf,
1978                                       address->prefixlen);
1979
1980                         link_save(link);
1981                 }
1982
1983                 break;
1984         default:
1985                 assert_not_reached("Received invalid RTNL message type");
1986         }
1987
1988         return 1;
1989 }
1990
1991 static int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1992         Link *link = userdata;
1993         int r;
1994
1995         assert(rtnl);
1996         assert(m);
1997         assert(link);
1998
1999         for (; m; m = sd_rtnl_message_next(m)) {
2000                 r = sd_rtnl_message_get_errno(m);
2001                 if (r < 0) {
2002                         log_debug_link(link, "getting address failed: %s", strerror(-r));
2003                         continue;
2004                 }
2005
2006                 r = link_rtnl_process_address(rtnl, m, link->manager);
2007                 if (r < 0)
2008                         log_warning_link(link, "could not process address: %s", strerror(-r));
2009         }
2010
2011         return 1;
2012 }
2013
2014 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
2015         Link *link;
2016         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
2017         _cleanup_udev_device_unref_ struct udev_device *device = NULL;
2018         char ifindex_str[2 + DECIMAL_STR_MAX(int)];
2019         int r;
2020
2021         assert(m);
2022         assert(m->rtnl);
2023         assert(message);
2024         assert(ret);
2025
2026         r = link_new(m, message, ret);
2027         if (r < 0)
2028                 return r;
2029
2030         link = *ret;
2031
2032         log_debug_link(link, "link %"PRIu64" added", link->ifindex);
2033
2034         r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex, 0);
2035         if (r < 0)
2036                 return r;
2037
2038         r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0, NULL);
2039         if (r < 0)
2040                 return r;
2041
2042         if (detect_container(NULL) <= 0) {
2043                 /* not in a container, udev will be around */
2044                 sprintf(ifindex_str, "n%"PRIu64, link->ifindex);
2045                 device = udev_device_new_from_device_id(m->udev, ifindex_str);
2046                 if (!device) {
2047                         log_warning_link(link, "could not find udev device");
2048                         return -errno;
2049                 }
2050
2051                 if (udev_device_get_is_initialized(device) <= 0) {
2052                         /* not yet ready */
2053                         log_debug_link(link, "udev initializing link...");
2054                         return 0;
2055                 }
2056
2057                 r = link_initialized(link, device);
2058                 if (r < 0)
2059                         return r;
2060         } else {
2061                 r = link_initialized_and_synced(m->rtnl, NULL, link);
2062                 if (r < 0)
2063                         return r;
2064         }
2065
2066         return 0;
2067 }
2068
2069 int link_update(Link *link, sd_rtnl_message *m) {
2070         struct ether_addr mac;
2071         char *ifname;
2072         int r;
2073
2074         assert(link);
2075         assert(link->ifname);
2076         assert(m);
2077
2078         if (link->state == LINK_STATE_LINGER) {
2079                 link_ref(link);
2080                 log_info_link(link, "link readded");
2081                 link->state = LINK_STATE_ENSLAVING;
2082         }
2083
2084         r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
2085         if (r >= 0 && !streq(ifname, link->ifname)) {
2086                 log_info_link(link, "renamed to %s", ifname);
2087
2088                 free(link->ifname);
2089                 link->ifname = strdup(ifname);
2090                 if (!link->ifname)
2091                         return -ENOMEM;
2092         }
2093
2094         if (!link->original_mtu) {
2095                 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
2096                 if (r >= 0)
2097                         log_debug_link(link, "saved original MTU: %"
2098                                        PRIu16, link->original_mtu);
2099         }
2100
2101         /* The kernel may broadcast NEWLINK messages without the MAC address
2102            set, simply ignore them. */
2103         r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
2104         if (r >= 0) {
2105                 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN)) {
2106
2107                         memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet, ETH_ALEN);
2108
2109                         log_debug_link(link, "MAC address: "
2110                                        "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2111                                        mac.ether_addr_octet[0],
2112                                        mac.ether_addr_octet[1],
2113                                        mac.ether_addr_octet[2],
2114                                        mac.ether_addr_octet[3],
2115                                        mac.ether_addr_octet[4],
2116                                        mac.ether_addr_octet[5]);
2117
2118                         if (link->ipv4ll) {
2119                                 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
2120                                 if (r < 0) {
2121                                         log_warning_link(link, "Could not update MAC "
2122                                                          "address in IPv4LL client: %s",
2123                                                          strerror(-r));
2124                                         return r;
2125                                 }
2126                         }
2127
2128                         if (link->dhcp_client) {
2129                                 r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
2130                                 if (r < 0) {
2131                                         log_warning_link(link, "Could not update MAC "
2132                                                          "address in DHCP client: %s",
2133                                                          strerror(-r));
2134                                         return r;
2135                                 }
2136                         }
2137                 }
2138         }
2139
2140         return link_update_flags(link, m);
2141 }
2142
2143 static void serialize_addresses(FILE *f, const char *key, Address *address) {
2144         Address *ad;
2145
2146         assert(f);
2147         assert(key);
2148
2149         if (!address)
2150                 return;
2151
2152         fprintf(f, "%s=", key);
2153
2154         LIST_FOREACH(addresses, ad, address) {
2155                 char buf[INET6_ADDRSTRLEN];
2156
2157                 if (inet_ntop(ad->family, &ad->in_addr, buf, INET6_ADDRSTRLEN))
2158                         fprintf(f, "%s%s", buf, (ad->addresses_next) ? " ": "");
2159         }
2160
2161         fputs("\n", f);
2162 }
2163
2164 static void link_update_operstate(Link *link) {
2165
2166         assert(link);
2167
2168         if (link->kernel_operstate == IF_OPER_DORMANT)
2169                 link->operstate = LINK_OPERSTATE_DORMANT;
2170         else if (link_has_carrier(link->flags, link->kernel_operstate)) {
2171                 Address *address;
2172                 uint8_t scope = RT_SCOPE_NOWHERE;
2173
2174                 /* if we have carrier, check what addresses we have */
2175                 LIST_FOREACH(addresses, address, link->addresses) {
2176                         if (address->scope < scope)
2177                                 scope = address->scope;
2178                 }
2179
2180                 if (scope < RT_SCOPE_SITE)
2181                         /* universally accessible addresses found */
2182                         link->operstate = LINK_OPERSTATE_ROUTABLE;
2183                 else if (scope < RT_SCOPE_HOST)
2184                         /* only link or site local addresses found */
2185                         link->operstate = LINK_OPERSTATE_DEGRADED;
2186                 else
2187                         /* no useful addresses found */
2188                         link->operstate = LINK_OPERSTATE_CARRIER;
2189         } else
2190                 link->operstate = LINK_OPERSTATE_UNKNOWN;
2191 }
2192
2193 int link_save(Link *link) {
2194         _cleanup_free_ char *temp_path = NULL;
2195         _cleanup_fclose_ FILE *f = NULL;
2196         const char *admin_state, *oper_state;
2197         int r;
2198
2199         assert(link);
2200         assert(link->state_file);
2201         assert(link->lease_file);
2202         assert(link->manager);
2203
2204         link_update_operstate(link);
2205
2206         r = manager_save(link->manager);
2207         if (r < 0)
2208                 return r;
2209
2210         if (link->state == LINK_STATE_LINGER) {
2211                 unlink(link->state_file);
2212                 return 0;
2213         }
2214
2215         admin_state = link_state_to_string(link->state);
2216         assert(admin_state);
2217
2218         oper_state = link_operstate_to_string(link->operstate);
2219         assert(oper_state);
2220
2221         r = fopen_temporary(link->state_file, &f, &temp_path);
2222         if (r < 0)
2223                 goto finish;
2224
2225         fchmod(fileno(f), 0644);
2226
2227         fprintf(f,
2228                 "# This is private data. Do not parse.\n"
2229                 "ADMIN_STATE=%s\n"
2230                 "OPER_STATE=%s\n"
2231                 "FLAGS=%u\n",
2232                 admin_state, oper_state, link->flags);
2233
2234         if (link->network) {
2235                 serialize_addresses(f, "DNS", link->network->dns);
2236                 serialize_addresses(f, "NTP", link->network->ntp);
2237         }
2238
2239         if (link->dhcp_lease) {
2240                 assert(link->network);
2241
2242                 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
2243                 if (r < 0)
2244                         goto finish;
2245
2246                 fprintf(f,
2247                         "DHCP_LEASE=%s\n"
2248                         "DHCP_USE_DNS=%s\n"
2249                         "DHCP_USE_NTP=%s\n",
2250                         link->lease_file,
2251                         yes_no(link->network->dhcp_dns),
2252                         yes_no(link->network->dhcp_ntp));
2253         } else
2254                 unlink(link->lease_file);
2255
2256         fflush(f);
2257
2258         if (ferror(f) || rename(temp_path, link->state_file) < 0) {
2259                 r = -errno;
2260                 unlink(link->state_file);
2261                 unlink(temp_path);
2262         }
2263
2264 finish:
2265         if (r < 0)
2266                 log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
2267
2268         return r;
2269 }
2270
2271 static const char* const link_state_table[_LINK_STATE_MAX] = {
2272         [LINK_STATE_INITIALIZING] = "initializing",
2273         [LINK_STATE_ENSLAVING] = "configuring",
2274         [LINK_STATE_SETTING_ADDRESSES] = "configuring",
2275         [LINK_STATE_SETTING_ROUTES] = "configuring",
2276         [LINK_STATE_CONFIGURED] = "configured",
2277         [LINK_STATE_UNMANAGED] = "unmanaged",
2278         [LINK_STATE_FAILED] = "failed",
2279         [LINK_STATE_LINGER] = "linger",
2280 };
2281
2282 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
2283
2284 static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
2285         [LINK_OPERSTATE_UNKNOWN] = "unknown",
2286         [LINK_OPERSTATE_DORMANT] = "dormant",
2287         [LINK_OPERSTATE_CARRIER] = "carrier",
2288         [LINK_OPERSTATE_DEGRADED] = "degraded",
2289         [LINK_OPERSTATE_ROUTABLE] = "routable",
2290 };
2291
2292 DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);