]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-util.c
network: add RoutingPolicyRule.Family= setting
[thirdparty/systemd.git] / src / network / networkd-util.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
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
2d792895 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
2d792895 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
f6c6ff97
YW
27static const char * const routing_policy_rule_address_family_table[_ADDRESS_FAMILY_MAX] = {
28 [ADDRESS_FAMILY_YES] = "both",
29 [ADDRESS_FAMILY_IPV4] = "ipv4",
30 [ADDRESS_FAMILY_IPV6] = "ipv6",
31};
32
2d792895
YW
33DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(address_family, AddressFamily, ADDRESS_FAMILY_YES);
34DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(link_local_address_family, AddressFamily, ADDRESS_FAMILY_YES);
f6c6ff97 35DEFINE_STRING_TABLE_LOOKUP(routing_policy_rule_address_family, AddressFamily);
2d792895
YW
36DEFINE_CONFIG_PARSE_ENUM(config_parse_link_local_address_family, link_local_address_family,
37 AddressFamily, "Failed to parse option");
fc2f9534 38
2d792895 39int config_parse_address_family_with_kernel(
fc2f9534
LP
40 const char* unit,
41 const char *filename,
42 unsigned line,
43 const char *section,
44 unsigned section_line,
45 const char *lvalue,
46 int ltype,
47 const char *rvalue,
48 void *data,
49 void *userdata) {
50
2d792895 51 AddressFamily *fwd = data, s;
fc2f9534
LP
52
53 assert(filename);
54 assert(lvalue);
55 assert(rvalue);
56 assert(data);
57
765afd5c
LP
58 /* This function is mostly obsolete now. It simply redirects
59 * "kernel" to "no". In older networkd versions we used to
5238e957 60 * distinguish IPForward=off from IPForward=kernel, where the
765afd5c
LP
61 * former would explicitly turn off forwarding while the
62 * latter would simply not touch the setting. But that logic
63 * is gone, hence silently accept the old setting, but turn it
64 * to "no". */
65
2d792895 66 s = address_family_from_string(rvalue);
fc2f9534
LP
67 if (s < 0) {
68 if (streq(rvalue, "kernel"))
765afd5c 69 s = ADDRESS_FAMILY_NO;
fc2f9534 70 else {
85e070c2 71 log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse IPForward= option, ignoring: %s", rvalue);
fc2f9534
LP
72 return 0;
73 }
74 }
75
76 *fwd = s;
77
78 return 0;
79}
f02ba163
DD
80
81/* Router lifetime can be set with netlink interface since kernel >= 4.5
5238e957 82 * so for the supported kernel we don't need to expire routes in userspace */
f02ba163
DD
83int kernel_route_expiration_supported(void) {
84 static int cached = -1;
85 int r;
86
87 if (cached < 0) {
88 Condition c = {
89 .type = CONDITION_KERNEL_VERSION,
90 .parameter = (char *) ">= 4.5"
91 };
92 r = condition_test(&c);
93 if (r < 0)
94 return r;
95
96 cached = r;
97 }
98 return cached;
99}
48315d3d
YW
100
101static void network_config_hash_func(const NetworkConfigSection *c, struct siphash *state) {
102 siphash24_compress(c->filename, strlen(c->filename), state);
103 siphash24_compress(&c->line, sizeof(c->line), state);
104}
105
106static int network_config_compare_func(const NetworkConfigSection *x, const NetworkConfigSection *y) {
107 int r;
108
109 r = strcmp(x->filename, y->filename);
110 if (r != 0)
111 return r;
112
113 return CMP(x->line, y->line);
114}
115
116DEFINE_HASH_OPS(network_config_hash_ops, NetworkConfigSection, network_config_hash_func, network_config_compare_func);
117
118int network_config_section_new(const char *filename, unsigned line, NetworkConfigSection **s) {
119 NetworkConfigSection *cs;
120
121 cs = malloc0(offsetof(NetworkConfigSection, filename) + strlen(filename) + 1);
122 if (!cs)
123 return -ENOMEM;
124
125 strcpy(cs->filename, filename);
126 cs->line = line;
127
128 *s = TAKE_PTR(cs);
129
130 return 0;
131}
132
133void network_config_section_free(NetworkConfigSection *cs) {
134 free(cs);
135}