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