+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
#include "dns-domain.h"
#include "fd-util.h"
#include "hostname-util.h"
+#include "in-addr-util.h"
#include "network-internal.h"
#include "networkd-manager.h"
#include "networkd-network.h"
#include "stat-util.h"
#include "string-table.h"
#include "string-util.h"
+#include "strv.h"
#include "util.h"
static void network_config_hash_func(const void *p, struct siphash *state) {
}
void network_config_section_free(NetworkConfigSection *cs) {
- free(cs);
+ free(cs);
+}
+
+/* Set defaults following RFC7844 */
+void network_apply_anonymize_if_set(Network *network) {
+ if (!network->dhcp_anonymize)
+ return;
+ /* RFC7844 3.7
+ SHOULD NOT send the Host Name option */
+ network->dhcp_send_hostname = false;
+ /* RFC7844 section 3.:
+ MAY contain the Client Identifier option
+ Section 3.5:
+ clients MUST use client identifiers based solely
+ on the link-layer address */
+ /* NOTE: Using MAC, as it does not reveal extra information,
+ * and some servers might not answer if this option is not sent */
+ network->dhcp_client_identifier = DHCP_CLIENT_ID_MAC;
+ /* RFC 7844 3.10:
+ SHOULD NOT use the Vendor Class Identifier option */
+ /* NOTE: it was not initiallized to any value in network_load_one. */
+ network->dhcp_vendor_class_identifier = false;
+ /* RFC7844 section 3.6.:
+ The client intending to protect its privacy SHOULD only request a
+ minimal number of options in the PRL and SHOULD also randomly shuffle
+ the ordering of option codes in the PRL. If this random ordering
+ cannot be implemented, the client MAY order the option codes in the
+ PRL by option code number (lowest to highest).
+ */
+ /* NOTE: dhcp_use_mtu is false by default,
+ * though it was not initiallized to any value in network_load_one.
+ * Maybe there should be another var called *send*?
+ * (to use the MTU sent by the server but to do not send
+ * the option in the PRL). */
+ network->dhcp_use_mtu = false;
+ /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
+ * but this is needed to use them. */
+ network->dhcp_use_routes = true;
+ /* RFC7844 section 3.6.
+ * same comments as previous option */
+ network->dhcp_use_timezone = false;
}
static int network_load_one(Manager *manager, const char *filename) {
LIST_HEAD_INIT(network->ipv6_proxy_ndp_addresses);
LIST_HEAD_INIT(network->address_labels);
LIST_HEAD_INIT(network->static_prefixes);
+ LIST_HEAD_INIT(network->rules);
network->stacked_netdevs = hashmap_new(&string_hash_ops);
if (!network->stacked_netdevs)
if (!network->prefixes_by_section)
return log_oom();
+ network->rules_by_section = hashmap_new(&network_config_hash_ops);
+ if (!network->rules_by_section)
+ return log_oom();
+
network->filename = strdup(filename);
if (!network->filename)
return log_oom();
network->dhcp_use_dns = true;
network->dhcp_use_hostname = true;
network->dhcp_use_routes = true;
+ /* NOTE: this var might be overwriten by network_apply_anonymize_if_set */
network->dhcp_send_hostname = true;
+ /* To enable/disable RFC7844 Anonymity Profiles */
+ network->dhcp_anonymize = false;
network->dhcp_route_metric = DHCP_ROUTE_METRIC;
+ /* NOTE: this var might be overwrite by network_apply_anonymize_if_set */
network->dhcp_client_identifier = DHCP_CLIENT_ID_DUID;
network->dhcp_route_table = RT_TABLE_MAIN;
+ network->dhcp_route_table_set = false;
+ /* NOTE: the following vars were not set to any default,
+ * even if they are commented in the man?
+ * These vars might be overwriten by network_apply_anonymize_if_set */
+ network->dhcp_vendor_class_identifier = false;
+ /* NOTE: from man: UseMTU=... Defaults to false*/
+ network->dhcp_use_mtu = false;
+ /* NOTE: from man: UseTimezone=... Defaults to "no".*/
+ network->dhcp_use_timezone = false;
network->dhcp_server_emit_dns = true;
network->dhcp_server_emit_ntp = true;
network->dhcp_server_emit_router = true;
network->dhcp_server_emit_timezone = true;
+ network->router_emit_dns = true;
+ network->router_emit_domains = true;
+
network->use_bpdu = true;
network->allow_port_to_be_root = true;
network->unicast_flood = true;
"Network\0"
"Address\0"
"IPv6AddressLabel\0"
+ "RoutingPolicyRule\0"
"Route\0"
"DHCP\0"
"DHCPv4\0" /* compat */
"IPv6PrefixDelegation\0"
"IPv6Prefix\0",
config_item_perf_lookup, network_network_gperf_lookup,
- false, network);
+ CONFIG_PARSE_WARN, network);
if (r < 0)
return r;
+ network_apply_anonymize_if_set(network);
+
/* IPMasquerade=yes implies IPForward=yes */
if (network->ip_masquerade)
network->ip_forward |= ADDRESS_FAMILY_IPV4;
while ((network = manager->networks))
network_free(network);
- r = conf_files_list_strv(&files, ".network", NULL, network_dirs);
+ 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");
}
void network_free(Network *network) {
- NetDev *netdev;
- Route *route;
- Address *address;
- FdbEntry *fdb_entry;
IPv6ProxyNDPAddress *ipv6_proxy_ndp_address;
+ RoutingPolicyRule *rule;
+ FdbEntry *fdb_entry;
AddressLabel *label;
Prefix *prefix;
+ Address *address;
+ NetDev *netdev;
+ Route *route;
Iterator i;
if (!network)
while ((prefix = network->static_prefixes))
prefix_free(prefix);
+ while ((rule = network->rules))
+ routing_policy_rule_free(rule);
+
hashmap_free(network->addresses_by_section);
hashmap_free(network->routes_by_section);
hashmap_free(network->fdb_entries_by_section);
hashmap_free(network->address_labels_by_section);
hashmap_free(network->prefixes_by_section);
+ hashmap_free(network->rules_by_section);
if (network->manager) {
if (network->manager->networks)
return 0;
}
- if (netdev->kind != NETDEV_KIND_IPIP &&
- netdev->kind != NETDEV_KIND_SIT &&
- netdev->kind != NETDEV_KIND_GRE &&
- netdev->kind != NETDEV_KIND_GRETAP &&
- netdev->kind != NETDEV_KIND_IP6GRE &&
- netdev->kind != NETDEV_KIND_IP6GRETAP &&
- netdev->kind != NETDEV_KIND_VTI &&
- netdev->kind != NETDEV_KIND_VTI6 &&
- netdev->kind != NETDEV_KIND_IP6TNL
- ) {
+ if (!IN_SET(netdev->kind,
+ NETDEV_KIND_IPIP,
+ NETDEV_KIND_SIT,
+ NETDEV_KIND_GRE,
+ NETDEV_KIND_GRETAP,
+ NETDEV_KIND_IP6GRE,
+ NETDEV_KIND_IP6GRETAP,
+ NETDEV_KIND_VTI,
+ NETDEV_KIND_VTI6,
+ NETDEV_KIND_IP6TNL)) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"NetDev is not a tunnel, ignoring assignment: %s", rvalue);
return 0;
return 0;
}
+int config_parse_radv_dns(
+ 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 *n = data;
+ const char *p = rvalue;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+
+ for (;;) {
+ _cleanup_free_ char *w = NULL;
+ union in_addr_union a;
+
+ r = extract_first_word(&p, &w, NULL, 0);
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract word, ignoring: %s", rvalue);
+ return 0;
+ }
+ if (r == 0)
+ break;
+
+ if (in_addr_from_string(AF_INET6, w, &a) >= 0) {
+ struct in6_addr *m;
+
+ m = realloc(n->router_dns, (n->n_router_dns + 1) * sizeof(struct in6_addr));
+ if (!m)
+ return log_oom();
+
+ m[n->n_router_dns++] = a.in6;
+ n->router_dns = m;
+
+ } else
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse DNS server address, ignoring: %s", w);
+
+ }
+
+ return 0;
+}
+
+int config_parse_radv_search_domains(
+ 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 *n = data;
+ const char *p = rvalue;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+
+ for (;;) {
+ _cleanup_free_ char *w = NULL;
+ _cleanup_free_ char *idna = NULL;
+
+ r = extract_first_word(&p, &w, NULL, 0);
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract word, ignoring: %s", rvalue);
+ return 0;
+ }
+ if (r == 0)
+ break;
+
+ r = dns_name_apply_idna(w, &idna);
+ if (r > 0) {
+ r = strv_push(&n->router_search_domains, idna);
+ if (r >= 0)
+ idna = NULL;
+ } else if (r == 0) {
+ r = strv_push(&n->router_search_domains, w);
+ if (r >= 0)
+ w = NULL;
+ }
+ }
+
+ return 0;
+}
+
int config_parse_dhcp_server_ntp(
const char *unit,
const char *filename,
const char *rvalue,
void *data,
void *userdata) {
+ Network *network = data;
uint32_t rt;
int r;
return 0;
}
- *((uint32_t *)data) = rt;
+ network->dhcp_route_table = rt;
+ network->dhcp_route_table_set = true;
return 0;
}