]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-network.c
Merge pull request #16061 from filbranden/standalone1
[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
17f9c355
YW
419 .dhcp_server_emit_dns = true,
420 .dhcp_server_emit_ntp = true,
299d578f 421 .dhcp_server_emit_sip = true,
17f9c355
YW
422 .dhcp_server_emit_router = true,
423 .dhcp_server_emit_timezone = true,
424
02e9e34b 425 .router_prefix_subnet_id = -1,
17f9c355
YW
426 .router_emit_dns = true,
427 .router_emit_domains = true,
428
429 .use_bpdu = -1,
430 .hairpin = -1,
431 .fast_leave = -1,
432 .allow_port_to_be_root = -1,
433 .unicast_flood = -1,
7f15b714 434 .multicast_flood = -1,
d3aa8b49 435 .multicast_to_unicast = -1,
7f15b714
TJ
436 .neighbor_suppression = -1,
437 .learning = -1,
1087623b
SS
438 .bridge_proxy_arp = -1,
439 .bridge_proxy_arp_wifi = -1,
17f9c355 440 .priority = LINK_BRIDGE_PORT_PRIORITY_INVALID,
0fadb2a4 441 .multicast_router = _MULTICAST_ROUTER_INVALID,
17f9c355
YW
442
443 .lldp_mode = LLDP_MODE_ROUTERS_ONLY,
444
7ece6f58 445 .dns_default_route = -1,
17f9c355
YW
446 .llmnr = RESOLVE_SUPPORT_YES,
447 .mdns = RESOLVE_SUPPORT_NO,
448 .dnssec_mode = _DNSSEC_MODE_INVALID,
449 .dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID,
450
0321cea7 451 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
2d792895 452 .link_local = _ADDRESS_FAMILY_INVALID,
17f9c355 453
94d76d07
YW
454 .ipv4_accept_local = -1,
455
17f9c355
YW
456 .ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_NO,
457 .ipv6_accept_ra = -1,
458 .ipv6_dad_transmits = -1,
459 .ipv6_hop_limit = -1,
460 .ipv6_proxy_ndp = -1,
461 .duid.type = _DUID_TYPE_INVALID,
462 .proxy_arp = -1,
463 .arp = -1,
464 .multicast = -1,
465 .allmulticast = -1,
466 .ipv6_accept_ra_use_dns = true,
062c2eea
SS
467 .ipv6_accept_ra_use_autonomous_prefix = true,
468 .ipv6_accept_ra_use_onlink_prefix = true,
17f9c355 469 .ipv6_accept_ra_route_table = RT_TABLE_MAIN,
d5fa3339 470 .ipv6_accept_ra_route_table_set = false,
d739fdde 471 .ipv6_accept_ra_start_dhcp6_client = true,
c423be28 472
bd0d471c
DS
473 .configure_without_carrier = false,
474 .ignore_carrier_loss = -1,
7da377ef 475 .keep_configuration = _KEEP_CONFIGURATION_INVALID,
a6f1848a 476 .ipv6_address_gen_mode = _LINK_IPV6_ADDRESS_GEN_MODE_INVALID,
c423be28 477 .can_triple_sampling = -1,
52aa38f1 478 .can_termination = -1,
afe42aef 479 .ip_service_type = -1,
17f9c355 480 };
f579559b 481
4f9ff96a
LP
482 r = config_parse_many(
483 filename, NETWORK_DIRS, dropin_dirname,
484 "Match\0"
485 "Link\0"
486 "Network\0"
487 "Address\0"
488 "Neighbor\0"
489 "IPv6AddressLabel\0"
490 "RoutingPolicyRule\0"
491 "Route\0"
492 "NextHop\0"
493 "DHCP\0" /* compat */
494 "DHCPv4\0"
495 "DHCPv6\0"
496 "DHCPServer\0"
497 "IPv6AcceptRA\0"
498 "IPv6NDPProxyAddress\0"
499 "Bridge\0"
500 "BridgeFDB\0"
501 "BridgeVLAN\0"
502 "IPv6PrefixDelegation\0"
503 "IPv6Prefix\0"
504 "IPv6RoutePrefix\0"
505 "LLDP\0"
506 "TrafficControlQueueingDiscipline\0"
507 "CAN\0"
508 "QDisc\0"
509 "BFIFO\0"
510 "CAKE\0"
511 "ControlledDelay\0"
512 "DeficitRoundRobinScheduler\0"
513 "DeficitRoundRobinSchedulerClass\0"
4f9ff96a
LP
514 "FairQueueing\0"
515 "FairQueueingControlledDelay\0"
516 "GenericRandomEarlyDetection\0"
517 "HeavyHitterFilter\0"
518 "HierarchyTokenBucket\0"
519 "HierarchyTokenBucketClass\0"
520 "NetworkEmulator\0"
b12aaee5
SS
521 "PFIFO\0"
522 "PFIFOFast\0"
523 "PFIFOHeadDrop\0"
4f9ff96a 524 "PIE\0"
b12aaee5 525 "QuickFairQueueing\0"
4d7ddaf9 526 "QuickFairQueueingClass\0"
4f9ff96a
LP
527 "StochasticFairBlue\0"
528 "StochasticFairnessQueueing\0"
529 "TokenBucketFilter\0"
530 "TrivialLinkEqualizer\0",
531 config_item_perf_lookup, network_network_gperf_lookup,
532 CONFIG_PARSE_WARN,
533 network,
534 &network->timestamp);
102bc043 535 if (r < 0)
f579559b 536 return r;
f579559b 537
add8d07d 538 network_apply_anonymize_if_set(network);
539
fa7cd711
YW
540 r = network_add_ipv4ll_route(network);
541 if (r < 0)
542 log_warning_errno(r, "%s: Failed to add IPv4LL route, ignoring: %m", network->filename);
543
5d5003ab
YW
544 r = network_add_default_route_on_device(network);
545 if (r < 0)
546 log_warning_errno(r, "%s: Failed to add default route on device, ignoring: %m",
547 network->filename);
548
7f06b3e1
YW
549 if (network_verify(network) < 0)
550 /* Ignore .network files that do not match the conditions. */
551 return 0;
552
553 r = ordered_hashmap_ensure_allocated(networks, &string_hash_ops);
dbffab87
TG
554 if (r < 0)
555 return r;
556
7f06b3e1 557 r = ordered_hashmap_put(*networks, network->name, network);
dbffab87
TG
558 if (r < 0)
559 return r;
560
f579559b 561 network = NULL;
f579559b
TG
562 return 0;
563}
564
7f06b3e1 565int network_load(Manager *manager, OrderedHashmap **networks) {
477e73b5
ZJS
566 _cleanup_strv_free_ char **files = NULL;
567 char **f;
f579559b
TG
568 int r;
569
570 assert(manager);
571
7f06b3e1 572 ordered_hashmap_clear_with_destructor(*networks, network_unref);
f579559b 573
dc0d4078 574 r = conf_files_list_strv(&files, ".network", NULL, 0, NETWORK_DIRS);
f647962d
MS
575 if (r < 0)
576 return log_error_errno(r, "Failed to enumerate network files: %m");
f579559b 577
715d398e 578 STRV_FOREACH(f, files) {
7f06b3e1 579 r = network_load_one(manager, networks, *f);
f579559b 580 if (r < 0)
be711082 581 log_error_errno(r, "Failed to load %s, ignoring: %m", *f);
f579559b
TG
582 }
583
f579559b
TG
584 return 0;
585}
586
7f06b3e1
YW
587int network_reload(Manager *manager) {
588 OrderedHashmap *new_networks = NULL;
589 Network *n, *old;
590 Iterator i;
591 int r;
592
593 assert(manager);
594
595 r = network_load(manager, &new_networks);
596 if (r < 0)
597 goto failure;
598
599 ORDERED_HASHMAP_FOREACH(n, new_networks, i) {
600 r = network_get_by_name(manager, n->name, &old);
601 if (r < 0)
602 continue; /* The .network file is new. */
603
604 if (n->timestamp != old->timestamp)
605 continue; /* The .network file is modified. */
606
607 if (!streq(n->filename, old->filename))
608 continue;
609
610 r = ordered_hashmap_replace(new_networks, old->name, old);
611 if (r < 0)
612 goto failure;
613
614 network_ref(old);
615 network_unref(n);
616 }
617
618 ordered_hashmap_free_with_destructor(manager->networks, network_unref);
619 manager->networks = new_networks;
620
621 return 0;
622
623failure:
624 ordered_hashmap_free_with_destructor(new_networks, network_unref);
625
626 return r;
627}
628
35ac3b76 629static Network *network_free(Network *network) {
a0e5c15d 630 IPv6ProxyNDPAddress *ipv6_proxy_ndp_address;
95081e08 631 RoutePrefix *route_prefix;
bce67bbe 632 RoutingPolicyRule *rule;
95081e08 633 AddressLabel *label;
bce67bbe 634 FdbEntry *fdb_entry;
e4a71bf3 635 Neighbor *neighbor;
bce67bbe 636 Address *address;
c16c7808
SS
637 NextHop *nexthop;
638 Prefix *prefix;
bce67bbe 639 Route *route;
f579559b
TG
640
641 if (!network)
35ac3b76 642 return NULL;
f579559b
TG
643
644 free(network->filename);
645
e90d0374 646 set_free_free(network->match_mac);
4bb7cc82 647 set_free_free(network->match_permanent_mac);
5256e00e
TG
648 strv_free(network->match_path);
649 strv_free(network->match_driver);
650 strv_free(network->match_type);
651 strv_free(network->match_name);
44005bfb 652 strv_free(network->match_property);
78404d22 653 strv_free(network->match_wlan_iftype);
8d968fdd 654 strv_free(network->match_ssid);
277ba8d1 655 set_free_free(network->match_bssid);
c4f58dea 656 condition_free_list(network->conditions);
f579559b
TG
657
658 free(network->description);
edb85f0d 659 free(network->dhcp_vendor_class_identifier);
7b8d23a9 660 free(network->dhcp_mudurl);
af1c0de0 661 strv_free(network->dhcp_user_class);
27cb34f5 662 free(network->dhcp_hostname);
727b5734 663 set_free(network->dhcp_black_listed_ip);
5bc945be 664 set_free(network->dhcp_request_options);
35f6a5cb 665 set_free(network->dhcp6_request_options);
c106cc36 666 free(network->mac);
3175a8c2 667 free(network->dhcp6_mudurl);
f37f2a6b 668 strv_free(network->dhcp6_user_class);
ed0d1b2e 669 strv_free(network->dhcp6_vendor_class);
c106cc36 670
0f3ff4ea
SS
671 if (network->dhcp_acd)
672 sd_ipv4acd_unref(network->dhcp_acd);
673
b0e39c82 674 strv_free(network->ntp);
5512a963 675 free(network->dns);
299d578f 676 strv_free(network->sip);
f6269fe7 677 strv_free(network->smtp);
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);
e520ce64 684 set_free_free(network->ndisc_black_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);
1a04db0f
LP
743 free(network->dhcp_server_dns);
744 free(network->dhcp_server_ntp);
299d578f 745 free(network->dhcp_server_sip);
433e14fd
YW
746 free(network->dhcp_server_pop3);
747 free(network->dhcp_server_smtp);
748 free(network->dhcp_server_lpr);
8eb9058d 749
8a516214
LP
750 set_free_free(network->dnssec_negative_trust_anchors);
751
e9a8c550
SS
752 free(network->lldp_mud);
753
0e96961d 754 ordered_hashmap_free(network->dhcp_client_send_options);
7354900d 755 ordered_hashmap_free(network->dhcp_client_send_vendor_options);
0e96961d 756 ordered_hashmap_free(network->dhcp_server_send_options);
7354900d 757 ordered_hashmap_free(network->dhcp_server_send_vendor_options);
5f506a55 758 ordered_hashmap_free(network->ipv6_tokens);
1c3ec1cd 759 ordered_hashmap_free(network->dhcp6_client_send_options);
b4ccc5de 760 ordered_hashmap_free(network->dhcp6_client_send_vendor_options);
cb29c156 761
35ac3b76 762 return mfree(network);
f579559b
TG
763}
764
35ac3b76
YW
765DEFINE_TRIVIAL_REF_UNREF_FUNC(Network, network, network_free);
766
dbffab87
TG
767int network_get_by_name(Manager *manager, const char *name, Network **ret) {
768 Network *network;
769
770 assert(manager);
771 assert(name);
772 assert(ret);
773
715d398e 774 network = ordered_hashmap_get(manager->networks, name);
dbffab87
TG
775 if (!network)
776 return -ENOENT;
777
778 *ret = network;
779
780 return 0;
781}
782
ef62949a 783int network_get(Manager *manager, unsigned short iftype, sd_device *device,
c643bda5
YW
784 const char *ifname, char * const *alternative_names, const char *driver,
785 const struct ether_addr *mac, const struct ether_addr *permanent_mac,
78404d22
YW
786 enum nl80211_iftype wlan_iftype, const char *ssid, const struct ether_addr *bssid,
787 Network **ret) {
51517f9e 788 Network *network;
715d398e 789 Iterator i;
f579559b
TG
790
791 assert(manager);
f579559b 792 assert(ret);
af3aa302 793
715d398e 794 ORDERED_HASHMAP_FOREACH(network, manager->networks, i)
4bb7cc82
YW
795 if (net_match_config(network->match_mac, network->match_permanent_mac,
796 network->match_path, network->match_driver,
44005bfb 797 network->match_type, network->match_name, network->match_property,
78404d22 798 network->match_wlan_iftype, network->match_ssid, network->match_bssid,
c643bda5 799 device, mac, permanent_mac, driver, iftype,
4bb7cc82 800 ifname, alternative_names, wlan_iftype, ssid, bssid)) {
24c083df 801 if (network->match_name && device) {
ca6038b8
TG
802 const char *attr;
803 uint8_t name_assign_type = NET_NAME_UNKNOWN;
804
51517f9e 805 if (sd_device_get_sysattr_value(device, "name_assign_type", &attr) >= 0)
dc751688 806 (void) safe_atou8(attr, &name_assign_type);
32bc8adc
TG
807
808 if (name_assign_type == NET_NAME_ENUM)
a2fae7bb
TG
809 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
810 ifname, network->filename);
32bc8adc 811 else
a2fae7bb 812 log_debug("%s: found matching network '%s'", ifname, network->filename);
32bc8adc 813 } else
a2fae7bb 814 log_debug("%s: found matching network '%s'", ifname, network->filename);
32bc8adc 815
f579559b
TG
816 *ret = network;
817 return 0;
818 }
f579559b
TG
819
820 *ret = NULL;
821
822 return -ENOENT;
823}
824
7d342c03 825int network_apply(Network *network, Link *link) {
c4a03a56
TG
826 assert(network);
827 assert(link);
828
c9c908a6 829 link->network = network_ref(network);
f579559b 830
5512a963 831 if (network->n_dns > 0 ||
3df9bec5 832 !strv_isempty(network->ntp) ||
5e2a51d5
ZJS
833 !ordered_set_isempty(network->search_domains) ||
834 !ordered_set_isempty(network->route_domains))
84de38c5 835 link_dirty(link);
3bef724f 836
f579559b
TG
837 return 0;
838}
02b59d57 839
adfeee49 840bool network_has_static_ipv6_configurations(Network *network) {
439689c6 841 Address *address;
adfeee49
YW
842 Route *route;
843 FdbEntry *fdb;
844 Neighbor *neighbor;
439689c6
SS
845
846 assert(network);
847
adfeee49 848 LIST_FOREACH(addresses, address, network->static_addresses)
439689c6
SS
849 if (address->family == AF_INET6)
850 return true;
adfeee49
YW
851
852 LIST_FOREACH(routes, route, network->static_routes)
853 if (route->family == AF_INET6)
854 return true;
855
856 LIST_FOREACH(static_fdb_entries, fdb, network->static_fdb_entries)
857 if (fdb->family == AF_INET6)
858 return true;
859
860 LIST_FOREACH(neighbors, neighbor, network->neighbors)
861 if (neighbor->family == AF_INET6)
862 return true;
863
864 if (!LIST_IS_EMPTY(network->address_labels))
865 return true;
866
867 if (!LIST_IS_EMPTY(network->static_prefixes))
868 return true;
439689c6
SS
869
870 return false;
871}
872
cebe1257 873int config_parse_stacked_netdev(const char *unit,
02b59d57
TG
874 const char *filename,
875 unsigned line,
876 const char *section,
877 unsigned section_line,
878 const char *lvalue,
879 int ltype,
880 const char *rvalue,
881 void *data,
882 void *userdata) {
95dba435
YW
883 _cleanup_free_ char *name = NULL;
884 NetDevKind kind = ltype;
cebe1257 885 Hashmap **h = data;
02b59d57
TG
886 int r;
887
888 assert(filename);
889 assert(lvalue);
890 assert(rvalue);
891 assert(data);
95dba435
YW
892 assert(IN_SET(kind,
893 NETDEV_KIND_VLAN, NETDEV_KIND_MACVLAN, NETDEV_KIND_MACVTAP,
69c317a0 894 NETDEV_KIND_IPVLAN, NETDEV_KIND_IPVTAP, NETDEV_KIND_VXLAN,
98d20a17 895 NETDEV_KIND_L2TP, NETDEV_KIND_MACSEC, _NETDEV_KIND_TUNNEL,
896 NETDEV_KIND_XFRM));
54abf461 897
cebe1257 898 if (!ifname_valid(rvalue)) {
3772cfde
ZJS
899 log_syntax(unit, LOG_ERR, filename, line, 0,
900 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue, rvalue);
54abf461
TG
901 return 0;
902 }
903
cebe1257
YW
904 name = strdup(rvalue);
905 if (!name)
906 return log_oom();
3e570042 907
cebe1257
YW
908 r = hashmap_ensure_allocated(h, &string_hash_ops);
909 if (r < 0)
910 return log_oom();
326cb406 911
cebe1257 912 r = hashmap_put(*h, name, INT_TO_PTR(kind));
83ec4592 913 if (r < 0)
3772cfde 914 log_syntax(unit, LOG_ERR, filename, line, r,
83ec4592
ZJS
915 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name);
916 else if (r == 0)
917 log_syntax(unit, LOG_DEBUG, filename, line, r,
918 "NetDev '%s' specified twice, ignoring.", name);
919 else
920 name = NULL;
47e2dc31 921
fe6b2d55
TG
922 return 0;
923}
7951dea2 924
3df9bec5
LP
925int config_parse_domains(
926 const char *unit,
927 const char *filename,
928 unsigned line,
929 const char *section,
930 unsigned section_line,
931 const char *lvalue,
932 int ltype,
933 const char *rvalue,
934 void *data,
935 void *userdata) {
936
937 const char *p;
938 Network *n = data;
6192b846
TG
939 int r;
940
3df9bec5
LP
941 assert(n);
942 assert(lvalue);
943 assert(rvalue);
6192b846 944
3df9bec5 945 if (isempty(rvalue)) {
5e2a51d5
ZJS
946 n->search_domains = ordered_set_free_free(n->search_domains);
947 n->route_domains = ordered_set_free_free(n->route_domains);
3df9bec5
LP
948 return 0;
949 }
67272d15 950
3df9bec5
LP
951 p = rvalue;
952 for (;;) {
953 _cleanup_free_ char *w = NULL, *normalized = NULL;
954 const char *domain;
955 bool is_route;
956
957 r = extract_first_word(&p, &w, NULL, 0);
958 if (r < 0) {
ab24039f
ZJS
959 log_syntax(unit, LOG_ERR, filename, line, r,
960 "Failed to extract search or route domain, ignoring: %s", rvalue);
3df9bec5
LP
961 break;
962 }
963 if (r == 0)
964 break;
965
966 is_route = w[0] == '~';
967 domain = is_route ? w + 1 : w;
968
969 if (dns_name_is_root(domain) || streq(domain, "*")) {
ab24039f
ZJS
970 /* If the root domain appears as is, or the special token "*" is found, we'll
971 * consider this as routing domain, unconditionally. */
3df9bec5 972 is_route = true;
ab24039f
ZJS
973 domain = "."; /* make sure we don't allow empty strings, thus write the root
974 * domain as "." */
3df9bec5 975 } else {
7470cc4c 976 r = dns_name_normalize(domain, 0, &normalized);
3df9bec5 977 if (r < 0) {
ab24039f
ZJS
978 log_syntax(unit, LOG_ERR, filename, line, r,
979 "'%s' is not a valid domain name, ignoring.", domain);
3df9bec5
LP
980 continue;
981 }
982
983 domain = normalized;
984
985 if (is_localhost(domain)) {
ab24039f
ZJS
986 log_syntax(unit, LOG_ERR, filename, line, 0,
987 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
988 domain);
37de2509 989 continue;
3df9bec5 990 }
37de2509 991 }
40274ed6 992
5e2a51d5
ZJS
993 OrderedSet **set = is_route ? &n->route_domains : &n->search_domains;
994 r = ordered_set_ensure_allocated(set, &string_hash_ops);
995 if (r < 0)
996 return r;
997
998 r = ordered_set_put_strdup(*set, domain);
09451975
LP
999 if (r < 0)
1000 return log_oom();
40274ed6 1001 }
f15b6e5a 1002
6192b846
TG
1003 return 0;
1004}
1005
60c35566 1006int config_parse_ipv6token(
7f77697a
TG
1007 const char* unit,
1008 const char *filename,
1009 unsigned line,
1010 const char *section,
1011 unsigned section_line,
1012 const char *lvalue,
1013 int ltype,
1014 const char *rvalue,
1015 void *data,
1016 void *userdata) {
1017
1018 union in_addr_union buffer;
1019 struct in6_addr *token = data;
1020 int r;
1021
1022 assert(filename);
1023 assert(lvalue);
1024 assert(rvalue);
1025 assert(token);
1026
1027 r = in_addr_from_string(AF_INET6, rvalue, &buffer);
1028 if (r < 0) {
ab24039f
ZJS
1029 log_syntax(unit, LOG_ERR, filename, line, r,
1030 "Failed to parse IPv6 token, ignoring: %s", rvalue);
7f77697a
TG
1031 return 0;
1032 }
1033
c606db69 1034 if (in_addr_is_null(AF_INET6, &buffer)) {
ab24039f
ZJS
1035 log_syntax(unit, LOG_ERR, filename, line, 0,
1036 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue);
7f77697a
TG
1037 return 0;
1038 }
1039
1040 if ((buffer.in6.s6_addr32[0] | buffer.in6.s6_addr32[1]) != 0) {
ab24039f
ZJS
1041 log_syntax(unit, LOG_ERR, filename, line, 0,
1042 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue);
7f77697a
TG
1043 return 0;
1044 }
1045
1046 *token = buffer.in6;
1047
1048 return 0;
1049}
8add5f79 1050
49092e22 1051static const char* const ipv6_privacy_extensions_table[_IPV6_PRIVACY_EXTENSIONS_MAX] = {
1f0d9695
LP
1052 [IPV6_PRIVACY_EXTENSIONS_NO] = "no",
1053 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC] = "prefer-public",
1054 [IPV6_PRIVACY_EXTENSIONS_YES] = "yes",
49092e22
SS
1055};
1056
b146ad71
YW
1057DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions, IPv6PrivacyExtensions,
1058 IPV6_PRIVACY_EXTENSIONS_YES);
49092e22
SS
1059
1060int config_parse_ipv6_privacy_extensions(
1061 const char* unit,
1062 const char *filename,
1063 unsigned line,
1064 const char *section,
1065 unsigned section_line,
1066 const char *lvalue,
1067 int ltype,
1068 const char *rvalue,
1069 void *data,
1070 void *userdata) {
1071
b146ad71 1072 IPv6PrivacyExtensions s, *ipv6_privacy_extensions = data;
49092e22
SS
1073
1074 assert(filename);
1075 assert(lvalue);
1076 assert(rvalue);
1077 assert(ipv6_privacy_extensions);
1078
b146ad71
YW
1079 s = ipv6_privacy_extensions_from_string(rvalue);
1080 if (s < 0) {
1081 if (streq(rvalue, "kernel"))
1082 s = _IPV6_PRIVACY_EXTENSIONS_INVALID;
1083 else {
1084 log_syntax(unit, LOG_ERR, filename, line, 0,
1085 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue);
1086 return 0;
49092e22 1087 }
49092e22
SS
1088 }
1089
b146ad71
YW
1090 *ipv6_privacy_extensions = s;
1091
49092e22
SS
1092 return 0;
1093}
a7d0ef44 1094
1ac608c9
LP
1095int config_parse_hostname(
1096 const char *unit,
1097 const char *filename,
1098 unsigned line,
1099 const char *section,
1100 unsigned section_line,
1101 const char *lvalue,
1102 int ltype,
1103 const char *rvalue,
1104 void *data,
1105 void *userdata) {
1106
6528693a
YW
1107 _cleanup_free_ char *hn = NULL;
1108 char **hostname = data;
a7d0ef44
SS
1109 int r;
1110
1111 assert(filename);
1112 assert(lvalue);
1113 assert(rvalue);
1114
1ac608c9 1115 r = config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &hn, userdata);
a7d0ef44
SS
1116 if (r < 0)
1117 return r;
1118
1ac608c9 1119 if (!hostname_is_valid(hn, false)) {
ab24039f
ZJS
1120 log_syntax(unit, LOG_ERR, filename, line, 0,
1121 "Hostname is not valid, ignoring assignment: %s", rvalue);
a7d0ef44
SS
1122 return 0;
1123 }
1124
6528693a
YW
1125 r = dns_name_is_valid(hn);
1126 if (r < 0) {
ab24039f
ZJS
1127 log_syntax(unit, LOG_ERR, filename, line, r,
1128 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue);
6528693a
YW
1129 return 0;
1130 }
1131 if (r == 0) {
ab24039f
ZJS
1132 log_syntax(unit, LOG_ERR, filename, line, 0,
1133 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue);
6528693a
YW
1134 return 0;
1135 }
1136
1137 return free_and_replace(*hostname, hn);
a7d0ef44 1138}
8eb9058d
LP
1139
1140int config_parse_timezone(
1141 const char *unit,
1142 const char *filename,
1143 unsigned line,
1144 const char *section,
1145 unsigned section_line,
1146 const char *lvalue,
1147 int ltype,
1148 const char *rvalue,
1149 void *data,
1150 void *userdata) {
1151
19f9e4e2
YW
1152 _cleanup_free_ char *tz = NULL;
1153 char **datap = data;
8eb9058d
LP
1154 int r;
1155
1156 assert(filename);
1157 assert(lvalue);
1158 assert(rvalue);
1159
1160 r = config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &tz, userdata);
1161 if (r < 0)
1162 return r;
1163
089fb865 1164 if (!timezone_is_valid(tz, LOG_ERR)) {
ab24039f
ZJS
1165 log_syntax(unit, LOG_ERR, filename, line, 0,
1166 "Timezone is not valid, ignoring assignment: %s", rvalue);
8eb9058d
LP
1167 return 0;
1168 }
1169
19f9e4e2 1170 return free_and_replace(*datap, tz);
8eb9058d 1171}
1a04db0f 1172
53253824
SS
1173int config_parse_dns(
1174 const char *unit,
1175 const char *filename,
1176 unsigned line,
1177 const char *section,
1178 unsigned section_line,
1179 const char *lvalue,
1180 int ltype,
1181 const char *rvalue,
1182 void *data,
1183 void *userdata) {
1184
1185 Network *n = userdata;
1186 int r;
1187
1188 assert(filename);
1189 assert(lvalue);
1190 assert(rvalue);
1191
1192 for (;;) {
1193 _cleanup_free_ char *w = NULL;
1194 union in_addr_union a;
5512a963 1195 struct in_addr_data *m;
53253824
SS
1196 int family;
1197
5512a963 1198 r = extract_first_word(&rvalue, &w, NULL, 0);
53253824
SS
1199 if (r == -ENOMEM)
1200 return log_oom();
1201 if (r < 0) {
ab24039f
ZJS
1202 log_syntax(unit, LOG_ERR, filename, line, r,
1203 "Invalid syntax, ignoring: %s", rvalue);
53253824
SS
1204 break;
1205 }
5512a963
LP
1206 if (r == 0)
1207 break;
53253824
SS
1208
1209 r = in_addr_from_string_auto(w, &family, &a);
1210 if (r < 0) {
ab24039f
ZJS
1211 log_syntax(unit, LOG_ERR, filename, line, r,
1212 "Failed to parse dns server address, ignoring: %s", w);
53253824
SS
1213 continue;
1214 }
1215
62d74c78 1216 m = reallocarray(n->dns, n->n_dns + 1, sizeof(struct in_addr_data));
5512a963 1217 if (!m)
53253824
SS
1218 return log_oom();
1219
5512a963
LP
1220 m[n->n_dns++] = (struct in_addr_data) {
1221 .family = family,
1222 .address = a,
1223 };
1224
1225 n->dns = m;
53253824
SS
1226 }
1227
1228 return 0;
1229}
1230
8a516214
LP
1231int config_parse_dnssec_negative_trust_anchors(
1232 const char *unit,
1233 const char *filename,
1234 unsigned line,
1235 const char *section,
1236 unsigned section_line,
1237 const char *lvalue,
1238 int ltype,
1239 const char *rvalue,
1240 void *data,
1241 void *userdata) {
1242
1243 const char *p = rvalue;
1244 Network *n = data;
1245 int r;
1246
3df9bec5 1247 assert(n);
8a516214
LP
1248 assert(lvalue);
1249 assert(rvalue);
1250
1251 if (isempty(rvalue)) {
1252 n->dnssec_negative_trust_anchors = set_free_free(n->dnssec_negative_trust_anchors);
1253 return 0;
1254 }
1255
1256 for (;;) {
1257 _cleanup_free_ char *w = NULL;
1258
1259 r = extract_first_word(&p, &w, NULL, 0);
1260 if (r < 0) {
ab24039f
ZJS
1261 log_syntax(unit, LOG_ERR, filename, line, r,
1262 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue);
8a516214
LP
1263 break;
1264 }
1265 if (r == 0)
1266 break;
1267
1268 r = dns_name_is_valid(w);
1269 if (r <= 0) {
ab24039f
ZJS
1270 log_syntax(unit, LOG_ERR, filename, line, r,
1271 "%s is not a valid domain name, ignoring.", w);
8a516214
LP
1272 continue;
1273 }
1274
cbbf38ae
LP
1275 r = set_ensure_allocated(&n->dnssec_negative_trust_anchors, &dns_name_hash_ops);
1276 if (r < 0)
1277 return log_oom();
1278
8a516214
LP
1279 r = set_put(n->dnssec_negative_trust_anchors, w);
1280 if (r < 0)
1281 return log_oom();
1282 if (r > 0)
1283 w = NULL;
1284 }
1285
1286 return 0;
1287}
b2a81c0b 1288
26575990
LP
1289int config_parse_ntp(
1290 const char *unit,
1291 const char *filename,
1292 unsigned line,
1293 const char *section,
1294 unsigned section_line,
1295 const char *lvalue,
1296 int ltype,
1297 const char *rvalue,
1298 void *data,
1299 void *userdata) {
1300
1301 char ***l = data;
1302 int r;
1303
1304 assert(l);
1305 assert(lvalue);
1306 assert(rvalue);
1307
1308 if (isempty(rvalue)) {
1309 *l = strv_free(*l);
1310 return 0;
1311 }
1312
1313 for (;;) {
1314 _cleanup_free_ char *w = NULL;
1315
1316 r = extract_first_word(&rvalue, &w, NULL, 0);
1317 if (r == -ENOMEM)
1318 return log_oom();
1319 if (r < 0) {
ab24039f
ZJS
1320 log_syntax(unit, LOG_ERR, filename, line, r,
1321 "Failed to extract NTP server name, ignoring: %s", rvalue);
26575990
LP
1322 break;
1323 }
1324 if (r == 0)
1325 break;
1326
1327 r = dns_name_is_valid_or_address(w);
1328 if (r <= 0) {
ab24039f
ZJS
1329 log_syntax(unit, LOG_ERR, filename, line, r,
1330 "%s is not a valid domain name or IP address, ignoring.", w);
26575990 1331 continue;
af1c0de0
SS
1332 }
1333
c448459d
ZJS
1334 if (strv_length(*l) > MAX_NTP_SERVERS) {
1335 log_syntax(unit, LOG_WARNING, filename, line, 0,
1336 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1337 MAX_NTP_SERVERS, w);
1338 break;
1339 }
1340
1341 r = strv_consume(l, TAKE_PTR(w));
af1c0de0
SS
1342 if (r < 0)
1343 return log_oom();
af1c0de0
SS
1344 }
1345
1346 return 0;
1347}
1348
4ac77d63
YW
1349int config_parse_required_for_online(
1350 const char *unit,
1351 const char *filename,
1352 unsigned line,
1353 const char *section,
1354 unsigned section_line,
1355 const char *lvalue,
1356 int ltype,
1357 const char *rvalue,
1358 void *data,
1359 void *userdata) {
1360
1361 Network *network = data;
75cd4a5d 1362 LinkOperationalStateRange range;
4ac77d63
YW
1363 bool required = true;
1364 int r;
1365
1366 if (isempty(rvalue)) {
1367 network->required_for_online = true;
75cd4a5d 1368 network->required_operstate_for_online = LINK_OPERSTATE_RANGE_DEFAULT;
4ac77d63
YW
1369 return 0;
1370 }
1371
75cd4a5d
DDM
1372 r = parse_operational_state_range(rvalue, &range);
1373 if (r < 0) {
4ac77d63
YW
1374 r = parse_boolean(rvalue);
1375 if (r < 0) {
1376 log_syntax(unit, LOG_ERR, filename, line, r,
1377 "Failed to parse %s= setting, ignoring assignment: %s",
1378 lvalue, rvalue);
1379 return 0;
1380 }
1381
1382 required = r;
75cd4a5d 1383 range = LINK_OPERSTATE_RANGE_DEFAULT;
4ac77d63
YW
1384 }
1385
1386 network->required_for_online = required;
75cd4a5d 1387 network->required_operstate_for_online = range;
4ac77d63
YW
1388
1389 return 0;
1390}
7da377ef
SS
1391
1392DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration, keep_configuration, KeepConfiguration,
1393 "Failed to parse KeepConfiguration= setting");
1394
1395static const char* const keep_configuration_table[_KEEP_CONFIGURATION_MAX] = {
95355a28
YW
1396 [KEEP_CONFIGURATION_NO] = "no",
1397 [KEEP_CONFIGURATION_DHCP_ON_STOP] = "dhcp-on-stop",
1398 [KEEP_CONFIGURATION_DHCP] = "dhcp",
1399 [KEEP_CONFIGURATION_STATIC] = "static",
1400 [KEEP_CONFIGURATION_YES] = "yes",
7da377ef
SS
1401};
1402
1403DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration, KeepConfiguration, KEEP_CONFIGURATION_YES);