X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fnetwork%2Fnetworkd-link.c;h=8674eee9487a8949ed05d1deb25e63fcddd9d1ad;hp=b597b166844b4e088c7e9855c080d879ae178c61;hb=28aeb07f55ddf338c8705c002bde391cebbdc5a3;hpb=46ba9fbae2517e6fee2a2b486ef9f06a62284b8c diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index b597b1668..8674eee94 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -106,8 +106,6 @@ static void link_free(Link *link) { if (!link) return; - assert(link->manager); - while ((address = link->addresses)) { LIST_REMOVE(addresses, link->addresses, address); address_free(address); @@ -128,7 +126,8 @@ static void link_free(Link *link) { sd_dhcp6_client_unref(link->dhcp6_client); sd_icmp6_nd_unref(link->icmp6_router_discovery); - hashmap_remove(link->manager->links, &link->ifindex); + if (link->manager) + hashmap_remove(link->manager->links, &link->ifindex); free(link->ifname); @@ -366,7 +365,7 @@ static int link_enter_configured(Link *link) { } static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - Link *link = userdata; + _cleanup_link_unref_ Link *link = userdata; int r; assert(link->route_messages > 0); @@ -376,10 +375,8 @@ static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { link->route_messages --; - if (IN_SET(LINK_STATE_FAILED, LINK_STATE_LINGER)) { - link_unref(link); + if (IN_SET(LINK_STATE_FAILED, LINK_STATE_LINGER)) return 1; - } r = sd_rtnl_message_get_errno(m); if (r < 0 && r != -EEXIST) @@ -397,8 +394,6 @@ static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { link_enter_configured(link); } - link_unref(link); - return 1; } @@ -546,6 +541,7 @@ static int link_enter_set_routes(Link *link) { route_gw->dst_addr.in = gateway; route_gw->dst_prefixlen = 32; route_gw->scope = RT_SCOPE_LINK; + route_gw->metrics = DHCP_STATIC_ROUTE_METRIC; r = route_configure(route_gw, link, &route_handler); if (r < 0) { @@ -559,6 +555,7 @@ static int link_enter_set_routes(Link *link) { route->family = AF_INET; route->in_addr.in = gateway; + route->metrics = DHCP_STATIC_ROUTE_METRIC; r = route_configure(route, link, &route_handler); if (r < 0) { @@ -584,17 +581,15 @@ static int link_enter_set_routes(Link *link) { } static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - Link *link = userdata; + _cleanup_link_unref_ Link *link = userdata; int r; assert(m); assert(link); assert(link->ifname); - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) { - link_unref(link); + if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) return 1; - } r = sd_rtnl_message_get_errno(m); if (r < 0 && r != -ESRCH) @@ -605,13 +600,11 @@ static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) "ERRNO=%d", -r, NULL); - link_unref(link); - return 0; } static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - Link *link = userdata; + _cleanup_link_unref_ Link *link = userdata; int r; assert(m); @@ -623,10 +616,8 @@ static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { link->addr_messages --; - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) { - link_unref(link); + if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) return 1; - } r = sd_rtnl_message_get_errno(m); if (r < 0 && r != -EEXIST) @@ -642,8 +633,6 @@ static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { link_enter_set_routes(link); } - link_unref(link); - return 1; } @@ -778,17 +767,15 @@ static int link_enter_set_addresses(Link *link) { } static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - Link *link = userdata; + _cleanup_link_unref_ Link *link = userdata; int r; assert(m); assert(link); assert(link->ifname); - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) { - link_unref(link); + if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) return 1; - } r = sd_rtnl_message_get_errno(m); if (r < 0 && r != -ENOENT) @@ -799,23 +786,19 @@ static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userd "ERRNO=%d", -r, NULL); - link_unref(link); - return 0; } static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - Link *link = userdata; + _cleanup_link_unref_ Link *link = userdata; int r; assert(m); assert(link); assert(link->ifname); - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) { - link_unref(link); + if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) return 1; - } r = sd_rtnl_message_get_errno(m); if (r < 0 && r != -EADDRNOTAVAIL) @@ -826,28 +809,22 @@ static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdat "ERRNO=%d", -r, NULL); - link_unref(link); - return 0; } static int set_hostname_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { - Link *link = userdata; + _cleanup_link_unref_ Link *link = userdata; int r; assert(link); - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) { - link_unref(link); + if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) return 1; - } r = sd_bus_message_get_errno(m); if (r < 0) log_warning_link(link, "Could not set hostname: %s", strerror(-r)); - link_unref(link); - return 1; } @@ -881,26 +858,26 @@ static int link_set_hostname(Link *link, const char *hostname) { return r; r = sd_bus_call_async(link->manager->bus, NULL, m, set_hostname_handler, link, 0); - if (r < 0) + if (r < 0) { log_error_link(link, "Could not set transient hostname: %s", strerror(-r)); + return r; + } link_ref(link); - return r; + return 0; } static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - Link *link = userdata; + _cleanup_link_unref_ Link *link = userdata; int r; assert(m); assert(link); assert(link->ifname); - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) { - link_unref(link); + if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) return 1; - } r = sd_rtnl_message_get_errno(m); if (r < 0) @@ -910,8 +887,6 @@ static int set_mtu_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { "ERRNO=%d", -r, NULL); - link_unref(link); - return 1; } @@ -1683,15 +1658,13 @@ static int link_update_flags(Link *link, sd_rtnl_message *m) { } static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - Link *link = userdata; + _cleanup_link_unref_ Link *link = userdata; int r; assert(link); - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) { - link_unref(link); + if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) return 1; - } r = sd_rtnl_message_get_errno(m); if (r < 0) { @@ -1705,8 +1678,6 @@ static int link_up_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { NULL); } - link_unref(link); - return 1; } @@ -1764,7 +1735,7 @@ static int link_enslaved(Link *link) { } static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - Link *link = userdata; + _cleanup_link_unref_ Link *link = userdata; int r; assert(link); @@ -1774,10 +1745,8 @@ static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { link->enslaving --; - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) { - link_unref(link); + if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) return 1; - } r = sd_rtnl_message_get_errno(m); if (r < 0) { @@ -1788,7 +1757,6 @@ static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { "ERRNO=%d", -r, NULL); link_enter_failed(link); - link_unref(link); return 1; } @@ -1797,8 +1765,6 @@ static int enslave_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { if (link->enslaving == 0) link_enslaved(link); - link_unref(link); - return 1; } @@ -2082,7 +2048,7 @@ static int link_configure(Link *link) { } static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - Link *link = userdata; + _cleanup_link_unref_ Link *link = userdata; Network *network; int r; @@ -2091,14 +2057,14 @@ static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m, void * assert(link->manager); if (link->state != LINK_STATE_INITIALIZING) - return 0; + return 1; log_debug_link(link, "link state is up-to-date"); r = network_get(link->manager, link->udev_device, link->ifname, &link->mac, &network); if (r == -ENOENT) { link_enter_unmanaged(link); - return 0; + return 1; } else if (r < 0) return r; @@ -2110,7 +2076,7 @@ static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m, void * if (r < 0) return r; - return 0; + return 1; } int link_initialized(Link *link, struct udev_device *device) { @@ -2142,6 +2108,8 @@ int link_initialized(Link *link, struct udev_device *device) { if (r < 0) return r; + link_ref(link); + return 0; } @@ -2268,12 +2236,13 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *use } static int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { - Link *link = userdata; + _cleanup_link_unref_ Link *link = userdata; int r; assert(rtnl); assert(m); assert(link); + assert(link->manager); for (; m; m = sd_rtnl_message_next(m)) { r = sd_rtnl_message_get_errno(m); @@ -2318,6 +2287,8 @@ int link_add(Manager *m, sd_rtnl_message *message, Link **ret) { if (r < 0) return r; + link_ref(link); + if (detect_container(NULL) <= 0) { /* not in a container, udev will be around */ sprintf(ifindex_str, "n%"PRIu64, link->ifindex); @@ -2337,6 +2308,9 @@ int link_add(Manager *m, sd_rtnl_message *message, Link **ret) { if (r < 0) return r; } else { + /* we are calling a callback directly, so must take a ref */ + link_ref(link); + r = link_initialized_and_synced(m->rtnl, NULL, link); if (r < 0) return r;