1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** NetX Component */
16 /** */
17 /** Internet Control Message Protocol (ICMP) */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define NX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26
27 #include "nx_api.h"
28 #include "nx_ipv6.h"
29 #include "nx_icmpv6.h"
30
31 #ifdef NX_IPSEC_ENABLE
32 #include "nx_ipsec.h"
33 #endif /* NX_IPSEC_ENABLE */
34
35
36 #ifdef FEATURE_NX_IPV6
37
38
39 /**************************************************************************/
40 /* */
41 /* FUNCTION RELEASE */
42 /* */
43 /* _nx_icmpv6_perform_DAD PORTABLE C */
44 /* 6.1.11 */
45 /* AUTHOR */
46 /* */
47 /* Yuxin Zhou, Microsoft Corporation */
48 /* */
49 /* DESCRIPTION */
50 /* */
51 /* This function is called from IP thread periodic process routine. */
52 /* It starts the Duplicate Address Detection process if the interface */
53 /* address is in tentative state (not validated yet). It does nothing */
54 /* to an address if the state of the address is not tentative. */
55 /* */
56 /* INPUT */
57 /* */
58 /* ip_ptr Pointer to IP instance */
59 /* */
60 /* OUTPUT */
61 /* */
62 /* None */
63 /* */
64 /* CALLS */
65 /* */
66 /* _nx_icmpv6_DAD_clear_NDCache_entry Remove entry from cache table */
67 /* _nx_icmpv6_send_ns Send a Neighbor Solicitation */
68 /* message */
69 /* [ipv6_address_change_notify] User callback fucntion */
70 /* */
71 /* CALLED BY */
72 /* */
73 /* _nx_ip_thraed_entry */
74 /* */
75 /* RELEASE HISTORY */
76 /* */
77 /* DATE NAME DESCRIPTION */
78 /* */
79 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
80 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
81 /* resulting in version 6.1 */
82 /* 04-25-2022 Yuxin Zhou Modified comment(s), and */
83 /* added internal ip address */
84 /* change notification, */
85 /* resulting in version 6.1.11 */
86 /* */
87 /**************************************************************************/
88
89 #ifndef NX_DISABLE_IPV6_DAD
90
_nx_icmpv6_perform_DAD(NX_IP * ip_ptr)91 VOID _nx_icmpv6_perform_DAD(NX_IP *ip_ptr)
92 {
93
94 UINT i;
95 NXD_IPV6_ADDRESS *nx_ipv6_address_next;
96
97 #ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY
98 UINT ipv6_addr_index;
99 #endif /* NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */
100
101 /* Go through all addresses bound to the IP instance. */
102 for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
103 {
104
105 /* Check if this interface valid. */
106 if (!ip_ptr -> nx_ip_interface[i].nxd_interface_ipv6_address_list_head)
107 {
108 continue;
109 }
110
111 /* Only interested in addresses in the tentative state. */
112 for (nx_ipv6_address_next = ip_ptr -> nx_ip_interface[i].nxd_interface_ipv6_address_list_head;
113 nx_ipv6_address_next;
114 nx_ipv6_address_next = nx_ipv6_address_next -> nxd_ipv6_address_next)
115 {
116
117 /* Check the address state. */
118 if (nx_ipv6_address_next -> nxd_ipv6_address_state == NX_IPV6_ADDR_STATE_TENTATIVE)
119 {
120
121 /* Check if the number of NS messages is used up. */
122 if (nx_ipv6_address_next -> nxd_ipv6_address_DupAddrDetectTransmit)
123 {
124
125 /* No. This interface is still under DAD. Transmit a NS */
126 _nx_icmpv6_send_ns(ip_ptr,
127 nx_ipv6_address_next -> nxd_ipv6_address,
128 0, nx_ipv6_address_next, 0, NX_NULL);
129
130 nx_ipv6_address_next -> nxd_ipv6_address_DupAddrDetectTransmit--;
131 }
132 else
133 {
134
135 /* So far we didn't get any conflict addresses back.
136 So promote the address to VALID */
137
138 nx_ipv6_address_next -> nxd_ipv6_address_state = NX_IPV6_ADDR_STATE_VALID;
139 _nx_icmpv6_DAD_clear_NDCache_entry(ip_ptr,
140 nx_ipv6_address_next -> nxd_ipv6_address);
141
142 #ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY
143 /* If the callback function is set, invoke the callback function . */
144 if (ip_ptr -> nx_ipv6_address_change_notify)
145 {
146 ipv6_addr_index = (ULONG)nx_ipv6_address_next -> nxd_ipv6_address_index;
147 ip_ptr -> nx_ipv6_address_change_notify(ip_ptr, NX_IPV6_ADDRESS_DAD_SUCCESSFUL,
148 i, ipv6_addr_index, &nx_ipv6_address_next -> nxd_ipv6_address[0]);
149 }
150
151 /* If the internal callback function is set, invoke the callback function . */
152 if (ip_ptr -> nx_ipv6_address_change_notify_internal)
153 {
154 ipv6_addr_index = (ULONG)nx_ipv6_address_next -> nxd_ipv6_address_index;
155 ip_ptr -> nx_ipv6_address_change_notify_internal(ip_ptr, NX_IPV6_ADDRESS_DAD_SUCCESSFUL,
156 i, ipv6_addr_index, &nx_ipv6_address_next -> nxd_ipv6_address[0]);
157 }
158 #endif /* NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */
159 }
160 }
161 }
162 }
163 }
164
165 #endif /* NX_DISABLE_IPV6_DAD */
166
167
168 #endif /* FEATURE_NX_IPV6 */
169
170