chiark / gitweb /
networkd: link - save link flags when the link is added
[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 #include <unistd.h>
25
26 #include "networkd-link.h"
27 #include "networkd-netdev.h"
28 #include "libudev-private.h"
29 #include "udev-util.h"
30 #include "util.h"
31 #include "virt.h"
32 #include "bus-util.h"
33 #include "network-internal.h"
34 #include "conf-parser.h"
35
36 #include "dhcp-lease-internal.h"
37
38 #define FLAG_STRING(string, flag, old, new) \
39         (((old ^ new) & flag) \
40                 ? ((old & flag) ? (" -" string) : (" +" string)) \
41                 : "")
42
43 static int link_update_flags(Link *link, sd_rtnl_message *m) {
44         unsigned flags, unknown_flags_added, unknown_flags_removed, unknown_flags;
45         uint8_t operstate;
46         int r;
47
48         assert(link);
49
50         r = sd_rtnl_message_link_get_flags(m, &flags);
51         if (r < 0) {
52                 log_warning_link(link, "Could not get link flags");
53                 return r;
54         }
55
56         r = sd_rtnl_message_read_u8(m, IFLA_OPERSTATE, &operstate);
57         if (r < 0)
58                 /* if we got a message without operstate, take it to mean
59                    the state was unchanged */
60                 operstate = link->kernel_operstate;
61
62         if ((link->flags == flags) && (link->kernel_operstate == operstate))
63                 return 0;
64
65         if (link->flags != flags) {
66                 log_debug_link(link, "flags change:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
67                                FLAG_STRING("LOOPBACK", IFF_LOOPBACK, link->flags, flags),
68                                FLAG_STRING("MASTER", IFF_MASTER, link->flags, flags),
69                                FLAG_STRING("SLAVE", IFF_SLAVE, link->flags, flags),
70                                FLAG_STRING("UP", IFF_UP, link->flags, flags),
71                                FLAG_STRING("DORMANT", IFF_DORMANT, link->flags, flags),
72                                FLAG_STRING("LOWER_UP", IFF_LOWER_UP, link->flags, flags),
73                                FLAG_STRING("RUNNING", IFF_RUNNING, link->flags, flags),
74                                FLAG_STRING("MULTICAST", IFF_MULTICAST, link->flags, flags),
75                                FLAG_STRING("BROADCAST", IFF_BROADCAST, link->flags, flags),
76                                FLAG_STRING("POINTOPOINT", IFF_POINTOPOINT, link->flags, flags),
77                                FLAG_STRING("PROMISC", IFF_PROMISC, link->flags, flags),
78                                FLAG_STRING("ALLMULTI", IFF_ALLMULTI, link->flags, flags),
79                                FLAG_STRING("PORTSEL", IFF_PORTSEL, link->flags, flags),
80                                FLAG_STRING("AUTOMEDIA", IFF_AUTOMEDIA, link->flags, flags),
81                                FLAG_STRING("DYNAMIC", IFF_DYNAMIC, link->flags, flags),
82                                FLAG_STRING("NOARP", IFF_NOARP, link->flags, flags),
83                                FLAG_STRING("NOTRAILERS", IFF_NOTRAILERS, link->flags, flags),
84                                FLAG_STRING("DEBUG", IFF_DEBUG, link->flags, flags),
85                                FLAG_STRING("ECHO", IFF_ECHO, link->flags, flags));
86
87                 unknown_flags = ~(IFF_LOOPBACK | IFF_MASTER | IFF_SLAVE | IFF_UP |
88                                   IFF_DORMANT | IFF_LOWER_UP | IFF_RUNNING |
89                                   IFF_MULTICAST | IFF_BROADCAST | IFF_POINTOPOINT |
90                                   IFF_PROMISC | IFF_ALLMULTI | IFF_PORTSEL |
91                                   IFF_AUTOMEDIA | IFF_DYNAMIC | IFF_NOARP |
92                                   IFF_NOTRAILERS | IFF_DEBUG | IFF_ECHO);
93                 unknown_flags_added = ((link->flags ^ flags) & flags & unknown_flags);
94                 unknown_flags_removed = ((link->flags ^ flags) & link->flags & unknown_flags);
95
96                 /* link flags are currently at most 18 bits, let's align to
97                  * printing 20 */
98                 if (unknown_flags_added)
99                         log_debug_link(link,
100                                        "unknown link flags gained: %#.5x (ignoring)",
101                                        unknown_flags_added);
102
103                 if (unknown_flags_removed)
104                         log_debug_link(link,
105                                        "unknown link flags lost: %#.5x (ignoring)",
106                                        unknown_flags_removed);
107         }
108
109         link->flags = flags;
110         link->kernel_operstate = operstate;
111
112         link_save(link);
113
114         return 0;
115 }
116
117 static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
118         _cleanup_link_unref_ Link *link = NULL;
119         uint16_t type;
120         const char *ifname;
121         int r, ifindex;
122
123         assert(manager);
124         assert(message);
125         assert(ret);
126
127         r = sd_rtnl_message_get_type(message, &type);
128         if (r < 0)
129                 return r;
130         else if (type != RTM_NEWLINK)
131                 return -EINVAL;
132
133         r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
134         if (r < 0)
135                 return r;
136         else if (ifindex <= 0)
137                 return -EINVAL;
138
139         r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname);
140         if (r < 0)
141                 return r;
142
143         link = new0(Link, 1);
144         if (!link)
145                 return -ENOMEM;
146
147         link->n_ref = 1;
148         link->manager = manager;
149         link->state = LINK_STATE_PENDING;
150         link->ifindex = ifindex;
151         link->ifname = strdup(ifname);
152         if (!link->ifname)
153                 return -ENOMEM;
154
155         r = sd_rtnl_message_read_ether_addr(message, IFLA_ADDRESS, &link->mac);
156         if (r < 0)
157                 log_debug_link(link, "MAC address not found for new device, continuing without");
158
159         r = asprintf(&link->state_file, "/run/systemd/netif/links/%d",
160                      link->ifindex);
161         if (r < 0)
162                 return -ENOMEM;
163
164         r = asprintf(&link->lease_file, "/run/systemd/netif/leases/%d",
165                      link->ifindex);
166         if (r < 0)
167                 return -ENOMEM;
168
169         r = hashmap_ensure_allocated(&manager->links, NULL, NULL);
170         if (r < 0)
171                 return r;
172
173         r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
174         if (r < 0)
175                 return r;
176
177         r = link_update_flags(link, message);
178         if (r < 0)
179                 return r;
180
181         *ret = link;
182         link = NULL;
183
184         return 0;
185 }
186
187 static void link_free(Link *link) {
188         Address *address;
189
190         if (!link)
191                 return;
192
193         while ((address = link->addresses)) {
194                 LIST_REMOVE(addresses, link->addresses, address);
195                 address_free(address);
196         }
197
198         while ((address = link->pool_addresses)) {
199                 LIST_REMOVE(addresses, link->pool_addresses, address);
200                 address_free(address);
201         }
202
203         sd_dhcp_client_unref(link->dhcp_client);
204         sd_dhcp_lease_unref(link->dhcp_lease);
205
206         unlink(link->lease_file);
207         free(link->lease_file);
208
209         sd_ipv4ll_unref(link->ipv4ll);
210         sd_dhcp6_client_unref(link->dhcp6_client);
211         sd_icmp6_nd_unref(link->icmp6_router_discovery);
212
213         if (link->manager)
214                 hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex));
215
216         free(link->ifname);
217
218         unlink(link->state_file);
219         free(link->state_file);
220
221         udev_device_unref(link->udev_device);
222
223         free(link);
224 }
225
226 Link *link_unref(Link *link) {
227         if (link && (-- link->n_ref <= 0))
228                 link_free(link);
229
230         return NULL;
231 }
232
233 Link *link_ref(Link *link) {
234         if (link)
235                 assert_se(++ link->n_ref >= 2);
236
237         return link;
238 }
239
240 int link_get(Manager *m, int ifindex, Link **ret) {
241         Link *link;
242
243         assert(m);
244         assert(ifindex);
245         assert(ret);
246
247         link = hashmap_get(m->links, INT_TO_PTR(ifindex));
248         if (!link)
249                 return -ENODEV;
250
251         *ret = link;
252
253         return 0;
254 }
255
256 void link_drop(Link *link) {
257         if (!link || link->state == LINK_STATE_LINGER)
258                 return;
259
260         link->state = LINK_STATE_LINGER;
261
262         log_debug_link(link, "link removed");
263
264         link_unref(link);
265
266         return;
267 }
268
269 static void link_enter_unmanaged(Link *link) {
270         assert(link);
271
272         log_debug_link(link, "unmanaged");
273
274         link->state = LINK_STATE_UNMANAGED;
275
276         link_save(link);
277 }
278
279 static int link_stop_clients(Link *link) {
280         int r = 0, k;
281
282         assert(link);
283         assert(link->manager);
284         assert(link->manager->event);
285
286         if (!link->network)
287                 return 0;
288
289         if (link->dhcp_client) {
290                 k = sd_dhcp_client_stop(link->dhcp_client);
291                 if (k < 0) {
292                         log_warning_link(link, "Could not stop DHCPv4 client: %s",
293                                          strerror(-r));
294                         r = k;
295                 }
296         }
297
298         if (link->ipv4ll) {
299                 k = sd_ipv4ll_stop(link->ipv4ll);
300                 if (k < 0) {
301                         log_warning_link(link, "Could not stop IPv4 link-local: %s",
302                                          strerror(-r));
303                         r = k;
304                 }
305         }
306
307         if (link->dhcp_server) {
308                 k = sd_dhcp_server_stop(link->dhcp_server);
309                 if (k < 0) {
310                         log_warning_link(link, "Could not stop DHCPv4 server: %s",
311                                          strerror(-r));
312                         r = k;
313                 }
314         }
315
316         if(link->icmp6_router_discovery) {
317
318                 if (link->dhcp6_client) {
319                         k = sd_dhcp6_client_stop(link->dhcp6_client);
320                         if (k < 0) {
321                                 log_warning_link(link, "Could not stop DHCPv6 client: %s",
322                                                  strerror(-r));
323                                 r = k;
324                         }
325                 }
326
327                 k = sd_icmp6_nd_stop(link->icmp6_router_discovery);
328                 if (k < 0) {
329                         log_warning_link(link,
330                                          "Could not stop ICMPv6 router discovery: %s",
331                                          strerror(-r));
332                         r = k;
333                 }
334         }
335
336         return r;
337 }
338
339 void link_enter_failed(Link *link) {
340         assert(link);
341
342         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
343                 return;
344
345         log_warning_link(link, "failed");
346
347         link->state = LINK_STATE_FAILED;
348
349         link_stop_clients(link);
350
351         link_save(link);
352 }
353
354 static Address* link_find_dhcp_server_address(Link *link) {
355         Address *address;
356
357         assert(link);
358         assert(link->network);
359
360         /* The the first statically configured address if there is any */
361         LIST_FOREACH(addresses, address, link->network->static_addresses) {
362
363                 if (address->family != AF_INET)
364                         continue;
365
366                 if (in_addr_is_null(address->family, &address->in_addr))
367                         continue;
368
369                 return address;
370         }
371
372         /* If that didn't work, find a suitable address we got from the pool */
373         LIST_FOREACH(addresses, address, link->pool_addresses) {
374                 if (address->family != AF_INET)
375                         continue;
376
377                 return address;
378         }
379
380         return NULL;
381 }
382
383 static int link_enter_configured(Link *link) {
384         int r;
385
386         assert(link);
387         assert(link->network);
388         assert(link->state == LINK_STATE_SETTING_ROUTES);
389
390         if (link->network->dhcp_server &&
391             !sd_dhcp_server_is_running(link->dhcp_server)) {
392                 struct in_addr pool_start;
393                 Address *address;
394
395                 address = link_find_dhcp_server_address(link);
396                 if (!address) {
397                         log_warning_link(link,
398                                          "Failed to find suitable address for DHCPv4 server instance.");
399                         link_enter_failed(link);
400                         return 0;
401                 }
402
403                 log_debug_link(link, "offering DHCPv4 leases");
404
405                 r = sd_dhcp_server_set_address(link->dhcp_server,
406                                                &address->in_addr.in,
407                                                address->prefixlen);
408                 if (r < 0)
409                         return r;
410
411                 /* offer 32 addresses starting from the address following the server address */
412                 pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
413                 r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
414                                                   &pool_start, 32);
415                 if (r < 0)
416                         return r;
417
418                 /* TODO:
419                 r = sd_dhcp_server_set_router(link->dhcp_server,
420                                               &main_address->in_addr.in);
421                 if (r < 0)
422                         return r;
423
424                 r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
425                                                  main_address->prefixlen);
426                 if (r < 0)
427                         return r;
428                 */
429
430                 r = sd_dhcp_server_start(link->dhcp_server);
431                 if (r < 0) {
432                         log_warning_link(link, "could not start DHCPv4 server "
433                                          "instance: %s", strerror(-r));
434
435                         link_enter_failed(link);
436
437                         return 0;
438                 }
439         }
440
441         log_info_link(link, "link configured");
442
443         link->state = LINK_STATE_CONFIGURED;
444
445         link_save(link);
446
447         return 0;
448 }
449
450 void link_client_handler(Link *link) {
451         assert(link);
452         assert(link->network);
453
454         if (!link->static_configured)
455                 return;
456
457         if (link->network->ipv4ll)
458                 if (!link->ipv4ll_address ||
459                     !link->ipv4ll_route)
460                         return;
461
462         if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4))
463                 if (!link->dhcp4_configured)
464                         return;
465
466         if (link->state != LINK_STATE_CONFIGURED)
467                 link_enter_configured(link);
468
469         return;
470 }
471
472 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
473         _cleanup_link_unref_ Link *link = userdata;
474         int r;
475
476         assert(link->link_messages > 0);
477         assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
478                       LINK_STATE_SETTING_ROUTES, LINK_STATE_FAILED,
479                       LINK_STATE_LINGER));
480
481         link->link_messages --;
482
483         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
484                 return 1;
485
486         r = sd_rtnl_message_get_errno(m);
487         if (r < 0 && r != -EEXIST)
488                 log_struct_link(LOG_WARNING, link,
489                                 "MESSAGE=%-*s: could not set route: %s",
490                                 IFNAMSIZ,
491                                 link->ifname, strerror(-r),
492                                 "ERRNO=%d", -r,
493                                 NULL);
494
495         if (link->link_messages == 0) {
496                 log_debug_link(link, "routes set");
497                 link->static_configured = true;
498                 link_client_handler(link);
499         }
500
501         return 1;
502 }
503
504 static int link_enter_set_routes(Link *link) {
505         Route *rt;
506         int r;
507
508         assert(link);
509         assert(link->network);
510         assert(link->state == LINK_STATE_SETTING_ADDRESSES);
511
512         link->state = LINK_STATE_SETTING_ROUTES;
513
514         LIST_FOREACH(routes, rt, link->network->static_routes) {
515                 r = route_configure(rt, link, &route_handler);
516                 if (r < 0) {
517                         log_warning_link(link,
518                                          "could not set routes: %s",
519                                          strerror(-r));
520                         link_enter_failed(link);
521                         return r;
522                 }
523
524                 link->link_messages ++;
525         }
526
527         if (link->link_messages == 0) {
528                 link->static_configured = true;
529                 link_client_handler(link);
530         } else
531                 log_debug_link(link, "setting routes");
532
533         return 0;
534 }
535
536 int link_route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
537         _cleanup_link_unref_ Link *link = userdata;
538         int r;
539
540         assert(m);
541         assert(link);
542         assert(link->ifname);
543
544         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
545                 return 1;
546
547         r = sd_rtnl_message_get_errno(m);
548         if (r < 0 && r != -ESRCH)
549                 log_struct_link(LOG_WARNING, link,
550                                 "MESSAGE=%-*s: could not drop route: %s",
551                                 IFNAMSIZ,
552                                 link->ifname, strerror(-r),
553                                 "ERRNO=%d", -r,
554                                 NULL);
555
556         return 1;
557 }
558
559 int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
560         _cleanup_link_unref_ Link *link = userdata;
561         int r;
562
563         assert(rtnl);
564         assert(m);
565         assert(link);
566         assert(link->manager);
567
568         for (; m; m = sd_rtnl_message_next(m)) {
569                 r = sd_rtnl_message_get_errno(m);
570                 if (r < 0) {
571                         log_debug_link(link, "getting address failed: %s",
572                                        strerror(-r));
573                         continue;
574                 }
575
576                 r = link_rtnl_process_address(rtnl, m, link->manager);
577                 if (r < 0)
578                         log_warning_link(link, "could not process address: %s",
579                                          strerror(-r));
580         }
581
582         return 1;
583 }
584
585 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
586         _cleanup_link_unref_ Link *link = userdata;
587         int r;
588
589         assert(rtnl);
590         assert(m);
591         assert(link);
592         assert(link->ifname);
593         assert(link->link_messages > 0);
594         assert(IN_SET(link->state, LINK_STATE_SETTING_ADDRESSES,
595                LINK_STATE_FAILED, LINK_STATE_LINGER));
596
597         link->link_messages --;
598
599         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
600                 return 1;
601
602         r = sd_rtnl_message_get_errno(m);
603         if (r < 0 && r != -EEXIST)
604                 log_struct_link(LOG_WARNING, link,
605                                 "MESSAGE=%-*s: could not set address: %s",
606                                 IFNAMSIZ,
607                                 link->ifname, strerror(-r),
608                                 "ERRNO=%d", -r,
609                                 NULL);
610         else if (r >= 0) {
611                 /* calling handler directly so take a ref */
612                 link_ref(link);
613                 link_get_address_handler(rtnl, m, link);
614         }
615
616         if (link->link_messages == 0) {
617                 log_debug_link(link, "addresses set");
618                 link_enter_set_routes(link);
619         }
620
621         return 1;
622 }
623
624 static int link_enter_set_addresses(Link *link) {
625         Address *ad;
626         int r;
627
628         assert(link);
629         assert(link->network);
630         assert(link->state != _LINK_STATE_INVALID);
631
632         link->state = LINK_STATE_SETTING_ADDRESSES;
633
634         LIST_FOREACH(addresses, ad, link->network->static_addresses) {
635                 r = address_configure(ad, link, &address_handler);
636                 if (r < 0) {
637                         log_warning_link(link,
638                                          "could not set addresses: %s",
639                                          strerror(-r));
640                         link_enter_failed(link);
641                         return r;
642                 }
643
644                 link->link_messages ++;
645         }
646
647         if (link->link_messages == 0) {
648                 link_enter_set_routes(link);
649         } else
650                 log_debug_link(link, "setting addresses");
651
652         return 0;
653 }
654
655 int link_address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
656         _cleanup_link_unref_ Link *link = userdata;
657         int r;
658
659         assert(m);
660         assert(link);
661         assert(link->ifname);
662
663         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
664                 return 1;
665
666         r = sd_rtnl_message_get_errno(m);
667         if (r < 0 && r != -EADDRNOTAVAIL)
668                 log_struct_link(LOG_WARNING, link,
669                                 "MESSAGE=%-*s: could not drop address: %s",
670                                 IFNAMSIZ,
671                                 link->ifname, strerror(-r),
672                                 "ERRNO=%d", -r,
673                                 NULL);
674
675         return 1;
676 }
677
678 static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata,
679                                 sd_bus_error *ret_error) {
680         _cleanup_link_unref_ Link *link = userdata;
681         int r;
682
683         assert(link);
684
685         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
686                 return 1;
687
688         r = sd_bus_message_get_errno(m);
689         if (r < 0)
690                 r = -r;
691         if (r > 0)
692                 log_warning_link(link, "Could not set hostname: %s",
693                                  strerror(r));
694
695         return 1;
696 }
697
698 int link_set_hostname(Link *link, const char *hostname) {
699         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
700         int r = 0;
701
702         assert(link);
703         assert(link->manager);
704         assert(hostname);
705
706         log_debug_link(link, "Setting transient hostname: '%s'", hostname);
707
708         if (!link->manager->bus) {
709                 /* TODO: replace by assert when we can rely on kdbus */
710                 log_info_link(link,
711                               "Not connected to system bus, ignoring transient hostname.");
712                 return 0;
713         }
714
715         r = sd_bus_message_new_method_call(
716                         link->manager->bus,
717                         &m,
718                         "org.freedesktop.hostname1",
719                         "/org/freedesktop/hostname1",
720                         "org.freedesktop.hostname1",
721                         "SetHostname");
722         if (r < 0)
723                 return r;
724
725         r = sd_bus_message_append(m, "sb", hostname, false);
726         if (r < 0)
727                 return r;
728
729         r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler,
730                               link, 0);
731         if (r < 0) {
732                 log_error_link(link, "Could not set transient hostname: %s",
733                                strerror(-r));
734                 return r;
735         }
736
737         link_ref(link);
738
739         return 0;
740 }
741
742 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
743         _cleanup_link_unref_ Link *link = userdata;
744         int r;
745
746         assert(m);
747         assert(link);
748         assert(link->ifname);
749
750         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
751                 return 1;
752
753         r = sd_rtnl_message_get_errno(m);
754         if (r < 0)
755                 log_struct_link(LOG_WARNING, link,
756                                 "MESSAGE=%-*s: could not set MTU: %s",
757                                 IFNAMSIZ, link->ifname, strerror(-r),
758                                 "ERRNO=%d", -r,
759                                 NULL);
760
761         return 1;
762 }
763
764 int link_set_mtu(Link *link, uint32_t mtu) {
765         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
766         int r;
767
768         assert(link);
769         assert(link->manager);
770         assert(link->manager->rtnl);
771
772         log_debug_link(link, "setting MTU: %" PRIu32, mtu);
773
774         r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
775                                      RTM_SETLINK, link->ifindex);
776         if (r < 0) {
777                 log_error_link(link, "Could not allocate RTM_SETLINK message");
778                 return r;
779         }
780
781         r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
782         if (r < 0) {
783                 log_error_link(link, "Could not append MTU: %s", strerror(-r));
784                 return r;
785         }
786
787         r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link,
788                                0, NULL);
789         if (r < 0) {
790                 log_error_link(link,
791                                "Could not send rtnetlink message: %s",
792                                strerror(-r));
793                 return r;
794         }
795
796         link_ref(link);
797
798         return 0;
799 }
800
801 static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
802         Link *link = userdata;
803
804         assert(link);
805         assert(link->network);
806         assert(link->manager);
807
808         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
809                 return;
810
811         switch(event) {
812         case DHCP6_EVENT_STOP:
813         case DHCP6_EVENT_RESEND_EXPIRE:
814         case DHCP6_EVENT_RETRANS_MAX:
815         case DHCP6_EVENT_IP_ACQUIRE:
816                 log_debug_link(link, "DHCPv6 event %d", event);
817
818                 break;
819
820         default:
821                 if (event < 0)
822                         log_warning_link(link, "DHCPv6 error: %s",
823                                          strerror(-event));
824                 else
825                         log_warning_link(link, "DHCPv6 unknown event: %d",
826                                          event);
827                 return;
828         }
829 }
830
831 static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
832         Link *link = userdata;
833         int r;
834
835         assert(link);
836         assert(link->network);
837         assert(link->manager);
838
839         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
840                 return;
841
842         switch(event) {
843         case ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE:
844         case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER:
845                 return;
846
847         case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT:
848         case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED:
849                 break;
850
851         default:
852                 if (event < 0)
853                         log_warning_link(link, "ICMPv6 error: %s",
854                                          strerror(-event));
855                 else
856                         log_warning_link(link, "ICMPv6 unknown event: %d",
857                                          event);
858
859                 return;
860         }
861
862         if (link->dhcp6_client)
863                 return;
864
865         r = sd_dhcp6_client_new(&link->dhcp6_client);
866         if (r < 0)
867                 return;
868
869         r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
870         if (r < 0) {
871                 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
872                 return;
873         }
874
875         r = sd_dhcp6_client_set_mac(link->dhcp6_client, &link->mac);
876         if (r < 0) {
877                 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
878                 return;
879         }
880
881         r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
882         if (r < 0) {
883                 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
884                 return;
885         }
886
887         r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
888                                          link);
889         if (r < 0) {
890                 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
891                 return;
892         }
893
894         r = sd_dhcp6_client_start(link->dhcp6_client);
895         if (r < 0)
896                 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
897 }
898
899 static int link_acquire_conf(Link *link) {
900         int r;
901
902         assert(link);
903         assert(link->network);
904         assert(link->manager);
905         assert(link->manager->event);
906
907         if (link->network->ipv4ll) {
908                 assert(link->ipv4ll);
909
910                 log_debug_link(link, "acquiring IPv4 link-local address");
911
912                 r = sd_ipv4ll_start(link->ipv4ll);
913                 if (r < 0) {
914                         log_warning_link(link, "could not acquire IPv4 "
915                                          "link-local address");
916                         return r;
917                 }
918         }
919
920         if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
921                 assert(link->dhcp_client);
922
923                 log_debug_link(link, "acquiring DHCPv4 lease");
924
925                 r = sd_dhcp_client_start(link->dhcp_client);
926                 if (r < 0) {
927                         log_warning_link(link, "could not acquire DHCPv4 "
928                                          "lease");
929                         return r;
930                 }
931         }
932
933         if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
934                 assert(link->icmp6_router_discovery);
935
936                 log_debug_link(link, "discovering IPv6 routers");
937
938                 r = sd_icmp6_router_solicitation_start(link->icmp6_router_discovery);
939                 if (r < 0) {
940                         log_warning_link(link,
941                                          "could not start IPv6 router discovery");
942                         return r;
943                 }
944         }
945
946         return 0;
947 }
948
949 bool link_has_carrier(Link *link) {
950         /* see Documentation/networking/operstates.txt in the kernel sources */
951
952         if (link->kernel_operstate == IF_OPER_UP)
953                 return true;
954
955         if (link->kernel_operstate == IF_OPER_UNKNOWN)
956                 /* operstate may not be implemented, so fall back to flags */
957                 if ((link->flags & IFF_LOWER_UP) && !(link->flags & IFF_DORMANT))
958                         return true;
959
960         return false;
961 }
962
963 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
964         _cleanup_link_unref_ Link *link = userdata;
965         int r;
966
967         assert(link);
968
969         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
970                 return 1;
971
972         r = sd_rtnl_message_get_errno(m);
973         if (r < 0) {
974                 /* we warn but don't fail the link, as it may
975                    be brought up later */
976                 log_struct_link(LOG_WARNING, link,
977                                 "MESSAGE=%-*s: could not bring up interface: %s",
978                                 IFNAMSIZ,
979                                 link->ifname, strerror(-r),
980                                 "ERRNO=%d", -r,
981                                 NULL);
982         }
983
984         return 1;
985 }
986
987 static int link_up(Link *link) {
988         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
989         int r;
990
991         assert(link);
992         assert(link->manager);
993         assert(link->manager->rtnl);
994
995         log_debug_link(link, "bringing link up");
996
997         r = sd_rtnl_message_new_link(link->manager->rtnl, &req,
998                                      RTM_SETLINK, link->ifindex);
999         if (r < 0) {
1000                 log_error_link(link, "Could not allocate RTM_SETLINK message");
1001                 return r;
1002         }
1003
1004         r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
1005         if (r < 0) {
1006                 log_error_link(link, "Could not set link flags: %s",
1007                                strerror(-r));
1008                 return r;
1009         }
1010
1011         r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link,
1012                                0, NULL);
1013         if (r < 0) {
1014                 log_error_link(link,
1015                                "Could not send rtnetlink message: %s",
1016                                strerror(-r));
1017                 return r;
1018         }
1019
1020         link_ref(link);
1021
1022         return 0;
1023 }
1024
1025 static int link_joined(Link *link) {
1026         int r;
1027
1028         assert(link);
1029         assert(link->network);
1030
1031         if (!(link->flags & IFF_UP)) {
1032                 r = link_up(link);
1033                 if (r < 0) {
1034                         link_enter_failed(link);
1035                         return r;
1036                 }
1037         }
1038
1039         return link_enter_set_addresses(link);
1040 }
1041
1042 static int netdev_join_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
1043                                void *userdata) {
1044         _cleanup_link_unref_ Link *link = userdata;
1045         int r;
1046
1047         assert(link);
1048         assert(link->network);
1049
1050         link->enslaving --;
1051
1052         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
1053                 return 1;
1054
1055         r = sd_rtnl_message_get_errno(m);
1056         if (r < 0 && r != -EEXIST) {
1057                 log_struct_link(LOG_ERR, link,
1058                                 "MESSAGE=%-*s: could not join netdev: %s",
1059                                 IFNAMSIZ,
1060                                 link->ifname, strerror(-r),
1061                                 "ERRNO=%d", -r,
1062                                 NULL);
1063                 link_enter_failed(link);
1064                 return 1;
1065         } else
1066                 log_debug_link(link, "joined netdev");
1067
1068         if (link->enslaving <= 0)
1069                 link_joined(link);
1070
1071         return 1;
1072 }
1073
1074 static int link_enter_join_netdev(Link *link) {
1075         NetDev *netdev;
1076         Iterator i;
1077         int r;
1078
1079         assert(link);
1080         assert(link->network);
1081         assert(link->state == LINK_STATE_PENDING);
1082
1083         link->state = LINK_STATE_ENSLAVING;
1084
1085         link_save(link);
1086
1087         if (!link->network->bridge &&
1088             !link->network->bond &&
1089             hashmap_isempty(link->network->stacked_netdevs))
1090                 return link_joined(link);
1091
1092         if (link->network->bond) {
1093                 log_struct_link(LOG_DEBUG, link,
1094                                 "MESSAGE=%-*s: enslaving by '%s'",
1095                                 IFNAMSIZ,
1096                                 link->ifname, link->network->bond->ifname,
1097                                 NETDEVIF(link->network->bond),
1098                                 NULL);
1099
1100                 r = netdev_join(link->network->bond, link, &netdev_join_handler);
1101                 if (r < 0) {
1102                         log_struct_link(LOG_WARNING, link,
1103                                         "MESSAGE=%-*s: could not join netdev '%s': %s",
1104                                         IFNAMSIZ,
1105                                         link->ifname, link->network->bond->ifname,
1106                                         strerror(-r),
1107                                         NETDEVIF(link->network->bond),
1108                                         NULL);
1109                         link_enter_failed(link);
1110                         return r;
1111                 }
1112
1113                 link->enslaving ++;
1114         }
1115
1116         if (link->network->bridge) {
1117                 log_struct_link(LOG_DEBUG, link,
1118                                 "MESSAGE=%-*s: enslaving by '%s'",
1119                                 IFNAMSIZ,
1120                                 link->ifname, link->network->bridge->ifname,
1121                                 NETDEVIF(link->network->bridge),
1122                                 NULL);
1123
1124                 r = netdev_join(link->network->bridge, link,
1125                                 &netdev_join_handler);
1126                 if (r < 0) {
1127                         log_struct_link(LOG_WARNING, link,
1128                                         "MESSAGE=%-*s: could not join netdev '%s': %s",
1129                                         IFNAMSIZ,
1130                                         link->ifname, link->network->bridge->ifname,
1131                                         strerror(-r),
1132                                         NETDEVIF(link->network->bridge),
1133                                         NULL);
1134                         link_enter_failed(link);
1135                         return r;
1136                 }
1137
1138                 link->enslaving ++;
1139         }
1140
1141         HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
1142                 log_struct_link(LOG_DEBUG, link,
1143                                 "MESSAGE=%-*s: enslaving by '%s'",
1144                                 IFNAMSIZ,
1145                                 link->ifname, netdev->ifname, NETDEVIF(netdev),
1146                                 NULL);
1147
1148                 r = netdev_join(netdev, link, &netdev_join_handler);
1149                 if (r < 0) {
1150                         log_struct_link(LOG_WARNING, link,
1151                                         "MESSAGE=%-*s: could not join netdev '%s': %s",
1152                                         IFNAMSIZ,
1153                                         link->ifname, netdev->ifname,
1154                                         strerror(-r),
1155                                         NETDEVIF(netdev), NULL);
1156                         link_enter_failed(link);
1157                         return r;
1158                 }
1159
1160                 link->enslaving ++;
1161         }
1162
1163         return 0;
1164 }
1165
1166 static int link_configure(Link *link) {
1167         int r;
1168
1169         assert(link);
1170         assert(link->network);
1171         assert(link->state == LINK_STATE_PENDING);
1172
1173         if (link->network->ipv4ll) {
1174                 r = ipv4ll_configure(link);
1175                 if (r < 0)
1176                         return r;
1177         }
1178
1179         if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4)) {
1180                 r = dhcp4_configure(link);
1181                 if (r < 0)
1182                         return r;
1183         }
1184
1185         if (link->network->dhcp_server) {
1186                 r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
1187                 if (r < 0)
1188                         return r;
1189
1190                 r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
1191                 if (r < 0)
1192                         return r;
1193         }
1194
1195         if (IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V6)) {
1196                 r = sd_icmp6_nd_new(&link->icmp6_router_discovery);
1197                 if (r < 0)
1198                         return r;
1199
1200                 r = sd_icmp6_nd_attach_event(link->icmp6_router_discovery,
1201                                              NULL, 0);
1202                 if (r < 0)
1203                         return r;
1204
1205                 r = sd_icmp6_nd_set_mac(link->icmp6_router_discovery,
1206                                         &link->mac);
1207                 if (r < 0)
1208                         return r;
1209
1210                 r = sd_icmp6_nd_set_index(link->icmp6_router_discovery,
1211                                           link->ifindex);
1212                 if (r < 0)
1213                         return r;
1214
1215                 r = sd_icmp6_nd_set_callback(link->icmp6_router_discovery,
1216                                              icmp6_router_handler, link);
1217                 if (r < 0)
1218                         return r;
1219         }
1220
1221         if (link_has_carrier(link)) {
1222                 r = link_acquire_conf(link);
1223                 if (r < 0)
1224                         return r;
1225         }
1226
1227         return link_enter_join_netdev(link);
1228 }
1229
1230 static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m,
1231                                        void *userdata) {
1232         _cleanup_link_unref_ Link *link = userdata;
1233         Network *network;
1234         int r;
1235
1236         assert(link);
1237         assert(link->ifname);
1238         assert(link->manager);
1239
1240         if (link->state != LINK_STATE_PENDING)
1241                 return 1;
1242
1243         log_debug_link(link, "link state is up-to-date");
1244
1245         r = network_get(link->manager, link->udev_device, link->ifname,
1246                         &link->mac, &network);
1247         if (r == -ENOENT) {
1248                 link_enter_unmanaged(link);
1249                 return 1;
1250         } else if (r < 0)
1251                 return r;
1252
1253         r = network_apply(link->manager, network, link);
1254         if (r < 0)
1255                 return r;
1256
1257         r = link_configure(link);
1258         if (r < 0)
1259                 return r;
1260
1261         return 1;
1262 }
1263
1264 int link_initialized(Link *link, struct udev_device *device) {
1265         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1266         int r;
1267
1268         assert(link);
1269         assert(link->manager);
1270         assert(link->manager->rtnl);
1271         assert(device);
1272
1273         if (link->state != LINK_STATE_PENDING)
1274                 return 0;
1275
1276         if (link->udev_device)
1277                 return 0;
1278
1279         log_debug_link(link, "udev initialized link");
1280
1281         link->udev_device = udev_device_ref(device);
1282
1283         /* udev has initialized the link, but we don't know if we have yet
1284          * processed the NEWLINK messages with the latest state. Do a GETLINK,
1285          * when it returns we know that the pending NEWLINKs have already been
1286          * processed and that we are up-to-date */
1287
1288         r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
1289                                      link->ifindex);
1290         if (r < 0)
1291                 return r;
1292
1293         r = sd_rtnl_call_async(link->manager->rtnl, req,
1294                                link_initialized_and_synced, link, 0, NULL);
1295         if (r < 0)
1296                 return r;
1297
1298         link_ref(link);
1299
1300         return 0;
1301 }
1302
1303 int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message,
1304                               void *userdata) {
1305         Manager *m = userdata;
1306         Link *link = NULL;
1307         uint16_t type;
1308         _cleanup_address_free_ Address *address = NULL;
1309         Address *ad;
1310         char buf[INET6_ADDRSTRLEN];
1311         char valid_buf[FORMAT_TIMESPAN_MAX];
1312         const char *valid_str = NULL;
1313         bool address_dropped = false;
1314         int r, ifindex;
1315
1316         assert(rtnl);
1317         assert(message);
1318         assert(m);
1319
1320         r = sd_rtnl_message_get_type(message, &type);
1321         if (r < 0) {
1322                 log_warning("rtnl: could not get message type");
1323                 return 0;
1324         }
1325
1326         r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
1327         if (r < 0 || ifindex <= 0) {
1328                 log_warning("rtnl: received address message without valid ifindex, ignoring");
1329                 return 0;
1330         } else {
1331                 r = link_get(m, ifindex, &link);
1332                 if (r < 0 || !link) {
1333                         log_warning("rtnl: received address for a nonexistent link, ignoring");
1334                         return 0;
1335                 }
1336         }
1337
1338         r = address_new_dynamic(&address);
1339         if (r < 0)
1340                 return r;
1341
1342         r = sd_rtnl_message_addr_get_family(message, &address->family);
1343         if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) {
1344                 log_warning_link(link,
1345                                  "rtnl: received address with invalid family, ignoring");
1346                 return 0;
1347         }
1348
1349         r = sd_rtnl_message_addr_get_prefixlen(message, &address->prefixlen);
1350         if (r < 0) {
1351                 log_warning_link(link,
1352                                  "rtnl: received address with invalid prefixlen, ignoring");
1353                 return 0;
1354         }
1355
1356         r = sd_rtnl_message_addr_get_scope(message, &address->scope);
1357         if (r < 0) {
1358                 log_warning_link(link,
1359                                  "rtnl: received address with invalid scope, ignoring");
1360                 return 0;
1361         }
1362
1363         r = sd_rtnl_message_addr_get_flags(message, &address->flags);
1364         if (r < 0) {
1365                 log_warning_link(link,
1366                                  "rtnl: received address with invalid flags, ignoring");
1367                 return 0;
1368         }
1369
1370         switch (address->family) {
1371         case AF_INET:
1372                 r = sd_rtnl_message_read_in_addr(message, IFA_LOCAL,
1373                                                  &address->in_addr.in);
1374                 if (r < 0) {
1375                         log_warning_link(link,
1376                                          "rtnl: received address without valid address, ignoring");
1377                         return 0;
1378                 }
1379
1380                 break;
1381
1382         case AF_INET6:
1383                 r = sd_rtnl_message_read_in6_addr(message, IFA_ADDRESS,
1384                                                   &address->in_addr.in6);
1385                 if (r < 0) {
1386                         log_warning_link(link,
1387                                          "rtnl: received address without valid address, ignoring");
1388                         return 0;
1389                 }
1390
1391                 break;
1392
1393         default:
1394                 assert_not_reached("invalid address family");
1395         }
1396
1397         if (!inet_ntop(address->family, &address->in_addr, buf,
1398                        INET6_ADDRSTRLEN)) {
1399                 log_warning_link(link, "could not print address");
1400                 return 0;
1401         }
1402
1403         r = sd_rtnl_message_read_cache_info(message, IFA_CACHEINFO,
1404                                             &address->cinfo);
1405         if (r >= 0) {
1406                 if (address->cinfo.ifa_valid == CACHE_INFO_INFINITY_LIFE_TIME)
1407                         valid_str = "ever";
1408                 else
1409                         valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
1410                                                     address->cinfo.ifa_valid * USEC_PER_SEC,
1411                                                     USEC_PER_SEC);
1412         }
1413
1414         LIST_FOREACH(addresses, ad, link->addresses) {
1415                 if (address_equal(ad, address)) {
1416                         LIST_REMOVE(addresses, link->addresses, ad);
1417
1418                         address_free(ad);
1419
1420                         address_dropped = true;
1421
1422                         break;
1423                 }
1424         }
1425
1426         switch (type) {
1427         case RTM_NEWADDR:
1428                 if (!address_dropped)
1429                         log_debug_link(link, "added address: %s/%u (valid for %s)",
1430                                        buf, address->prefixlen,
1431                                        strna(valid_str));
1432                 else
1433                         log_debug_link(link, "updated address: %s/%u (valid for %s)",
1434                                        buf, address->prefixlen,
1435                                        strna(valid_str));
1436
1437                 LIST_PREPEND(addresses, link->addresses, address);
1438                 address = NULL;
1439
1440                 link_save(link);
1441
1442                 break;
1443         case RTM_DELADDR:
1444                 if (address_dropped) {
1445                         log_debug_link(link, "removed address: %s/%u (valid for %s)",
1446                                        buf, address->prefixlen,
1447                                        strna(valid_str));
1448
1449                         link_save(link);
1450                 } else
1451                         log_warning_link(link,
1452                                          "removing non-existent address: %s/%u (valid for %s)",
1453                                          buf, address->prefixlen,
1454                                          strna(valid_str));
1455
1456                 break;
1457         default:
1458                 assert_not_reached("Received invalid RTNL message type");
1459         }
1460
1461         return 1;
1462 }
1463
1464 int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
1465         Link *link;
1466         _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1467         _cleanup_udev_device_unref_ struct udev_device *device = NULL;
1468         char ifindex_str[2 + DECIMAL_STR_MAX(int)];
1469         int r;
1470
1471         assert(m);
1472         assert(m->rtnl);
1473         assert(message);
1474         assert(ret);
1475
1476         r = link_new(m, message, ret);
1477         if (r < 0)
1478                 return r;
1479
1480         link = *ret;
1481
1482         log_debug_link(link, "link %d added", link->ifindex);
1483
1484         r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex,
1485                                      0);
1486         if (r < 0)
1487                 return r;
1488
1489         r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0,
1490                                NULL);
1491         if (r < 0)
1492                 return r;
1493
1494         link_ref(link);
1495
1496         if (detect_container(NULL) <= 0) {
1497                 /* not in a container, udev will be around */
1498                 sprintf(ifindex_str, "n%d", link->ifindex);
1499                 device = udev_device_new_from_device_id(m->udev, ifindex_str);
1500                 if (!device) {
1501                         log_warning_link(link,
1502                                          "could not find udev device: %m");
1503                         return -errno;
1504                 }
1505
1506                 if (udev_device_get_is_initialized(device) <= 0) {
1507                         /* not yet ready */
1508                         log_debug_link(link, "link pending udev initialization...");
1509                         return 0;
1510                 }
1511
1512                 r = link_initialized(link, device);
1513                 if (r < 0)
1514                         return r;
1515         } else {
1516                 /* we are calling a callback directly, so must take a ref */
1517                 link_ref(link);
1518
1519                 r = link_initialized_and_synced(m->rtnl, NULL, link);
1520                 if (r < 0)
1521                         return r;
1522         }
1523
1524         return 0;
1525 }
1526
1527 int link_update(Link *link, sd_rtnl_message *m) {
1528         struct ether_addr mac;
1529         const char *ifname;
1530         uint32_t mtu;
1531         bool had_carrier, carrier_gained, carrier_lost;
1532         int r;
1533
1534         assert(link);
1535         assert(link->ifname);
1536         assert(m);
1537
1538         if (link->state == LINK_STATE_LINGER) {
1539                 link_ref(link);
1540                 log_info_link(link, "link readded");
1541                 link->state = LINK_STATE_ENSLAVING;
1542         }
1543
1544         r = sd_rtnl_message_read_string(m, IFLA_IFNAME, &ifname);
1545         if (r >= 0 && !streq(ifname, link->ifname)) {
1546                 log_info_link(link, "renamed to %s", ifname);
1547
1548                 free(link->ifname);
1549                 link->ifname = strdup(ifname);
1550                 if (!link->ifname)
1551                         return -ENOMEM;
1552         }
1553
1554         r = sd_rtnl_message_read_u32(m, IFLA_MTU, &mtu);
1555         if (r >= 0 && mtu > 0) {
1556                 link->mtu = mtu;
1557                 if (!link->original_mtu) {
1558                         link->original_mtu = mtu;
1559                         log_debug_link(link, "saved original MTU: %"
1560                                        PRIu32, link->original_mtu);
1561                 }
1562
1563                 if (link->dhcp_client) {
1564                         r = sd_dhcp_client_set_mtu(link->dhcp_client,
1565                                                    link->mtu);
1566                         if (r < 0) {
1567                                 log_warning_link(link,
1568                                                  "Could not update MTU in DHCP client: %s",
1569                                                  strerror(-r));
1570                                 return r;
1571                         }
1572                 }
1573         }
1574
1575         /* The kernel may broadcast NEWLINK messages without the MAC address
1576            set, simply ignore them. */
1577         r = sd_rtnl_message_read_ether_addr(m, IFLA_ADDRESS, &mac);
1578         if (r >= 0) {
1579                 if (memcmp(link->mac.ether_addr_octet, mac.ether_addr_octet,
1580                            ETH_ALEN)) {
1581
1582                         memcpy(link->mac.ether_addr_octet, mac.ether_addr_octet,
1583                                ETH_ALEN);
1584
1585                         log_debug_link(link, "MAC address: "
1586                                        "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1587                                        mac.ether_addr_octet[0],
1588                                        mac.ether_addr_octet[1],
1589                                        mac.ether_addr_octet[2],
1590                                        mac.ether_addr_octet[3],
1591                                        mac.ether_addr_octet[4],
1592                                        mac.ether_addr_octet[5]);
1593
1594                         if (link->ipv4ll) {
1595                                 r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
1596                                 if (r < 0) {
1597                                         log_warning_link(link,
1598                                                          "Could not update MAC address in IPv4LL client: %s",
1599                                                          strerror(-r));
1600                                         return r;
1601                                 }
1602                         }
1603
1604                         if (link->dhcp_client) {
1605                                 r = sd_dhcp_client_set_mac(link->dhcp_client,
1606                                                            &link->mac);
1607                                 if (r < 0) {
1608                                         log_warning_link(link,
1609                                                          "Could not update MAC address in DHCP client: %s",
1610                                                          strerror(-r));
1611                                         return r;
1612                                 }
1613                         }
1614
1615                         if (link->dhcp6_client) {
1616                                 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
1617                                                             &link->mac);
1618                                 if (r < 0) {
1619                                         log_warning_link(link,
1620                                                          "Could not update MAC address in DHCPv6 client: %s",
1621                                                          strerror(-r));
1622                                         return r;
1623                                 }
1624                         }
1625                 }
1626         }
1627
1628         had_carrier = link_has_carrier(link);
1629
1630         r = link_update_flags(link, m);
1631         if (r < 0)
1632                 return r;
1633
1634         carrier_gained = !had_carrier && link_has_carrier(link);
1635         carrier_lost = had_carrier && !link_has_carrier(link);
1636
1637         if (carrier_gained) {
1638                 log_info_link(link, "gained carrier");
1639
1640                 if (link->network) {
1641                         r = link_acquire_conf(link);
1642                         if (r < 0) {
1643                                 link_enter_failed(link);
1644                                 return r;
1645                         }
1646                 }
1647         } else if (carrier_lost) {
1648                 log_info_link(link, "lost carrier");
1649
1650                 r = link_stop_clients(link);
1651                 if (r < 0) {
1652                         link_enter_failed(link);
1653                         return r;
1654                 }
1655         }
1656
1657         return 0;
1658 }
1659
1660 static void link_update_operstate(Link *link) {
1661
1662         assert(link);
1663
1664         if (link->kernel_operstate == IF_OPER_DORMANT)
1665                 link->operstate = LINK_OPERSTATE_DORMANT;
1666         else if (link_has_carrier(link)) {
1667                 Address *address;
1668                 uint8_t scope = RT_SCOPE_NOWHERE;
1669
1670                 /* if we have carrier, check what addresses we have */
1671                 LIST_FOREACH(addresses, address, link->addresses) {
1672                         if (address->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED))
1673                                 continue;
1674
1675                         if (address->scope < scope)
1676                                 scope = address->scope;
1677                 }
1678
1679                 if (scope < RT_SCOPE_SITE)
1680                         /* universally accessible addresses found */
1681                         link->operstate = LINK_OPERSTATE_ROUTABLE;
1682                 else if (scope < RT_SCOPE_HOST)
1683                         /* only link or site local addresses found */
1684                         link->operstate = LINK_OPERSTATE_DEGRADED;
1685                 else
1686                         /* no useful addresses found */
1687                         link->operstate = LINK_OPERSTATE_CARRIER;
1688         } else if (link->flags & IFF_UP)
1689                 link->operstate = LINK_OPERSTATE_NO_CARRIER;
1690         else
1691                 link->operstate = LINK_OPERSTATE_OFF;
1692 }
1693
1694 int link_save(Link *link) {
1695         _cleanup_free_ char *temp_path = NULL;
1696         _cleanup_fclose_ FILE *f = NULL;
1697         const char *admin_state, *oper_state;
1698         int r;
1699
1700         assert(link);
1701         assert(link->state_file);
1702         assert(link->lease_file);
1703         assert(link->manager);
1704
1705         link_update_operstate(link);
1706
1707         r = manager_save(link->manager);
1708         if (r < 0)
1709                 return r;
1710
1711         if (link->state == LINK_STATE_LINGER) {
1712                 unlink(link->state_file);
1713                 return 0;
1714         }
1715
1716         admin_state = link_state_to_string(link->state);
1717         assert(admin_state);
1718
1719         oper_state = link_operstate_to_string(link->operstate);
1720         assert(oper_state);
1721
1722         r = fopen_temporary(link->state_file, &f, &temp_path);
1723         if (r < 0)
1724                 return r;
1725
1726         fchmod(fileno(f), 0644);
1727
1728         fprintf(f,
1729                 "# This is private data. Do not parse.\n"
1730                 "ADMIN_STATE=%s\n"
1731                 "OPER_STATE=%s\n",
1732                 admin_state, oper_state);
1733
1734         if (link->network) {
1735                 char **address, **domain;
1736                 bool space;
1737
1738                 fputs("DNS=", f);
1739                 space = false;
1740                 STRV_FOREACH(address, link->network->dns) {
1741                         if (space)
1742                                 fputc(' ', f);
1743                         fputs(*address, f);
1744                         space = true;
1745                 }
1746
1747                 if (link->network->dhcp_dns &&
1748                     link->dhcp_lease) {
1749                         const struct in_addr *addresses;
1750
1751                         r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
1752                         if (r > 0) {
1753                                 if (space)
1754                                         fputc(' ', f);
1755                                 serialize_in_addrs(f, addresses, r);
1756                         }
1757                 }
1758
1759                 fputs("\n", f);
1760
1761                 fprintf(f, "NTP=");
1762                 space = false;
1763                 STRV_FOREACH(address, link->network->ntp) {
1764                         if (space)
1765                                 fputc(' ', f);
1766                         fputs(*address, f);
1767                         space = true;
1768                 }
1769
1770                 if (link->network->dhcp_ntp &&
1771                     link->dhcp_lease) {
1772                         const struct in_addr *addresses;
1773
1774                         r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
1775                         if (r > 0) {
1776                                 if (space)
1777                                         fputc(' ', f);
1778                                 serialize_in_addrs(f, addresses, r);
1779                         }
1780                 }
1781
1782                 fputs("\n", f);
1783
1784                 fprintf(f, "DOMAINS=");
1785                 space = false;
1786                 STRV_FOREACH(domain, link->network->domains) {
1787                         if (space)
1788                                 fputc(' ', f);
1789                         fputs(*domain, f);
1790                         space = true;
1791                 }
1792
1793                 if (link->network->dhcp_domains &&
1794                     link->dhcp_lease) {
1795                         const char *domainname;
1796
1797                         r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
1798                         if (r >= 0) {
1799                                 if (space)
1800                                         fputc(' ', f);
1801                                 fputs(domainname, f);
1802                         }
1803                 }
1804
1805                 fputs("\n", f);
1806
1807                 fprintf(f, "WILDCARD_DOMAIN=%s\n",
1808                         yes_no(link->network->wildcard_domain));
1809
1810                 fprintf(f, "LLMNR=%s\n",
1811                         llmnr_support_to_string(link->network->llmnr));
1812         }
1813
1814         if (link->dhcp_lease) {
1815                 assert(link->network);
1816
1817                 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
1818                 if (r < 0)
1819                         goto fail;
1820
1821                 fprintf(f,
1822                         "DHCP_LEASE=%s\n",
1823                         link->lease_file);
1824         } else
1825                 unlink(link->lease_file);
1826
1827         r = fflush_and_check(f);
1828         if (r < 0)
1829                 goto fail;
1830
1831         if (rename(temp_path, link->state_file) < 0) {
1832                 r = -errno;
1833                 goto fail;
1834         }
1835
1836         return 0;
1837 fail:
1838         log_error_link(link, "Failed to save link data to %s: %s", link->state_file, strerror(-r));
1839         unlink(link->state_file);
1840         unlink(temp_path);
1841         return r;
1842 }
1843
1844 static const char* const link_state_table[_LINK_STATE_MAX] = {
1845         [LINK_STATE_PENDING] = "pending",
1846         [LINK_STATE_ENSLAVING] = "configuring",
1847         [LINK_STATE_SETTING_ADDRESSES] = "configuring",
1848         [LINK_STATE_SETTING_ROUTES] = "configuring",
1849         [LINK_STATE_CONFIGURED] = "configured",
1850         [LINK_STATE_UNMANAGED] = "unmanaged",
1851         [LINK_STATE_FAILED] = "failed",
1852         [LINK_STATE_LINGER] = "linger",
1853 };
1854
1855 DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
1856
1857 static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
1858         [LINK_OPERSTATE_OFF] = "off",
1859         [LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
1860         [LINK_OPERSTATE_DORMANT] = "dormant",
1861         [LINK_OPERSTATE_CARRIER] = "carrier",
1862         [LINK_OPERSTATE_DEGRADED] = "degraded",
1863         [LINK_OPERSTATE_ROUTABLE] = "routable",
1864 };
1865
1866 DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);