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