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