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