]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-util.c
mkosi: Switch to fedora 40
[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"
3ae6b3bf 6#include "logarithm.h"
fd221544 7#include "networkd-link.h"
fc2f9534 8#include "networkd-util.h"
6bedfcbb 9#include "parse-util.h"
8b43440b 10#include "string-table.h"
07630cea 11#include "string-util.h"
89fa9a6b 12#include "web-util.h"
fc2f9534 13
a093533c
YW
14/* This is used in log messages, and never used in parsing settings. So, upper cases are OK. */
15static const char * const network_config_source_table[_NETWORK_CONFIG_SOURCE_MAX] = {
16 [NETWORK_CONFIG_SOURCE_FOREIGN] = "foreign",
17 [NETWORK_CONFIG_SOURCE_STATIC] = "static",
18 [NETWORK_CONFIG_SOURCE_IPV4LL] = "IPv4LL",
19 [NETWORK_CONFIG_SOURCE_DHCP4] = "DHCPv4",
20 [NETWORK_CONFIG_SOURCE_DHCP6] = "DHCPv6",
a27588d4 21 [NETWORK_CONFIG_SOURCE_DHCP_PD] = "DHCP-PD",
a093533c 22 [NETWORK_CONFIG_SOURCE_NDISC] = "NDisc",
2e62139a 23 [NETWORK_CONFIG_SOURCE_RUNTIME] = "runtime",
a093533c
YW
24};
25
26DEFINE_STRING_TABLE_LOOKUP_TO_STRING(network_config_source, NetworkConfigSource);
27
28int network_config_state_to_string_alloc(NetworkConfigState s, char **ret) {
67b65e11 29 static const char* states[] = {
67b65e11
ZJS
30 [LOG2U(NETWORK_CONFIG_STATE_REQUESTING)] = "requesting",
31 [LOG2U(NETWORK_CONFIG_STATE_CONFIGURING)] = "configuring",
32 [LOG2U(NETWORK_CONFIG_STATE_CONFIGURED)] = "configured",
33 [LOG2U(NETWORK_CONFIG_STATE_MARKED)] = "marked",
34 [LOG2U(NETWORK_CONFIG_STATE_REMOVING)] = "removing",
a093533c
YW
35 };
36 _cleanup_free_ char *buf = NULL;
37
38 assert(ret);
39
67b65e11
ZJS
40 for (size_t i = 0; i < ELEMENTSOF(states); i++)
41 if (FLAGS_SET(s, 1 << i)) {
42 assert(states[i]);
43
44 if (!strextend_with_separator(&buf, ",", states[i]))
45 return -ENOMEM;
46 }
a093533c
YW
47
48 *ret = TAKE_PTR(buf);
49 return 0;
50}
51
52static const char * const address_family_table[_ADDRESS_FAMILY_MAX] = {
135c4aad
LP
53 [ADDRESS_FAMILY_NO] = "no",
54 [ADDRESS_FAMILY_YES] = "yes",
55 [ADDRESS_FAMILY_IPV4] = "ipv4",
56 [ADDRESS_FAMILY_IPV6] = "ipv6",
e800fd24
YW
57};
58
a093533c 59static const char * const routing_policy_rule_address_family_table[_ADDRESS_FAMILY_MAX] = {
135c4aad
LP
60 [ADDRESS_FAMILY_YES] = "both",
61 [ADDRESS_FAMILY_IPV4] = "ipv4",
62 [ADDRESS_FAMILY_IPV6] = "ipv6",
f6c6ff97
YW
63};
64
a093533c 65static const char * const nexthop_address_family_table[_ADDRESS_FAMILY_MAX] = {
135c4aad
LP
66 [ADDRESS_FAMILY_IPV4] = "ipv4",
67 [ADDRESS_FAMILY_IPV6] = "ipv6",
f1923efc
YW
68};
69
a093533c 70static const char * const duplicate_address_detection_address_family_table[_ADDRESS_FAMILY_MAX] = {
135c4aad
LP
71 [ADDRESS_FAMILY_NO] = "none",
72 [ADDRESS_FAMILY_YES] = "both",
73 [ADDRESS_FAMILY_IPV4] = "ipv4",
74 [ADDRESS_FAMILY_IPV6] = "ipv6",
051e77ca
SS
75};
76
a093533c 77static const char * const dhcp_deprecated_address_family_table[_ADDRESS_FAMILY_MAX] = {
135c4aad
LP
78 [ADDRESS_FAMILY_NO] = "none",
79 [ADDRESS_FAMILY_YES] = "both",
80 [ADDRESS_FAMILY_IPV4] = "v4",
81 [ADDRESS_FAMILY_IPV6] = "v6",
bde8467a
YW
82};
83
a093533c 84static const char * const ip_masquerade_address_family_table[_ADDRESS_FAMILY_MAX] = {
4c72d851
YW
85 [ADDRESS_FAMILY_NO] = "no",
86 [ADDRESS_FAMILY_YES] = "both",
87 [ADDRESS_FAMILY_IPV4] = "ipv4",
88 [ADDRESS_FAMILY_IPV6] = "ipv6",
89};
90
a093533c 91static const char * const dhcp_lease_server_type_table[_SD_DHCP_LEASE_SERVER_TYPE_MAX] = {
ddb82ec2
LP
92 [SD_DHCP_LEASE_DNS] = "DNS servers",
93 [SD_DHCP_LEASE_NTP] = "NTP servers",
94 [SD_DHCP_LEASE_SIP] = "SIP servers",
95 [SD_DHCP_LEASE_POP3] = "POP3 servers",
96 [SD_DHCP_LEASE_SMTP] = "SMTP servers",
97 [SD_DHCP_LEASE_LPR] = "LPR servers",
ddc026f3
ZJS
98};
99
2d792895 100DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(address_family, AddressFamily, ADDRESS_FAMILY_YES);
3ca1fab7
ZJS
101
102AddressFamily link_local_address_family_from_string(const char *s) {
103 if (streq_ptr(s, "fallback")) /* compat name */
104 return ADDRESS_FAMILY_YES;
105 if (streq_ptr(s, "fallback-ipv4")) /* compat name */
106 return ADDRESS_FAMILY_IPV4;
107 return address_family_from_string(s);
108}
109
f6c6ff97 110DEFINE_STRING_TABLE_LOOKUP(routing_policy_rule_address_family, AddressFamily);
f1923efc 111DEFINE_STRING_TABLE_LOOKUP(nexthop_address_family, AddressFamily);
051e77ca 112DEFINE_STRING_TABLE_LOOKUP(duplicate_address_detection_address_family, AddressFamily);
2d792895
YW
113DEFINE_CONFIG_PARSE_ENUM(config_parse_link_local_address_family, link_local_address_family,
114 AddressFamily, "Failed to parse option");
bde8467a 115DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_deprecated_address_family, AddressFamily);
4c72d851 116DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(ip_masquerade_address_family, AddressFamily);
2324fd3a 117DEFINE_STRING_TABLE_LOOKUP(dhcp_lease_server_type, sd_dhcp_lease_server_type_t);
fc2f9534 118
4c72d851
YW
119int config_parse_ip_masquerade(
120 const char *unit,
121 const char *filename,
122 unsigned line,
123 const char *section,
124 unsigned section_line,
125 const char *lvalue,
126 int ltype,
127 const char *rvalue,
128 void *data,
129 void *userdata) {
130
131 AddressFamily a, *ret = data;
132 int r;
133
134 if (isempty(rvalue)) {
135 *ret = ADDRESS_FAMILY_NO;
136 return 0;
137 }
138
139 r = parse_boolean(rvalue);
140 if (r >= 0) {
141 if (r)
142 log_syntax(unit, LOG_WARNING, filename, line, 0,
143 "IPMasquerade=%s is deprecated, and it is handled as \"ipv4\" instead of \"both\". "
144 "Please use \"ipv4\" or \"both\".",
145 rvalue);
146
147 *ret = r ? ADDRESS_FAMILY_IPV4 : ADDRESS_FAMILY_NO;
148 return 0;
149 }
150
151 a = ip_masquerade_address_family_from_string(rvalue);
152 if (a < 0) {
153 log_syntax(unit, LOG_WARNING, filename, line, a,
154 "Failed to parse IPMasquerade= setting, ignoring assignment: %s", rvalue);
155 return 0;
156 }
157
158 *ret = a;
159 return 0;
160}
161
89fa9a6b
ZJS
162int config_parse_mud_url(
163 const char *unit,
164 const char *filename,
165 unsigned line,
166 const char *section,
167 unsigned section_line,
168 const char *lvalue,
169 int ltype,
170 const char *rvalue,
77976a68
YW
171 void *data,
172 void *userdata) {
173
174 _cleanup_free_ char *unescaped = NULL;
99534007 175 char **url = ASSERT_PTR(data);
77976a68 176 ssize_t l;
89fa9a6b
ZJS
177
178 assert(filename);
179 assert(lvalue);
180 assert(rvalue);
89fa9a6b 181
77976a68
YW
182 if (isempty(rvalue)) {
183 *url = mfree(*url);
184 return 0;
185 }
89fa9a6b
ZJS
186
187 l = cunescape(rvalue, 0, &unescaped);
188 if (l < 0) {
189 log_syntax(unit, LOG_WARNING, filename, line, l,
190 "Failed to unescape MUD URL, ignoring: %s", rvalue);
191 return 0;
192 }
193
194 if (l > UINT8_MAX || !http_url_is_valid(unescaped)) {
195 log_syntax(unit, LOG_WARNING, filename, line, 0,
196 "Invalid MUD URL, ignoring: %s", rvalue);
197 return 0;
198 }
199
77976a68 200 return free_and_replace(*url, unescaped);
89fa9a6b
ZJS
201}
202
fd221544
YW
203int log_link_message_full_errno(Link *link, sd_netlink_message *m, int level, int err, const char *msg) {
204 const char *err_msg = NULL;
205
206 /* link may be NULL. */
207
208 (void) sd_netlink_message_read_string(m, NLMSGERR_ATTR_MSG, &err_msg);
209 return log_link_full_errno(link, level, err,
210 "%s: %s%s%s%m",
211 msg,
212 strempty(err_msg),
213 err_msg && !endswith(err_msg, ".") ? "." : "",
214 err_msg ? " " : "");
215}