chiark / gitweb /
networkd: fix confusion from missing braces
[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                 link_update_flags(link, link->flags | IFF_UP);
1061         else
1062                 log_struct_link(LOG_WARNING, link,
1063                                 "MESSAGE=%s: could not bring up interface: %s",
1064                                 link->ifname, strerror(-r),
1065                                 "ERRNO=%d", -r,
1066                                 NULL);
1067         return 1;
1068 }
1069
1070 static int link_up(Link *link) {
1071         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1072         int r;
1073
1074         assert(link);
1075         assert(link->manager);
1076         assert(link->manager->rtnl);
1077
1078         log_debug_link(link, "bringing link up");
1079
1080         r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1081                                      RTM_SETLINK, link->ifindex);
1082         if (r < 0) {
1083                 log_error_link(link, "Could not allocate RTM_SETLINK message");
1084                 return r;
1085         }
1086
1087         r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1088         if (r < 0) {
1089                 log_error_link(link, "Could not set link flags: %s", strerror(-r));
1090                 return r;
1091         }
1092
1093         r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
1094         if (r < 0) {
1095                 log_error_link(link,
1096                                "Could not send rtnetlink message: %s", strerror(-r));
1097                 return r;
1098         }
1099
1100         return 0;
1101 }
1102
1103 static int link_enslaved(Link *link) {
1104         int r;
1105
1106         assert(link);
1107         assert(link->state == LINK_STATE_ENSLAVING);
1108         assert(link->network);
1109
1110         r = link_up(link);
1111         if (r < 0) {
1112                 link_enter_failed(link);
1113                 return r;
1114         }
1115
1116         if (!link->network->dhcp && !link->network->ipv4ll)
1117                 return link_enter_set_addresses(link);
1118
1119         return 0;
1120 }
1121
1122 static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1123         Link *link = userdata;
1124         int r;
1125
1126         assert(link);
1127         assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
1128         assert(link->network);
1129
1130         link->enslaving --;
1131
1132         if (link->state == LINK_STATE_FAILED)
1133                 return 1;
1134
1135         r = sd_rtnl_message_get_errno(m);
1136         if (r < 0) {
1137                 log_struct_link(LOG_ERR, link,
1138                                 "MESSAGE=%s: could not enslave: %s",
1139                                 link->ifname, strerror(-r),
1140                                 "ERRNO=%d", -r,
1141                                 NULL);
1142                 link_enter_failed(link);
1143                 return 1;
1144         }
1145
1146         log_debug_link(link, "enslaved");
1147
1148         if (link->enslaving == 0)
1149                 link_enslaved(link);
1150
1151         return 1;
1152 }
1153
1154 static int link_enter_enslave(Link *link) {
1155         NetDev *vlan, *macvlan;
1156         Iterator i;
1157         int r;
1158
1159         assert(link);
1160         assert(link->network);
1161         assert(link->state == _LINK_STATE_INVALID);
1162
1163         link->state = LINK_STATE_ENSLAVING;
1164
1165         link_save(link);
1166
1167         if (!link->network->bridge && !link->network->bond &&
1168             hashmap_isempty(link->network->vlans) &&
1169             hashmap_isempty(link->network->macvlans))
1170                 return link_enslaved(link);
1171
1172         if (link->network->bridge) {
1173                 log_struct_link(LOG_DEBUG, link,
1174                                 "MESSAGE=%s: enslaving by '%s'",
1175                                 link->ifname, link->network->bridge->name,
1176                                 NETDEV(link->network->bridge),
1177                                 NULL);
1178
1179                 r = netdev_enslave(link->network->bridge, link, &enslave_handler);
1180                 if (r < 0) {
1181                         log_struct_link(LOG_WARNING, link,
1182                                         "MESSAGE=%s: could not enslave by '%s': %s",
1183                                         link->ifname, link->network->bridge->name, strerror(-r),
1184                                         NETDEV(link->network->bridge),
1185                                         NULL);
1186                         link_enter_failed(link);
1187                         return r;
1188                 }
1189
1190                 link->enslaving ++;
1191         }
1192
1193         if (link->network->bond) {
1194                 log_struct_link(LOG_DEBUG, link,
1195                                 "MESSAGE=%s: enslaving by '%s'",
1196                                 link->ifname, link->network->bond->name,
1197                                 NETDEV(link->network->bond),
1198                                 NULL);
1199
1200                 r = netdev_enslave(link->network->bond, link, &enslave_handler);
1201                 if (r < 0) {
1202                         log_struct_link(LOG_WARNING, link,
1203                                         "MESSAGE=%s: could not enslave by '%s': %s",
1204                                         link->ifname, link->network->bond->name, strerror(-r),
1205                                         NETDEV(link->network->bond),
1206                                         NULL);
1207                         link_enter_failed(link);
1208                         return r;
1209                 }
1210
1211                 link->enslaving ++;
1212         }
1213
1214         HASHMAP_FOREACH(vlan, link->network->vlans, i) {
1215                 log_struct_link(LOG_DEBUG, link,
1216                                 "MESSAGE=%s: enslaving by '%s'",
1217                                 link->ifname, vlan->name, NETDEV(vlan), NULL);
1218
1219                 r = netdev_enslave(vlan, link, &enslave_handler);
1220                 if (r < 0) {
1221                         log_struct_link(LOG_WARNING, link,
1222                                         "MESSAGE=%s: could not enslave by '%s': %s",
1223                                         link->ifname, vlan->name, strerror(-r),
1224                                         NETDEV(vlan), NULL);
1225                         link_enter_failed(link);
1226                         return r;
1227                 }
1228
1229                 link->enslaving ++;
1230         }
1231
1232         HASHMAP_FOREACH(macvlan, link->network->macvlans, i) {
1233                 log_struct_link(LOG_DEBUG, link,
1234                                 "MESSAGE=%s: enslaving by '%s'",
1235                                 link->ifname, macvlan->name, NETDEV(macvlan), NULL);
1236
1237                 r = netdev_enslave(macvlan, link, &enslave_handler);
1238                 if (r < 0) {
1239                         log_struct_link(LOG_WARNING, link,
1240                                         "MESSAGE=%s: could not enslave by '%s': %s",
1241                                         link->ifname, macvlan->name, strerror(-r),
1242                                         NETDEV(macvlan), NULL);
1243                         link_enter_failed(link);
1244                         return r;
1245                 }
1246
1247                 link->enslaving ++;
1248         }
1249
1250         return 0;
1251 }
1252
1253 static int link_getlink_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
1254                                 void *userdata) {
1255         Link *link = userdata;
1256         int r;
1257
1258         assert(link);
1259
1260         if (link->state == LINK_STATE_FAILED)
1261                 return 1;
1262
1263         r = sd_rtnl_message_get_errno(m);
1264         if (r < 0) {
1265                 log_struct_link(LOG_ERR, link,
1266                                 "MESSAGE=%s: could not get state: %s",
1267                                 link->ifname, strerror(-r),
1268                                 "ERRNO=%d", -r,
1269                                 NULL);
1270                 link_enter_failed(link);
1271                 return 1;
1272         }
1273
1274         log_debug_link(link, "got link state");
1275
1276         link_update(link, m);
1277
1278         return 1;
1279 }
1280
1281 static int link_getlink(Link *link) {
1282         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1283         int r;
1284
1285         assert(link);
1286         assert(link->manager);
1287         assert(link->manager->rtnl);
1288
1289         log_debug_link(link, "requesting link status");
1290
1291         r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
1292                                      RTM_GETLINK, link->ifindex);
1293         if (r < 0) {
1294                 log_error_link(link, "Could not allocate RTM_GETLINK message");
1295                 return r;
1296         }
1297
1298         r = sd_rtnl_call_async(link->manager->rtnl, req, link_getlink_handler,
1299                                link, 0, NULL);
1300         if (r < 0) {
1301                 log_error_link(link,
1302                                "Could not send rtnetlink message: %s", strerror(-r));
1303                 return r;
1304         }
1305
1306         return 0;
1307 }
1308
1309 int link_configure(Link *link) {
1310         int r;
1311
1312         assert(link);
1313         assert(link->network);
1314         assert(link->state == _LINK_STATE_INVALID);
1315
1316         r = link_getlink(link);
1317         if (r < 0) {
1318                 link_enter_failed(link);
1319                 return r;
1320         }
1321
1322         return link_enter_enslave(link);
1323 }
1324
1325 int link_update(Link *link, sd_rtnl_message *m) {
1326         unsigned flags;
1327         int r;
1328
1329         assert(link);
1330         assert(m);
1331
1332         if (link->state == LINK_STATE_FAILED)
1333                 return 0;
1334
1335         r = sd_rtnl_message_link_get_flags(m, &flags);
1336         if (r < 0) {
1337                 log_warning_link(link, "Could not get link flags");
1338                 return r;
1339         }
1340
1341         if (link->network->dhcp && link->network->dhcp_mtu &&
1342             !link->original_mtu) {
1343                 r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu);
1344                 if (r >= 0)
1345                         log_debug_link(link, "saved original MTU: %"
1346                                        PRIu16, link->original_mtu);
1347         }
1348
1349         r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &link->mac);
1350         if (r >= 0) {
1351                 log_debug_link(link, "MAC address: "
1352                                "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1353                                 link->mac.ether_addr_octet[0],
1354                                 link->mac.ether_addr_octet[1],
1355                                 link->mac.ether_addr_octet[2],
1356                                 link->mac.ether_addr_octet[3],
1357                                 link->mac.ether_addr_octet[4],
1358                                 link->mac.ether_addr_octet[5]);
1359         }
1360
1361         return link_update_flags(link, flags);
1362 }
1363
1364 int link_save(Link *link) {
1365         _cleanup_free_ char *temp_path = NULL;
1366         _cleanup_fclose_ FILE *f = NULL;
1367         int r;
1368
1369         assert(link);
1370         assert(link->state_file);
1371
1372         r = mkdir_safe_label("/run/systemd/network/links", 0755, 0, 0);
1373         if (r < 0)
1374                 goto finish;
1375
1376         r = fopen_temporary(link->state_file, &f, &temp_path);
1377         if (r < 0)
1378                 goto finish;
1379
1380         fchmod(fileno(f), 0644);
1381
1382         fprintf(f,
1383                 "# This is private data. Do not parse.\n"
1384                 "STATE=%s\n",
1385                 link_state_to_string(link->state));
1386
1387         if (link->dhcp_lease) {
1388                 const char *lease_file = "/run/systemd/network/leases/test.lease";
1389
1390                 r = dhcp_lease_save(link->dhcp_lease, lease_file);
1391                 if (r < 0)
1392                         goto finish;
1393
1394                 fprintf(f, "DHCP_LEASE=%s\n", lease_file);
1395         }
1396
1397         fflush(f);
1398
1399         if (ferror(f) || rename(temp_path, link->state_file) < 0) {
1400                 r = -errno;
1401                 unlink(link->state_file);
1402                 unlink(temp_path);
1403         }
1404
1405 finish:
1406         if (r < 0)
1407                 log_error("Failed to save link data %s: %s", link->state_file, strerror(-r));
1408
1409         return r;
1410 }
1411
1412 static const char* const link_state_table[_LINK_STATE_MAX] = {
1413         [LINK_STATE_ENSLAVING] = "configuring",
1414         [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1415         [LINK_STATE_SETTING_ROUTES] = "configuring",
1416         [LINK_STATE_CONFIGURED] = "configured",
1417         [LINK_STATE_FAILED] = "failed",
1418 };
1419
1420 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);