第 1 章 - Azure RTOS NetX Duo DHCPv6 客户端简介

在 IPv6 网络中,DHCPv6 会将 DHCP 替换为 DHCPv6 服务器中的动态全局 IP 地址分配,并提供大部分相同的功能以及许多增强功能。 本文档将详细介绍如何使用 Azure RTOS NetX Duo DHCPv6 客户端 API 来获取 IPv6 地址。

DHCPv6 通信

DHCPv6 协议使用 UDP。 客户端和服务器分别使用端口 546 和端口 547 来交换 DHCPv6 消息。 客户端将其链路本地地址用作源地址,来向可用的 DHCPv6 服务器启动 DHCPv6 请求。 当客户端发送面向网络上所有 DHCPv6 服务器的消息时,它使用 All_DHCP_Relay_Agents_and_Servers 多播地址 FF02::01:02。 这是保留的链路范围多播地址。

请求 IPv6 地址的 DHCPv6 过程

若要开始请求全局 IPv6 地址分配的过程,客户端首先需要使用 nx_dhcpv6_send_solicit 服务发送 SOLICIT 消息:

UINT nx_dhcpv6_request_solicit(NX_DHCPV6 *dhcpv6_ptr)

此消息使用 All_DHCP_Relay_Agents_and_Servers 地址发送到所有服务器。 在 SOLICIT 请求中,客户端可能会请求分配特定 IPv6 地址以提示服务器。 客户端可能还会在 SOLICIT 消息的 Option 请求中从服务器(例如 DNS 服务器或 NTP 服务器)请求其他网络配置信息及其他选项。

可为客户端请求提供服务的 DHCPv6 服务器将使用 ADVERTISE 消息做出响应,该消息包含可分配给客户端的 IPv6 地址、IPv6 地址租用时间以及客户端请求的任何其他信息。 DHCPv6 客户端协议要求客户端等待一段时间,以从网络上的所有 DHCPv6 服务器接收 ADVERTISE 消息。 客户端将对每条 ADVERTISE 消息进行预处理以使其成为有效的消息,并扫描选项数据以获取各个 DHCPv6 参数。 客户端还会检查“首选项”选项中的首选项值(如果服务器提供)。 如果收到多条 ADVERTISE 消息,NetX DHCPv6 客户端会选择等待期结束时从中收到最高首选项值的服务器。

客户端收到首选项值为 255 的 ADVERTISE 消息时除外。 客户端会立即接受该消息,并放弃所有后续 ADVERTISE 消息。

如果 DHCPv6 客户端没有从任何服务器收到响应,则会在等待一段时间后重新发送一条 SOLICIT 消息,而其所等待的这段重新传输期即定义为等待期。 RFC 3315 所述的 DHCPv6 协议将 SOLICIT 状态下的初始重新传输超时定义为 1 秒。 如果 DHCPv6 客户端无法收到有效的服务器响应,后续重新传输间隔会翻倍,最长为 120 秒。

选择服务器后,客户端将从 ADVERTISE 消息提取数据,并向服务器发回 REQUEST 消息以接受已分配的地址信息和租用时间。 服务器将使用 REPLY 消息做出响应,确认客户端 IPv6 地址已向服务器注册为已分配给客户端。

DHCPv6 客户端将向 IP 实例(例如 NetX Duo)注册已分配的 IPv6 地址。 如果为重复地址检测 (DAD) 协议(默认启用)进行了配置,NetX Duo 将自动发送 Neighbor Solicit 消息,验证已分配的地址在网络上是否唯一。 如果是唯一的,则当每个已分配的地址都从 TENTATIVE 提升至 VALID 时,它会通知 DHCPv6 客户端。 DHCPv6 客户端将提升至 BOUND 状态,并且设备可能会使用该 IPv6 地址来发送和传输消息。 如果 DAD 协议验证未通过,NetX Duo 会通知 DHCPv6 客户端,DHCPv6 客户端将为已分配的 IPv6 地址向服务器发回 DECLINE 消息并将 DHCPv6 客户端状态重置为 INIT。

