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