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