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