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_DAD_failure                              PORTABLE C      */
44 /*                                                           6.1          */
45 /*  AUTHOR                                                                */
46 /*                                                                        */
47 /*    Yuxin Zhou, Microsoft Corporation                                   */
48 /*                                                                        */
49 /*  DESCRIPTION                                                           */
50 /*                                                                        */
51 /*    This function is called when the DAD process determines that a      */
52 /*    duplicate address is present on the local network.  The interface   */
53 /*    is set to an invalid state.                                         */
54 /*                                                                        */
55 /*  INPUT                                                                 */
56 /*                                                                        */
57 /*    ip_ptr                                IP stack instance             */
58 /*    ipv6_address                          The local IPv6 interface      */
59 /*                                            that detects the failure.   */
60 /*                                                                        */
61 /*  OUTPUT                                                                */
62 /*                                                                        */
63 /*    None                                                                */
64 /*                                                                        */
65 /*  CALLS                                                                 */
66 /*                                                                        */
67 /*    [ipv6_address_change_notify]         User callback function         */
68 /*                                                                        */
69 /*  CALLED BY                                                             */
70 /*                                                                        */
71 /*    _nx_icmpv6_process_na                                               */
72 /*                                                                        */
73 /*  RELEASE HISTORY                                                       */
74 /*                                                                        */
75 /*    DATE              NAME                      DESCRIPTION             */
76 /*                                                                        */
77 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
78 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
79 /*                                            resulting in version 6.1    */
80 /*                                                                        */
81 /**************************************************************************/
82 
83 #ifndef NX_DISABLE_IPV6_DAD
_nx_icmpv6_DAD_failure(NX_IP * ip_ptr,NXD_IPV6_ADDRESS * ipv6_address)84 VOID _nx_icmpv6_DAD_failure(NX_IP *ip_ptr, NXD_IPV6_ADDRESS *ipv6_address)
85 {
86 #ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY
87 UINT              interface_index;
88 UINT              ipv6_addr_index;
89 #endif /* NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */
90 NXD_IPV6_ADDRESS *address_ptr;
91 
92     /* Set the interface to an invalid state. */
93     ipv6_address -> nxd_ipv6_address_state = NX_IPV6_ADDR_STATE_UNKNOWN;
94     ipv6_address -> nxd_ipv6_address_valid = NX_FALSE;
95 
96     /* Indicate the DAD process is disabled. */
97     ipv6_address -> nxd_ipv6_address_DupAddrDetectTransmit = 0;
98 #ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY
99     if (ip_ptr -> nx_ipv6_address_change_notify)
100     {
101         ipv6_addr_index = (ULONG)ipv6_address -> nxd_ipv6_address_index;
102         interface_index = (ULONG)ipv6_address -> nxd_ipv6_address_attached -> nx_interface_index;
103         ip_ptr -> nx_ipv6_address_change_notify(ip_ptr, NX_IPV6_ADDRESS_DAD_FAILURE, interface_index, ipv6_addr_index, &ipv6_address -> nxd_ipv6_address[0]);
104     }
105 #else
106     NX_PARAMETER_NOT_USED(ip_ptr);
107 #endif /* NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */
108 
109     /* Remove address from interface. */
110     if (ipv6_address == ipv6_address -> nxd_ipv6_address_attached -> nxd_interface_ipv6_address_list_head)
111     {
112         ipv6_address -> nxd_ipv6_address_attached -> nxd_interface_ipv6_address_list_head = ipv6_address -> nxd_ipv6_address_next;
113     }
114     else
115     {
116 
117         for (address_ptr = ipv6_address -> nxd_ipv6_address_attached -> nxd_interface_ipv6_address_list_head;
118              address_ptr != NX_NULL;
119              address_ptr = address_ptr -> nxd_ipv6_address_next)
120         {
121             if (address_ptr -> nxd_ipv6_address_next == ipv6_address)
122             {
123                 address_ptr -> nxd_ipv6_address_next = ipv6_address -> nxd_ipv6_address_next;
124             }
125         }
126     }
127 }
128 
129 #endif  /* NX_DISABLE_IPV6_DAD */
130 #endif  /* FEATURE_NX_IPV6 */
131 
132