]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-util.c
license: LGPL-2.1+ -> LGPL-2.1-or-later
[thirdparty/systemd.git] / src / network / networkd-util.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
fc2f9534 2
f02ba163 3#include "condition.h"
fc2f9534 4#include "conf-parser.h"
fc2f9534 5#include "networkd-util.h"
6bedfcbb 6#include "parse-util.h"
8b43440b 7#include "string-table.h"
07630cea
LP
8#include "string-util.h"
9#include "util.h"
fc2f9534 10
ddc026f3 11static const char* const address_family_table[_ADDRESS_FAMILY_MAX] = {
e800fd24
YW
12 [ADDRESS_FAMILY_NO] = "no",
13 [ADDRESS_FAMILY_YES] = "yes",
14 [ADDRESS_FAMILY_IPV4] = "ipv4",
15 [ADDRESS_FAMILY_IPV6] = "ipv6",
16};
17
ddc026f3 18static const char* const link_local_address_family_table[_ADDRESS_FAMILY_MAX] = {
e800fd24
YW
19 [ADDRESS_FAMILY_NO] = "no",
20 [ADDRESS_FAMILY_YES] = "yes",
21 [ADDRESS_FAMILY_IPV4] = "ipv4",
22 [ADDRESS_FAMILY_IPV6] = "ipv6",
23 [ADDRESS_FAMILY_FALLBACK] = "fallback",
24 [ADDRESS_FAMILY_FALLBACK_IPV4] = "ipv4-fallback",
25};
26
ddc026f3 27static const char* const routing_policy_rule_address_family_table[_ADDRESS_FAMILY_MAX] = {
f6c6ff97
YW
28 [ADDRESS_FAMILY_YES] = "both",
29 [ADDRESS_FAMILY_IPV4] = "ipv4",
30 [ADDRESS_FAMILY_IPV6] = "ipv6",
31};
32
ddc026f3 33static const char* const duplicate_address_detection_address_family_table[_ADDRESS_FAMILY_MAX] = {
051e77ca
SS
34 [ADDRESS_FAMILY_NO] = "none",
35 [ADDRESS_FAMILY_YES] = "both",
36 [ADDRESS_FAMILY_IPV4] = "ipv4",
37 [ADDRESS_FAMILY_IPV6] = "ipv6",
38};
39
ddb82ec2
LP
40static const char* const dhcp_lease_server_type_table[_SD_DHCP_LEASE_SERVER_TYPE_MAX] = {
41 [SD_DHCP_LEASE_DNS] = "DNS servers",
42 [SD_DHCP_LEASE_NTP] = "NTP servers",
43 [SD_DHCP_LEASE_SIP] = "SIP servers",
44 [SD_DHCP_LEASE_POP3] = "POP3 servers",
45 [SD_DHCP_LEASE_SMTP] = "SMTP servers",
46 [SD_DHCP_LEASE_LPR] = "LPR servers",
ddc026f3
ZJS
47};
48
2d792895
YW
49DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(address_family, AddressFamily, ADDRESS_FAMILY_YES);
50DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(link_local_address_family, AddressFamily, ADDRESS_FAMILY_YES);
f6c6ff97 51DEFINE_STRING_TABLE_LOOKUP(routing_policy_rule_address_family, AddressFamily);
051e77ca 52DEFINE_STRING_TABLE_LOOKUP(duplicate_address_detection_address_family, AddressFamily);
2d792895
YW
53DEFINE_CONFIG_PARSE_ENUM(config_parse_link_local_address_family, link_local_address_family,
54 AddressFamily, "Failed to parse option");
ddb82ec2 55DEFINE_STRING_TABLE_LOOKUP(dhcp_lease_server_type, sd_dhcp_lease_server_type);
fc2f9534 56
2d792895 57int config_parse_address_family_with_kernel(
fc2f9534
LP
58 const char* unit,
59 const char *filename,
60 unsigned line,
61 const char *section,
62 unsigned section_line,
63 const char *lvalue,
64 int ltype,
65 const char *rvalue,
66 void *data,
67 void *userdata) {
68
2d792895 69 AddressFamily *fwd = data, s;
fc2f9534
LP
70
71 assert(filename);
72 assert(lvalue);
73 assert(rvalue);
74 assert(data);
75
765afd5c
LP
76 /* This function is mostly obsolete now. It simply redirects
77 * "kernel" to "no". In older networkd versions we used to
5238e957 78 * distinguish IPForward=off from IPForward=kernel, where the
765afd5c
LP
79 * former would explicitly turn off forwarding while the
80 * latter would simply not touch the setting. But that logic
81 * is gone, hence silently accept the old setting, but turn it
82 * to "no". */
83
2d792895 84 s = address_family_from_string(rvalue);
fc2f9534
LP
85 if (s < 0) {
86 if (streq(rvalue, "kernel"))
765afd5c 87 s = ADDRESS_FAMILY_NO;
fc2f9534 88 else {
d96edb2c 89 log_syntax(unit, LOG_WARNING, filename, line, 0, "Failed to parse IPForward= option, ignoring: %s", rvalue);
fc2f9534
LP
90 return 0;
91 }
92 }
93
94 *fwd = s;
95
96 return 0;
97}
f02ba163
DD
98
99/* Router lifetime can be set with netlink interface since kernel >= 4.5
5238e957 100 * so for the supported kernel we don't need to expire routes in userspace */
f02ba163
DD
101int kernel_route_expiration_supported(void) {
102 static int cached = -1;
103 int r;
104
105 if (cached < 0) {
106 Condition c = {
107 .type = CONDITION_KERNEL_VERSION,
108 .parameter = (char *) ">= 4.5"
109 };
a0b191b7 110 r = condition_test(&c, NULL);
f02ba163
DD
111 if (r < 0)
112 return r;
113
114 cached = r;
115 }
116 return cached;
117}
48315d3d
YW
118
119static void network_config_hash_func(const NetworkConfigSection *c, struct siphash *state) {
f281fc1e 120 siphash24_compress_string(c->filename, state);
48315d3d
YW
121 siphash24_compress(&c->line, sizeof(c->line), state);
122}
123
124static int network_config_compare_func(const NetworkConfigSection *x, const NetworkConfigSection *y) {
125 int r;
126
127 r = strcmp(x->filename, y->filename);
128 if (r != 0)
129 return r;
130
131 return CMP(x->line, y->line);
132}
133
134DEFINE_HASH_OPS(network_config_hash_ops, NetworkConfigSection, network_config_hash_func, network_config_compare_func);
135
136int network_config_section_new(const char *filename, unsigned line, NetworkConfigSection **s) {
137 NetworkConfigSection *cs;
138
139 cs = malloc0(offsetof(NetworkConfigSection, filename) + strlen(filename) + 1);
140 if (!cs)
141 return -ENOMEM;
142
143 strcpy(cs->filename, filename);
144 cs->line = line;
145
146 *s = TAKE_PTR(cs);
147
148 return 0;
149}
150
151void network_config_section_free(NetworkConfigSection *cs) {
152 free(cs);
153}
833f3663
YW
154
155unsigned hashmap_find_free_section_line(Hashmap *hashmap) {
156 NetworkConfigSection *cs;
157 unsigned n = 0;
158 void *entry;
159
160 HASHMAP_FOREACH_KEY(entry, cs, hashmap)
161 if (n < cs->line)
162 n = cs->line;
163
164 return n + 1;
165}