X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=src%2Fnetwork%2Fnetworkd-link.c;h=bad984ef9306efe2336a318115325efdc592e183;hb=8a9b3a23fd0153e3b3e6768d03002819c2fc50e4;hp=69f3e1212a4f3b26045858d88413cea38c1c45a8;hpb=defdbbb6dc62b7985072bfb68e7f8ef3f4c75246;p=thirdparty%2Fsystemd.git diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 69f3e1212a4..bad984ef930 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ /*** This file is part of systemd. @@ -33,6 +34,7 @@ #include "networkd-manager.h" #include "networkd-ndisc.h" #include "networkd-radv.h" +#include "networkd-routing-policy-rule.h" #include "set.h" #include "socket-util.h" #include "stdio-util.h" @@ -225,6 +227,9 @@ static bool link_ipv6_accept_ra_enabled(Link *link) { if (!link->network) return false; + if (!link_ipv6ll_enabled(link)) + return false; + /* If unset use system default (enabled if local forwarding is disabled. * disabled if local forwarding is enabled). * If set, ignore or enforce RA independent of local forwarding state. @@ -497,8 +502,8 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { static void link_free(Link *link) { Address *address; - Iterator i; Link *carrier; + Iterator i; if (!link) return; @@ -767,6 +772,36 @@ void link_check_ready(Link *link) { return; } +static int link_set_routing_policy_rule(Link *link) { + RoutingPolicyRule *rule, *rrule = NULL; + int r; + + assert(link); + assert(link->network); + + LIST_FOREACH(rules, rule, link->network->rules) { + r = routing_policy_rule_get(link->manager, rule->family, &rule->from, rule->from_prefixlen, &rule->to, + rule->to_prefixlen, rule->tos, rule->fwmark, rule->table, &rrule); + if (r == 1) { + (void) routing_policy_rule_make_local(link->manager, rrule); + continue; + } + + r = routing_policy_rule_configure(rule, link, link_routing_policy_rule_handler, false); + if (r < 0) { + log_link_warning_errno(link, r, "Could not set routing policy rules: %m"); + link_enter_failed(link); + return r; + } + + link->link_messages++; + } + + routing_policy_rule_purge(link->manager, link); + + return 0; +} + static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { _cleanup_link_unref_ Link *link = userdata; int r; @@ -2135,6 +2170,12 @@ static int link_joined(Link *link) { log_link_error_errno(link, r, "Could not set bridge vlan: %m"); } + /* Skip setting up addresses until it gets carrier, + or it would try to set addresses twice, + which is bad for non-idempotent steps. */ + if (!link_has_carrier(link) && !link->network->configure_without_carrier) + return 0; + return link_enter_set_addresses(link); } @@ -2443,7 +2484,7 @@ static int link_drop_foreign_config(Link *link) { } static int link_drop_config(Link *link) { - Address *address; + Address *address, *pool_address; Route *route; Iterator i; int r; @@ -2456,6 +2497,15 @@ static int link_drop_config(Link *link) { r = address_remove(address, link, link_address_remove_handler); if (r < 0) return r; + + /* If this address came from an address pool, clean up the pool */ + LIST_FOREACH(addresses, pool_address, link->pool_addresses) { + if (address_equal(address, pool_address)) { + LIST_REMOVE(addresses, link->pool_addresses, pool_address); + address_free(pool_address); + break; + } + } } SET_FOREACH(route, link->routes, i) { @@ -2632,7 +2682,9 @@ static int link_configure(Link *link) { return r; } - if (link_has_carrier(link)) { + (void) link_set_routing_policy_rule(link); + + if (link_has_carrier(link) || link->network->configure_without_carrier) { r = link_acquire_conf(link); if (r < 0) return r; @@ -2733,7 +2785,7 @@ int link_initialized(Link *link, struct udev_device *device) { return r; r = sd_netlink_call_async(link->manager->rtnl, req, - link_initialized_and_synced, link, 0, NULL); + link_initialized_and_synced, link, 0, NULL); if (r < 0) return r; @@ -2901,7 +2953,7 @@ network_file_fail: goto dhcp4_address_fail; } - r = sd_dhcp_client_new(&link->dhcp_client); + r = sd_dhcp_client_new(&link->dhcp_client, link->network->dhcp_anonymize); if (r < 0) return log_link_error_errno(link, r, "Failed to create DHCPv4 client: %m"); @@ -3045,6 +3097,9 @@ static int link_carrier_lost(Link *link) { return r; } + if (link_dhcp4_server_enabled(link)) + (void) sd_dhcp_server_stop(link->dhcp_server); + r = link_drop_config(link); if (r < 0) return r; @@ -3106,7 +3161,7 @@ int link_update(Link *link, sd_netlink_message *m) { r = sd_netlink_message_read_string(m, IFLA_IFNAME, &ifname); if (r >= 0 && !streq(ifname, link->ifname)) { - log_link_info(link, "Renamed to %s", ifname); + log_link_info(link, "Interface name change detected, %s has been renamed to %s.", link->ifname, ifname); link_free_carrier_maps(link); @@ -3169,8 +3224,6 @@ int link_update(Link *link, sd_netlink_message *m) { } if (link->dhcp_client) { - const DUID *duid = link_duid(link); - r = sd_dhcp_client_set_mac(link->dhcp_client, (const uint8_t *) &link->mac, sizeof (link->mac), @@ -3178,13 +3231,30 @@ int link_update(Link *link, sd_netlink_message *m) { if (r < 0) return log_link_warning_errno(link, r, "Could not update MAC address in DHCP client: %m"); - r = sd_dhcp_client_set_iaid_duid(link->dhcp_client, - link->network->iaid, - duid->type, - duid->raw_data_len > 0 ? duid->raw_data : NULL, - duid->raw_data_len); - if (r < 0) - return log_link_warning_errno(link, r, "Could not update DUID/IAID in DHCP client: %m"); + switch (link->network->dhcp_client_identifier) { + case DHCP_CLIENT_ID_DUID: { + const DUID *duid = link_duid(link); + + r = sd_dhcp_client_set_iaid_duid(link->dhcp_client, + link->network->iaid, + duid->type, + duid->raw_data_len > 0 ? duid->raw_data : NULL, + duid->raw_data_len); + if (r < 0) + return log_link_warning_errno(link, r, "Could not update DUID/IAID in DHCP client: %m"); + break; + } + case DHCP_CLIENT_ID_MAC: + r = sd_dhcp_client_set_client_id(link->dhcp_client, + ARPHRD_ETHER, + (const uint8_t *)&link->mac, + sizeof(link->mac)); + if(r < 0) + return log_link_warning_errno(link, r, "Could not update MAC client id in DHCP client: %m"); + break; + default: + assert_not_reached("Unknown client identifier type."); + } } if (link->dhcp6_client) { @@ -3259,16 +3329,16 @@ static void print_link_hashmap(FILE *f, const char *prefix, Hashmap* h) { if (hashmap_isempty(h)) return; - fputs(prefix, f); + fputs_unlocked(prefix, f); HASHMAP_FOREACH(link, h, i) { if (space) - fputc(' ', f); + fputc_unlocked(' ', f); fprintf(f, "%i", link->ifindex); space = true; } - fputc('\n', f); + fputc_unlocked('\n', f); } int link_save(Link *link) { @@ -3326,7 +3396,7 @@ int link_save(Link *link) { fprintf(f, "NETWORK_FILE=%s\n", link->network->filename); - fputs("DNS=", f); + fputs_unlocked("DNS=", f); space = false; for (j = 0; j < link->network->n_dns; j++) { @@ -3340,8 +3410,8 @@ int link_save(Link *link) { } if (space) - fputc(' ', f); - fputs(b, f); + fputc_unlocked(' ', f); + fputs_unlocked(b, f); space = true; } @@ -3352,7 +3422,7 @@ int link_save(Link *link) { r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses); if (r > 0) { if (space) - fputc(' ', f); + fputc_unlocked(' ', f); serialize_in_addrs(f, addresses, r); space = true; } @@ -3364,7 +3434,7 @@ int link_save(Link *link) { r = sd_dhcp6_lease_get_dns(dhcp6_lease, &in6_addrs); if (r > 0) { if (space) - fputc(' ', f); + fputc_unlocked(' ', f); serialize_in6_addrs(f, in6_addrs, r); space = true; } @@ -3378,16 +3448,16 @@ int link_save(Link *link) { SET_FOREACH(dd, link->ndisc_rdnss, i) { if (space) - fputc(' ', f); + fputc_unlocked(' ', f); serialize_in6_addrs(f, &dd->address, 1); space = true; } } - fputc('\n', f); + fputc_unlocked('\n', f); - fputs("NTP=", f); + fputs_unlocked("NTP=", f); space = false; fputstrv(f, link->network->ntp, NULL, &space); @@ -3398,7 +3468,7 @@ int link_save(Link *link) { r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses); if (r > 0) { if (space) - fputc(' ', f); + fputc_unlocked(' ', f); serialize_in_addrs(f, addresses, r); space = true; } @@ -3412,7 +3482,7 @@ int link_save(Link *link) { &in6_addrs); if (r > 0) { if (space) - fputc(' ', f); + fputc_unlocked(' ', f); serialize_in6_addrs(f, in6_addrs, r); space = true; } @@ -3422,7 +3492,7 @@ int link_save(Link *link) { fputstrv(f, hosts, NULL, &space); } - fputc('\n', f); + fputc_unlocked('\n', f); if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) { if (link->dhcp_lease) { @@ -3433,7 +3503,7 @@ int link_save(Link *link) { (void) sd_dhcp6_lease_get_domains(dhcp6_lease, &dhcp6_domains); } - fputs("DOMAINS=", f); + fputs_unlocked("DOMAINS=", f); space = false; fputstrv(f, link->network->search_domains, NULL, &space); @@ -3451,9 +3521,9 @@ int link_save(Link *link) { fputs_with_space(f, NDISC_DNSSL_DOMAIN(dd), NULL, &space); } - fputc('\n', f); + fputc_unlocked('\n', f); - fputs("ROUTE_DOMAINS=", f); + fputs_unlocked("ROUTE_DOMAINS=", f); space = false; fputstrv(f, link->network->route_domains, NULL, &space); @@ -3471,7 +3541,7 @@ int link_save(Link *link) { fputs_with_space(f, NDISC_DNSSL_DOMAIN(dd), NULL, &space); } - fputc('\n', f); + fputc_unlocked('\n', f); fprintf(f, "LLMNR=%s\n", resolve_support_to_string(link->network->llmnr)); @@ -3485,14 +3555,14 @@ int link_save(Link *link) { if (!set_isempty(link->network->dnssec_negative_trust_anchors)) { const char *n; - fputs("DNSSEC_NTA=", f); + fputs_unlocked("DNSSEC_NTA=", f); space = false; SET_FOREACH(n, link->network->dnssec_negative_trust_anchors, i) fputs_with_space(f, n, NULL, &space); - fputc('\n', f); + fputc_unlocked('\n', f); } - fputs("ADDRESSES=", f); + fputs_unlocked("ADDRESSES=", f); space = false; SET_FOREACH(a, link->addresses, i) { _cleanup_free_ char *address_str = NULL; @@ -3504,9 +3574,9 @@ int link_save(Link *link) { fprintf(f, "%s%s/%u", space ? " " : "", address_str, a->prefixlen); space = true; } - fputc('\n', f); + fputc_unlocked('\n', f); - fputs("ROUTES=", f); + fputs_unlocked("ROUTES=", f); space = false; SET_FOREACH(route, link->routes, i) { _cleanup_free_ char *route_str = NULL; @@ -3515,12 +3585,13 @@ int link_save(Link *link) { if (r < 0) goto fail; - fprintf(f, "%s%s/%hhu/%hhu/%"PRIu32"/%hhu/"USEC_FMT, space ? " " : "", route_str, + fprintf(f, "%s%s/%hhu/%hhu/%"PRIu32"/%"PRIu32"/"USEC_FMT, + space ? " " : "", route_str, route->dst_prefixlen, route->tos, route->priority, route->table, route->lifetime); space = true; } - fputc('\n', f); + fputc_unlocked('\n', f); } print_link_hashmap(f, "CARRIER_BOUND_TO=", link->bound_to_links); @@ -3538,9 +3609,9 @@ int link_save(Link *link) { r = sd_dhcp_lease_get_address(link->dhcp_lease, &address); if (r >= 0) { - fputs("DHCP4_ADDRESS=", f); + fputs_unlocked("DHCP4_ADDRESS=", f); serialize_in_addrs(f, &address, 1); - fputc('\n', f); + fputc_unlocked('\n', f); } r = dhcp_lease_save(link->dhcp_lease, link->lease_file); @@ -3558,9 +3629,9 @@ int link_save(Link *link) { r = sd_ipv4ll_get_address(link->ipv4ll, &address); if (r >= 0) { - fputs("IPV4LL_ADDRESS=", f); + fputs_unlocked("IPV4LL_ADDRESS=", f); serialize_in_addrs(f, &address, 1); - fputc('\n', f); + fputc_unlocked('\n', f); } }