地址分配和验证成功的通知

如果在 nx_dhcpv6_client_create 服务中为 DHCPv6 客户端配置了状态更改回调,则应用程序可以根据状态更改确定 DHCPv6 客户端地址请求的结果。 如果客户端没有从服务器收到任何响应,则会观察到状态从 SOLICIT 更改为 INIT。 如果客户端从服务器收到了响应,但服务器无法分配地址,则 DHCPv6 客户端服务器错误回调(如果已在 nx_dhcpv6_client_create 服务中配置)会通知应用程序。如果客户端实现了绑定状态,但随后失败了 DAD 检查,则会看到从绑定到 INIT 的状态发生了更改。 请注意,启用了 DAD 的应用程序必须留出一定时间来完成 DAD 检查,然后再开始请求过程。 通常,该时间约为 400-500 个时钟周期(在大部分情况下为 4-5 秒)。

放弃 IPv6 地址

当客户端需要释放已分配的 IPv6 地址时,它会通过调用 nx_dhcpv6_request_release 服务来通知 DHCPv6 服务器:

UINT nx_dhcpv6_request_release(NX_DHCPV6 *dhcpv6_ptr)

DHCPv6 客户端将向分配地址的服务器发送包含已分配的地址的单播 RELEASE 消息,并等待接收 REPLY 消息以确认服务器收到了该消息。

注意:对于将关闭电源但计划在重启后继续使用已分配的 IPv6 地址的客户端,过程有所不同。 除非客户端计划在打开电源后请求新地址,否则关闭电源时不会发送 RELEASE 消息。 有关此情况的说明,请参阅“非易失性内存要求”。

DHCPv6 租约超时

在每个非临时地址身份关联 (IANA) 块中,服务器分配的 IPv6 租约包含两个超时参数:T1 和 T2。 本用户指南的其他章节介绍 IANA。 如果 DHCPv6 客户绑定到已分配的 IPv6 地址后的经过时间等于 T1,则 DHCPv6 客户端会通过发送 RENEW 消息自动开始续订 IPv6 地址。 如果经过时间等于 T2,则当 RENEW 请求未收到任何响应时,DHCPv6 客户端会自动发送 REBIND 消息。

服务器会随 IANA 块中包含的每个身份关联 (IA) 块一起分配另外两个 IPv6 租约参数:首选生存期和有效生存期。 首选生存期和有效生存期分别指已分配的 IPv6 地址被弃用或失效的时间。 T1 必须小于首选生存期。 T2 必须小于有效生存期。

IP 线程任务要求

在创建 DHCPv6 客户端以使用 DHCPv6 客户端服务之前,NetX Duo DHCPv6 客户端要求创建 NetX Duo IP 实例。

使用 DHCPv6 客户端之前,必须在 IP 实例上启用 UDP、IPv6 和 ICMPv6。

  • nx_udp_enable

  • nxd_ipv6_enable

  • nxd_icmp_enable

数据包池要求

在创建 NetX Duo DHCPv6 客户端之前,需要先创建数据包池以用于发送 DHCPv6 消息。 与数据包有效负载和可用数据包数相关的数据包池大小可由用户配置,并取决于应用程序将发送的 DHCPv6 消息及其他传输数据的预计数量。

典型的 DHCPv6 消息约为 200 个字节,具体取决于客户端请求的 IA 地址和 DHCPv6 选项的数量。

网络要求

NetX Duo DHCPv6 客户端要求创建绑定到端口 546 的 UDP 套接字。 该套接字在创建 DHCPv6 客户端任务时创建。

非易失性内存要求

