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