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 Protocol (IP)                                              */
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_ip.h"
29 #include "nx_ipv6.h"
30 
31 /**************************************************************************/
32 /*                                                                        */
33 /*  FUNCTION                                               RELEASE        */
34 /*                                                                        */
35 /*    _nxd_ipv6_address_delete                            PORTABLE C      */
36 /*                                                           6.1          */
37 /*  AUTHOR                                                                */
38 /*                                                                        */
39 /*    Yuxin Zhou, Microsoft Corporation                                   */
40 /*                                                                        */
41 /*  DESCRIPTION                                                           */
42 /*                                                                        */
43 /*  This function removes the IPv6 address at the specified address list  */
44 /*  index on the IP instance.                                             */
45 /*                                                                        */
46 /*  INPUT                                                                 */
47 /*                                                                        */
48 /*    ip_ptr                            IP control block pointer          */
49 /*    address_index                     Index into IPv6 address list      */
50 /*                                                                        */
51 /*  OUTPUT                                                                */
52 /*                                                                        */
53 /*    status                            Completion status                 */
54 /*                                                                        */
55 /*  CALLS                                                                 */
56 /*                                                                        */
57 /*    tx_mutex_get                      Get protection mutex              */
58 /*    tx_mutex_put                      Put protection mutex              */
59 /*    nx_ipv6_multicast_leave           Leave IPv6 multicast group        */
60 /*    [ipv6_address_change_notify]      User callback function            */
61 /*                                                                        */
62 /*  CALLED BY                                                             */
63 /*                                                                        */
64 /*    Application Code                                                    */
65 /*                                                                        */
66 /*  RELEASE HISTORY                                                       */
67 /*                                                                        */
68 /*    DATE              NAME                      DESCRIPTION             */
69 /*                                                                        */
70 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
71 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
72 /*                                            resulting in version 6.1    */
73 /*                                                                        */
74 /**************************************************************************/
_nxd_ipv6_address_delete(NX_IP * ip_ptr,UINT address_index)75 UINT  _nxd_ipv6_address_delete(NX_IP *ip_ptr, UINT address_index)
76 {
77 #ifdef FEATURE_NX_IPV6
78 UINT              result;
79 NXD_IPV6_ADDRESS *ipv6_address, *address_list;
80 #ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY
81 VOID              (*address_change_notify)(NX_IP *, UINT, UINT, UINT, ULONG *);
82 UINT              if_index;
83 ULONG             obsoleted_address[4];
84 
85     address_change_notify = NX_NULL;
86 #endif /* NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */
87 
88 
89     result = NX_NO_INTERFACE_ADDRESS;
90 
91     /* Place protection while the IPv6 address is modified. */
92     tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
93 
94 
95     /* Get the ip address.  */
96     ipv6_address = &ip_ptr -> nx_ipv6_address[address_index];
97 
98     /* Check the validity of the address.  */
99     if (ipv6_address -> nxd_ipv6_address_valid)
100     {
101 
102         /* Delete the information in the list.  */
103         address_list = ipv6_address -> nxd_ipv6_address_attached -> nxd_interface_ipv6_address_list_head;
104 
105 
106         /* The delete address is in the head of the list.  */
107         if (ipv6_address == address_list)
108         {
109 
110             ipv6_address -> nxd_ipv6_address_attached -> nxd_interface_ipv6_address_list_head = ipv6_address -> nxd_ipv6_address_next;
111             result = NX_SUCCESS;
112         }
113         else
114         {
115             /* Find the address in the list.  */
116             while (address_list && (address_list -> nxd_ipv6_address_next != ipv6_address))
117             {
118 
119                 /* Move to the next address. */
120                 address_list = address_list -> nxd_ipv6_address_next;
121             }
122 
123             /* Break out of the while loop, either the address has been found, or the end of the list has been reached. */
124             if (address_list)
125             {
126                 address_list -> nxd_ipv6_address_next = ipv6_address -> nxd_ipv6_address_next;
127                 result = NX_SUCCESS;
128             }
129         }
130 
131         if (result == NX_SUCCESS)
132         {
133         ULONG multicast_address[4];
134 
135             SET_SOLICITED_NODE_MULTICAST_ADDRESS(multicast_address, ipv6_address -> nxd_ipv6_address);
136             /* First remove the corresponding solicited node multicast address. */
137             _nx_ipv6_multicast_leave(ip_ptr, &multicast_address[0], ipv6_address -> nxd_ipv6_address_attached);
138 
139 #ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY
140             /* Pickup the current notification callback and additional information pointers.  */
141             address_change_notify =  ip_ptr -> nx_ipv6_address_change_notify;
142 
143             obsoleted_address[0] = ipv6_address -> nxd_ipv6_address[0];
144             obsoleted_address[1] = ipv6_address -> nxd_ipv6_address[1];
145             obsoleted_address[2] = ipv6_address -> nxd_ipv6_address[2];
146             obsoleted_address[3] = ipv6_address -> nxd_ipv6_address[3];
147 
148             if_index = ipv6_address -> nxd_ipv6_address_attached -> nx_interface_index;
149 #endif /* NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */
150 
151             /* At this point ipv6_address is off the interface IPv6 address list. */
152             memset(ipv6_address, 0, sizeof(NXD_IPV6_ADDRESS));
153 
154             /* Set index of ipv6_address. */
155             ipv6_address -> nxd_ipv6_address_index = (UCHAR)address_index;
156         }
157     }
158 
159     /* Release the protection while the IPv6 address is modified. */
160     tx_mutex_put(&(ip_ptr -> nx_ip_protection));
161 
162 
163 #ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY
164     /* Is the application configured for notification of address changes and/or
165        prefix_length change?  */
166     if (address_change_notify && (result == NX_SUCCESS))
167     {
168 
169         /* Yes, call the application's address change notify function.  */
170         /*lint -e{644} suppress variable might not be initialized, since "if_index" was initialized as long as result is NX_SUCCESS. */
171         (address_change_notify)(ip_ptr, NX_IPV6_ADDRESS_MANUAL_DELETE, if_index, address_index, &obsoleted_address[0]);
172     }
173 #endif /* NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */
174 
175     /* Return completion status.  */
176     return(result);
177 
178 #else /* !FEATURE_NX_IPV6 */
179     NX_PARAMETER_NOT_USED(ip_ptr);
180     NX_PARAMETER_NOT_USED(address_index);
181 
182     return(NX_NOT_SUPPORTED);
183 
184 #endif /* FEATURE_NX_IPV6 */
185 }
186 
187