]>
Commit | Line | Data |
---|---|---|
a0245818 SE |
1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
2 | /* | |
3 | * Copyright (C) Microsoft Corporation | |
4 | * Author: Sean Edmond <[email protected]> | |
5 | * | |
6 | */ | |
7 | ||
8 | #ifndef __DHCP6_H__ | |
9 | #define __DHCP6_H__ | |
10 | ||
11 | /* Message types */ | |
12 | #define DHCP6_MSG_SOLICIT 1 | |
13 | #define DHCP6_MSG_ADVERTISE 2 | |
14 | #define DHCP6_MSG_REQUEST 3 | |
15 | #define DHCP6_MSG_REPLY 7 | |
16 | ||
17 | /* Option Codes */ | |
18 | #define DHCP6_OPTION_CLIENTID 1 | |
19 | #define DHCP6_OPTION_SERVERID 2 | |
20 | #define DHCP6_OPTION_IA_NA 3 | |
21 | #define DHCP6_OPTION_IA_TA 4 | |
22 | #define DHCP6_OPTION_IAADDR 5 | |
23 | #define DHCP6_OPTION_ORO 6 | |
24 | #define DHCP6_OPTION_PREFERENCE 7 | |
25 | #define DHCP6_OPTION_ELAPSED_TIME 8 | |
26 | #define DHCP6_OPTION_STATUS_CODE 13 | |
27 | #define DHCP6_OPTION_OPT_BOOTFILE_URL 59 | |
28 | #define DHCP6_OPTION_OPT_BOOTFILE_PARAM 60 | |
29 | #define DHCP6_OPTION_SOL_MAX_RT 82 | |
30 | #define DHCP6_OPTION_CLIENT_ARCH_TYPE 61 | |
31 | #define DHCP6_OPTION_VENDOR_CLASS 16 | |
32 | #define DHCP6_OPTION_NII 62 | |
33 | ||
34 | /* DUID */ | |
35 | #define DUID_TYPE_LL 3 | |
36 | #define DUID_HW_TYPE_ENET 1 | |
37 | #define DUID_LL_SIZE (sizeof(struct dhcp6_option_duid_ll) + ETH_ALEN) | |
38 | #define DUID_MAX_SIZE DUID_LL_SIZE /* only supports DUID-LL currently */ | |
39 | ||
40 | /* vendor-class-data to send in vendor clas option */ | |
2f7c7159 | 41 | #define DHCP6_VCI_STRING "U-Boot" |
a0245818 SE |
42 | |
43 | #define DHCP6_MULTICAST_ADDR "ff02::1:2" /* DHCP multicast address */ | |
44 | ||
45 | /* DHCP6 States supported */ | |
46 | enum dhcp6_state { | |
47 | DHCP6_INIT, | |
48 | DHCP6_SOLICIT, | |
49 | DHCP6_REQUEST, | |
50 | DHCP6_DONE, | |
51 | DHCP6_FAIL, | |
52 | }; | |
53 | ||
54 | /* DHCP6 Status codes */ | |
55 | enum dhcp6_status { | |
56 | DHCP6_SUCCESS = 0, | |
57 | DHCP6_UNSPEC_FAIL = 1, | |
58 | DHCP6_NO_ADDRS_AVAIL = 2, | |
59 | DHCP6_NO_BINDING = 3, | |
60 | DHCP6_NOT_ON_LINK = 4, | |
61 | DHCP6_USE_MULTICAST = 5, | |
62 | DHCP6_NO_PREFIX_AVAIL = 6, | |
63 | }; | |
64 | ||
65 | /* DHCP6 message header format */ | |
66 | struct dhcp6_hdr { | |
67 | unsigned int msg_type : 8; /* message type */ | |
68 | unsigned int trans_id : 24; /* transaction ID */ | |
69 | } __packed; | |
70 | ||
71 | /* DHCP6 option header format */ | |
72 | struct dhcp6_option_hdr { | |
73 | __be16 option_id; /* option id */ | |
74 | __be16 option_len; /* Option length */ | |
75 | u8 option_data[0]; /* Option data */ | |
76 | } __packed; | |
77 | ||
78 | /* DHCP6_OPTION_CLIENTID option (DUID-LL) */ | |
79 | struct dhcp6_option_duid_ll { | |
80 | __be16 duid_type; | |
81 | __be16 hw_type; | |
82 | u8 ll_addr[0]; | |
83 | } __packed; | |
84 | ||
85 | /* DHCP6_OPTION_ELAPSED_TIME option */ | |
86 | struct dhcp6_option_elapsed_time { | |
87 | __be16 elapsed_time; | |
88 | } __packed; | |
89 | ||
90 | /* DHCP6_OPTION_IA_TA option */ | |
91 | struct dhcp6_option_ia_ta { | |
92 | __be32 iaid; | |
93 | u8 ia_ta_options[0]; | |
94 | } __packed; | |
95 | ||
96 | /* DHCP6_OPTION_IA_NA option */ | |
97 | struct dhcp6_option_ia_na { | |
98 | __be32 iaid; | |
99 | __be32 t1; | |
100 | __be32 t2; | |
101 | u8 ia_na_options[0]; | |
102 | } __packed; | |
103 | ||
104 | /* OPTION_ORO option */ | |
105 | struct dhcp6_option_oro { | |
106 | __be16 req_option_code[0]; | |
107 | } __packed; | |
108 | ||
109 | /* DHCP6_OPTION_CLIENT_ARCH_TYPE option */ | |
110 | struct dhcp6_option_client_arch { | |
111 | __be16 arch_type[0]; | |
112 | } __packed; | |
113 | ||
114 | /* vendor-class-data inside OPTION_VENDOR_CLASS option */ | |
115 | struct vendor_class_data { | |
116 | __be16 vendor_class_len; | |
117 | u8 opaque_data[0]; | |
118 | } __packed; | |
119 | ||
120 | /* DHCP6_OPTION_VENDOR_CLASS option */ | |
121 | struct dhcp6_option_vendor_class { | |
122 | __be32 enterprise_number; | |
123 | struct vendor_class_data vendor_class_data[0]; | |
124 | } __packed; | |
125 | ||
126 | /** | |
127 | * struct dhcp6_rx_pkt_status - Structure that holds status | |
128 | * from a received message | |
129 | * @client_id_match: Client ID was found and matches DUID sent | |
130 | * @server_id_found: Server ID was found in the message | |
131 | * @server_uid_ptr: Pointer to received server ID | |
132 | * @server_uid_size: Size of received server ID | |
133 | * @ia_addr_found: IA addr option was found in received message | |
134 | * @ia_addr_ipv6: The IPv6 address received in IA | |
135 | * @ia_status_code: Status code received in the IA | |
136 | * @status_code: Top-level status code received | |
137 | * @preference: Preference code received | |
138 | */ | |
139 | struct dhcp6_rx_pkt_status { | |
140 | bool client_id_match; | |
141 | bool server_id_found; | |
142 | uchar *server_uid_ptr; | |
143 | u16 server_uid_size; | |
144 | bool ia_addr_found; | |
145 | struct in6_addr ia_addr_ipv6; | |
146 | enum dhcp6_status ia_status_code; | |
147 | enum dhcp6_status status_code; | |
148 | u8 preference; | |
149 | }; | |
150 | ||
151 | /** | |
152 | * struct dhcp6_server_uid - Structure that holds the server UID | |
153 | * received from an ADVERTISE and saved | |
154 | * given the server selection criteria. | |
155 | * @uid_ptr: Dynamically allocated and copied server UID | |
156 | * @uid_size: Size of the server UID in uid_ptr (in bytes) | |
157 | * @preference: Preference code associated with this server UID | |
158 | */ | |
159 | struct dhcp6_server_uid { | |
160 | uchar *uid_ptr; | |
161 | u16 uid_size; | |
162 | u8 preference; | |
163 | }; | |
164 | ||
165 | /** | |
166 | * struct dhcp6_sm_params - Structure that holds DHCP6 | |
167 | * state machine parameters | |
168 | * @curr_state: current DHCP6 state | |
169 | * @next_state: next DHCP6 state | |
170 | * @dhcp6_start_ms: timestamp DHCP6 start | |
171 | * @dhcp6_retry_start_ms: timestamp of current TX message start | |
172 | * @dhcp6_retry_ms: timestamp of last retransmission | |
173 | * @retry_cnt: retry count | |
174 | * @trans_id: transaction ID | |
175 | * @ia_id: transmitted IA ID | |
176 | * @irt_ms: Initial retransmission time (in ms) | |
177 | * @mrt_ms: Maximum retransmission time (in ms) | |
178 | * @mrc: Maximum retransmission count | |
179 | * @mrd_ms: Maximum retransmission duration (in ms) | |
180 | * @rt_ms: retransmission timeout (is ms) | |
181 | * @rt_prev_ms: previous retransmission timeout | |
182 | * @rx_status: Status from received message | |
183 | * @server_uid: Saved Server UID for selected server | |
184 | * @duid: pointer to transmitted Client DUID | |
185 | */ | |
186 | struct dhcp6_sm_params { | |
187 | enum dhcp6_state curr_state; | |
188 | enum dhcp6_state next_state; | |
189 | ulong dhcp6_start_ms; | |
190 | ulong dhcp6_retry_start_ms; | |
191 | ulong dhcp6_retry_ms; | |
192 | u32 retry_cnt; | |
193 | u32 trans_id; | |
194 | u32 ia_id; | |
195 | int irt_ms; | |
196 | int mrt_ms; | |
197 | int mrc; | |
198 | int mrd_ms; | |
199 | int rt_ms; | |
200 | int rt_prev_ms; | |
201 | struct dhcp6_rx_pkt_status rx_status; | |
202 | struct dhcp6_server_uid server_uid; | |
203 | char duid[DUID_MAX_SIZE]; | |
204 | }; | |
205 | ||
206 | /* Starts a DHCPv6 4-message exchange as a DHCPv6 client. On successful exchange, | |
207 | * the DHCPv6 state machine will transition from internal states: | |
208 | * DHCP6_INIT->DHCP6_SOLICIT->DHCP6_REQUEST->DHCP6_DONE | |
209 | * | |
210 | * Transmitted SOLICIT and REQUEST packets will set/request the minimum required | |
211 | * DHCPv6 options to PXE boot. | |
212 | * | |
213 | * After a successful exchange, the DHCPv6 assigned address will be set in net_ip6 | |
214 | * | |
215 | * Additionally, the following will be set after receiving these options: | |
216 | * DHCP6_OPTION_OPT_BOOTFILE_URL (option 59) -> net_server_ip6, net_boot_file_name | |
217 | * DHCP6_OPTION_OPT_BOOTFILE_PARAM (option 60) - > pxelinux_configfile | |
218 | * | |
219 | * Illustration of a 4-message exchange with 2 servers (copied from | |
220 | * https://www.rfc-editor.org/rfc/rfc8415): | |
221 | * | |
222 | * Server Server | |
223 | * (not selected) Client (selected) | |
224 | * | |
225 | * v v v | |
226 | * | | | | |
227 | * | Begins initialization | | |
228 | * | | | | |
229 | * start of | _____________/|\_____________ | | |
230 | * 4-message |/ Solicit | Solicit \| | |
231 | * exchange | | | | |
232 | * Determines | Determines | |
233 | * configuration | configuration | |
234 | * | | | | |
235 | * |\ | ____________/| | |
236 | * | \________ | /Advertise | | |
237 | * | Advertise\ |/ | | |
238 | * | \ | | | |
239 | * | Collects Advertises | | |
240 | * | \ | | | |
241 | * | Selects configuration | | |
242 | * | | | | |
243 | * | _____________/|\_____________ | | |
244 | * |/ Request | Request \| | |
245 | * | | | | |
246 | * | | Commits configuration | |
247 | * | | | | |
248 | * end of | | _____________/| | |
249 | * 4-message | |/ Reply | | |
250 | * exchange | | | | |
251 | * | Initialization complete | | |
252 | * | | | | |
253 | */ | |
254 | void dhcp6_start(void); | |
255 | ||
256 | #endif /* __DHCP6_H__ */ |