networkd-link.c revision eb27aeca247a4cf8816fffc4c0dbcab55ead3864
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/***
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2013 Tom Gundersen <teg@jklm.no>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Lesser General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering***/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
8bdbb8d9cbe1d35708385573d70984ab4533812dLennart Poettering#include <netinet/ether.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <linux/if.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "networkd.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "libudev-private.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "bus-util.h"
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poetteringint link_new(Manager *manager, struct udev_device *device, Link **ret) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering _cleanup_link_free_ Link *link = NULL;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering const char *mac;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering struct ether_addr *mac_addr;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen const char *ifname;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(device);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(ret);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen link = new0(Link, 1);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!link)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -ENOMEM;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link->manager = manager;
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering link->state = _LINK_STATE_INVALID;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering link->ifindex = udev_device_get_ifindex(device);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (link->ifindex <= 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering mac = udev_device_get_sysattr_value(device, "address");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (mac) {
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen mac_addr = ether_aton(mac);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (mac_addr)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering memcpy(&link->mac, mac_addr, sizeof(struct ether_addr));
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ifname = udev_device_get_sysname(device);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link->ifname = strdup(ifname);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = hashmap_put(manager->links, &link->ifindex, link);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering *ret = link;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return 0;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen}
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenvoid link_free(Link *link) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!link)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(link->manager);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (link->dhcp)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen sd_dhcp_client_free(link->dhcp);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen route_free(link->dhcp_route);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen link->dhcp_route = NULL;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen address_free(link->dhcp_address);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen link->dhcp_address = NULL;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen hashmap_remove(link->manager->links, &link->ifindex);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering free(link->ifname);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering free(link);
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen}
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint link_add(Manager *m, struct udev_device *device, Link **ret) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen Link *link;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen Network *network;
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering uint64_t ifindex;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen NetdevKind kind;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(device);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen ifindex = udev_device_get_ifindex(device);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering link = hashmap_get(m->links, &ifindex);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (link) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen *ret = link;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return -EEXIST;
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen r = link_new(m, device, &link);
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering *ret = link;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering kind = netdev_kind_from_string(udev_device_get_devtype(device));
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (kind != _NETDEV_KIND_INVALID) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = netdev_set_link(m, kind, link);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (r < 0 && r != -ENOENT)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return r;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering }
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = network_get(m, device, &network);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (r < 0)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return r == -ENOENT ? 0 : r;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering r = network_apply(m, network, link);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (r < 0)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return r;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return 0;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering}
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poetteringstatic int link_enter_configured(Link *link) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering assert(link);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering assert(link->state == LINK_STATE_SETTING_ROUTES);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering log_info_link(link, "link configured");
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering link->state = LINK_STATE_CONFIGURED;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering return 0;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering}
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poetteringstatic void link_enter_failed(Link *link) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering assert(link);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering log_warning_link(link, "failed");
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering link->state = LINK_STATE_FAILED;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering}
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poetteringstatic int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering Link *link = userdata;
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering int r;
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering assert(link->route_messages > 0);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering assert(link->state == LINK_STATE_SETTING_ADDRESSES ||
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering link->state == LINK_STATE_SETTING_ROUTES ||
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering link->state == LINK_STATE_FAILED);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering link->route_messages --;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (link->state == LINK_STATE_FAILED)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return 1;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = sd_rtnl_message_get_errno(m);
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering if (r < 0 && r != -EEXIST)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering log_struct_link(LOG_WARNING, link,
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering "MESSAGE=%s: could not set route: %s",
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering link->ifname, strerror(-r),
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "ERRNO=%d", -r,
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering NULL);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering /* we might have received an old reply after moving back to SETTING_ADDRESSES,
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering * ignore it */
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (link->route_messages == 0 && link->state == LINK_STATE_SETTING_ROUTES) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_debug_link(link, "routes set");
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering link_enter_configured(link);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return 1;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering}
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poetteringstatic int link_enter_set_routes(Link *link) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering Route *route;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering int r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(link);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(link->network);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(link->state == LINK_STATE_SETTING_ADDRESSES);
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering link->state = LINK_STATE_SETTING_ROUTES;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (!link->network->static_routes && !link->dhcp_route)
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering return link_enter_configured(link);
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_debug_link(link, "setting routes");
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering LIST_FOREACH(static_routes, route, link->network->static_routes) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = route_configure(route, link, &route_handler);
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering if (r < 0) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_warning_link(link,
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "could not set routes: %s", strerror(-r));
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering link_enter_failed(link);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering link->route_messages ++;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering }
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (link->dhcp_route) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering r = route_configure(link->dhcp_route, link, &route_handler);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (r < 0) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_warning_link(link,
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "could not set routes: %s", strerror(-r));
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering link_enter_failed(link);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering link->route_messages ++;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return 0;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering}
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poetteringstatic int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering Link *link = userdata;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering int r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(m);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(link);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering assert(link->ifname);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering assert(link->addr_messages > 0);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering assert(link->state == LINK_STATE_SETTING_ADDRESSES || link->state == LINK_STATE_FAILED);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering link->addr_messages --;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (link->state == LINK_STATE_FAILED)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return 1;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering r = sd_rtnl_message_get_errno(m);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (r < 0 && r != -EEXIST)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering log_struct_link(LOG_WARNING, link,
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "MESSAGE=%s: could not set address: %s",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering link->ifname, strerror(-r),
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "ERRNO=%d", -r,
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering NULL);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (link->addr_messages == 0) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering log_debug_link(link, "addresses set");
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering link_enter_set_routes(link);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering }
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return 1;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering}
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poetteringstatic int link_enter_set_addresses(Link *link) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering Address *address;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering int r;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering assert(link);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering assert(link->network);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering assert(link->state != _LINK_STATE_INVALID);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering link->state = LINK_STATE_SETTING_ADDRESSES;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (!link->network->static_addresses && !link->dhcp_address)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return link_enter_set_routes(link);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering log_debug_link(link, "setting addresses");
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering LIST_FOREACH(static_addresses, address, link->network->static_addresses) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering r = address_configure(address, link, &address_handler);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers log_warning_link(link,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "could not set addresses: %s", strerror(-r));
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers link_enter_failed(link);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return r;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering }
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link->addr_messages ++;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (link->dhcp_address) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = address_configure(link->dhcp_address, link, &address_handler);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_warning_link(link,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "could not set addresses: %s", strerror(-r));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link_enter_failed(link);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return r;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link->addr_messages ++;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Link *link = userdata;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(link);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(link->ifname);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (link->state == LINK_STATE_FAILED)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 1;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_rtnl_message_get_errno(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0 && r != -ENOENT)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_struct_link(LOG_WARNING, link,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "MESSAGE=%s: could not drop address: %s",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link->ifname, strerror(-r),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "ERRNO=%d", -r,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 1;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_message_get_errno(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_warning("Could not set hostname: %s", strerror(-r));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 1;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int set_hostname(sd_bus *bus, const char *hostname) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r = 0;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering assert(hostname);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering log_debug("Setting transient hostname: '%s'", hostname);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (!bus) { /* TODO: replace by assert when we can rely on kdbus */
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering log_info("Not connected to system bus, ignoring transient hostname.");
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return 0;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering }
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering r = sd_bus_message_new_method_call(
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering bus,
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "org.freedesktop.hostname1",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "/org/freedesktop/hostname1",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "org.freedesktop.hostname1",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "SetHostname",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering &m);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (r < 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return r;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering r = sd_bus_message_append(m, "sb", hostname, false);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (r < 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return r;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = sd_bus_call_async(bus, m, set_hostname_handler, NULL, 0, NULL);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (r < 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_error("Could not set transient hostname: %s", strerror(-r));
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return r;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering}
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poetteringstatic int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Link *link = userdata;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering assert(m);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering assert(link);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering assert(link->ifname);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (link->state == LINK_STATE_FAILED)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return 1;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering r = sd_rtnl_message_get_errno(m);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (r < 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering log_struct_link(LOG_WARNING, link,
e7e9b6bb0b0bc5b1eb256a44f8afec6b634f26efZbigniew Jędrzejewski-Szmek "MESSAGE=%s: could not set MTU: %s",
e7e9b6bb0b0bc5b1eb256a44f8afec6b634f26efZbigniew Jędrzejewski-Szmek link->ifname, strerror(-r),
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "ERRNO=%d", -r,
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering NULL);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return 1;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering}
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poetteringstatic int link_set_mtu(Link *link, uint32_t mtu) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering int r;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
a6c616024db23fef34152c1432892824a07799ccLennart Poettering assert(link);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers assert(link->manager);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering assert(link->manager->rtnl);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering log_debug_link(link, "setting MTU: %" PRIu32, mtu);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering r = sd_rtnl_message_link_new(RTM_SETLINK, link->ifindex, &req);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (r < 0) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering log_error_link(link, "Could not allocate RTM_SETLINK message");
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return r;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering }
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers r = sd_rtnl_message_append_u32(req, IFLA_MTU, mtu);
a6c616024db23fef34152c1432892824a07799ccLennart Poettering if (r < 0) {
a6c616024db23fef34152c1432892824a07799ccLennart Poettering log_error_link(link, "Could not append MTU: %s", strerror(-r));
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return r;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_rtnl_call_async(link->manager->rtnl, req, set_mtu_handler, link, 0, NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers log_error_link(link,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers "Could not send rtnetlink message: %s", strerror(-r));
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return r;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return 0;
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt}
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Link *link = userdata;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering struct in_addr address;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering struct in_addr netmask;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering struct in_addr gateway;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int prefixlen;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers assert(link);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers assert(link->network);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers assert(link->manager);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (link->state == LINK_STATE_FAILED)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (event < 0) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers log_warning_link(link, "DHCP error: %s", strerror(-event));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link_enter_failed(link);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (event == DHCP_EVENT_NO_LEASE)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers log_debug_link(link, "IP address in use.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (event == DHCP_EVENT_IP_CHANGE || event == DHCP_EVENT_EXPIRED ||
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen event == DHCP_EVENT_STOP) {
27e72d6b22890ba4a8cbc05c49667cd1cccf1461Simon Peeters if (link->network->dhcp_critical) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_warning_link(link, "DHCPv4 connection considered system critical, "
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt "ignoring request to reconfigure it down.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return;
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (link->dhcp_address) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen address_drop(link->dhcp_address, link, address_drop_handler);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen address_free(link->dhcp_address);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers link->dhcp_address = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (link->dhcp_route) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering route_free(link->dhcp_route);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link->dhcp_route = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (link->network->dhcp_mtu) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering uint16_t mtu;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers r = sd_dhcp_client_get_mtu(client, &mtu);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r >= 0 && link->original_mtu != mtu) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers r = link_set_mtu(link, link->original_mtu);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers log_warning_link(link, "DHCP error: could not reset MTU");
8c841f21f5042b11acc91cc1b039cb162cbbe8f4Djalal Harouni link_enter_failed(link);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (link->network->dhcp_hostname) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = set_hostname(link->manager->bus, "");
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r < 0)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_error("Failed to reset transient hostname");
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = sd_dhcp_client_get_address(client, &address);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r < 0) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_warning_link(link, "DHCP error: no address");
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen link_enter_failed(link);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = sd_dhcp_client_get_netmask(client, &netmask);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r < 0) {
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering log_warning_link(link, "DHCP error: no netmask");
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering link_enter_failed(link);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers prefixlen = sd_dhcp_client_prefixlen(&netmask);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (prefixlen < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_warning_link(link, "DHCP error: no prefixlen");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link_enter_failed(link);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = sd_dhcp_client_get_router(client, &gateway);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_warning_link(link, "DHCP error: no router");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link_enter_failed(link);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (event == DHCP_EVENT_IP_CHANGE || event == DHCP_EVENT_IP_ACQUIRE) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_address_free_ Address *addr = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_route_free_ Route *rt = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering struct in_addr *nameservers;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering size_t nameservers_size;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_struct_link(LOG_INFO, link,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "MESSAGE=%s: DHCPv4 address %u.%u.%u.%u/%u via %u.%u.%u.%u",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen link->ifname,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen ADDRESS_FMT_VAL(address),
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen prefixlen,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen ADDRESS_FMT_VAL(gateway),
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "ADDRESS=%u.%u.%u.%u",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen ADDRESS_FMT_VAL(address),
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "PREFIXLEN=%u",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen prefixlen,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "GATEWAY=%u.%u.%u.%u",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen ADDRESS_FMT_VAL(gateway),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = address_new_dynamic(&addr);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error_link(link, "Could not allocate address");
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering link_enter_failed(link);
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering return;
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering addr->family = AF_INET;
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering addr->in_addr.in = address;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering addr->prefixlen = prefixlen;
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering addr->netmask = netmask;
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering r = route_new_dynamic(&rt);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering log_error_link(link, "Could not allocate route");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link_enter_failed(link);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return;
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering }
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering rt->family = AF_INET;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering rt->in_addr.in = gateway;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering link->dhcp_address = addr;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering link->dhcp_route = rt;
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering addr = NULL;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering rt = NULL;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering if (link->network->dhcp_dns) {
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering r = sd_dhcp_client_get_dns(client, &nameservers, &nameservers_size);
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering if (r >= 0) {
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering r = manager_update_resolv_conf(link->manager);
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering if (r < 0)
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering log_error("Failed to update resolv.conf");
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering }
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering }
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering if (link->network->dhcp_mtu) {
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering uint16_t mtu;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering r = sd_dhcp_client_get_mtu(client, &mtu);
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering if (r >= 0) {
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering r = link_set_mtu(link, mtu);
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering if (r < 0)
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering log_error_link(link, "Failed to set MTU "
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering "to %" PRIu16, mtu);
3d94f76c99da13e5603831d0b278f8c8c21bcb02Lennart Poettering }
a4475f577bd0daf762d6c3b4e58bc484e0cb74afLennart Poettering }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (link->network->dhcp_hostname) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering const char *hostname;
34a6778fb9d1065f3fbb8e2243b9f0f25d1d18f1Zbigniew Jędrzejewski-Szmek
34a6778fb9d1065f3fbb8e2243b9f0f25d1d18f1Zbigniew Jędrzejewski-Szmek r = sd_dhcp_client_get_hostname(client, &hostname);
34a6778fb9d1065f3fbb8e2243b9f0f25d1d18f1Zbigniew Jędrzejewski-Szmek if (r >= 0) {
34a6778fb9d1065f3fbb8e2243b9f0f25d1d18f1Zbigniew Jędrzejewski-Szmek r = set_hostname(link->manager->bus, hostname);
34a6778fb9d1065f3fbb8e2243b9f0f25d1d18f1Zbigniew Jędrzejewski-Szmek if (r < 0)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_error("Failed to set transient hostname "
f69157a66ffe413b4cf8bd79057487fc8921e78bThomas Hindoe Paaboel Andersen "to '%s'", hostname);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering link_enter_set_addresses(link);
bc9fd78c7bfc39881e19457e476393635f8b0442Lennart Poettering }
bc9fd78c7bfc39881e19457e476393635f8b0442Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return;
bc9fd78c7bfc39881e19457e476393635f8b0442Lennart Poettering}
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poetteringstatic int link_acquire_conf(Link *link) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering int r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering assert(link);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering assert(link->network);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering assert(link->network->dhcp);
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering assert(link->manager);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering assert(link->manager->event);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (!link->dhcp) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = sd_dhcp_client_new(&link->dhcp);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (r < 0)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = sd_dhcp_client_attach_event(link->dhcp, NULL, 0);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (r < 0)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = sd_dhcp_client_set_index(link->dhcp, link->ifindex);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (r < 0)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = sd_dhcp_client_set_mac(link->dhcp, &link->mac);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (r < 0)
bc9fd78c7bfc39881e19457e476393635f8b0442Lennart Poettering return r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = sd_dhcp_client_set_callback(link->dhcp, dhcp_handler, link);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (r < 0)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering if (link->network->dhcp_mtu) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = sd_dhcp_client_set_request_option(link->dhcp, 26);
fbadf04511389c4a0687ba5e9baf0ecebdbb07f1Lennart Poettering if (r < 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
fbadf04511389c4a0687ba5e9baf0ecebdbb07f1Lennart Poettering log_debug_link(link, "acquiring DHCPv4 lease");
bc9fd78c7bfc39881e19457e476393635f8b0442Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = sd_dhcp_client_start(link->dhcp);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (r < 0)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return 0;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering}
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poetteringstatic int link_update_flags(Link *link, unsigned flags) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering int r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering assert(link);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering assert(link->network);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (link->state == LINK_STATE_FAILED)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return 0;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (link->flags == flags) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_debug_link(link, "link status unchanged: %#.8x", flags);
6261f11fc3d0a8b63c5afa5313d96607a008b54eLennart Poettering return 0;
6261f11fc3d0a8b63c5afa5313d96607a008b54eLennart Poettering }
6261f11fc3d0a8b63c5afa5313d96607a008b54eLennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if ((link->flags & IFF_UP) != (flags & IFF_UP))
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_info_link(link,
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering "link is %s", flags & IFF_UP ? "up": "down");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if ((link->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (flags & IFF_LOWER_UP) {
249968612f16a71df909d6e73785c18a9ff36a65Lennart Poettering log_info_link(link, "carrier on");
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering if (link->network->dhcp) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = link_acquire_conf(link);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (r < 0) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_warning_link(link, "Could not acquire DHCPv4 lease: %s", strerror(-r));
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering link_enter_failed(link);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return r;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering } else {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_info_link(link, "carrier off");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (link->network->dhcp) {
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering r = sd_dhcp_client_stop(link->dhcp);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (r < 0) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_warning_link(link, "Could not stop DHCPv4 client: %s", strerror(-r));
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering link_enter_failed(link);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering return r;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering }
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt }
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering }
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering }
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering log_debug_link(link,
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering "link status updated: %#.8x -> %#.8x", link->flags, flags);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering link->flags = flags;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering return 0;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering}
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poetteringstatic int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering Link *link = userdata;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering int r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering assert(link);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (link->state == LINK_STATE_FAILED)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return 1;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = sd_rtnl_message_get_errno(m);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (r < 0) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_struct_link(LOG_ERR, link,
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering "MESSAGE=%s: could not bring up interface: %s",
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering link->ifname, strerror(-r),
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering "ERRNO=%d", -r,
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering NULL);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering link_enter_failed(link);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return 1;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering link_update_flags(link, link->flags | IFF_UP);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return 1;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering}
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poetteringstatic int link_up(Link *link) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering int r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering assert(link);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering assert(link->manager);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering assert(link->manager->rtnl);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_debug_link(link, "bringing link up");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = sd_rtnl_message_link_new(RTM_SETLINK, link->ifindex, &req);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt if (r < 0) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_error_link(link, "Could not allocate RTM_SETLINK message");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (r < 0) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_error_link(link, "Could not set link flags: %s", strerror(-r));
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (r < 0) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_error_link(link,
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering "Could not send rtnetlink message: %s", strerror(-r));
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return r;
3db729cb8e6822114e9323f4041dcdc080f2fb3cJason A. Donenfeld }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt return 0;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering}
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poetteringstatic int link_enslaved(Link *link) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering int r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering assert(link);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering assert(link->state == LINK_STATE_ENSLAVING);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering assert(link->network);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = link_up(link);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (r < 0) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering link_enter_failed(link);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (!link->network->dhcp)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return link_enter_set_addresses(link);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return 0;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering}
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poetteringstatic int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering Link *link = userdata;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering int r;
a6c616024db23fef34152c1432892824a07799ccLennart Poettering
a6c616024db23fef34152c1432892824a07799ccLennart Poettering assert(link);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering assert(link->state == LINK_STATE_ENSLAVING || link->state == LINK_STATE_FAILED);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering assert(link->network);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering link->enslaving --;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (link->state == LINK_STATE_FAILED)
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering return 1;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = sd_rtnl_message_get_errno(m);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering if (r < 0) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering log_struct_link(LOG_ERR, link,
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt "MESSAGE=%s: could not enslave: %s",
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering link->ifname, strerror(-r),
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering "ERRNO=%d", -r,
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering NULL);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering link_enter_failed(link);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return 1;
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_debug_link(link, "enslaved");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering if (link->enslaving == 0)
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering link_enslaved(link);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return 1;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering}
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic int link_enter_enslave(Link *link) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering int r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering assert(link);
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek assert(link->network);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(link->state == _LINK_STATE_INVALID);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link->state = LINK_STATE_ENSLAVING;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering if (!link->network->bridge && !link->network->bond && !link->network->vlan)
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen return link_enslaved(link);
53755121e1c8ebd3db0330bc82965ecf9a986449Lennart Poettering
53755121e1c8ebd3db0330bc82965ecf9a986449Lennart Poettering if (link->network->bridge) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_struct_link(LOG_DEBUG, link,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "MESSAGE=%s: enslaving by '%s'",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link->ifname, link->network->bridge->name,
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering NETDEV(link->network->bridge),
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = netdev_enslave(link->network->bridge, link, &enslave_handler);
4f8f66cb4236783cd3cbee97fefc9aaa8469ac08Zbigniew Jędrzejewski-Szmek if (r < 0) {
4f8f66cb4236783cd3cbee97fefc9aaa8469ac08Zbigniew Jędrzejewski-Szmek log_struct_link(LOG_WARNING, link,
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering "MESSAGE=%s: could not enslave by '%s': %s",
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering link->ifname, link->network->bridge->name, strerror(-r),
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering NETDEV(link->network->bridge),
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering NULL);
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering link_enter_failed(link);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link->enslaving ++;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (link->network->vlan) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_struct_link(LOG_DEBUG, link,
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen "MESSAGE=%s: enslaving by '%s'",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link->ifname, link->network->vlan->name,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NETDEV(link->network->vlan),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = netdev_enslave(link->network->vlan, link, &enslave_handler);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_struct_link(LOG_WARNING, link,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "MESSAGE=%s: could not enslave by '%s': %s",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link->ifname, link->network->vlan->name,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering strerror(-r), NETDEV(link->network->vlan),
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link_enter_failed(link);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering link->enslaving ++;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int link_get_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Link *link = userdata;
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(link);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (link->state == LINK_STATE_FAILED)
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek return 1;
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_rtnl_message_get_errno(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_struct_link(LOG_ERR, link,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "MESSAGE=%s: could not get state: %s",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link->ifname, strerror(-r),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "ERRNO=%d", -r,
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering NULL);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering link_enter_failed(link);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering return 1;
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_debug_link(link, "got link state");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link_update(link, m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 1;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int link_get(Link *link) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(link);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(link->manager);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(link->manager->rtnl);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_debug_link(link, "requesting link status");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_rtnl_message_link_new(RTM_GETLINK, link->ifindex, &req);
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen if (r < 0) {
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen log_error_link(link, "Could not allocate RTM_GETLINK message");
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen return r;
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_rtnl_call_async(link->manager->rtnl, req, link_get_handler, link, 0, NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error_link(link,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "Could not send rtnetlink message: %s", strerror(-r));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint link_configure(Link *link) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering assert(link);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering assert(link->network);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering assert(link->state == _LINK_STATE_INVALID);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering r = link_get(link);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering if (r < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link_enter_failed(link);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return link_enter_enslave(link);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint link_update(Link *link, sd_rtnl_message *m) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering unsigned flags;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering void *data;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering uint16_t type;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(link);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(m);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (link->state == LINK_STATE_FAILED)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_rtnl_message_link_get_flags(m, &flags);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_warning_link(link, "Could not get link flags");
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering while (sd_rtnl_message_read(m, &type, &data) > 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (type == IFLA_MTU && link->network->dhcp &&
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link->network->dhcp_mtu && !link->original_mtu) {
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering link->original_mtu = *(uint16_t *) data;
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering log_debug_link(link, "saved original MTU: %" PRIu16,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering link->original_mtu);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return link_update_flags(link, flags);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering