1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include <linux/rtnetlink.h>
5 #include "alloc-util.h"
7 #include "conf-parser.h"
10 #include "networkd-link.h"
11 #include "networkd-network.h"
12 #include "networkd-util.h"
13 #include "parse-util.h"
14 #include "string-table.h"
15 #include "string-util.h"
18 /* This is used in log messages, and never used in parsing settings. So, upper cases are OK. */
19 static const char * const network_config_source_table
[_NETWORK_CONFIG_SOURCE_MAX
] = {
20 [NETWORK_CONFIG_SOURCE_FOREIGN
] = "foreign",
21 [NETWORK_CONFIG_SOURCE_STATIC
] = "static",
22 [NETWORK_CONFIG_SOURCE_IPV4LL
] = "IPv4LL",
23 [NETWORK_CONFIG_SOURCE_DHCP4
] = "DHCPv4",
24 [NETWORK_CONFIG_SOURCE_DHCP6
] = "DHCPv6",
25 [NETWORK_CONFIG_SOURCE_DHCP_PD
] = "DHCP-PD",
26 [NETWORK_CONFIG_SOURCE_NDISC
] = "NDisc",
27 [NETWORK_CONFIG_SOURCE_RUNTIME
] = "runtime",
30 DEFINE_STRING_TABLE_LOOKUP(network_config_source
, NetworkConfigSource
);
32 int network_config_state_to_string_alloc(NetworkConfigState s
, char **ret
) {
33 static const char* states
[] = {
34 [LOG2U(NETWORK_CONFIG_STATE_REQUESTING
)] = "requesting",
35 [LOG2U(NETWORK_CONFIG_STATE_CONFIGURING
)] = "configuring",
36 [LOG2U(NETWORK_CONFIG_STATE_CONFIGURED
)] = "configured",
37 [LOG2U(NETWORK_CONFIG_STATE_MARKED
)] = "marked",
38 [LOG2U(NETWORK_CONFIG_STATE_REMOVING
)] = "removing",
40 _cleanup_free_
char *buf
= NULL
;
44 for (size_t i
= 0; i
< ELEMENTSOF(states
); i
++)
46 if (!strextend_with_separator(&buf
, ",", ASSERT_PTR(states
[i
])))
53 static const char * const address_family_table
[_ADDRESS_FAMILY_MAX
] = {
54 [ADDRESS_FAMILY_NO
] = "no",
55 [ADDRESS_FAMILY_YES
] = "yes",
56 [ADDRESS_FAMILY_IPV4
] = "ipv4",
57 [ADDRESS_FAMILY_IPV6
] = "ipv6",
60 static const char * const routing_policy_rule_address_family_table
[_ADDRESS_FAMILY_MAX
] = {
61 [ADDRESS_FAMILY_YES
] = "both",
62 [ADDRESS_FAMILY_IPV4
] = "ipv4",
63 [ADDRESS_FAMILY_IPV6
] = "ipv6",
66 static const char * const nexthop_address_family_table
[_ADDRESS_FAMILY_MAX
] = {
67 [ADDRESS_FAMILY_IPV4
] = "ipv4",
68 [ADDRESS_FAMILY_IPV6
] = "ipv6",
71 static const char * const duplicate_address_detection_address_family_table
[_ADDRESS_FAMILY_MAX
] = {
72 [ADDRESS_FAMILY_NO
] = "none",
73 [ADDRESS_FAMILY_YES
] = "both",
74 [ADDRESS_FAMILY_IPV4
] = "ipv4",
75 [ADDRESS_FAMILY_IPV6
] = "ipv6",
78 static const char * const dhcp_deprecated_address_family_table
[_ADDRESS_FAMILY_MAX
] = {
79 [ADDRESS_FAMILY_NO
] = "none",
80 [ADDRESS_FAMILY_YES
] = "both",
81 [ADDRESS_FAMILY_IPV4
] = "v4",
82 [ADDRESS_FAMILY_IPV6
] = "v6",
85 static const char * const ip_masquerade_address_family_table
[_ADDRESS_FAMILY_MAX
] = {
86 [ADDRESS_FAMILY_NO
] = "no",
87 [ADDRESS_FAMILY_YES
] = "both",
88 [ADDRESS_FAMILY_IPV4
] = "ipv4",
89 [ADDRESS_FAMILY_IPV6
] = "ipv6",
92 static const char * const dhcp_lease_server_type_table
[_SD_DHCP_LEASE_SERVER_TYPE_MAX
] = {
93 [SD_DHCP_LEASE_DNS
] = "DNS servers",
94 [SD_DHCP_LEASE_NTP
] = "NTP servers",
95 [SD_DHCP_LEASE_SIP
] = "SIP servers",
96 [SD_DHCP_LEASE_POP3
] = "POP3 servers",
97 [SD_DHCP_LEASE_SMTP
] = "SMTP servers",
98 [SD_DHCP_LEASE_LPR
] = "LPR servers",
101 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(address_family
, AddressFamily
, ADDRESS_FAMILY_YES
);
103 AddressFamily
link_local_address_family_from_string(const char *s
) {
104 if (streq_ptr(s
, "fallback")) /* compat name */
105 return ADDRESS_FAMILY_YES
;
106 if (streq_ptr(s
, "fallback-ipv4")) /* compat name */
107 return ADDRESS_FAMILY_IPV4
;
108 return address_family_from_string(s
);
111 DEFINE_STRING_TABLE_LOOKUP(routing_policy_rule_address_family
, AddressFamily
);
112 DEFINE_STRING_TABLE_LOOKUP(nexthop_address_family
, AddressFamily
);
113 DEFINE_STRING_TABLE_LOOKUP(duplicate_address_detection_address_family
, AddressFamily
);
114 DEFINE_CONFIG_PARSE_ENUM(config_parse_link_local_address_family
, link_local_address_family
, AddressFamily
);
115 DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_deprecated_address_family
, AddressFamily
);
116 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(ip_masquerade_address_family
, AddressFamily
);
117 DEFINE_STRING_TABLE_LOOKUP(dhcp_lease_server_type
, sd_dhcp_lease_server_type_t
);
119 bool link_should_mark_config(Link
*link
, bool only_static
, NetworkConfigSource source
, uint8_t protocol
) {
120 /* Always mark static configs. */
121 if (source
== NETWORK_CONFIG_SOURCE_STATIC
)
124 /* When 'only_static' is true, do not mark other configs. */
128 /* Always ignore dynamically assigned configs. */
129 if (source
!= NETWORK_CONFIG_SOURCE_FOREIGN
)
132 /* When only_static is false, the logic is conditionalized with KeepConfiguration=. Hence, the
133 * interface needs to have a matching .network file. */
135 assert(link
->network
);
137 /* When KeepConfiguration=yes, keep all foreign configs. */
138 if (FLAGS_SET(link
->network
->keep_configuration
, KEEP_CONFIGURATION_YES
))
141 /* When static, keep all static configs. */
142 if (FLAGS_SET(link
->network
->keep_configuration
, KEEP_CONFIGURATION_STATIC
) &&
143 protocol
== RTPROT_STATIC
)
146 /* When dynamic, keep all dynamic configs. */
147 if (FLAGS_SET(link
->network
->keep_configuration
, KEEP_CONFIGURATION_DYNAMIC
) &&
148 IN_SET(protocol
, RTPROT_DHCP
, RTPROT_RA
, RTPROT_REDIRECT
))
151 /* Otherwise, mark the config. */
155 int config_parse_ip_masquerade(
157 const char *filename
,
160 unsigned section_line
,
167 AddressFamily a
, *ret
= data
;
170 if (isempty(rvalue
)) {
171 *ret
= ADDRESS_FAMILY_NO
;
175 r
= parse_boolean(rvalue
);
178 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
179 "IPMasquerade=%s is deprecated, and it is handled as \"ipv4\" instead of \"both\". "
180 "Please use \"ipv4\" or \"both\".",
183 *ret
= r
? ADDRESS_FAMILY_IPV4
: ADDRESS_FAMILY_NO
;
187 a
= ip_masquerade_address_family_from_string(rvalue
);
189 log_syntax(unit
, LOG_WARNING
, filename
, line
, a
,
190 "Failed to parse IPMasquerade= setting, ignoring assignment: %s", rvalue
);
198 int config_parse_mud_url(
200 const char *filename
,
203 unsigned section_line
,
210 _cleanup_free_
char *unescaped
= NULL
;
211 char **url
= ASSERT_PTR(data
);
218 if (isempty(rvalue
)) {
223 l
= cunescape(rvalue
, 0, &unescaped
);
225 log_syntax(unit
, LOG_WARNING
, filename
, line
, l
,
226 "Failed to unescape MUD URL, ignoring: %s", rvalue
);
230 if (l
> UINT8_MAX
|| !http_url_is_valid(unescaped
)) {
231 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
232 "Invalid MUD URL, ignoring: %s", rvalue
);
236 return free_and_replace(*url
, unescaped
);