]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-util.c
Respect install_sysconfdir
[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"
89fa9a6b 5#include "escape.h"
fd221544 6#include "networkd-link.h"
fc2f9534 7#include "networkd-util.h"
6bedfcbb 8#include "parse-util.h"
8b43440b 9#include "string-table.h"
07630cea 10#include "string-util.h"
89fa9a6b 11#include "web-util.h"
fc2f9534 12
ddc026f3 13static const char* const address_family_table[_ADDRESS_FAMILY_MAX] = {
135c4aad
LP
14 [ADDRESS_FAMILY_NO] = "no",
15 [ADDRESS_FAMILY_YES] = "yes",
16 [ADDRESS_FAMILY_IPV4] = "ipv4",
17 [ADDRESS_FAMILY_IPV6] = "ipv6",
e800fd24
YW
18};
19
ddc026f3 20static const char* const routing_policy_rule_address_family_table[_ADDRESS_FAMILY_MAX] = {
135c4aad
LP
21 [ADDRESS_FAMILY_YES] = "both",
22 [ADDRESS_FAMILY_IPV4] = "ipv4",
23 [ADDRESS_FAMILY_IPV6] = "ipv6",
f6c6ff97
YW
24};
25
f1923efc 26static const char* const nexthop_address_family_table[_ADDRESS_FAMILY_MAX] = {
135c4aad
LP
27 [ADDRESS_FAMILY_IPV4] = "ipv4",
28 [ADDRESS_FAMILY_IPV6] = "ipv6",
f1923efc
YW
29};
30
ddc026f3 31static const char* const duplicate_address_detection_address_family_table[_ADDRESS_FAMILY_MAX] = {
135c4aad
LP
32 [ADDRESS_FAMILY_NO] = "none",
33 [ADDRESS_FAMILY_YES] = "both",
34 [ADDRESS_FAMILY_IPV4] = "ipv4",
35 [ADDRESS_FAMILY_IPV6] = "ipv6",
051e77ca
SS
36};
37
bde8467a 38static const char* const dhcp_deprecated_address_family_table[_ADDRESS_FAMILY_MAX] = {
135c4aad
LP
39 [ADDRESS_FAMILY_NO] = "none",
40 [ADDRESS_FAMILY_YES] = "both",
41 [ADDRESS_FAMILY_IPV4] = "v4",
42 [ADDRESS_FAMILY_IPV6] = "v6",
bde8467a
YW
43};
44
4c72d851
YW
45static const char* const ip_masquerade_address_family_table[_ADDRESS_FAMILY_MAX] = {
46 [ADDRESS_FAMILY_NO] = "no",
47 [ADDRESS_FAMILY_YES] = "both",
48 [ADDRESS_FAMILY_IPV4] = "ipv4",
49 [ADDRESS_FAMILY_IPV6] = "ipv6",
50};
51
ddb82ec2
LP
52static const char* const dhcp_lease_server_type_table[_SD_DHCP_LEASE_SERVER_TYPE_MAX] = {
53 [SD_DHCP_LEASE_DNS] = "DNS servers",
54 [SD_DHCP_LEASE_NTP] = "NTP servers",
55 [SD_DHCP_LEASE_SIP] = "SIP servers",
56 [SD_DHCP_LEASE_POP3] = "POP3 servers",
57 [SD_DHCP_LEASE_SMTP] = "SMTP servers",
58 [SD_DHCP_LEASE_LPR] = "LPR servers",
ddc026f3
ZJS
59};
60
2d792895 61DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(address_family, AddressFamily, ADDRESS_FAMILY_YES);
3ca1fab7
ZJS
62
63AddressFamily link_local_address_family_from_string(const char *s) {
64 if (streq_ptr(s, "fallback")) /* compat name */
65 return ADDRESS_FAMILY_YES;
66 if (streq_ptr(s, "fallback-ipv4")) /* compat name */
67 return ADDRESS_FAMILY_IPV4;
68 return address_family_from_string(s);
69}
70
f6c6ff97 71DEFINE_STRING_TABLE_LOOKUP(routing_policy_rule_address_family, AddressFamily);
f1923efc 72DEFINE_STRING_TABLE_LOOKUP(nexthop_address_family, AddressFamily);
051e77ca 73DEFINE_STRING_TABLE_LOOKUP(duplicate_address_detection_address_family, AddressFamily);
2d792895
YW
74DEFINE_CONFIG_PARSE_ENUM(config_parse_link_local_address_family, link_local_address_family,
75 AddressFamily, "Failed to parse option");
bde8467a 76DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_deprecated_address_family, AddressFamily);
4c72d851 77DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(ip_masquerade_address_family, AddressFamily);
2324fd3a 78DEFINE_STRING_TABLE_LOOKUP(dhcp_lease_server_type, sd_dhcp_lease_server_type_t);
fc2f9534 79
2d792895 80int config_parse_address_family_with_kernel(
fc2f9534
LP
81 const char* unit,
82 const char *filename,
83 unsigned line,
84 const char *section,
85 unsigned section_line,
86 const char *lvalue,
87 int ltype,
88 const char *rvalue,
89 void *data,
90 void *userdata) {
91
2d792895 92 AddressFamily *fwd = data, s;
fc2f9534
LP
93
94 assert(filename);
95 assert(lvalue);
96 assert(rvalue);
97 assert(data);
98
765afd5c
LP
99 /* This function is mostly obsolete now. It simply redirects
100 * "kernel" to "no". In older networkd versions we used to
5238e957 101 * distinguish IPForward=off from IPForward=kernel, where the
765afd5c
LP
102 * former would explicitly turn off forwarding while the
103 * latter would simply not touch the setting. But that logic
104 * is gone, hence silently accept the old setting, but turn it
105 * to "no". */
106
2d792895 107 s = address_family_from_string(rvalue);
fc2f9534
LP
108 if (s < 0) {
109 if (streq(rvalue, "kernel"))
765afd5c 110 s = ADDRESS_FAMILY_NO;
fc2f9534 111 else {
d96edb2c 112 log_syntax(unit, LOG_WARNING, filename, line, 0, "Failed to parse IPForward= option, ignoring: %s", rvalue);
fc2f9534
LP
113 return 0;
114 }
115 }
116
117 *fwd = s;
118
119 return 0;
120}
f02ba163 121
4c72d851
YW
122int config_parse_ip_masquerade(
123 const char *unit,
124 const char *filename,
125 unsigned line,
126 const char *section,
127 unsigned section_line,
128 const char *lvalue,
129 int ltype,
130 const char *rvalue,
131 void *data,
132 void *userdata) {
133
134 AddressFamily a, *ret = data;
135 int r;
136
137 if (isempty(rvalue)) {
138 *ret = ADDRESS_FAMILY_NO;
139 return 0;
140 }
141
142 r = parse_boolean(rvalue);
143 if (r >= 0) {
144 if (r)
145 log_syntax(unit, LOG_WARNING, filename, line, 0,
146 "IPMasquerade=%s is deprecated, and it is handled as \"ipv4\" instead of \"both\". "
147 "Please use \"ipv4\" or \"both\".",
148 rvalue);
149
150 *ret = r ? ADDRESS_FAMILY_IPV4 : ADDRESS_FAMILY_NO;
151 return 0;
152 }
153
154 a = ip_masquerade_address_family_from_string(rvalue);
155 if (a < 0) {
156 log_syntax(unit, LOG_WARNING, filename, line, a,
157 "Failed to parse IPMasquerade= setting, ignoring assignment: %s", rvalue);
158 return 0;
159 }
160
161 *ret = a;
162 return 0;
163}
164
89fa9a6b
ZJS
165int config_parse_mud_url(
166 const char *unit,
167 const char *filename,
168 unsigned line,
169 const char *section,
170 unsigned section_line,
171 const char *lvalue,
172 int ltype,
173 const char *rvalue,
77976a68
YW
174 void *data,
175 void *userdata) {
176
177 _cleanup_free_ char *unescaped = NULL;
178 char **url = data;
179 ssize_t l;
89fa9a6b
ZJS
180
181 assert(filename);
182 assert(lvalue);
183 assert(rvalue);
77976a68 184 assert(url);
89fa9a6b 185
77976a68
YW
186 if (isempty(rvalue)) {
187 *url = mfree(*url);
188 return 0;
189 }
89fa9a6b
ZJS
190
191 l = cunescape(rvalue, 0, &unescaped);
192 if (l < 0) {
193 log_syntax(unit, LOG_WARNING, filename, line, l,
194 "Failed to unescape MUD URL, ignoring: %s", rvalue);
195 return 0;
196 }
197
198 if (l > UINT8_MAX || !http_url_is_valid(unescaped)) {
199 log_syntax(unit, LOG_WARNING, filename, line, 0,
200 "Invalid MUD URL, ignoring: %s", rvalue);
201 return 0;
202 }
203
77976a68 204 return free_and_replace(*url, unescaped);
89fa9a6b
ZJS
205}
206
f02ba163 207/* Router lifetime can be set with netlink interface since kernel >= 4.5
5238e957 208 * so for the supported kernel we don't need to expire routes in userspace */
f02ba163
DD
209int kernel_route_expiration_supported(void) {
210 static int cached = -1;
211 int r;
212
213 if (cached < 0) {
214 Condition c = {
215 .type = CONDITION_KERNEL_VERSION,
216 .parameter = (char *) ">= 4.5"
217 };
a0b191b7 218 r = condition_test(&c, NULL);
f02ba163
DD
219 if (r < 0)
220 return r;
221
222 cached = r;
223 }
224 return cached;
225}
48315d3d
YW
226
227static void network_config_hash_func(const NetworkConfigSection *c, struct siphash *state) {
f281fc1e 228 siphash24_compress_string(c->filename, state);
48315d3d
YW
229 siphash24_compress(&c->line, sizeof(c->line), state);
230}
231
232static int network_config_compare_func(const NetworkConfigSection *x, const NetworkConfigSection *y) {
233 int r;
234
235 r = strcmp(x->filename, y->filename);
236 if (r != 0)
237 return r;
238
239 return CMP(x->line, y->line);
240}
241
242DEFINE_HASH_OPS(network_config_hash_ops, NetworkConfigSection, network_config_hash_func, network_config_compare_func);
243
244int network_config_section_new(const char *filename, unsigned line, NetworkConfigSection **s) {
245 NetworkConfigSection *cs;
246
247 cs = malloc0(offsetof(NetworkConfigSection, filename) + strlen(filename) + 1);
248 if (!cs)
249 return -ENOMEM;
250
251 strcpy(cs->filename, filename);
252 cs->line = line;
253
254 *s = TAKE_PTR(cs);
255
256 return 0;
257}
258
833f3663
YW
259unsigned hashmap_find_free_section_line(Hashmap *hashmap) {
260 NetworkConfigSection *cs;
261 unsigned n = 0;
262 void *entry;
263
264 HASHMAP_FOREACH_KEY(entry, cs, hashmap)
265 if (n < cs->line)
266 n = cs->line;
267
268 return n + 1;
269}
fd221544
YW
270
271int log_link_message_full_errno(Link *link, sd_netlink_message *m, int level, int err, const char *msg) {
272 const char *err_msg = NULL;
273
274 /* link may be NULL. */
275
276 (void) sd_netlink_message_read_string(m, NLMSGERR_ATTR_MSG, &err_msg);
277 return log_link_full_errno(link, level, err,
278 "%s: %s%s%s%m",
279 msg,
280 strempty(err_msg),
281 err_msg && !endswith(err_msg, ".") ? "." : "",
282 err_msg ? " " : "");
283}