如果 DHCPv6 客户端在关闭电源时解除其与 DHCPv6 服务器的 IPv6 租约,并在重启后请求新的 IPv6 地址,则不需要非易失性内存存储。 如果客户端希望继续使用已分配的租约,则必须在重启时将有关 DHCPv6 客户端的某些信息存储到非易失性内容。

第 2 章中的“使用 NetX Duo DHCPv6 客户端”进一步介绍非易失性内存要求和 DHCPv6 客户端 API。

NetX Duo DHCPv6 客户端限制

NetX Duo DHCPv6 客户端的当前版本存在以下限制:

  • 即使服务器指明允许这样做,NetX Duo DHCPv6 客户端也不支持使用服务器单播选项向 DHCPv6 服务器发送单播 DHCPv6 消息。

  • NetX Duo DHCPv6 客户端不支持 Reconfigure 请求,当发送该请求时,服务器将对网络上的客户端启动 IPv6 地址更改。

  • NetX Duo DHCPv6 客户端不支持 DHCPv6 唯一标识符控制块的“企业”格式, 它仅支持“链路层”格式和“链路层加时间”格式。

  • NetX Duo DHCPv6 客户端不支持临时关联 (TA) 地址请求,但支持非临时 (IANA) 选项请求。

多宿主和多地址支持

DHCPv6 客户端支持多个接口和每个接口多个地址。 DHCPv6 客户端服务 nx_dhcpv6_client_set_interface 使客户端应用程序可以设置应用程序将在其上与 DHCPv6 服务器通信的网络接口。 DHCPv6 客户端默认为主接口(索引为零)。

对于每个接口多个地址,DHCPv6 客户端会保留地址的内部列表,该列表从索引 0 开始。 请注意,向 DHCPv6 客户端注册的同一个地址在接口地址的 IP 表中不一定位于同一个索引。

对于用于检索有关客户端 IPv6 地址租约的信息的 DHCPv6 客户端服务,有些服务要求指定地址索引。 获取首选生存期和有效生存期的示例如下:

UINT nx_dhcpv6_get_valid_ip_address_lease_time(NX_DHCPV6 *dhcpv6_ptr, 
											  UINT address_index, 
											  NXD_ADDRESS *ip_address,
                                              ULONG preferred_lifetime, 
											  ULONG *valid_lifetime)

客户端应用程序也可以使用 nx_dhcpv6_get_valid_ip_address_count 服务来检索已分配的有效 IPv6 地址数量:

UINT nx_dhcpv6_get_valid_ip_address_count(NX_DHCPV6 *dhcpv6_ptr, 
										  UINT *address_count)

在 NetX Duo 实现多地址支持前创建的旧版 DHCPv6 客户端服务不接受地址索引。 因此,使用这些服务时,无论为客户端分配的 IA 地址数为多少,都会从主要全局 IA 地址获取所请求的数据。 下面显示了一个示例:

UINT nx_dhcpv6_get_IP_address(NX_DHCPV6 *dhcpv6_ptr, 
                              NXD_ADDRESS *ip_address)

NetX Duo DHCPv6 客户端回调函数

nx_dhcpv6_state_change_callback

当 DHCPv6 客户端在处理 DHCPv6 请求后更改为新的 DHCPv6 状态时,会使用此回调函数通知应用程序。

nx_dhcpv6_server_error_handler

当 DHCPv6 客户端收到的服务器回复包含具有非零(未成功)状态的 Status 选项时,客户端会使用这一包含服务器错误状态代码的回调通知应用程序。

注意:这些回调函数通过 DHCPv6 客户端线程任务进行调用,因此客户端应用程序不能调用任何需要对 DHCPv6 客户端进行互斥控制的 NetX Duo DHCPv6 客户端服务(例如 nx_dhcpv6_start 和 nx_dhcpv6_stop),也不能调用任何直接通过回调发送消息的 API(例如 nx_dhcpv6_request_release)。

DHCPv6 RFC

NetX Duo DHCP 符合 RFC3315、RFC3646 和相关 RFC。