2 This file is part of systemd.
4 Copyright 2014 Vinay Kulkarni <kulkarniv@vmware.com>
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include "conf-parser.h"
24 #include "dhcp-identifier.h"
25 #include "hexdecoct.h"
26 #include "networkd-conf.h"
27 #include "string-table.h"
29 int manager_parse_config_file(Manager
*m
) {
32 return config_parse_many(PKGSYSCONFDIR
"/networkd.conf",
33 CONF_PATHS_NULSTR("systemd/networkd.conf.d"),
35 config_item_perf_lookup
, networkd_gperf_lookup
,
39 static const char* const duid_type_table
[_DUID_TYPE_MAX
] = {
40 [DUID_TYPE_RAW
] = "raw",
41 [DUID_TYPE_LLT
] = "link-layer-time",
42 [DUID_TYPE_EN
] = "vendor",
43 [DUID_TYPE_LL
] = "link-layer",
44 [DUID_TYPE_UUID
] = "uuid"
46 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(duid_type
, DUIDType
);
47 DEFINE_CONFIG_PARSE_ENUM(config_parse_duid_type
, duid_type
, DUIDType
, "Failed to parse DUID type");
49 int config_parse_duid_rawdata(
54 unsigned section_line
,
63 const char *pduid
= rvalue
;
64 Manager
*m
= userdata
;
65 Network
*n
= userdata
;
67 uint16_t dhcp_duid_type
= 0;
68 uint8_t dhcp_duid
[MAX_DUID_LEN
];
69 size_t len
, count
= 0, duid_start_offset
= 0, dhcp_duid_len
= 0;
76 duidtype
= (ltype
== DUID_CONFIG_SOURCE_GLOBAL
) ? m
->duid_type
: n
->duid_type
;
78 if (duidtype
== _DUID_TYPE_INVALID
)
79 duidtype
= DUID_TYPE_RAW
;
84 /* RawData contains DUID-LLT link-layer address (offset 6) */
85 duid_start_offset
= 6;
89 /* RawData contains DUID-EN identifier (offset 4) */
90 duid_start_offset
= 4;
94 /* RawData contains DUID-LL link-layer address (offset 2) */
95 duid_start_offset
= 2;
99 /* RawData specifies UUID (offset 0) - fall thru */
102 /* First two bytes of RawData is DUID Type - fall thru */
108 if (duidtype
!= DUID_TYPE_RAW
)
109 dhcp_duid_type
= (uint16_t) duidtype
;
111 /* RawData contains DUID in format " NN:NN:NN... " */
116 r
= extract_first_word(&pduid
, &cbyte
, ":", 0);
118 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to read DUID, ignoring assignment: %s.", rvalue
);
123 if (duid_start_offset
+ dhcp_duid_len
>= MAX_DUID_LEN
) {
124 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Max DUID length exceeded, ignoring assignment: %s.", rvalue
);
129 if (len
!= 1 && len
!= 2) {
130 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Invalid length - DUID byte: %s, ignoring assignment: %s.", cbyte
, rvalue
);
133 n1
= unhexchar(cbyte
[0]);
135 n2
= unhexchar(cbyte
[1]);
139 if (n1
< 0 || n2
< 0) {
140 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Invalid DUID byte: %s. Ignoring assignment: %s.", cbyte
, rvalue
);
144 byte
= ((uint8_t) n1
<< (4 * (len
-1))) | (uint8_t) n2
;
146 /* If DUID_TYPE_RAW, first two bytes hold DHCP DUID type code */
147 if (duidtype
== DUID_TYPE_RAW
&& count
< 2) {
148 dhcp_duid_type
|= (byte
<< (8 * (1 - count
)));
153 dhcp_duid
[duid_start_offset
+ dhcp_duid_len
] = byte
;
157 if (ltype
== DUID_CONFIG_SOURCE_GLOBAL
) {
158 m
->duid_type
= duidtype
;
159 m
->dhcp_duid_type
= dhcp_duid_type
;
160 m
->dhcp_duid_len
= dhcp_duid_len
;
161 memcpy(&m
->dhcp_duid
[duid_start_offset
], dhcp_duid
, dhcp_duid_len
);
163 /* DUID_CONFIG_SOURCE_NETWORK */
164 n
->duid_type
= duidtype
;
165 n
->dhcp_duid_type
= dhcp_duid_type
;
166 n
->dhcp_duid_len
= dhcp_duid_len
;
167 memcpy(&n
->dhcp_duid
[duid_start_offset
], dhcp_duid
, dhcp_duid_len
);