chiark / gitweb /
networkd: dhcp - only set the MTU option once
[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
29 int link_new(Manager *manager, struct udev_device *device, Link **ret) {
30         _cleanup_link_free_ Link *link = NULL;
31         const char *mac;
32         struct ether_addr *mac_addr;
33         const char *ifname;
34         int r;
35
36         assert(device);
37         assert(ret);
38
39         link = new0(Link, 1);
40         if (!link)
41                 return -ENOMEM;
42
43         link->manager = manager;
44         link->state = _LINK_STATE_INVALID;
45
46         link->ifindex = udev_device_get_ifindex(device);
47         if (link->ifindex <= 0)
48                 return -EINVAL;
49
50         mac = udev_device_get_sysattr_value(device, "address");
51         if (mac) {
52                 mac_addr = ether_aton(mac);
53                 if (mac_addr)
54                         memcpy(&link->mac, mac_addr, sizeof(struct ether_addr));
55         }
56
57         ifname = udev_device_get_sysname(device);
58         link->ifname = strdup(ifname);
59
60         r = hashmap_put(manager->links, &link->ifindex, link);
61         if (r < 0)
62                 return r;
63
64         *ret = link;
65         link = NULL;
66
67         return 0;
68 }
69
70 void link_free(Link *link) {
71         if (!link)
72                 return;
73
74         assert(link->manager);
75
76         if (link->dhcp)
77                 sd_dhcp_client_free(link->dhcp);
78
79         route_free(link->dhcp_route);
80         link->dhcp_route = NULL;
81
82         address_free(link->dhcp_address);
83         link->dhcp_address = NULL;
84
85         hashmap_remove(link->manager->links, &link->ifindex);
86
87         free(link->ifname);
88
89         free(link);
90 }
91
92 int link_add(Manager *m, struct udev_device *device, Link **ret) {
93         Link *link;
94         Network *network;
95         int r;
96         uint64_t ifindex;
97         const char *devtype;
98
99         assert(m);
100         assert(device);
101
102         ifindex = udev_device_get_ifindex(device);
103         link = hashmap_get(m->links, &ifindex);
104         if (link) {
105                 *ret = link;
106                 return -EEXIST;
107         }
108
109         r = link_new(m, device, &link);
110         if (r < 0)
111                 return r;
112
113         *ret = link;
114
115         devtype = udev_device_get_devtype(device);
116         if (streq_ptr(devtype, "bridge")) {
117                 r = bridge_set_link(m, link);
118                 if (r < 0 && r != -ENOENT)
119                         return r;
120         }
121
122         r = network_get(m, device, &network);
123         if (r < 0)
124                 return r == -ENOENT ? 0 : r;
125
126         r = network_apply(m, network, link);
127         if (r < 0)
128                 return r;
129
130         return 0;
131 }
132
133 static int link_enter_configured(Link *link) {
134         assert(link);
135         assert(link->state == LINK_STATE_SETTING_ROUTES);
136
137         log_info_link(link, "link configured");
138
139         link->state = LINK_STATE_CONFIGURED;
140
141         return 0;
142 }
143
144 static void link_enter_failed(Link *link) {
145         assert(link);
146
147         log_warning_link(link, "failed");
148
149         link->state = LINK_STATE_FAILED;
150 }
151
152 static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
153         Link *link = userdata;
154         int r;
155
156         assert(link->route_messages > 0);
157         assert(link->state == LINK_STATE_SETTING_ADDRESSES ||
158                link->state == LINK_STATE_SETTING_ROUTES ||
159                link->state == LINK_STATE_FAILED);
160
161         link->route_messages --;
162
163         if (link->state == LINK_STATE_FAILED)
164                 return 1;
165
166         r = sd_rtnl_message_get_errno(m);
167         if (r < 0 && r != -EEXIST)
168                 log_warning_link(link, "could not set route: %s", strerror(-r));
169
170         /* we might have received an old reply after moving back to SETTING_ADDRESSES,
171          * ignore it */
172         if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
173                 log_debug_link(link, "routes set");
174                 link_enter_configured(link);
175         }
176
177         return 1;
178 }
179
180 static int link_enter_set_routes(Link *link) {
181         Route *route;
182         int r;
183
184         assert(link);
185         assert(link->network);
186         assert(link->state == LINK_STATE_SETTING_ADDRESSES);
187
188         link->state = LINK_STATE_SETTING_ROUTES;
189
190         if (!link->network->static_routes && !link->dhcp_route)
191                 return link_enter_configured(link);
192
193         log_debug_link(link, "setting routes");
194
195         LIST_FOREACH(static_routes, route, link->network->static_routes) {
196                 r = route_configure(route, link, &route_handler);
197                 if (r < 0) {
198                         log_warning_link(link,
199                                          "could not set routes: %s", strerror(-r));
200                         link_enter_failed(link);
201                         return r;
202                 }
203
204                 link->route_messages ++;
205         }
206
207         if (link->dhcp_route) {
208                 r = route_configure(link->dhcp_route, link, &route_handler);
209                 if (r < 0) {
210                         log_warning_link(link,
211                                          "could not set routes: %s", strerror(-r));
212                         link_enter_failed(link);
213                         return r;
214                 }
215
216                 link->route_messages ++;
217         }
218
219         return 0;
220 }
221
222 static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
223         Link *link = userdata;
224         int r;
225
226         assert(m);
227         assert(link);
228         assert(link->ifname);
229         assert(link->addr_messages > 0);
230         assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
231
232         link->addr_messages --;
233
234         if (link->state == LINK_STATE_FAILED)
235                 return 1;
236
237         r = sd_rtnl_message_get_errno(m);
238         if (r < 0 && r != -EEXIST)
239                 log_struct_link(LOG_ERR, link,
240                                 "MESSAGE=%s: could not set address: %s",
241                                 link->ifname, strerror(-r),
242                                 "ERRNO=%d", -r,
243                                 NULL);
244
245         if (link->addr_messages == 0) {
246                 log_debug_link(link, "addresses set");
247                 link_enter_set_routes(link);
248         }
249
250         return 1;
251 }
252
253 static int link_enter_set_addresses(Link *link) {
254         Address *address;
255         int r;
256
257         assert(link);
258         assert(link->network);
259         assert(link->state != _LINK_STATE_INVALID);
260
261         link->state = LINK_STATE_SETTING_ADDRESSES;
262
263         if (!link->network->static_addresses && !link->dhcp_address)
264                 return link_enter_set_routes(link);
265
266         log_debug_link(link, "setting addresses");
267
268         LIST_FOREACH(static_addresses, address, link->network->static_addresses) {
269                 r = address_configure(address, link, &address_handler);
270                 if (r < 0) {
271                         log_warning_link(link,
272                                          "could not set addresses: %s", strerror(-r));
273                         link_enter_failed(link);
274                         return r;
275                 }
276
277                 link->addr_messages ++;
278         }
279
280         if (link->dhcp_address) {
281                 r = address_configure(link->dhcp_address, link, &address_handler);
282                 if (r < 0) {
283                         log_warning_link(link,
284                                          "could not set addresses: %s", strerror(-r));
285                         link_enter_failed(link);
286                         return r;
287                 }
288
289                 link->addr_messages ++;
290         }
291
292         return 0;
293 }
294
295 static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
296         Link *link = userdata;
297         int r;
298
299         assert(m);
300         assert(link);
301         assert(link->ifname);
302
303         if (link->state == LINK_STATE_FAILED)
304                 return 1;
305
306         r = sd_rtnl_message_get_errno(m);
307         if (r < 0 && r != -EEXIST)
308                 log_warning_link(link, "could not drop address: %s", strerror(-r));
309
310         return 1;
311 }
312
313 static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
314         Link *link = userdata;
315         int r;
316
317         assert(m);
318         assert(link);
319         assert(link->ifname);
320
321         if (link->state == LINK_STATE_FAILED)
322                 return 1;
323
324         r = sd_rtnl_message_get_errno(m);
325         if (r < 0 && r != -EEXIST)
326                 log_warning_link(link, "Could not set MTU: %s", strerror(-r));
327
328         return 1;
329 }
330
331 static int link_set_mtu(Link *link, uint32_t mtu) {
332         _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
333         int r;
334
335         assert(link);
336         assert(link->manager);
337         assert(link->manager->rtnl);
338
339         log_debug_link(link, "setting MTU: %" PRIu32, mtu);
340
341         r = sd_rtnl_message_link_new(RTM_SETLINK, link->ifindex, &req);
342         if (r < 0) {
343                 log_error_link(link, "Could not allocate RTM_SETLINK message");
344                 return r;
345         }
346
347         r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
348         if (r < 0) {
349                 log_error_link(link, "Could not append MTU: %s", strerror(-r));
350                 return r;
351         }
352
353         r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
354         if (r < 0) {
355                 log_error_link(link,
356                                "Could not send rtnetlink message: %s", strerror(-r));
357                 return r;
358         }
359
360         return 0;
361 }
362
363 static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
364         Link *link = userdata;
365         struct in_addr address;
366         struct in_addr netmask;
367         struct in_addr gateway;
368         int prefixlen;
369         int r;
370
371         assert(link);
372         assert(link->network);
373
374         if (link->state == LINK_STATE_FAILED)
375                 return;
376
377         if (event < 0) {
378                 log_warning_link(link, "DHCP error: %s", strerror(-event));
379                 link_enter_failed(link);
380                 return;
381         }
382
383         if (event == DHCP_EVENT_NO_LEASE)
384                 log_debug_link(link, "IP address in use.");
385
386         if (event == DHCP_EVENT_IP_CHANGE || event == DHCP_EVENT_EXPIRED ||
387             event == DHCP_EVENT_STOP) {
388                 if (link->dhcp_address) {
389                         address_drop(link->dhcp_address, link, address_drop_handler);
390
391                         address_free(link->dhcp_address);
392                         link->dhcp_address = NULL;
393                 }
394
395                 if (link->dhcp_route) {
396                         route_free(link->dhcp_route);
397                         link->dhcp_route = NULL;
398                 }
399
400                 if (link->network->dhcp_mtu) {
401                         uint16_t mtu;
402
403                         r = sd_dhcp_client_get_mtu(client, &mtu);
404                         if (r >= 0 && link->original_mtu != mtu) {
405                                 r = link_set_mtu(link, link->original_mtu);
406                                 if (r < 0) {
407                                         log_warning_link(link, "DHCP error: could not reset MTU");
408                                         link_enter_failed(link);
409                                         return;
410                                 }
411                         }
412                 }
413         }
414
415         r = sd_dhcp_client_get_address(client, &address);
416         if (r < 0) {
417                 log_warning_link(link, "DHCP error: no address");
418                 link_enter_failed(link);
419                 return;
420         }
421
422         r = sd_dhcp_client_get_netmask(client, &netmask);
423         if (r < 0) {
424                 log_warning_link(link, "DHCP error: no netmask");
425                 link_enter_failed(link);
426                 return;
427         }
428
429         prefixlen = sd_dhcp_client_prefixlen(&netmask);
430         if (prefixlen < 0) {
431                 log_warning_link(link, "DHCP error: no prefixlen");
432                 link_enter_failed(link);
433                 return;
434         }
435
436         r = sd_dhcp_client_get_router(client, &gateway);
437         if (r < 0) {
438                 log_warning_link(link, "DHCP error: no router");
439                 link_enter_failed(link);
440                 return;
441         }
442
443         if (event == DHCP_EVENT_IP_CHANGE || event == DHCP_EVENT_IP_ACQUIRE) {
444                 _cleanup_address_free_ Address *addr = NULL;
445                 _cleanup_route_free_ Route *rt = NULL;
446                 struct in_addr **nameservers;
447
448                 log_struct_link(LOG_INFO, link,
449                                 "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
450                                 link->ifname,
451                                 ADDRESS_FMT_VAL(address),
452                                 prefixlen,
453                                 ADDRESS_FMT_VAL(gateway),
454                                 "ADDRESS=%u.%u.%u.%u",
455                                 ADDRESS_FMT_VAL(address),
456                                 "PREFIXLEN=%u",
457                                 prefixlen,
458                                 "GATEWAY=%u.%u.%u.%u",
459                                 ADDRESS_FMT_VAL(gateway),
460                                 NULL);
461
462                 r = address_new_dynamic(&addr);
463                 if (r < 0) {
464                         log_error_link(link, "Could not allocate address");
465                         link_enter_failed(link);
466                         return;
467                 }
468
469                 addr->family = AF_INET;
470                 addr->in_addr.in = address;
471                 addr->prefixlen = prefixlen;
472                 addr->netmask = netmask;
473
474                 r = route_new_dynamic(&rt);
475                 if (r < 0) {
476                         log_error_link(link, "Could not allocate route");
477                         link_enter_failed(link);
478                         return;
479                 }
480
481                 rt->family = AF_INET;
482                 rt->in_addr.in = gateway;
483
484                 link->dhcp_address = addr;
485                 link->dhcp_route = rt;
486                 addr = NULL;
487                 rt = NULL;
488
489                 if (link->network->dhcp_dns) {
490                         r = sd_dhcp_client_get_dns(client, &nameservers);
491                         if (r >= 0) {
492                                 r = manager_update_resolv_conf(link->manager);
493                                 if (r < 0)
494                                         log_error("Failed to update resolv.conf");
495                         }
496                 }
497
498                 if (link->network->dhcp_mtu) {
499                         uint16_t mtu;
500
501                         r = sd_dhcp_client_get_mtu(client, &mtu);
502                         if (r >= 0) {
503                                 r = link_set_mtu(link, mtu);
504                                 if (r < 0)
505                                         log_error_link(link, "Failed to set MTU "
506                                                              "to %" PRIu16, mtu);
507                         }
508                 }
509
510                 link_enter_set_addresses(link);
511         }
512
513         return;
514 }
515
516 static int link_acquire_conf(Link *link) {
517         int r;
518
519         assert(link);
520         assert(link->network);
521         assert(link->network->dhcp);
522         assert(link->manager);
523         assert(link->manager->event);
524
525         if (!link->dhcp) {
526                 link->dhcp = sd_dhcp_client_new(link->manager->event);
527                 if (!link->dhcp)
528                         return -ENOMEM;
529
530                 r = sd_dhcp_client_set_index(link->dhcp, link->ifindex);
531                 if (r < 0)
532                         return r;
533
534                 r = sd_dhcp_client_set_mac(link->dhcp, &link->mac);
535                 if (r < 0)
536                         return r;
537
538                 r = sd_dhcp_client_set_callback(link->dhcp, dhcp_handler, link);
539                 if (r < 0)
540                         return r;
541
542                 if (link->network->dhcp_mtu) {
543                         r = sd_dhcp_client_set_request_option(link->dhcp, 26);
544                         if (r < 0)
545                                 return r;
546                 }
547         }
548
549         log_debug_link(link, "acquiring DHCPv4 lease");
550
551         r = sd_dhcp_client_start(link->dhcp);
552         if (r < 0)
553                 return r;
554
555         return 0;
556 }
557
558 static int link_update_flags(Link *link, unsigned flags) {
559         int r;
560
561         assert(link);
562         assert(link->network);
563
564         if (link->state == LINK_STATE_FAILED)
565                 return 0;
566
567         if (link->flags == flags) {
568                 log_debug_link(link, "link status unchanged: %#.8x", flags);
569                 return 0;
570         }
571
572         if ((link->flags & IFF_UP) != (flags & IFF_UP))
573                 log_info_link(link,
574                               "power %s", flags & IFF_UP ? "on": "off");
575
576         if ((link->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
577                 if (flags & IFF_LOWER_UP) {
578                         log_info_link(link, "carrier on");
579
580                         if (link->network->dhcp) {
581                                 r = link_acquire_conf(link);
582                                 if (r < 0) {
583                                         log_warning_link(link, "Could not acquire DHCPv4 lease: %s", strerror(-r));
584                                         link_enter_failed(link);
585                                         return r;
586                                 }
587                         }
588                 } else {
589                         log_info_link(link, "carrier off");
590
591                         if (link->network->dhcp) {
592                                 r = sd_dhcp_client_stop(link->dhcp);
593                                 if (r < 0) {
594                                         log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
595                                         link_enter_failed(link);
596                                         return r;
597                                 }
598                         }
599                 }
600         }
601
602         log_debug_link(link,
603                        "link status updated: %#.8x -> %#.8x", link->flags, flags);
604
605         link->flags = flags;
606
607         return 0;
608 }
609
610 static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
611         Link *link = userdata;
612         int r;
613
614         assert(link);
615
616         if (link->state == LINK_STATE_FAILED)
617                 return 1;
618
619         r = sd_rtnl_message_get_errno(m);
620         if (r < 0) {
621                 log_warning_link(link,
622                                  "could not bring up interface: %s", strerror(-r));
623                 link_enter_failed(link);
624         }
625
626         link_update_flags(link, link->flags | IFF_UP);
627
628         return 1;
629 }
630
631 static int link_up(Link *link) {
632         _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
633         int r;
634
635         assert(link);
636         assert(link->manager);
637         assert(link->manager->rtnl);
638
639         log_debug_link(link, "bringing link up");
640
641         r = sd_rtnl_message_link_new(RTM_SETLINK, link->ifindex, &req);
642         if (r < 0) {
643                 log_error_link(link, "Could not allocate RTM_SETLINK message");
644                 return r;
645         }
646
647         r = sd_rtnl_message_link_set_flags(req, IFF_UP);
648         if (r < 0) {
649                 log_error_link(link, "Could not set link flags: %s", strerror(-r));
650                 return r;
651         }
652
653         r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
654         if (r < 0) {
655                 log_error_link(link,
656                                "Could not send rtnetlink message: %s", strerror(-r));
657                 return r;
658         }
659
660         return 0;
661 }
662
663 static int link_bridge_joined(Link *link) {
664         int r;
665
666         assert(link);
667         assert(link->state == LINK_STATE_JOINING_BRIDGE);
668         assert(link->network);
669
670         r = link_up(link);
671         if (r < 0) {
672                 link_enter_failed(link);
673                 return r;
674         }
675
676         if (!link->network->dhcp)
677                 return link_enter_set_addresses(link);
678
679         return 0;
680 }
681
682 static int bridge_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
683         Link *link = userdata;
684         int r;
685
686         assert(link);
687         assert(link->state == LINK_STATE_JOINING_BRIDGE || link->state == LINK_STATE_FAILED);
688         assert(link->network);
689
690         if (link->state == LINK_STATE_FAILED)
691                 return 1;
692
693         r = sd_rtnl_message_get_errno(m);
694         if (r < 0) {
695                 log_struct_link(LOG_ERR, link,
696                                 "MESSAGE=%s: could not join bridge '%s': %s",
697                                 link->ifname, link->network->bridge->name, strerror(-r),
698                                 BRIDGE(link->network->bridge),
699                                 NULL);
700                 link_enter_failed(link);
701                 return 1;
702         }
703
704         log_struct_link(LOG_DEBUG, link,
705                         "MESSAGE=%s: joined bridge '%s'",
706                         link->network->bridge->name,
707                         BRIDGE(link->network->bridge),
708                         NULL);
709
710         link_bridge_joined(link);
711
712         return 1;
713 }
714
715 static int link_enter_join_bridge(Link *link) {
716         int r;
717
718         assert(link);
719         assert(link->network);
720         assert(link->state == _LINK_STATE_INVALID);
721
722         link->state = LINK_STATE_JOINING_BRIDGE;
723
724         if (!link->network->bridge)
725                 return link_bridge_joined(link);
726
727         log_struct_link(LOG_DEBUG, link,
728                         "MESSAGE=%s: joining bridge '%s'",
729                         link->network->bridge->name,
730                         BRIDGE(link->network->bridge),
731                         NULL);
732         log_debug_link(link, "joining bridge");
733
734         r = bridge_join(link->network->bridge, link, &bridge_handler);
735         if (r < 0) {
736                 log_struct_link(LOG_WARNING, link,
737                                 "MESSAGE=%s: could not join bridge '%s': %s",
738                                 link->network->bridge->name, strerror(-r),
739                                 BRIDGE(link->network->bridge),
740                                 NULL);
741                 link_enter_failed(link);
742                 return r;
743         }
744
745         return 0;
746 }
747
748 static int link_get_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
749         Link *link = userdata;
750         int r;
751
752         assert(link);
753
754         if (link->state == LINK_STATE_FAILED)
755                 return 1;
756
757         r = sd_rtnl_message_get_errno(m);
758         if (r < 0) {
759                 log_warning_link(link, "could not get state: %s", strerror(-r));
760                 link_enter_failed(link);
761         }
762
763         log_debug_link(link, "got link state");
764
765         link_update(link, m);
766
767         return 1;
768 }
769
770 static int link_get(Link *link) {
771         _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
772         int r;
773
774         assert(link);
775         assert(link->manager);
776         assert(link->manager->rtnl);
777
778         log_debug_link(link, "requesting link status");
779
780         r = sd_rtnl_message_link_new(RTM_GETLINK, link->ifindex, &req);
781         if (r < 0) {
782                 log_error_link(link, "Could not allocate RTM_GETLINK message");
783                 return r;
784         }
785
786         r = sd_rtnl_call_async(link->manager->rtnl, req, link_get_handler, link, 0, NULL);
787         if (r < 0) {
788                 log_error_link(link,
789                                "Could not send rtnetlink message: %s", strerror(-r));
790                 return r;
791         }
792
793         return 0;
794 }
795
796 int link_configure(Link *link) {
797         int r;
798
799         assert(link);
800         assert(link->network);
801         assert(link->state == _LINK_STATE_INVALID);
802
803         r = link_get(link);
804         if (r < 0) {
805                 link_enter_failed(link);
806                 return r;
807         }
808
809         return link_enter_join_bridge(link);
810 }
811
812 int link_update(Link *link, sd_rtnl_message *m) {
813         unsigned flags;
814         void *data;
815         uint16_t type;
816         int r;
817
818         assert(link);
819         assert(m);
820
821         if (link->state == LINK_STATE_FAILED)
822                 return 0;
823
824         r = sd_rtnl_message_link_get_flags(m, &flags);
825         if (r < 0) {
826                 log_warning_link(link, "Could not get link flags");
827                 return r;
828         }
829
830         while (sd_rtnl_message_read(m, &type, &data) > 0) {
831                 if (type == IFLA_MTU && link->network->dhcp &&
832                     link->network->dhcp_mtu && !link->original_mtu) {
833                         link->original_mtu = *(uint16_t *) data;
834                         log_debug_link(link, "saved original MTU: %" PRIu16,
835                                        link->original_mtu);
836                 }
837         }
838
839         return link_update_flags(link, flags);
840 }