]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-conf.c
license: LGPL-2.1+ -> LGPL-2.1-or-later
[thirdparty/systemd.git] / src / network / networkd-conf.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 /***
3 Copyright © 2014 Vinay Kulkarni <kulkarniv@vmware.com>
4 ***/
5
6 #include <ctype.h>
7 #include <netinet/ip.h>
8
9 #include "conf-parser.h"
10 #include "def.h"
11 #include "dhcp-identifier.h"
12 #include "extract-word.h"
13 #include "hexdecoct.h"
14 #include "networkd-conf.h"
15 #include "networkd-manager.h"
16 #include "networkd-network.h"
17 #include "networkd-speed-meter.h"
18 #include "networkd-dhcp4.h"
19 #include "string-table.h"
20
21 int manager_parse_config_file(Manager *m) {
22 int r;
23
24 assert(m);
25
26 r = config_parse_many_nulstr(
27 PKGSYSCONFDIR "/networkd.conf",
28 CONF_PATHS_NULSTR("systemd/networkd.conf.d"),
29 "Network\0"
30 "DHCP\0",
31 config_item_perf_lookup, networkd_gperf_lookup,
32 CONFIG_PARSE_WARN,
33 m,
34 NULL);
35 if (r < 0)
36 return r;
37
38 if (m->use_speed_meter && m->speed_meter_interval_usec < SPEED_METER_MINIMUM_TIME_INTERVAL) {
39 char buf[FORMAT_TIMESPAN_MAX];
40
41 log_warning("SpeedMeterIntervalSec= is too small, using %s.",
42 format_timespan(buf, sizeof buf, SPEED_METER_MINIMUM_TIME_INTERVAL, USEC_PER_SEC));
43 m->speed_meter_interval_usec = SPEED_METER_MINIMUM_TIME_INTERVAL;
44 }
45
46 return 0;
47 }
48
49 static const char* const duid_type_table[_DUID_TYPE_MAX] = {
50 [DUID_TYPE_LLT] = "link-layer-time",
51 [DUID_TYPE_EN] = "vendor",
52 [DUID_TYPE_LL] = "link-layer",
53 [DUID_TYPE_UUID] = "uuid",
54 };
55 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(duid_type, DUIDType);
56
57 int config_parse_duid_type(
58 const char *unit,
59 const char *filename,
60 unsigned line,
61 const char *section,
62 unsigned section_line,
63 const char *lvalue,
64 int ltype,
65 const char *rvalue,
66 void *data,
67 void *userdata) {
68
69 _cleanup_free_ char *type_string = NULL;
70 const char *p = rvalue;
71 DUID *duid = data;
72 DUIDType type;
73 int r;
74
75 assert(filename);
76 assert(lvalue);
77 assert(rvalue);
78 assert(duid);
79
80 r = extract_first_word(&p, &type_string, ":", 0);
81 if (r == -ENOMEM)
82 return log_oom();
83 if (r < 0) {
84 log_syntax(unit, LOG_WARNING, filename, line, r,
85 "Invalid syntax, ignoring: %s", rvalue);
86 return 0;
87 }
88 if (r == 0) {
89 log_syntax(unit, LOG_WARNING, filename, line, 0,
90 "Failed to extract DUID type from '%s', ignoring.", rvalue);
91 return 0;
92 }
93
94 type = duid_type_from_string(type_string);
95 if (type < 0) {
96 log_syntax(unit, LOG_WARNING, filename, line, 0,
97 "Failed to parse DUID type '%s', ignoring.", type_string);
98 return 0;
99 }
100
101 if (!isempty(p)) {
102 usec_t u;
103
104 if (type != DUID_TYPE_LLT) {
105 log_syntax(unit, LOG_WARNING, filename, line, r,
106 "Invalid syntax, ignoring: %s", rvalue);
107 return 0;
108 }
109
110 r = parse_timestamp(p, &u);
111 if (r < 0) {
112 log_syntax(unit, LOG_WARNING, filename, line, r,
113 "Failed to parse timestamp, ignoring: %s", p);
114 return 0;
115 }
116
117 duid->llt_time = u;
118 }
119
120 duid->type = type;
121
122 return 0;
123 }
124
125 int config_parse_duid_rawdata(
126 const char *unit,
127 const char *filename,
128 unsigned line,
129 const char *section,
130 unsigned section_line,
131 const char *lvalue,
132 int ltype,
133 const char *rvalue,
134 void *data,
135 void *userdata) {
136
137 DUID *ret = data;
138 uint8_t raw_data[MAX_DUID_LEN];
139 unsigned count = 0;
140
141 assert(filename);
142 assert(lvalue);
143 assert(rvalue);
144 assert(ret);
145
146 /* RawData contains DUID in format "NN:NN:NN..." */
147 for (const char *p = rvalue;;) {
148 int n1, n2, len, r;
149 uint32_t byte;
150 _cleanup_free_ char *cbyte = NULL;
151
152 r = extract_first_word(&p, &cbyte, ":", 0);
153 if (r == -ENOMEM)
154 return log_oom();
155 if (r < 0) {
156 log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to read DUID, ignoring assignment: %s.", rvalue);
157 return 0;
158 }
159 if (r == 0)
160 break;
161
162 if (count >= MAX_DUID_LEN) {
163 log_syntax(unit, LOG_WARNING, filename, line, 0, "Max DUID length exceeded, ignoring assignment: %s.", rvalue);
164 return 0;
165 }
166
167 len = strlen(cbyte);
168 if (!IN_SET(len, 1, 2)) {
169 log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid length - DUID byte: %s, ignoring assignment: %s.", cbyte, rvalue);
170 return 0;
171 }
172 n1 = unhexchar(cbyte[0]);
173 if (len == 2)
174 n2 = unhexchar(cbyte[1]);
175 else
176 n2 = 0;
177
178 if (n1 < 0 || n2 < 0) {
179 log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid DUID byte: %s. Ignoring assignment: %s.", cbyte, rvalue);
180 return 0;
181 }
182
183 byte = ((uint8_t) n1 << (4 * (len-1))) | (uint8_t) n2;
184 raw_data[count++] = byte;
185 }
186
187 assert_cc(sizeof(raw_data) == sizeof(ret->raw_data));
188 memcpy(ret->raw_data, raw_data, count);
189 ret->raw_data_len = count;
190 return 0;
191 }