]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-network.c
Merge pull request #16316 from yuwata/backlight-use-actual-brightness
[thirdparty/systemd.git] / src / network / networkd-network.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
f579559b 2
9aa5d8ba
YW
3#include <net/if.h>
4#include <netinet/in.h>
01234e1f 5#include <linux/netdevice.h>
a0b191b7 6#include <unistd.h>
69a93e7d 7
b5efdb8a 8#include "alloc-util.h"
f579559b
TG
9#include "conf-files.h"
10#include "conf-parser.h"
37de2509 11#include "dns-domain.h"
3ffd4af2 12#include "fd-util.h"
07630cea 13#include "hostname-util.h"
88295a05 14#include "in-addr-util.h"
564ca984 15#include "networkd-dhcp-server.h"
fc2f9534 16#include "network-internal.h"
23f53b99 17#include "networkd-manager.h"
3ffd4af2 18#include "networkd-network.h"
6bedfcbb 19#include "parse-util.h"
b0c82192 20#include "path-lookup.h"
8a516214 21#include "set.h"
cebe1257 22#include "socket-util.h"
8fcde012 23#include "stat-util.h"
8b43440b 24#include "string-table.h"
07630cea 25#include "string-util.h"
700f1186 26#include "strv.h"
34658df2 27#include "tc.h"
07630cea 28#include "util.h"
f579559b 29
c448459d
ZJS
30/* Let's assume that anything above this number is a user misconfiguration. */
31#define MAX_NTP_SERVERS 128
32
add8d07d 33/* Set defaults following RFC7844 */
34void network_apply_anonymize_if_set(Network *network) {
35 if (!network->dhcp_anonymize)
36 return;
37 /* RFC7844 3.7
38 SHOULD NOT send the Host Name option */
39 network->dhcp_send_hostname = false;
40 /* RFC7844 section 3.:
41 MAY contain the Client Identifier option
42 Section 3.5:
43 clients MUST use client identifiers based solely
44 on the link-layer address */
45 /* NOTE: Using MAC, as it does not reveal extra information,
46 * and some servers might not answer if this option is not sent */
47 network->dhcp_client_identifier = DHCP_CLIENT_ID_MAC;
48 /* RFC 7844 3.10:
49 SHOULD NOT use the Vendor Class Identifier option */
727ba17f 50 network->dhcp_vendor_class_identifier = mfree(network->dhcp_vendor_class_identifier);
add8d07d 51 /* RFC7844 section 3.6.:
52 The client intending to protect its privacy SHOULD only request a
53 minimal number of options in the PRL and SHOULD also randomly shuffle
54 the ordering of option codes in the PRL. If this random ordering
55 cannot be implemented, the client MAY order the option codes in the
56 PRL by option code number (lowest to highest).
57 */
58 /* NOTE: dhcp_use_mtu is false by default,
59 * though it was not initiallized to any value in network_load_one.
60 * Maybe there should be another var called *send*?
61 * (to use the MTU sent by the server but to do not send
62 * the option in the PRL). */
63 network->dhcp_use_mtu = false;
28522b0d 64 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
65 * but this is needed to use them. */
66 network->dhcp_use_routes = true;
add8d07d 67 /* RFC7844 section 3.6.
68 * same comments as previous option */
69 network->dhcp_use_timezone = false;
70}
71
cebe1257
YW
72static int network_resolve_netdev_one(Network *network, const char *name, NetDevKind kind, NetDev **ret_netdev) {
73 const char *kind_string;
74 NetDev *netdev;
75 int r;
76
96db6412
YW
77 /* For test-networkd-conf, the check must be earlier than the assertions. */
78 if (!name)
79 return 0;
80
cebe1257
YW
81 assert(network);
82 assert(network->manager);
83 assert(network->filename);
84 assert(ret_netdev);
85
cebe1257
YW
86 if (kind == _NETDEV_KIND_TUNNEL)
87 kind_string = "tunnel";
88 else {
89 kind_string = netdev_kind_to_string(kind);
90 if (!kind_string)
91 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
92 "%s: Invalid NetDev kind of %s, ignoring assignment.",
93 network->filename, name);
94 }
95
96 r = netdev_get(network->manager, name, &netdev);
97 if (r < 0)
98 return log_error_errno(r, "%s: %s NetDev could not be found, ignoring assignment.",
99 network->filename, name);
100
101 if (netdev->kind != kind && !(kind == _NETDEV_KIND_TUNNEL &&
102 IN_SET(netdev->kind,
103 NETDEV_KIND_IPIP,
104 NETDEV_KIND_SIT,
105 NETDEV_KIND_GRE,
106 NETDEV_KIND_GRETAP,
107 NETDEV_KIND_IP6GRE,
108 NETDEV_KIND_IP6GRETAP,
109 NETDEV_KIND_VTI,
110 NETDEV_KIND_VTI6,
9282f75b
YW
111 NETDEV_KIND_IP6TNL,
112 NETDEV_KIND_ERSPAN)))
cebe1257
YW
113 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
114 "%s: NetDev %s is not a %s, ignoring assignment",
115 network->filename, name, kind_string);
116
117 *ret_netdev = netdev_ref(netdev);
118 return 1;
119}
120
121static int network_resolve_stacked_netdevs(Network *network) {
122 void *name, *kind;
123 Iterator i;
124 int r;
125
126 assert(network);
127
128 HASHMAP_FOREACH_KEY(kind, name, network->stacked_netdev_names, i) {
129 _cleanup_(netdev_unrefp) NetDev *netdev = NULL;
130
131 r = network_resolve_netdev_one(network, name, PTR_TO_INT(kind), &netdev);
132 if (r <= 0)
133 continue;
134
135 r = hashmap_ensure_allocated(&network->stacked_netdevs, &string_hash_ops);
136 if (r < 0)
137 return log_oom();
138
139 r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev);
140 if (r < 0)
141 return log_error_errno(r, "%s: Failed to add NetDev '%s' to network: %m",
142 network->filename, (const char *) name);
143
144 netdev = NULL;
145 }
146
147 return 0;
148}
149
96db6412 150int network_verify(Network *network) {
95081e08 151 RoutePrefix *route_prefix, *route_prefix_next;
564ca984 152 RoutingPolicyRule *rule, *rule_next;
fcbf4cb7
YW
153 Neighbor *neighbor, *neighbor_next;
154 AddressLabel *label, *label_next;
c16c7808 155 NextHop *nexthop, *nextnop_next;
564ca984
SS
156 Address *address, *address_next;
157 Prefix *prefix, *prefix_next;
158 Route *route, *route_next;
159 FdbEntry *fdb, *fdb_next;
34658df2 160 TrafficControl *tc;
8efb93f0 161 Iterator i;
0321cea7
YW
162
163 assert(network);
164 assert(network->filename);
165
4bb7cc82
YW
166 if (set_isempty(network->match_mac) && set_isempty(network->match_permanent_mac) &&
167 strv_isempty(network->match_path) && strv_isempty(network->match_driver) &&
168 strv_isempty(network->match_type) && strv_isempty(network->match_name) &&
25c86e4c
DDM
169 strv_isempty(network->match_property) && strv_isempty(network->match_wlan_iftype) &&
170 strv_isempty(network->match_ssid) && !network->conditions)
dade7349
ZJS
171 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
172 "%s: No valid settings found in the [Match] section, ignoring file. "
173 "To match all interfaces, add Name=* in the [Match] section.",
174 network->filename);
84ea567e 175
cebe1257 176 /* skip out early if configuration does not match the environment */
a0b191b7 177 if (!condition_test_list(network->conditions, environ, NULL, NULL, NULL))
cebe1257 178 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
3772cfde
ZJS
179 "%s: Conditions in the file do not match the system environment, skipping.",
180 network->filename);
cebe1257
YW
181
182 (void) network_resolve_netdev_one(network, network->bond_name, NETDEV_KIND_BOND, &network->bond);
183 (void) network_resolve_netdev_one(network, network->bridge_name, NETDEV_KIND_BRIDGE, &network->bridge);
184 (void) network_resolve_netdev_one(network, network->vrf_name, NETDEV_KIND_VRF, &network->vrf);
185 (void) network_resolve_stacked_netdevs(network);
186
187 /* Free unnecessary entries. */
188 network->bond_name = mfree(network->bond_name);
189 network->bridge_name = mfree(network->bridge_name);
190 network->vrf_name = mfree(network->vrf_name);
191 network->stacked_netdev_names = hashmap_free_free_key(network->stacked_netdev_names);
192
0321cea7
YW
193 if (network->bond) {
194 /* Bonding slave does not support addressing. */
195 if (network->ipv6_accept_ra > 0) {
ab24039f
ZJS
196 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
197 network->filename);
0321cea7
YW
198 network->ipv6_accept_ra = 0;
199 }
200 if (network->link_local >= 0 && network->link_local != ADDRESS_FAMILY_NO) {
ab24039f
ZJS
201 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
202 network->filename);
0321cea7
YW
203 network->link_local = ADDRESS_FAMILY_NO;
204 }
205 if (network->dhcp != ADDRESS_FAMILY_NO) {
ab24039f
ZJS
206 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
207 network->filename);
0321cea7
YW
208 network->dhcp = ADDRESS_FAMILY_NO;
209 }
210 if (network->dhcp_server) {
ab24039f
ZJS
211 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
212 network->filename);
0321cea7
YW
213 network->dhcp_server = false;
214 }
215 if (network->n_static_addresses > 0) {
ab24039f
ZJS
216 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
217 network->filename);
0321cea7
YW
218 while ((address = network->static_addresses))
219 address_free(address);
220 }
221 if (network->n_static_routes > 0) {
ab24039f
ZJS
222 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
223 network->filename);
0321cea7
YW
224 while ((route = network->static_routes))
225 route_free(route);
226 }
227 }
228
229 if (network->link_local < 0)
8f191801
YW
230 network->link_local = network->bridge ? ADDRESS_FAMILY_NO : ADDRESS_FAMILY_IPV6;
231
44013aa4
YW
232 if (!FLAGS_SET(network->link_local, ADDRESS_FAMILY_IPV6)) {
233 if (network->ipv6_accept_ra > 0) {
234 log_warning("%s: IPv6AcceptRA= is enabled by the .network file but IPv6 link local addressing is disabled. "
235 "Disabling IPv6AcceptRA=.", network->filename);
236 network->ipv6_accept_ra = false;
237 }
238
239 if (FLAGS_SET(network->dhcp, ADDRESS_FAMILY_IPV6)) {
240 log_warning("%s: DHCPv6 client is enabled by the .network file but IPv6 link local addressing is disabled. "
241 "Disabling DHCPv6 client.", network->filename);
242 SET_FLAG(network->dhcp, ADDRESS_FAMILY_IPV6, false);
243 }
244
245 if (network->router_prefix_delegation != RADV_PREFIX_DELEGATION_NONE) {
246 log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
247 "Disabling IPv6PrefixDelegation=.", network->filename);
248 network->router_prefix_delegation = RADV_PREFIX_DELEGATION_NONE;
249 }
250 }
251
29e81083
YW
252 if (FLAGS_SET(network->link_local, ADDRESS_FAMILY_FALLBACK_IPV4) &&
253 !FLAGS_SET(network->dhcp, ADDRESS_FAMILY_IPV4)) {
254 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
255 "Disabling the fallback assignment.", network->filename);
256 SET_FLAG(network->link_local, ADDRESS_FAMILY_FALLBACK_IPV4, false);
257 }
258
8f191801
YW
259 if (network->ipv6_accept_ra < 0 && network->bridge)
260 network->ipv6_accept_ra = false;
0321cea7
YW
261
262 /* IPMasquerade=yes implies IPForward=yes */
263 if (network->ip_masquerade)
264 network->ip_forward |= ADDRESS_FAMILY_IPV4;
265
933c70a0 266 if (network->mtu > 0 && network->dhcp_use_mtu) {
0321cea7
YW
267 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
268 "Disabling UseMTU=.", network->filename);
269 network->dhcp_use_mtu = false;
270 }
271
589397a2
DS
272 if (network->dhcp_use_gateway < 0)
273 network->dhcp_use_gateway = network->dhcp_use_routes;
274
bd0d471c
DS
275 if (network->ignore_carrier_loss < 0)
276 network->ignore_carrier_loss = network->configure_without_carrier;
277
7da377ef
SS
278 if (network->dhcp_critical >= 0) {
279 if (network->keep_configuration >= 0)
280 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
281 "Ignoring CriticalConnection=.", network->filename);
282 else if (network->dhcp_critical)
283 /* CriticalConnection=yes also preserve foreign static configurations. */
284 network->keep_configuration = KEEP_CONFIGURATION_YES;
285 else
80060352 286 network->keep_configuration = KEEP_CONFIGURATION_NO;
7da377ef
SS
287 }
288
289 if (network->keep_configuration < 0)
80060352 290 network->keep_configuration = KEEP_CONFIGURATION_NO;
7da377ef 291
4bec2f23 292 LIST_FOREACH_SAFE(addresses, address, address_next, network->static_addresses)
fcbf4cb7 293 if (address_section_verify(address) < 0)
4bec2f23 294 address_free(address);
4bec2f23 295
fcbf4cb7
YW
296 LIST_FOREACH_SAFE(routes, route, route_next, network->static_routes)
297 if (route_section_verify(route, network) < 0)
4bec2f23 298 route_free(route);
0321cea7 299
c16c7808
SS
300 LIST_FOREACH_SAFE(nexthops, nexthop, nextnop_next, network->static_nexthops)
301 if (nexthop_section_verify(nexthop) < 0)
302 nexthop_free(nexthop);
303
fcbf4cb7
YW
304 LIST_FOREACH_SAFE(static_fdb_entries, fdb, fdb_next, network->static_fdb_entries)
305 if (section_is_invalid(fdb->section))
306 fdb_entry_free(fdb);
307
308 LIST_FOREACH_SAFE(neighbors, neighbor, neighbor_next, network->neighbors)
044d4b40 309 if (neighbor_section_verify(neighbor) < 0)
fcbf4cb7
YW
310 neighbor_free(neighbor);
311
312 LIST_FOREACH_SAFE(labels, label, label_next, network->address_labels)
313 if (section_is_invalid(label->section))
314 address_label_free(label);
315
316 LIST_FOREACH_SAFE(prefixes, prefix, prefix_next, network->static_prefixes)
317 if (section_is_invalid(prefix->section))
318 prefix_free(prefix);
319
95081e08
YW
320 LIST_FOREACH_SAFE(route_prefixes, route_prefix, route_prefix_next, network->static_route_prefixes)
321 if (section_is_invalid(route_prefix->section))
322 route_prefix_free(route_prefix);
714a199e 323
fcbf4cb7 324 LIST_FOREACH_SAFE(rules, rule, rule_next, network->rules)
0aabccc8 325 if (routing_policy_rule_section_verify(rule) < 0)
fcbf4cb7 326 routing_policy_rule_free(rule);
4912ab77 327
8efb93f0 328 bool has_root = false, has_clsact = false;
34658df2
YW
329 ORDERED_HASHMAP_FOREACH(tc, network->tc_by_section, i)
330 if (traffic_control_section_verify(tc, &has_root, &has_clsact) < 0)
331 traffic_control_free(tc);
8efb93f0 332
0321cea7
YW
333 return 0;
334}
335
7f06b3e1 336int network_load_one(Manager *manager, OrderedHashmap **networks, const char *filename) {
838b2f7a 337 _cleanup_free_ char *fname = NULL, *name = NULL;
35ac3b76 338 _cleanup_(network_unrefp) Network *network = NULL;
f579559b 339 _cleanup_fclose_ FILE *file = NULL;
047a0dac 340 const char *dropin_dirname;
838b2f7a 341 char *d;
f579559b
TG
342 int r;
343
bf1bc670
TA
344 assert(manager);
345 assert(filename);
346
f579559b
TG
347 file = fopen(filename, "re");
348 if (!file) {
349 if (errno == ENOENT)
350 return 0;
1e7a0e21
LP
351
352 return -errno;
f579559b
TG
353 }
354
ed88bcfb
ZJS
355 if (null_or_empty_fd(fileno(file))) {
356 log_debug("Skipping empty file: %s", filename);
6916ec29
TG
357 return 0;
358 }
359
838b2f7a
YW
360 fname = strdup(filename);
361 if (!fname)
362 return log_oom();
363
364 name = strdup(basename(filename));
365 if (!name)
366 return log_oom();
367
368 d = strrchr(name, '.');
369 if (!d)
370 return -EINVAL;
371
372 *d = '\0';
373
374 dropin_dirname = strjoina(name, ".network.d");
375
17f9c355 376 network = new(Network, 1);
f579559b
TG
377 if (!network)
378 return log_oom();
379
17f9c355 380 *network = (Network) {
838b2f7a
YW
381 .filename = TAKE_PTR(fname),
382 .name = TAKE_PTR(name),
17f9c355 383
715d398e 384 .manager = manager,
35ac3b76
YW
385 .n_ref = 1,
386
17f9c355 387 .required_for_online = true,
75cd4a5d 388 .required_operstate_for_online = LINK_OPERSTATE_RANGE_DEFAULT,
17f9c355 389 .dhcp = ADDRESS_FAMILY_NO,
7da377ef 390 .dhcp_critical = -1,
17f9c355 391 .dhcp_use_ntp = true,
299d578f 392 .dhcp_use_sip = true,
17f9c355
YW
393 .dhcp_use_dns = true,
394 .dhcp_use_hostname = true,
395 .dhcp_use_routes = true,
589397a2 396 .dhcp_use_gateway = -1,
5238e957 397 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
17f9c355 398 .dhcp_send_hostname = true,
5f3b5f19 399 .dhcp_send_release = true,
17f9c355
YW
400 /* To enable/disable RFC7844 Anonymity Profiles */
401 .dhcp_anonymize = false,
402 .dhcp_route_metric = DHCP_ROUTE_METRIC,
c9c908a6 403 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
17f9c355
YW
404 .dhcp_client_identifier = DHCP_CLIENT_ID_DUID,
405 .dhcp_route_table = RT_TABLE_MAIN,
406 .dhcp_route_table_set = false,
407 /* NOTE: from man: UseMTU=... Defaults to false*/
408 .dhcp_use_mtu = false,
409 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
410 .dhcp_use_timezone = false,
411 .rapid_commit = true,
412
1bf1bfd9 413 .dhcp6_route_metric = DHCP_ROUTE_METRIC,
caa8ca42
SS
414 .dhcp6_use_ntp = true,
415 .dhcp6_use_dns = true,
416
9efa8a3c
SS
417 .dhcp6_pd_assign_prefix = true,
418
2a71d57f
LP
419 .dhcp_server_emit[SD_DHCP_LEASE_DNS].emit = true,
420 .dhcp_server_emit[SD_DHCP_LEASE_NTP].emit = true,
421 .dhcp_server_emit[SD_DHCP_LEASE_SIP].emit = true,
422
17f9c355
YW
423 .dhcp_server_emit_router = true,
424 .dhcp_server_emit_timezone = true,
425
02e9e34b 426 .router_prefix_subnet_id = -1,
17f9c355
YW
427 .router_emit_dns = true,
428 .router_emit_domains = true,
429
430 .use_bpdu = -1,
431 .hairpin = -1,
432 .fast_leave = -1,
433 .allow_port_to_be_root = -1,
434 .unicast_flood = -1,
7f15b714 435 .multicast_flood = -1,
d3aa8b49 436 .multicast_to_unicast = -1,
7f15b714
TJ
437 .neighbor_suppression = -1,
438 .learning = -1,
1087623b
SS
439 .bridge_proxy_arp = -1,
440 .bridge_proxy_arp_wifi = -1,
17f9c355 441 .priority = LINK_BRIDGE_PORT_PRIORITY_INVALID,
0fadb2a4 442 .multicast_router = _MULTICAST_ROUTER_INVALID,
17f9c355
YW
443
444 .lldp_mode = LLDP_MODE_ROUTERS_ONLY,
445
7ece6f58 446 .dns_default_route = -1,
17f9c355
YW
447 .llmnr = RESOLVE_SUPPORT_YES,
448 .mdns = RESOLVE_SUPPORT_NO,
449 .dnssec_mode = _DNSSEC_MODE_INVALID,
450 .dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID,
451
0321cea7 452 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
2d792895 453 .link_local = _ADDRESS_FAMILY_INVALID,
6f6296b9 454 .ipv6ll_address_gen_mode = _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID,
17f9c355 455
94d76d07
YW
456 .ipv4_accept_local = -1,
457
17f9c355
YW
458 .ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_NO,
459 .ipv6_accept_ra = -1,
460 .ipv6_dad_transmits = -1,
461 .ipv6_hop_limit = -1,
462 .ipv6_proxy_ndp = -1,
463 .duid.type = _DUID_TYPE_INVALID,
464 .proxy_arp = -1,
465 .arp = -1,
466 .multicast = -1,
467 .allmulticast = -1,
468 .ipv6_accept_ra_use_dns = true,
062c2eea
SS
469 .ipv6_accept_ra_use_autonomous_prefix = true,
470 .ipv6_accept_ra_use_onlink_prefix = true,
17f9c355 471 .ipv6_accept_ra_route_table = RT_TABLE_MAIN,
d5fa3339 472 .ipv6_accept_ra_route_table_set = false,
d739fdde 473 .ipv6_accept_ra_start_dhcp6_client = true,
c423be28 474
bd0d471c
DS
475 .configure_without_carrier = false,
476 .ignore_carrier_loss = -1,
7da377ef 477 .keep_configuration = _KEEP_CONFIGURATION_INVALID,
c423be28 478 .can_triple_sampling = -1,
52aa38f1 479 .can_termination = -1,
afe42aef 480 .ip_service_type = -1,
17f9c355 481 };
f579559b 482
4f9ff96a
LP
483 r = config_parse_many(
484 filename, NETWORK_DIRS, dropin_dirname,
485 "Match\0"
486 "Link\0"
487 "Network\0"
488 "Address\0"
489 "Neighbor\0"
490 "IPv6AddressLabel\0"
491 "RoutingPolicyRule\0"
492 "Route\0"
493 "NextHop\0"
494 "DHCP\0" /* compat */
495 "DHCPv4\0"
496 "DHCPv6\0"
497 "DHCPServer\0"
498 "IPv6AcceptRA\0"
499 "IPv6NDPProxyAddress\0"
500 "Bridge\0"
501 "BridgeFDB\0"
502 "BridgeVLAN\0"
503 "IPv6PrefixDelegation\0"
504 "IPv6Prefix\0"
505 "IPv6RoutePrefix\0"
506 "LLDP\0"
507 "TrafficControlQueueingDiscipline\0"
508 "CAN\0"
509 "QDisc\0"
510 "BFIFO\0"
511 "CAKE\0"
512 "ControlledDelay\0"
513 "DeficitRoundRobinScheduler\0"
514 "DeficitRoundRobinSchedulerClass\0"
d474aa51 515 "EnhancedTransmissionSelection\0"
4f9ff96a
LP
516 "FairQueueing\0"
517 "FairQueueingControlledDelay\0"
518 "GenericRandomEarlyDetection\0"
519 "HeavyHitterFilter\0"
520 "HierarchyTokenBucket\0"
521 "HierarchyTokenBucketClass\0"
522 "NetworkEmulator\0"
b12aaee5
SS
523 "PFIFO\0"
524 "PFIFOFast\0"
525 "PFIFOHeadDrop\0"
4f9ff96a 526 "PIE\0"
b12aaee5 527 "QuickFairQueueing\0"
4d7ddaf9 528 "QuickFairQueueingClass\0"
4f9ff96a
LP
529 "StochasticFairBlue\0"
530 "StochasticFairnessQueueing\0"
531 "TokenBucketFilter\0"
532 "TrivialLinkEqualizer\0",
533 config_item_perf_lookup, network_network_gperf_lookup,
534 CONFIG_PARSE_WARN,
535 network,
536 &network->timestamp);
102bc043 537 if (r < 0)
f579559b 538 return r;
f579559b 539
add8d07d 540 network_apply_anonymize_if_set(network);
541
fa7cd711
YW
542 r = network_add_ipv4ll_route(network);
543 if (r < 0)
544 log_warning_errno(r, "%s: Failed to add IPv4LL route, ignoring: %m", network->filename);
545
5d5003ab
YW
546 r = network_add_default_route_on_device(network);
547 if (r < 0)
548 log_warning_errno(r, "%s: Failed to add default route on device, ignoring: %m",
549 network->filename);
550
7f06b3e1
YW
551 if (network_verify(network) < 0)
552 /* Ignore .network files that do not match the conditions. */
553 return 0;
554
555 r = ordered_hashmap_ensure_allocated(networks, &string_hash_ops);
dbffab87
TG
556 if (r < 0)
557 return r;
558
7f06b3e1 559 r = ordered_hashmap_put(*networks, network->name, network);
dbffab87
TG
560 if (r < 0)
561 return r;
562
f579559b 563 network = NULL;
f579559b
TG
564 return 0;
565}
566
7f06b3e1 567int network_load(Manager *manager, OrderedHashmap **networks) {
477e73b5
ZJS
568 _cleanup_strv_free_ char **files = NULL;
569 char **f;
f579559b
TG
570 int r;
571
572 assert(manager);
573
7f06b3e1 574 ordered_hashmap_clear_with_destructor(*networks, network_unref);
f579559b 575
dc0d4078 576 r = conf_files_list_strv(&files, ".network", NULL, 0, NETWORK_DIRS);
f647962d
MS
577 if (r < 0)
578 return log_error_errno(r, "Failed to enumerate network files: %m");
f579559b 579
715d398e 580 STRV_FOREACH(f, files) {
7f06b3e1 581 r = network_load_one(manager, networks, *f);
f579559b 582 if (r < 0)
be711082 583 log_error_errno(r, "Failed to load %s, ignoring: %m", *f);
f579559b
TG
584 }
585
f579559b
TG
586 return 0;
587}
588
7f06b3e1
YW
589int network_reload(Manager *manager) {
590 OrderedHashmap *new_networks = NULL;
591 Network *n, *old;
592 Iterator i;
593 int r;
594
595 assert(manager);
596
597 r = network_load(manager, &new_networks);
598 if (r < 0)
599 goto failure;
600
601 ORDERED_HASHMAP_FOREACH(n, new_networks, i) {
602 r = network_get_by_name(manager, n->name, &old);
603 if (r < 0)
604 continue; /* The .network file is new. */
605
606 if (n->timestamp != old->timestamp)
607 continue; /* The .network file is modified. */
608
609 if (!streq(n->filename, old->filename))
610 continue;
611
612 r = ordered_hashmap_replace(new_networks, old->name, old);
613 if (r < 0)
614 goto failure;
615
616 network_ref(old);
617 network_unref(n);
618 }
619
620 ordered_hashmap_free_with_destructor(manager->networks, network_unref);
621 manager->networks = new_networks;
622
623 return 0;
624
625failure:
626 ordered_hashmap_free_with_destructor(new_networks, network_unref);
627
628 return r;
629}
630
35ac3b76 631static Network *network_free(Network *network) {
a0e5c15d 632 IPv6ProxyNDPAddress *ipv6_proxy_ndp_address;
95081e08 633 RoutePrefix *route_prefix;
bce67bbe 634 RoutingPolicyRule *rule;
95081e08 635 AddressLabel *label;
bce67bbe 636 FdbEntry *fdb_entry;
e4a71bf3 637 Neighbor *neighbor;
bce67bbe 638 Address *address;
c16c7808
SS
639 NextHop *nexthop;
640 Prefix *prefix;
bce67bbe 641 Route *route;
f579559b
TG
642
643 if (!network)
35ac3b76 644 return NULL;
f579559b
TG
645
646 free(network->filename);
647
e90d0374 648 set_free_free(network->match_mac);
4bb7cc82 649 set_free_free(network->match_permanent_mac);
5256e00e
TG
650 strv_free(network->match_path);
651 strv_free(network->match_driver);
652 strv_free(network->match_type);
653 strv_free(network->match_name);
44005bfb 654 strv_free(network->match_property);
78404d22 655 strv_free(network->match_wlan_iftype);
8d968fdd 656 strv_free(network->match_ssid);
277ba8d1 657 set_free_free(network->match_bssid);
c4f58dea 658 condition_free_list(network->conditions);
f579559b
TG
659
660 free(network->description);
edb85f0d 661 free(network->dhcp_vendor_class_identifier);
7b8d23a9 662 free(network->dhcp_mudurl);
af1c0de0 663 strv_free(network->dhcp_user_class);
27cb34f5 664 free(network->dhcp_hostname);
6b000af4 665 set_free(network->dhcp_deny_listed_ip);
5bc945be 666 set_free(network->dhcp_request_options);
35f6a5cb 667 set_free(network->dhcp6_request_options);
c106cc36 668 free(network->mac);
3175a8c2 669 free(network->dhcp6_mudurl);
f37f2a6b 670 strv_free(network->dhcp6_user_class);
ed0d1b2e 671 strv_free(network->dhcp6_vendor_class);
c106cc36 672
0f3ff4ea
SS
673 if (network->dhcp_acd)
674 sd_ipv4acd_unref(network->dhcp_acd);
675
b0e39c82 676 strv_free(network->ntp);
5512a963 677 free(network->dns);
5e2a51d5
ZJS
678 ordered_set_free_free(network->search_domains);
679 ordered_set_free_free(network->route_domains);
0d4ad91d 680 strv_free(network->bind_carrier);
cdd7812b 681
5e2a51d5 682 ordered_set_free_free(network->router_search_domains);
cdd7812b 683 free(network->router_dns);
6b000af4 684 set_free_free(network->ndisc_deny_listed_prefix);
3bef724f 685
cebe1257
YW
686 free(network->bridge_name);
687 free(network->bond_name);
688 free(network->vrf_name);
689 hashmap_free_free_key(network->stacked_netdev_names);
47e2dc31 690 netdev_unref(network->bridge);
47e2dc31 691 netdev_unref(network->bond);
6cb955c6 692 netdev_unref(network->vrf);
fa6f1e54 693 hashmap_free_with_destructor(network->stacked_netdevs, netdev_unref);
326cb406 694
f048a16b 695 while ((route = network->static_routes))
f579559b
TG
696 route_free(route);
697
c16c7808
SS
698 while ((nexthop = network->static_nexthops))
699 nexthop_free(nexthop);
700
f048a16b 701 while ((address = network->static_addresses))
f579559b
TG
702 address_free(address);
703
b98b483b
AR
704 while ((fdb_entry = network->static_fdb_entries))
705 fdb_entry_free(fdb_entry);
706
a0e5c15d
FK
707 while ((ipv6_proxy_ndp_address = network->ipv6_proxy_ndp_addresses))
708 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address);
709
e4a71bf3
WKI
710 while ((neighbor = network->neighbors))
711 neighbor_free(neighbor);
712
95b74ef6
SS
713 while ((label = network->address_labels))
714 address_label_free(label);
715
057abfd8
PF
716 while ((prefix = network->static_prefixes))
717 prefix_free(prefix);
718
95081e08
YW
719 while ((route_prefix = network->static_route_prefixes))
720 route_prefix_free(route_prefix);
9be6ae77 721
bce67bbe
SS
722 while ((rule = network->rules))
723 routing_policy_rule_free(rule);
724
6ae115c1
TG
725 hashmap_free(network->addresses_by_section);
726 hashmap_free(network->routes_by_section);
c16c7808 727 hashmap_free(network->nexthops_by_section);
b98b483b 728 hashmap_free(network->fdb_entries_by_section);
e4a71bf3 729 hashmap_free(network->neighbors_by_section);
95b74ef6 730 hashmap_free(network->address_labels_by_section);
057abfd8 731 hashmap_free(network->prefixes_by_section);
9be6ae77 732 hashmap_free(network->route_prefixes_by_section);
bce67bbe 733 hashmap_free(network->rules_by_section);
34658df2 734 ordered_hashmap_free_with_destructor(network->tc_by_section, traffic_control_free);
6ae115c1 735
7f06b3e1
YW
736 if (network->manager &&
737 network->manager->duids_requesting_uuid)
738 set_remove(network->manager->duids_requesting_uuid, &network->duid);
dbffab87
TG
739
740 free(network->name);
f579559b 741
8eb9058d 742 free(network->dhcp_server_timezone);
2a71d57f
LP
743
744 for (sd_dhcp_lease_server_type t = 0; t < _SD_DHCP_LEASE_SERVER_TYPE_MAX; t++)
745 free(network->dhcp_server_emit[t].addresses);
8eb9058d 746
8a516214
LP
747 set_free_free(network->dnssec_negative_trust_anchors);
748
e9a8c550
SS
749 free(network->lldp_mud);
750
0e96961d 751 ordered_hashmap_free(network->dhcp_client_send_options);
7354900d 752 ordered_hashmap_free(network->dhcp_client_send_vendor_options);
0e96961d 753 ordered_hashmap_free(network->dhcp_server_send_options);
7354900d 754 ordered_hashmap_free(network->dhcp_server_send_vendor_options);
5f506a55 755 ordered_hashmap_free(network->ipv6_tokens);
1c3ec1cd 756 ordered_hashmap_free(network->dhcp6_client_send_options);
b4ccc5de 757 ordered_hashmap_free(network->dhcp6_client_send_vendor_options);
cb29c156 758
35ac3b76 759 return mfree(network);
f579559b
TG
760}
761
35ac3b76
YW
762DEFINE_TRIVIAL_REF_UNREF_FUNC(Network, network, network_free);
763
dbffab87
TG
764int network_get_by_name(Manager *manager, const char *name, Network **ret) {
765 Network *network;
766
767 assert(manager);
768 assert(name);
769 assert(ret);
770
715d398e 771 network = ordered_hashmap_get(manager->networks, name);
dbffab87
TG
772 if (!network)
773 return -ENOENT;
774
775 *ret = network;
776
777 return 0;
778}
779
ef62949a 780int network_get(Manager *manager, unsigned short iftype, sd_device *device,
c643bda5
YW
781 const char *ifname, char * const *alternative_names, const char *driver,
782 const struct ether_addr *mac, const struct ether_addr *permanent_mac,
78404d22
YW
783 enum nl80211_iftype wlan_iftype, const char *ssid, const struct ether_addr *bssid,
784 Network **ret) {
51517f9e 785 Network *network;
715d398e 786 Iterator i;
f579559b
TG
787
788 assert(manager);
f579559b 789 assert(ret);
af3aa302 790
715d398e 791 ORDERED_HASHMAP_FOREACH(network, manager->networks, i)
4bb7cc82
YW
792 if (net_match_config(network->match_mac, network->match_permanent_mac,
793 network->match_path, network->match_driver,
44005bfb 794 network->match_type, network->match_name, network->match_property,
78404d22 795 network->match_wlan_iftype, network->match_ssid, network->match_bssid,
c643bda5 796 device, mac, permanent_mac, driver, iftype,
4bb7cc82 797 ifname, alternative_names, wlan_iftype, ssid, bssid)) {
24c083df 798 if (network->match_name && device) {
ca6038b8
TG
799 const char *attr;
800 uint8_t name_assign_type = NET_NAME_UNKNOWN;
801
51517f9e 802 if (sd_device_get_sysattr_value(device, "name_assign_type", &attr) >= 0)
dc751688 803 (void) safe_atou8(attr, &name_assign_type);
32bc8adc
TG
804
805 if (name_assign_type == NET_NAME_ENUM)
a2fae7bb
TG
806 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
807 ifname, network->filename);
32bc8adc 808 else
a2fae7bb 809 log_debug("%s: found matching network '%s'", ifname, network->filename);
32bc8adc 810 } else
a2fae7bb 811 log_debug("%s: found matching network '%s'", ifname, network->filename);
32bc8adc 812
f579559b
TG
813 *ret = network;
814 return 0;
815 }
f579559b
TG
816
817 *ret = NULL;
818
819 return -ENOENT;
820}
821
7d342c03 822int network_apply(Network *network, Link *link) {
c4a03a56
TG
823 assert(network);
824 assert(link);
825
c9c908a6 826 link->network = network_ref(network);
f579559b 827
5512a963 828 if (network->n_dns > 0 ||
3df9bec5 829 !strv_isempty(network->ntp) ||
5e2a51d5
ZJS
830 !ordered_set_isempty(network->search_domains) ||
831 !ordered_set_isempty(network->route_domains))
84de38c5 832 link_dirty(link);
3bef724f 833
f579559b
TG
834 return 0;
835}
02b59d57 836
adfeee49 837bool network_has_static_ipv6_configurations(Network *network) {
439689c6 838 Address *address;
adfeee49
YW
839 Route *route;
840 FdbEntry *fdb;
841 Neighbor *neighbor;
439689c6
SS
842
843 assert(network);
844
adfeee49 845 LIST_FOREACH(addresses, address, network->static_addresses)
439689c6
SS
846 if (address->family == AF_INET6)
847 return true;
adfeee49
YW
848
849 LIST_FOREACH(routes, route, network->static_routes)
850 if (route->family == AF_INET6)
851 return true;
852
853 LIST_FOREACH(static_fdb_entries, fdb, network->static_fdb_entries)
854 if (fdb->family == AF_INET6)
855 return true;
856
857 LIST_FOREACH(neighbors, neighbor, network->neighbors)
858 if (neighbor->family == AF_INET6)
859 return true;
860
861 if (!LIST_IS_EMPTY(network->address_labels))
862 return true;
863
864 if (!LIST_IS_EMPTY(network->static_prefixes))
865 return true;
439689c6
SS
866
867 return false;
868}
869
cebe1257 870int config_parse_stacked_netdev(const char *unit,
02b59d57
TG
871 const char *filename,
872 unsigned line,
873 const char *section,
874 unsigned section_line,
875 const char *lvalue,
876 int ltype,
877 const char *rvalue,
878 void *data,
879 void *userdata) {
95dba435
YW
880 _cleanup_free_ char *name = NULL;
881 NetDevKind kind = ltype;
cebe1257 882 Hashmap **h = data;
02b59d57
TG
883 int r;
884
885 assert(filename);
886 assert(lvalue);
887 assert(rvalue);
888 assert(data);
95dba435
YW
889 assert(IN_SET(kind,
890 NETDEV_KIND_VLAN, NETDEV_KIND_MACVLAN, NETDEV_KIND_MACVTAP,
69c317a0 891 NETDEV_KIND_IPVLAN, NETDEV_KIND_IPVTAP, NETDEV_KIND_VXLAN,
98d20a17 892 NETDEV_KIND_L2TP, NETDEV_KIND_MACSEC, _NETDEV_KIND_TUNNEL,
893 NETDEV_KIND_XFRM));
54abf461 894
cebe1257 895 if (!ifname_valid(rvalue)) {
3772cfde
ZJS
896 log_syntax(unit, LOG_ERR, filename, line, 0,
897 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue, rvalue);
54abf461
TG
898 return 0;
899 }
900
cebe1257
YW
901 name = strdup(rvalue);
902 if (!name)
903 return log_oom();
3e570042 904
cebe1257
YW
905 r = hashmap_ensure_allocated(h, &string_hash_ops);
906 if (r < 0)
907 return log_oom();
326cb406 908
cebe1257 909 r = hashmap_put(*h, name, INT_TO_PTR(kind));
83ec4592 910 if (r < 0)
3772cfde 911 log_syntax(unit, LOG_ERR, filename, line, r,
83ec4592
ZJS
912 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name);
913 else if (r == 0)
914 log_syntax(unit, LOG_DEBUG, filename, line, r,
915 "NetDev '%s' specified twice, ignoring.", name);
916 else
917 name = NULL;
47e2dc31 918
fe6b2d55
TG
919 return 0;
920}
7951dea2 921
3df9bec5
LP
922int config_parse_domains(
923 const char *unit,
924 const char *filename,
925 unsigned line,
926 const char *section,
927 unsigned section_line,
928 const char *lvalue,
929 int ltype,
930 const char *rvalue,
931 void *data,
932 void *userdata) {
933
934 const char *p;
935 Network *n = data;
6192b846
TG
936 int r;
937
3df9bec5
LP
938 assert(n);
939 assert(lvalue);
940 assert(rvalue);
6192b846 941
3df9bec5 942 if (isempty(rvalue)) {
5e2a51d5
ZJS
943 n->search_domains = ordered_set_free_free(n->search_domains);
944 n->route_domains = ordered_set_free_free(n->route_domains);
3df9bec5
LP
945 return 0;
946 }
67272d15 947
3df9bec5
LP
948 p = rvalue;
949 for (;;) {
950 _cleanup_free_ char *w = NULL, *normalized = NULL;
951 const char *domain;
952 bool is_route;
953
954 r = extract_first_word(&p, &w, NULL, 0);
955 if (r < 0) {
ab24039f
ZJS
956 log_syntax(unit, LOG_ERR, filename, line, r,
957 "Failed to extract search or route domain, ignoring: %s", rvalue);
3df9bec5
LP
958 break;
959 }
960 if (r == 0)
961 break;
962
963 is_route = w[0] == '~';
964 domain = is_route ? w + 1 : w;
965
966 if (dns_name_is_root(domain) || streq(domain, "*")) {
ab24039f
ZJS
967 /* If the root domain appears as is, or the special token "*" is found, we'll
968 * consider this as routing domain, unconditionally. */
3df9bec5 969 is_route = true;
ab24039f
ZJS
970 domain = "."; /* make sure we don't allow empty strings, thus write the root
971 * domain as "." */
3df9bec5 972 } else {
7470cc4c 973 r = dns_name_normalize(domain, 0, &normalized);
3df9bec5 974 if (r < 0) {
ab24039f
ZJS
975 log_syntax(unit, LOG_ERR, filename, line, r,
976 "'%s' is not a valid domain name, ignoring.", domain);
3df9bec5
LP
977 continue;
978 }
979
980 domain = normalized;
981
982 if (is_localhost(domain)) {
ab24039f
ZJS
983 log_syntax(unit, LOG_ERR, filename, line, 0,
984 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
985 domain);
37de2509 986 continue;
3df9bec5 987 }
37de2509 988 }
40274ed6 989
5e2a51d5
ZJS
990 OrderedSet **set = is_route ? &n->route_domains : &n->search_domains;
991 r = ordered_set_ensure_allocated(set, &string_hash_ops);
992 if (r < 0)
993 return r;
994
995 r = ordered_set_put_strdup(*set, domain);
09451975
LP
996 if (r < 0)
997 return log_oom();
40274ed6 998 }
f15b6e5a 999
6192b846
TG
1000 return 0;
1001}
1002
60c35566 1003int config_parse_ipv6token(
7f77697a
TG
1004 const char* unit,
1005 const char *filename,
1006 unsigned line,
1007 const char *section,
1008 unsigned section_line,
1009 const char *lvalue,
1010 int ltype,
1011 const char *rvalue,
1012 void *data,
1013 void *userdata) {
1014
1015 union in_addr_union buffer;
1016 struct in6_addr *token = data;
1017 int r;
1018
1019 assert(filename);
1020 assert(lvalue);
1021 assert(rvalue);
1022 assert(token);
1023
1024 r = in_addr_from_string(AF_INET6, rvalue, &buffer);
1025 if (r < 0) {
ab24039f
ZJS
1026 log_syntax(unit, LOG_ERR, filename, line, r,
1027 "Failed to parse IPv6 token, ignoring: %s", rvalue);
7f77697a
TG
1028 return 0;
1029 }
1030
c606db69 1031 if (in_addr_is_null(AF_INET6, &buffer)) {
ab24039f
ZJS
1032 log_syntax(unit, LOG_ERR, filename, line, 0,
1033 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue);
7f77697a
TG
1034 return 0;
1035 }
1036
1037 if ((buffer.in6.s6_addr32[0] | buffer.in6.s6_addr32[1]) != 0) {
ab24039f
ZJS
1038 log_syntax(unit, LOG_ERR, filename, line, 0,
1039 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue);
7f77697a
TG
1040 return 0;
1041 }
1042
1043 *token = buffer.in6;
1044
1045 return 0;
1046}
8add5f79 1047
49092e22 1048static const char* const ipv6_privacy_extensions_table[_IPV6_PRIVACY_EXTENSIONS_MAX] = {
1f0d9695
LP
1049 [IPV6_PRIVACY_EXTENSIONS_NO] = "no",
1050 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC] = "prefer-public",
1051 [IPV6_PRIVACY_EXTENSIONS_YES] = "yes",
49092e22
SS
1052};
1053
b146ad71
YW
1054DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions, IPv6PrivacyExtensions,
1055 IPV6_PRIVACY_EXTENSIONS_YES);
49092e22
SS
1056
1057int config_parse_ipv6_privacy_extensions(
1058 const char* unit,
1059 const char *filename,
1060 unsigned line,
1061 const char *section,
1062 unsigned section_line,
1063 const char *lvalue,
1064 int ltype,
1065 const char *rvalue,
1066 void *data,
1067 void *userdata) {
1068
b146ad71 1069 IPv6PrivacyExtensions s, *ipv6_privacy_extensions = data;
49092e22
SS
1070
1071 assert(filename);
1072 assert(lvalue);
1073 assert(rvalue);
1074 assert(ipv6_privacy_extensions);
1075
b146ad71
YW
1076 s = ipv6_privacy_extensions_from_string(rvalue);
1077 if (s < 0) {
1078 if (streq(rvalue, "kernel"))
1079 s = _IPV6_PRIVACY_EXTENSIONS_INVALID;
1080 else {
1081 log_syntax(unit, LOG_ERR, filename, line, 0,
1082 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue);
1083 return 0;
49092e22 1084 }
49092e22
SS
1085 }
1086
b146ad71
YW
1087 *ipv6_privacy_extensions = s;
1088
49092e22
SS
1089 return 0;
1090}
a7d0ef44 1091
1ac608c9
LP
1092int config_parse_hostname(
1093 const char *unit,
1094 const char *filename,
1095 unsigned line,
1096 const char *section,
1097 unsigned section_line,
1098 const char *lvalue,
1099 int ltype,
1100 const char *rvalue,
1101 void *data,
1102 void *userdata) {
1103
6528693a
YW
1104 _cleanup_free_ char *hn = NULL;
1105 char **hostname = data;
a7d0ef44
SS
1106 int r;
1107
1108 assert(filename);
1109 assert(lvalue);
1110 assert(rvalue);
1111
1ac608c9 1112 r = config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &hn, userdata);
a7d0ef44
SS
1113 if (r < 0)
1114 return r;
1115
1ac608c9 1116 if (!hostname_is_valid(hn, false)) {
ab24039f
ZJS
1117 log_syntax(unit, LOG_ERR, filename, line, 0,
1118 "Hostname is not valid, ignoring assignment: %s", rvalue);
a7d0ef44
SS
1119 return 0;
1120 }
1121
6528693a
YW
1122 r = dns_name_is_valid(hn);
1123 if (r < 0) {
ab24039f
ZJS
1124 log_syntax(unit, LOG_ERR, filename, line, r,
1125 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue);
6528693a
YW
1126 return 0;
1127 }
1128 if (r == 0) {
ab24039f
ZJS
1129 log_syntax(unit, LOG_ERR, filename, line, 0,
1130 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue);
6528693a
YW
1131 return 0;
1132 }
1133
1134 return free_and_replace(*hostname, hn);
a7d0ef44 1135}
8eb9058d
LP
1136
1137int config_parse_timezone(
1138 const char *unit,
1139 const char *filename,
1140 unsigned line,
1141 const char *section,
1142 unsigned section_line,
1143 const char *lvalue,
1144 int ltype,
1145 const char *rvalue,
1146 void *data,
1147 void *userdata) {
1148
19f9e4e2
YW
1149 _cleanup_free_ char *tz = NULL;
1150 char **datap = data;
8eb9058d
LP
1151 int r;
1152
1153 assert(filename);
1154 assert(lvalue);
1155 assert(rvalue);
1156
1157 r = config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &tz, userdata);
1158 if (r < 0)
1159 return r;
1160
089fb865 1161 if (!timezone_is_valid(tz, LOG_ERR)) {
ab24039f
ZJS
1162 log_syntax(unit, LOG_ERR, filename, line, 0,
1163 "Timezone is not valid, ignoring assignment: %s", rvalue);
8eb9058d
LP
1164 return 0;
1165 }
1166
19f9e4e2 1167 return free_and_replace(*datap, tz);
8eb9058d 1168}
1a04db0f 1169
53253824
SS
1170int config_parse_dns(
1171 const char *unit,
1172 const char *filename,
1173 unsigned line,
1174 const char *section,
1175 unsigned section_line,
1176 const char *lvalue,
1177 int ltype,
1178 const char *rvalue,
1179 void *data,
1180 void *userdata) {
1181
1182 Network *n = userdata;
1183 int r;
1184
1185 assert(filename);
1186 assert(lvalue);
1187 assert(rvalue);
1188
1189 for (;;) {
1190 _cleanup_free_ char *w = NULL;
1191 union in_addr_union a;
5512a963 1192 struct in_addr_data *m;
53253824
SS
1193 int family;
1194
5512a963 1195 r = extract_first_word(&rvalue, &w, NULL, 0);
53253824
SS
1196 if (r == -ENOMEM)
1197 return log_oom();
1198 if (r < 0) {
ab24039f
ZJS
1199 log_syntax(unit, LOG_ERR, filename, line, r,
1200 "Invalid syntax, ignoring: %s", rvalue);
53253824
SS
1201 break;
1202 }
5512a963
LP
1203 if (r == 0)
1204 break;
53253824
SS
1205
1206 r = in_addr_from_string_auto(w, &family, &a);
1207 if (r < 0) {
ab24039f
ZJS
1208 log_syntax(unit, LOG_ERR, filename, line, r,
1209 "Failed to parse dns server address, ignoring: %s", w);
53253824
SS
1210 continue;
1211 }
1212
62d74c78 1213 m = reallocarray(n->dns, n->n_dns + 1, sizeof(struct in_addr_data));
5512a963 1214 if (!m)
53253824
SS
1215 return log_oom();
1216
5512a963
LP
1217 m[n->n_dns++] = (struct in_addr_data) {
1218 .family = family,
1219 .address = a,
1220 };
1221
1222 n->dns = m;
53253824
SS
1223 }
1224
1225 return 0;
1226}
1227
8a516214
LP
1228int config_parse_dnssec_negative_trust_anchors(
1229 const char *unit,
1230 const char *filename,
1231 unsigned line,
1232 const char *section,
1233 unsigned section_line,
1234 const char *lvalue,
1235 int ltype,
1236 const char *rvalue,
1237 void *data,
1238 void *userdata) {
1239
1240 const char *p = rvalue;
1241 Network *n = data;
1242 int r;
1243
3df9bec5 1244 assert(n);
8a516214
LP
1245 assert(lvalue);
1246 assert(rvalue);
1247
1248 if (isempty(rvalue)) {
1249 n->dnssec_negative_trust_anchors = set_free_free(n->dnssec_negative_trust_anchors);
1250 return 0;
1251 }
1252
1253 for (;;) {
1254 _cleanup_free_ char *w = NULL;
1255
1256 r = extract_first_word(&p, &w, NULL, 0);
1257 if (r < 0) {
ab24039f
ZJS
1258 log_syntax(unit, LOG_ERR, filename, line, r,
1259 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue);
8a516214
LP
1260 break;
1261 }
1262 if (r == 0)
1263 break;
1264
1265 r = dns_name_is_valid(w);
1266 if (r <= 0) {
ab24039f
ZJS
1267 log_syntax(unit, LOG_ERR, filename, line, r,
1268 "%s is not a valid domain name, ignoring.", w);
8a516214
LP
1269 continue;
1270 }
1271
35e601d4 1272 r = set_ensure_consume(&n->dnssec_negative_trust_anchors, &dns_name_hash_ops, TAKE_PTR(w));
8a516214
LP
1273 if (r < 0)
1274 return log_oom();
8a516214
LP
1275 }
1276
1277 return 0;
1278}
b2a81c0b 1279
26575990
LP
1280int config_parse_ntp(
1281 const char *unit,
1282 const char *filename,
1283 unsigned line,
1284 const char *section,
1285 unsigned section_line,
1286 const char *lvalue,
1287 int ltype,
1288 const char *rvalue,
1289 void *data,
1290 void *userdata) {
1291
1292 char ***l = data;
1293 int r;
1294
1295 assert(l);
1296 assert(lvalue);
1297 assert(rvalue);
1298
1299 if (isempty(rvalue)) {
1300 *l = strv_free(*l);
1301 return 0;
1302 }
1303
1304 for (;;) {
1305 _cleanup_free_ char *w = NULL;
1306
1307 r = extract_first_word(&rvalue, &w, NULL, 0);
1308 if (r == -ENOMEM)
1309 return log_oom();
1310 if (r < 0) {
ab24039f
ZJS
1311 log_syntax(unit, LOG_ERR, filename, line, r,
1312 "Failed to extract NTP server name, ignoring: %s", rvalue);
26575990
LP
1313 break;
1314 }
1315 if (r == 0)
1316 break;
1317
1318 r = dns_name_is_valid_or_address(w);
1319 if (r <= 0) {
ab24039f
ZJS
1320 log_syntax(unit, LOG_ERR, filename, line, r,
1321 "%s is not a valid domain name or IP address, ignoring.", w);
26575990 1322 continue;
af1c0de0
SS
1323 }
1324
c448459d
ZJS
1325 if (strv_length(*l) > MAX_NTP_SERVERS) {
1326 log_syntax(unit, LOG_WARNING, filename, line, 0,
1327 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1328 MAX_NTP_SERVERS, w);
1329 break;
1330 }
1331
1332 r = strv_consume(l, TAKE_PTR(w));
af1c0de0
SS
1333 if (r < 0)
1334 return log_oom();
af1c0de0
SS
1335 }
1336
1337 return 0;
1338}
1339
4ac77d63
YW
1340int config_parse_required_for_online(
1341 const char *unit,
1342 const char *filename,
1343 unsigned line,
1344 const char *section,
1345 unsigned section_line,
1346 const char *lvalue,
1347 int ltype,
1348 const char *rvalue,
1349 void *data,
1350 void *userdata) {
1351
1352 Network *network = data;
75cd4a5d 1353 LinkOperationalStateRange range;
4ac77d63
YW
1354 bool required = true;
1355 int r;
1356
1357 if (isempty(rvalue)) {
1358 network->required_for_online = true;
75cd4a5d 1359 network->required_operstate_for_online = LINK_OPERSTATE_RANGE_DEFAULT;
4ac77d63
YW
1360 return 0;
1361 }
1362
75cd4a5d
DDM
1363 r = parse_operational_state_range(rvalue, &range);
1364 if (r < 0) {
4ac77d63
YW
1365 r = parse_boolean(rvalue);
1366 if (r < 0) {
1367 log_syntax(unit, LOG_ERR, filename, line, r,
1368 "Failed to parse %s= setting, ignoring assignment: %s",
1369 lvalue, rvalue);
1370 return 0;
1371 }
1372
1373 required = r;
75cd4a5d 1374 range = LINK_OPERSTATE_RANGE_DEFAULT;
4ac77d63
YW
1375 }
1376
1377 network->required_for_online = required;
75cd4a5d 1378 network->required_operstate_for_online = range;
4ac77d63
YW
1379
1380 return 0;
1381}
7da377ef
SS
1382
1383DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration, keep_configuration, KeepConfiguration,
1384 "Failed to parse KeepConfiguration= setting");
1385
1386static const char* const keep_configuration_table[_KEEP_CONFIGURATION_MAX] = {
95355a28
YW
1387 [KEEP_CONFIGURATION_NO] = "no",
1388 [KEEP_CONFIGURATION_DHCP_ON_STOP] = "dhcp-on-stop",
1389 [KEEP_CONFIGURATION_DHCP] = "dhcp",
1390 [KEEP_CONFIGURATION_STATIC] = "static",
1391 [KEEP_CONFIGURATION_YES] = "yes",
7da377ef
SS
1392};
1393
1394DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration, KeepConfiguration, KEEP_CONFIGURATION_YES);
6f6296b9
YW
1395
1396static const char* const ipv6_link_local_address_gen_mode_table[_IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_MAX] = {
1397 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_EUI64] = "eui64",
1398 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE] = "none",
1399 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY] = "stable-privacy",
1400 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_RANDOM] = "random",
1401};
1402
1403DEFINE_STRING_TABLE_LOOKUP(ipv6_link_local_address_gen_mode, IPv6LinkLocalAddressGenMode);
1404DEFINE_CONFIG_PARSE_ENUM(config_parse_ipv6_link_local_address_gen_mode, ipv6_link_local_address_gen_mode, IPv6LinkLocalAddressGenMode, "Failed to parse IPv6 link local address generation mode");