Line data Source code
1 : /* SPDX-License-Identifier: LGPL-2.1+ */
2 :
3 : #include "condition.h"
4 : #include "conf-parser.h"
5 : #include "networkd-util.h"
6 : #include "parse-util.h"
7 : #include "string-table.h"
8 : #include "string-util.h"
9 : #include "util.h"
10 :
11 : static const char * const address_family_table[_ADDRESS_FAMILY_MAX] = {
12 : [ADDRESS_FAMILY_NO] = "no",
13 : [ADDRESS_FAMILY_YES] = "yes",
14 : [ADDRESS_FAMILY_IPV4] = "ipv4",
15 : [ADDRESS_FAMILY_IPV6] = "ipv6",
16 : };
17 :
18 : static const char * const link_local_address_family_table[_ADDRESS_FAMILY_MAX] = {
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 :
27 : static 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 :
33 19 : DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(address_family, AddressFamily, ADDRESS_FAMILY_YES);
34 3 : DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(link_local_address_family, AddressFamily, ADDRESS_FAMILY_YES);
35 0 : DEFINE_STRING_TABLE_LOOKUP(routing_policy_rule_address_family, AddressFamily);
36 3 : DEFINE_CONFIG_PARSE_ENUM(config_parse_link_local_address_family, link_local_address_family,
37 : AddressFamily, "Failed to parse option");
38 :
39 0 : int config_parse_address_family_with_kernel(
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 :
51 0 : AddressFamily *fwd = data, s;
52 :
53 0 : assert(filename);
54 0 : assert(lvalue);
55 0 : assert(rvalue);
56 0 : assert(data);
57 :
58 : /* This function is mostly obsolete now. It simply redirects
59 : * "kernel" to "no". In older networkd versions we used to
60 : * distinguish IPForward=off from IPForward=kernel, where the
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 :
66 0 : s = address_family_from_string(rvalue);
67 0 : if (s < 0) {
68 0 : if (streq(rvalue, "kernel"))
69 0 : s = ADDRESS_FAMILY_NO;
70 : else {
71 0 : log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse IPForward= option, ignoring: %s", rvalue);
72 0 : return 0;
73 : }
74 : }
75 :
76 0 : *fwd = s;
77 :
78 0 : return 0;
79 : }
80 :
81 : /* Router lifetime can be set with netlink interface since kernel >= 4.5
82 : * so for the supported kernel we don't need to expire routes in userspace */
83 0 : int kernel_route_expiration_supported(void) {
84 : static int cached = -1;
85 : int r;
86 :
87 0 : if (cached < 0) {
88 0 : Condition c = {
89 : .type = CONDITION_KERNEL_VERSION,
90 : .parameter = (char *) ">= 4.5"
91 : };
92 0 : r = condition_test(&c);
93 0 : if (r < 0)
94 0 : return r;
95 :
96 0 : cached = r;
97 : }
98 0 : return cached;
99 : }
100 :
101 46 : static void network_config_hash_func(const NetworkConfigSection *c, struct siphash *state) {
102 46 : siphash24_compress(c->filename, strlen(c->filename), state);
103 46 : siphash24_compress(&c->line, sizeof(c->line), state);
104 46 : }
105 :
106 23 : static int network_config_compare_func(const NetworkConfigSection *x, const NetworkConfigSection *y) {
107 : int r;
108 :
109 23 : r = strcmp(x->filename, y->filename);
110 23 : if (r != 0)
111 0 : return r;
112 :
113 23 : return CMP(x->line, y->line);
114 : }
115 :
116 : DEFINE_HASH_OPS(network_config_hash_ops, NetworkConfigSection, network_config_hash_func, network_config_compare_func);
117 :
118 23 : int network_config_section_new(const char *filename, unsigned line, NetworkConfigSection **s) {
119 : NetworkConfigSection *cs;
120 :
121 23 : cs = malloc0(offsetof(NetworkConfigSection, filename) + strlen(filename) + 1);
122 23 : if (!cs)
123 0 : return -ENOMEM;
124 :
125 23 : strcpy(cs->filename, filename);
126 23 : cs->line = line;
127 :
128 23 : *s = TAKE_PTR(cs);
129 :
130 23 : return 0;
131 : }
132 :
133 34 : void network_config_section_free(NetworkConfigSection *cs) {
134 34 : free(cs);
135 34 : }
|