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