123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- /* SPDX-License-Identifier: GPL-2.0+ */
- /*
- * Copyright (C) Microsoft Corporation
- * Author: Sean Edmond <seanedmond@microsoft.com>
- *
- */
- #ifndef __DHCP6_H__
- #define __DHCP6_H__
- /* Message types */
- #define DHCP6_MSG_SOLICIT 1
- #define DHCP6_MSG_ADVERTISE 2
- #define DHCP6_MSG_REQUEST 3
- #define DHCP6_MSG_REPLY 7
- /* Option Codes */
- #define DHCP6_OPTION_CLIENTID 1
- #define DHCP6_OPTION_SERVERID 2
- #define DHCP6_OPTION_IA_NA 3
- #define DHCP6_OPTION_IA_TA 4
- #define DHCP6_OPTION_IAADDR 5
- #define DHCP6_OPTION_ORO 6
- #define DHCP6_OPTION_PREFERENCE 7
- #define DHCP6_OPTION_ELAPSED_TIME 8
- #define DHCP6_OPTION_STATUS_CODE 13
- #define DHCP6_OPTION_OPT_BOOTFILE_URL 59
- #define DHCP6_OPTION_OPT_BOOTFILE_PARAM 60
- #define DHCP6_OPTION_SOL_MAX_RT 82
- #define DHCP6_OPTION_CLIENT_ARCH_TYPE 61
- #define DHCP6_OPTION_VENDOR_CLASS 16
- #define DHCP6_OPTION_NII 62
- /* DUID */
- #define DUID_TYPE_LL 3
- #define DUID_HW_TYPE_ENET 1
- #define DUID_LL_SIZE (sizeof(struct dhcp6_option_duid_ll) + ETH_ALEN)
- #define DUID_MAX_SIZE DUID_LL_SIZE /* only supports DUID-LL currently */
- /* vendor-class-data to send in vendor clas option */
- #define DHCP6_VCI_STRING "U-Boot"
- #define DHCP6_MULTICAST_ADDR "ff02::1:2" /* DHCP multicast address */
- /* DHCP6 States supported */
- enum dhcp6_state {
- DHCP6_INIT,
- DHCP6_SOLICIT,
- DHCP6_REQUEST,
- DHCP6_DONE,
- DHCP6_FAIL,
- };
- /* DHCP6 Status codes */
- enum dhcp6_status {
- DHCP6_SUCCESS = 0,
- DHCP6_UNSPEC_FAIL = 1,
- DHCP6_NO_ADDRS_AVAIL = 2,
- DHCP6_NO_BINDING = 3,
- DHCP6_NOT_ON_LINK = 4,
- DHCP6_USE_MULTICAST = 5,
- DHCP6_NO_PREFIX_AVAIL = 6,
- };
- /* DHCP6 message header format */
- struct dhcp6_hdr {
- unsigned int msg_type : 8; /* message type */
- unsigned int trans_id : 24; /* transaction ID */
- } __packed;
- /* DHCP6 option header format */
- struct dhcp6_option_hdr {
- __be16 option_id; /* option id */
- __be16 option_len; /* Option length */
- u8 option_data[0]; /* Option data */
- } __packed;
- /* DHCP6_OPTION_CLIENTID option (DUID-LL) */
- struct dhcp6_option_duid_ll {
- __be16 duid_type;
- __be16 hw_type;
- u8 ll_addr[0];
- } __packed;
- /* DHCP6_OPTION_ELAPSED_TIME option */
- struct dhcp6_option_elapsed_time {
- __be16 elapsed_time;
- } __packed;
- /* DHCP6_OPTION_IA_TA option */
- struct dhcp6_option_ia_ta {
- __be32 iaid;
- u8 ia_ta_options[0];
- } __packed;
- /* DHCP6_OPTION_IA_NA option */
- struct dhcp6_option_ia_na {
- __be32 iaid;
- __be32 t1;
- __be32 t2;
- u8 ia_na_options[0];
- } __packed;
- /* OPTION_ORO option */
- struct dhcp6_option_oro {
- __be16 req_option_code[0];
- } __packed;
- /* DHCP6_OPTION_CLIENT_ARCH_TYPE option */
- struct dhcp6_option_client_arch {
- __be16 arch_type[0];
- } __packed;
- /* vendor-class-data inside OPTION_VENDOR_CLASS option */
- struct vendor_class_data {
- __be16 vendor_class_len;
- u8 opaque_data[0];
- } __packed;
- /* DHCP6_OPTION_VENDOR_CLASS option */
- struct dhcp6_option_vendor_class {
- __be32 enterprise_number;
- struct vendor_class_data vendor_class_data[0];
- } __packed;
- /**
- * struct dhcp6_rx_pkt_status - Structure that holds status
- * from a received message
- * @client_id_match: Client ID was found and matches DUID sent
- * @server_id_found: Server ID was found in the message
- * @server_uid_ptr: Pointer to received server ID
- * @server_uid_size: Size of received server ID
- * @ia_addr_found: IA addr option was found in received message
- * @ia_addr_ipv6: The IPv6 address received in IA
- * @ia_status_code: Status code received in the IA
- * @status_code: Top-level status code received
- * @preference: Preference code received
- */
- struct dhcp6_rx_pkt_status {
- bool client_id_match;
- bool server_id_found;
- uchar *server_uid_ptr;
- u16 server_uid_size;
- bool ia_addr_found;
- struct in6_addr ia_addr_ipv6;
- enum dhcp6_status ia_status_code;
- enum dhcp6_status status_code;
- u8 preference;
- };
- /**
- * struct dhcp6_server_uid - Structure that holds the server UID
- * received from an ADVERTISE and saved
- * given the server selection criteria.
- * @uid_ptr: Dynamically allocated and copied server UID
- * @uid_size: Size of the server UID in uid_ptr (in bytes)
- * @preference: Preference code associated with this server UID
- */
- struct dhcp6_server_uid {
- uchar *uid_ptr;
- u16 uid_size;
- u8 preference;
- };
- /**
- * struct dhcp6_sm_params - Structure that holds DHCP6
- * state machine parameters
- * @curr_state: current DHCP6 state
- * @next_state: next DHCP6 state
- * @dhcp6_start_ms: timestamp DHCP6 start
- * @dhcp6_retry_start_ms: timestamp of current TX message start
- * @dhcp6_retry_ms: timestamp of last retransmission
- * @retry_cnt: retry count
- * @trans_id: transaction ID
- * @ia_id: transmitted IA ID
- * @irt_ms: Initial retransmission time (in ms)
- * @mrt_ms: Maximum retransmission time (in ms)
- * @mrc: Maximum retransmission count
- * @mrd_ms: Maximum retransmission duration (in ms)
- * @rt_ms: retransmission timeout (is ms)
- * @rt_prev_ms: previous retransmission timeout
- * @rx_status: Status from received message
- * @server_uid: Saved Server UID for selected server
- * @duid: pointer to transmitted Client DUID
- */
- struct dhcp6_sm_params {
- enum dhcp6_state curr_state;
- enum dhcp6_state next_state;
- ulong dhcp6_start_ms;
- ulong dhcp6_retry_start_ms;
- ulong dhcp6_retry_ms;
- u32 retry_cnt;
- u32 trans_id;
- u32 ia_id;
- int irt_ms;
- int mrt_ms;
- int mrc;
- int mrd_ms;
- int rt_ms;
- int rt_prev_ms;
- struct dhcp6_rx_pkt_status rx_status;
- struct dhcp6_server_uid server_uid;
- char duid[DUID_MAX_SIZE];
- };
- /* Starts a DHCPv6 4-message exchange as a DHCPv6 client. On successful exchange,
- * the DHCPv6 state machine will transition from internal states:
- * DHCP6_INIT->DHCP6_SOLICIT->DHCP6_REQUEST->DHCP6_DONE
- *
- * Transmitted SOLICIT and REQUEST packets will set/request the minimum required
- * DHCPv6 options to PXE boot.
- *
- * After a successful exchange, the DHCPv6 assigned address will be set in net_ip6
- *
- * Additionally, the following will be set after receiving these options:
- * DHCP6_OPTION_OPT_BOOTFILE_URL (option 59) -> net_server_ip6, net_boot_file_name
- * DHCP6_OPTION_OPT_BOOTFILE_PARAM (option 60) - > pxelinux_configfile
- *
- * Illustration of a 4-message exchange with 2 servers (copied from
- * https://www.rfc-editor.org/rfc/rfc8415):
- *
- * Server Server
- * (not selected) Client (selected)
- *
- * v v v
- * | | |
- * | Begins initialization |
- * | | |
- * start of | _____________/|\_____________ |
- * 4-message |/ Solicit | Solicit \|
- * exchange | | |
- * Determines | Determines
- * configuration | configuration
- * | | |
- * |\ | ____________/|
- * | \________ | /Advertise |
- * | Advertise\ |/ |
- * | \ | |
- * | Collects Advertises |
- * | \ | |
- * | Selects configuration |
- * | | |
- * | _____________/|\_____________ |
- * |/ Request | Request \|
- * | | |
- * | | Commits configuration
- * | | |
- * end of | | _____________/|
- * 4-message | |/ Reply |
- * exchange | | |
- * | Initialization complete |
- * | | |
- */
- void dhcp6_start(void);
- #endif /* __DHCP6_H__ */
|