]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-conf.c
core: move reset_arguments() to the end of main's finish
[thirdparty/systemd.git] / src / network / networkd-conf.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
413708d1 2/***
96b2fb93 3 Copyright © 2014 Vinay Kulkarni <kulkarniv@vmware.com>
413708d1
VK
4 ***/
5
6#include <ctype.h>
afe42aef 7#include <netinet/ip.h>
413708d1
VK
8
9#include "conf-parser.h"
10#include "def.h"
11#include "dhcp-identifier.h"
23f53b99 12#include "extract-word.h"
b7f71444 13#include "hexdecoct.h"
413708d1 14#include "networkd-conf.h"
a879e1a4 15#include "networkd-manager.h"
23f53b99 16#include "networkd-network.h"
a879e1a4 17#include "networkd-speed-meter.h"
afe42aef 18#include "networkd-dhcp4.h"
413708d1
VK
19#include "string-table.h"
20
21int manager_parse_config_file(Manager *m) {
a879e1a4
YW
22 int r;
23
413708d1
VK
24 assert(m);
25
4f9ff96a
LP
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);
a879e1a4
YW
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;
413708d1
VK
47}
48
49static const char* const duid_type_table[_DUID_TYPE_MAX] = {
413708d1
VK
50 [DUID_TYPE_LLT] = "link-layer-time",
51 [DUID_TYPE_EN] = "vendor",
52 [DUID_TYPE_LL] = "link-layer",
8341a5c3 53 [DUID_TYPE_UUID] = "uuid",
413708d1
VK
54};
55DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(duid_type, DUIDType);
0cf7c3fd
YW
56
57int 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}
413708d1
VK
124
125int 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) {
076ea6f6 136
8341a5c3
ZJS
137 DUID *ret = data;
138 uint8_t raw_data[MAX_DUID_LEN];
139 unsigned count = 0;
413708d1
VK
140
141 assert(filename);
142 assert(lvalue);
143 assert(rvalue);
8341a5c3 144 assert(ret);
413708d1 145
8341a5c3 146 /* RawData contains DUID in format "NN:NN:NN..." */
d96edb2c 147 for (const char *p = rvalue;;) {
8341a5c3 148 int n1, n2, len, r;
076ea6f6 149 uint32_t byte;
82edec54 150 _cleanup_free_ char *cbyte = NULL;
076ea6f6 151
d96edb2c
YW
152 r = extract_first_word(&p, &cbyte, ":", 0);
153 if (r == -ENOMEM)
154 return log_oom();
413708d1 155 if (r < 0) {
d96edb2c 156 log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to read DUID, ignoring assignment: %s.", rvalue);
076ea6f6 157 return 0;
413708d1
VK
158 }
159 if (r == 0)
160 break;
d96edb2c 161
8341a5c3 162 if (count >= MAX_DUID_LEN) {
d96edb2c 163 log_syntax(unit, LOG_WARNING, filename, line, 0, "Max DUID length exceeded, ignoring assignment: %s.", rvalue);
076ea6f6 164 return 0;
413708d1
VK
165 }
166
b7f71444 167 len = strlen(cbyte);
4c701096 168 if (!IN_SET(len, 1, 2)) {
d96edb2c 169 log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid length - DUID byte: %s, ignoring assignment: %s.", cbyte, rvalue);
076ea6f6 170 return 0;
413708d1 171 }
b7f71444
VK
172 n1 = unhexchar(cbyte[0]);
173 if (len == 2)
174 n2 = unhexchar(cbyte[1]);
076ea6f6
LP
175 else
176 n2 = 0;
177
178 if (n1 < 0 || n2 < 0) {
d96edb2c 179 log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid DUID byte: %s. Ignoring assignment: %s.", cbyte, rvalue);
076ea6f6 180 return 0;
b7f71444 181 }
076ea6f6
LP
182
183 byte = ((uint8_t) n1 << (4 * (len-1))) | (uint8_t) n2;
8341a5c3 184 raw_data[count++] = byte;
b7f71444 185 }
413708d1 186
8341a5c3
ZJS
187 assert_cc(sizeof(raw_data) == sizeof(ret->raw_data));
188 memcpy(ret->raw_data, raw_data, count);
189 ret->raw_data_len = count;
413708d1
VK
190 return 0;
191}