X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=src%2Fnetwork%2Fnetworkd-network.c;h=a5e7cad58a4c9b910d4bd647e8397fe26912a424;hb=2bb24885de191d5a9d8abbac0bca0c1da0559847;hp=836776ae8496c5ae4ff6e608b6375e7e50e713c3;hpb=3f8f021541c58ca2fd8d05b7808c7395b90d6937;p=thirdparty%2Fsystemd.git diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 836776ae849..a5e7cad58a4 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -1,7 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -#include #include +#include +#include #include "alloc-util.h" #include "conf-files.h" @@ -10,7 +11,6 @@ #include "fd-util.h" #include "hostname-util.h" #include "in-addr-util.h" -#include "missing_network.h" #include "network-internal.h" #include "networkd-manager.h" #include "networkd-network.h" @@ -143,24 +143,6 @@ static int network_resolve_stacked_netdevs(Network *network) { return 0; } -static uint32_t network_get_stacked_netdevs_mtu(Network *network) { - uint32_t mtu = 0; - NetDev *dev; - Iterator i; - - HASHMAP_FOREACH(dev, network->stacked_netdevs, i) - if (dev->kind == NETDEV_KIND_VLAN && dev->mtu > 0) - /* See vlan_dev_change_mtu() in kernel. - * Note that the additional 4bytes may not be necessary for all devices. */ - mtu = MAX(mtu, dev->mtu + 4); - - else if (dev->kind == NETDEV_KIND_MACVLAN && dev->mtu > mtu) - /* See macvlan_change_mtu() in kernel. */ - mtu = dev->mtu; - - return mtu; -} - int network_verify(Network *network) { Address *address, *address_next; Route *route, *route_next; @@ -169,11 +151,18 @@ int network_verify(Network *network) { AddressLabel *label, *label_next; Prefix *prefix, *prefix_next; RoutingPolicyRule *rule, *rule_next; - uint32_t mtu; assert(network); assert(network->filename); + if (set_isempty(network->match_mac) && strv_isempty(network->match_path) && + strv_isempty(network->match_driver) && strv_isempty(network->match_type) && + strv_isempty(network->match_name) && !network->conditions) + log_warning("%s: No valid settings found in the [Match] section. " + "The file will match all interfaces. " + "If that is intended, please add Name=* in the [Match] section.", + network->filename); + /* skip out early if configuration does not match the environment */ if (!condition_test_list(network->conditions, NULL, NULL, NULL)) return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), @@ -230,6 +219,13 @@ int network_verify(Network *network) { if (network->link_local < 0) network->link_local = network->bridge ? ADDRESS_FAMILY_NO : ADDRESS_FAMILY_IPV6; + if (FLAGS_SET(network->link_local, ADDRESS_FAMILY_FALLBACK_IPV4) && + !FLAGS_SET(network->dhcp, ADDRESS_FAMILY_IPV4)) { + log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. " + "Disabling the fallback assignment.", network->filename); + SET_FLAG(network->link_local, ADDRESS_FAMILY_FALLBACK_IPV4, false); + } + if (network->ipv6_accept_ra < 0 && network->bridge) network->ipv6_accept_ra = false; @@ -237,16 +233,7 @@ int network_verify(Network *network) { if (network->ip_masquerade) network->ip_forward |= ADDRESS_FAMILY_IPV4; - network->mtu_is_set = network->mtu > 0; - mtu = network_get_stacked_netdevs_mtu(network); - if (network->mtu < mtu) { - if (network->mtu_is_set) - log_notice("%s: Bumping MTUBytes= from %"PRIu32" to %"PRIu32" because of stacked device", - network->filename, network->mtu, mtu); - network->mtu = mtu; - } - - if (network->mtu_is_set && network->dhcp_use_mtu) { + if (network->mtu > 0 && network->dhcp_use_mtu) { log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. " "Disabling UseMTU=.", network->filename); network->dhcp_use_mtu = false; @@ -285,7 +272,7 @@ int network_verify(Network *network) { int network_load_one(Manager *manager, const char *filename) { _cleanup_free_ char *fname = NULL, *name = NULL; - _cleanup_(network_freep) Network *network = NULL; + _cleanup_(network_unrefp) Network *network = NULL; _cleanup_fclose_ FILE *file = NULL; const char *dropin_dirname; char *d; @@ -331,6 +318,9 @@ int network_load_one(Manager *manager, const char *filename) { .filename = TAKE_PTR(fname), .name = TAKE_PTR(name), + .manager = manager, + .n_ref = 1, + .required_for_online = true, .required_operstate_for_online = LINK_OPERSTATE_DEGRADED, .dhcp = ADDRESS_FAMILY_NO, @@ -338,12 +328,12 @@ int network_load_one(Manager *manager, const char *filename) { .dhcp_use_dns = true, .dhcp_use_hostname = true, .dhcp_use_routes = true, - /* NOTE: this var might be overwriten by network_apply_anonymize_if_set */ + /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */ .dhcp_send_hostname = true, /* To enable/disable RFC7844 Anonymity Profiles */ .dhcp_anonymize = false, .dhcp_route_metric = DHCP_ROUTE_METRIC, - /* NOTE: this var might be overwrite by network_apply_anonymize_if_set */ + /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */ .dhcp_client_identifier = DHCP_CLIENT_ID_DUID, .dhcp_route_table = RT_TABLE_MAIN, .dhcp_route_table_set = false, @@ -370,7 +360,10 @@ int network_load_one(Manager *manager, const char *filename) { .multicast_to_unicast = -1, .neighbor_suppression = -1, .learning = -1, + .bridge_proxy_arp = -1, + .bridge_proxy_arp_wifi = -1, .priority = LINK_BRIDGE_PORT_PRIORITY_INVALID, + .multicast_router = _MULTICAST_ROUTER_INVALID, .lldp_mode = LLDP_MODE_ROUTERS_ONLY, @@ -433,14 +426,16 @@ int network_load_one(Manager *manager, const char *filename) { if (r < 0) log_warning_errno(r, "%s: Failed to add IPv4LL route, ignoring: %m", network->filename); - LIST_PREPEND(networks, manager->networks, network); - network->manager = manager; + r = network_add_default_route_on_device(network); + if (r < 0) + log_warning_errno(r, "%s: Failed to add default route on device, ignoring: %m", + network->filename); - r = hashmap_ensure_allocated(&manager->networks_by_name, &string_hash_ops); + r = ordered_hashmap_ensure_allocated(&manager->networks, &string_hash_ops); if (r < 0) return r; - r = hashmap_put(manager->networks_by_name, network->name, network); + r = ordered_hashmap_put(manager->networks, network->name, network); if (r < 0) return r; @@ -452,21 +447,19 @@ int network_load_one(Manager *manager, const char *filename) { } int network_load(Manager *manager) { - Network *network; _cleanup_strv_free_ char **files = NULL; char **f; int r; assert(manager); - while ((network = manager->networks)) - network_free(network); + ordered_hashmap_clear_with_destructor(manager->networks, network_unref); r = conf_files_list_strv(&files, ".network", NULL, 0, NETWORK_DIRS); if (r < 0) return log_error_errno(r, "Failed to enumerate network files: %m"); - STRV_FOREACH_BACKWARDS(f, files) { + STRV_FOREACH(f, files) { r = network_load_one(manager, *f); if (r < 0) return r; @@ -475,7 +468,7 @@ int network_load(Manager *manager) { return 0; } -void network_free(Network *network) { +static Network *network_free(Network *network) { IPv6ProxyNDPAddress *ipv6_proxy_ndp_address; RoutingPolicyRule *rule; FdbEntry *fdb_entry; @@ -486,7 +479,7 @@ void network_free(Network *network) { Route *route; if (!network) - return; + return NULL; free(network->filename); @@ -501,7 +494,7 @@ void network_free(Network *network) { free(network->dhcp_vendor_class_identifier); strv_free(network->dhcp_user_class); free(network->dhcp_hostname); - + set_free(network->dhcp_black_listed_ip); free(network->mac); strv_free(network->ntp); @@ -512,6 +505,7 @@ void network_free(Network *network) { ordered_set_free_free(network->router_search_domains); free(network->router_dns); + set_free_free(network->ndisc_black_listed_prefix); free(network->bridge_name); free(network->bond_name); @@ -555,11 +549,8 @@ void network_free(Network *network) { hashmap_free(network->rules_by_section); if (network->manager) { - if (network->manager->networks) - LIST_REMOVE(networks, network->manager->networks, network); - - if (network->manager->networks_by_name && network->name) - hashmap_remove(network->manager->networks_by_name, network->name); + if (network->manager->networks && network->name) + ordered_hashmap_remove(network->manager->networks, network->name); if (network->manager->duids_requesting_uuid) set_remove(network->manager->duids_requesting_uuid, &network->duid); @@ -573,9 +564,11 @@ void network_free(Network *network) { set_free_free(network->dnssec_negative_trust_anchors); - free(network); + return mfree(network); } +DEFINE_TRIVIAL_REF_UNREF_FUNC(Network, network, network_free); + int network_get_by_name(Manager *manager, const char *name, Network **ret) { Network *network; @@ -583,7 +576,7 @@ int network_get_by_name(Manager *manager, const char *name, Network **ret) { assert(name); assert(ret); - network = hashmap_get(manager->networks_by_name, name); + network = ordered_hashmap_get(manager->networks, name); if (!network) return -ENOENT; @@ -597,6 +590,7 @@ int network_get(Manager *manager, sd_device *device, Network **ret) { const char *path = NULL, *driver = NULL, *devtype = NULL; Network *network; + Iterator i; assert(manager); assert(ret); @@ -609,7 +603,7 @@ int network_get(Manager *manager, sd_device *device, (void) sd_device_get_devtype(device, &devtype); } - LIST_FOREACH(networks, network, manager->networks) { + ORDERED_HASHMAP_FOREACH(network, manager->networks, i) if (net_match_config(network->match_mac, network->match_path, network->match_driver, network->match_type, network->match_name, @@ -632,7 +626,6 @@ int network_get(Manager *manager, sd_device *device, *ret = network; return 0; } - } *ret = NULL; @@ -643,7 +636,7 @@ int network_apply(Network *network, Link *link) { assert(network); assert(link); - link->network = network; + link->network = network_ref(network); if (network->n_dns > 0 || !strv_isempty(network->ntp) || @@ -688,8 +681,8 @@ int config_parse_stacked_netdev(const char *unit, assert(data); assert(IN_SET(kind, NETDEV_KIND_VLAN, NETDEV_KIND_MACVLAN, NETDEV_KIND_MACVTAP, - NETDEV_KIND_IPVLAN, NETDEV_KIND_VXLAN, NETDEV_KIND_L2TP, - _NETDEV_KIND_TUNNEL)); + NETDEV_KIND_IPVLAN, NETDEV_KIND_IPVTAP, NETDEV_KIND_VXLAN, + NETDEV_KIND_L2TP, NETDEV_KIND_MACSEC, _NETDEV_KIND_TUNNEL)); if (!ifname_valid(rvalue)) { log_syntax(unit, LOG_ERR, filename, line, 0, @@ -812,6 +805,7 @@ int config_parse_ipv4ll( void *userdata) { AddressFamilyBoolean *link_local = data; + int r; assert(filename); assert(lvalue); @@ -822,7 +816,20 @@ int config_parse_ipv4ll( * config_parse_address_family_boolean(), except that it * applies only to IPv4 */ - SET_FLAG(*link_local, ADDRESS_FAMILY_IPV4, parse_boolean(rvalue)); + r = parse_boolean(rvalue); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to parse %s=%s, ignoring assignment. " + "Note that the setting %s= is deprecated, please use LinkLocalAddressing= instead.", + lvalue, rvalue, lvalue); + return 0; + } + + SET_FLAG(*link_local, ADDRESS_FAMILY_IPV4, r); + + log_syntax(unit, LOG_WARNING, filename, line, 0, + "%s=%s is deprecated, please use LinkLocalAddressing=%s instead.", + lvalue, rvalue, address_family_boolean_to_string(*link_local)); return 0; } @@ -854,7 +861,7 @@ int config_parse_dhcp( if (s < 0) { /* Previously, we had a slightly different enum here, - * support its values for compatbility. */ + * support its values for compatibility. */ if (streq(rvalue, "none")) s = ADDRESS_FAMILY_NO; @@ -1091,7 +1098,8 @@ int config_parse_dhcp_server_dns( for (;;) { _cleanup_free_ char *w = NULL; - struct in_addr a, *m; + union in_addr_union a; + struct in_addr *m; r = extract_first_word(&p, &w, NULL, 0); if (r == -ENOMEM) @@ -1104,9 +1112,10 @@ int config_parse_dhcp_server_dns( if (r == 0) break; - if (inet_pton(AF_INET, w, &a) <= 0) { - log_syntax(unit, LOG_ERR, filename, line, 0, - "Failed to parse DNS server address, ignoring: %s", w); + r = in_addr_from_string(AF_INET, w, &a); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to parse DNS server address '%s', ignoring assignment: %m", w); continue; } @@ -1114,7 +1123,7 @@ int config_parse_dhcp_server_dns( if (!m) return log_oom(); - m[n->n_dhcp_server_dns++] = a; + m[n->n_dhcp_server_dns++] = a.in; n->dhcp_server_dns = m; } @@ -1251,7 +1260,8 @@ int config_parse_dhcp_server_ntp( for (;;) { _cleanup_free_ char *w = NULL; - struct in_addr a, *m; + union in_addr_union a; + struct in_addr *m; r = extract_first_word(&p, &w, NULL, 0); if (r == -ENOMEM) @@ -1264,9 +1274,10 @@ int config_parse_dhcp_server_ntp( if (r == 0) return 0; - if (inet_pton(AF_INET, w, &a) <= 0) { - log_syntax(unit, LOG_ERR, filename, line, 0, - "Failed to parse NTP server address, ignoring: %s", w); + r = in_addr_from_string(AF_INET, w, &a); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to parse NTP server address '%s', ignoring: %m", w); continue; } @@ -1274,7 +1285,7 @@ int config_parse_dhcp_server_ntp( if (!m) return log_oom(); - m[n->n_dhcp_server_ntp++] = a; + m[n->n_dhcp_server_ntp++] = a.in; n->dhcp_server_ntp = m; } } @@ -1548,6 +1559,114 @@ int config_parse_section_route_table( return 0; } +int config_parse_dhcp_max_attempts( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Network *network = data; + uint64_t a; + int r; + + assert(network); + assert(lvalue); + assert(rvalue); + + if (isempty(rvalue)) { + network->dhcp_max_attempts = 0; + return 0; + } + + if (streq(rvalue, "infinity")) { + network->dhcp_max_attempts = (uint64_t) -1; + return 0; + } + + r = safe_atou64(rvalue, &a); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to parse DHCP maximum attempts, ignoring: %s", rvalue); + return 0; + } + + if (a == 0) { + log_syntax(unit, LOG_ERR, filename, line, 0, + "%s= must be positive integer or 'infinity', ignoring: %s", lvalue, rvalue); + return 0; + } + + network->dhcp_max_attempts = a; + + return 0; +} + +int config_parse_dhcp_black_listed_ip_address( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Network *network = data; + const char *p; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (isempty(rvalue)) { + network->dhcp_black_listed_ip = set_free(network->dhcp_black_listed_ip); + return 0; + } + + for (p = rvalue;;) { + _cleanup_free_ char *n = NULL; + union in_addr_union ip; + + r = extract_first_word(&p, &n, NULL, 0); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to parse DHCP black listed ip address, ignoring assignment: %s", + rvalue); + return 0; + } + if (r == 0) + return 0; + + r = in_addr_from_string(AF_INET, n, &ip); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "DHCP black listed ip address is invalid, ignoring assignment: %s", n); + continue; + } + + r = set_ensure_allocated(&network->dhcp_black_listed_ip, NULL); + if (r < 0) + return log_oom(); + + r = set_put(network->dhcp_black_listed_ip, UINT32_TO_PTR(ip.in.s_addr)); + if (r < 0) + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to store DHCP black listed ip address '%s', ignoring assignment: %m", n); + } + + return 0; +} + DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains, dhcp_use_domains, DHCPUseDomains, "Failed to parse DHCP use domains setting"); @@ -1559,16 +1678,6 @@ static const char* const dhcp_use_domains_table[_DHCP_USE_DOMAINS_MAX] = { DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains, DHCPUseDomains, DHCP_USE_DOMAINS_YES); -DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode, lldp_mode, LLDPMode, "Failed to parse LLDP= setting."); - -static const char* const lldp_mode_table[_LLDP_MODE_MAX] = { - [LLDP_MODE_NO] = "no", - [LLDP_MODE_YES] = "yes", - [LLDP_MODE_ROUTERS_ONLY] = "routers-only", -}; - -DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode, LLDPMode, LLDP_MODE_YES); - int config_parse_iaid(const char *unit, const char *filename, unsigned line,