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