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_ipv6.h"
29 #ifdef FEATURE_NX_IPV6
30 #include "nx_nd_cache.h"
31 #include "nx_icmpv6.h"
32 #endif /* FEATURE_NX_IPV6 */
33
34 /**************************************************************************/
35 /* */
36 /* FUNCTION RELEASE */
37 /* */
38 /* _nxd_ipv6_disable PORTABLE C */
39 /* 6.1 */
40 /* AUTHOR */
41 /* */
42 /* Yuxin Zhou, Microsoft Corporation */
43 /* */
44 /* DESCRIPTION */
45 /* */
46 /* This function disables the IPv6 for the specified IP instance. */
47 /* */
48 /* INPUT */
49 /* */
50 /* ip_ptr IP instance pointer */
51 /* */
52 /* OUTPUT */
53 /* */
54 /* status Completion status */
55 /* NX_ALREADY_ENABLED IPv6 already enabled on IP */
56 /* NX_NOT_SUPPORTED IPv6 not supported on this IP */
57 /* */
58 /* CALLS */
59 /* */
60 /* _nx_ipv6_multicast_leave Leave the multicast group */
61 /* _nxd_ipv6_default_router_table_init Initialize IPv6 routing table */
62 /* _nx_nd_cache_delete_internal Delete ND Cache Entry */
63 /* tx_mutex_get Obtain a protection mutex */
64 /* tx_mutex_put Release protection mutex */
65 /* */
66 /* CALLED BY */
67 /* */
68 /* Application Code */
69 /* */
70 /* RELEASE HISTORY */
71 /* */
72 /* DATE NAME DESCRIPTION */
73 /* */
74 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
75 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
76 /* resulting in version 6.1 */
77 /* */
78 /**************************************************************************/
_nxd_ipv6_disable(NX_IP * ip_ptr)79 UINT _nxd_ipv6_disable(NX_IP *ip_ptr)
80 {
81
82
83 #ifdef FEATURE_NX_IPV6
84
85 TX_INTERRUPT_SAVE_AREA
86 ULONG address[4];
87 UINT i;
88
89
90 /* Make sure IPv6 is not already enabled. */
91 /* Cast the function pointer into a ULONG. Since this is exactly what we wish to do, disable the lint warning with the following comment: */
92 /*lint -e{923} suppress cast of pointer to ULONG. */
93 if ((ALIGN_TYPE)ip_ptr -> nx_ipv6_packet_receive == NX_NULL)
94 {
95 return(NX_SUCCESS);
96 }
97
98 /* If trace is enabled, insert this event into the trace buffer. */
99 NX_TRACE_IN_LINE_INSERT(NX_TRACE_IPV6_DISABLE, ip_ptr, 0, 0, 0, NX_TRACE_IP_EVENTS, 0, 0);
100
101
102 /* Obtain the IP mutex so we can manipulate the internal routing table. */
103 tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
104
105 /* Disable Interrupt */
106 TX_DISABLE
107
108 /* Install IPv6 packet receive processing function pointer */
109 ip_ptr -> nx_ipv6_packet_receive = NX_NULL;
110
111 /* Enable Interrupt */
112 TX_RESTORE
113
114 /* Zero out the IPv6 default router table */
115 _nxd_ipv6_default_router_table_init(ip_ptr);
116
117 /* Clear IPv6 internal timers. */
118 ip_ptr -> nx_ipv6_reachable_timer = 0;
119 ip_ptr -> nx_ipv6_retrans_timer_ticks = 0;
120
121 /* Check if router solicitation is not disabled. */
122 #ifndef NX_DISABLE_ICMPV6_ROUTER_SOLICITATION
123
124 /* Create the all-node multicast group address, */
125 address[0] = 0xFF020000;
126 address[1] = 0;
127 address[2] = 0;
128 address[3] = 1;
129 #endif /* NX_DISABLE_ICMPV6_ROUTER_SOLICITATION */
130
131
132 /* Reset the router solicitation values . */
133 for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
134 {
135 if (ip_ptr -> nx_ip_interface[i].nx_interface_valid == NX_TRUE)
136 {
137 ip_ptr -> nx_ip_interface[i].nxd_interface_ipv6_address_list_head = NX_NULL;
138
139 #ifndef NX_DISABLE_ICMPV6_ROUTER_SOLICITATION
140 ip_ptr -> nx_ip_interface[i].nx_ipv6_rtr_solicitation_max = 0;
141 ip_ptr -> nx_ip_interface[i].nx_ipv6_rtr_solicitation_count = 0;
142 ip_ptr -> nx_ip_interface[i].nx_ipv6_rtr_solicitation_interval = 0;
143 ip_ptr -> nx_ip_interface[i].nx_ipv6_rtr_solicitation_timer = 0;
144
145 /* Leave all-node multicast group. */
146 _nx_ipv6_multicast_leave(ip_ptr, address, &ip_ptr -> nx_ip_interface[i]);
147
148 #endif /* NX_DISABLE_ICMPV6_ROUTER_SOLICITATION */
149 }
150 }
151
152
153 /* Remove the IPv6 addresses, and leave the corresponding multicast groups. */
154 for (i = 0; i < NX_MAX_IPV6_ADDRESSES; i++)
155 {
156 if (ip_ptr -> nx_ipv6_address[i].nxd_ipv6_address_valid)
157 {
158
159 SET_SOLICITED_NODE_MULTICAST_ADDRESS(address, ip_ptr -> nx_ipv6_address[i].nxd_ipv6_address);
160
161 _nx_ipv6_multicast_leave(ip_ptr, &address[0], ip_ptr -> nx_ipv6_address[i].nxd_ipv6_address_attached);
162 }
163 }
164
165 /* Zero out the IPv6 address structure table. */
166 memset(&ip_ptr -> nx_ipv6_address[0], 0, sizeof(ip_ptr -> nx_ipv6_address));
167
168 /* Clean up the ND Cache table. */
169 if (ip_ptr -> nx_ip_icmpv6_packet_process)
170 {
171 for (i = 0; i < NX_IPV6_NEIGHBOR_CACHE_SIZE; i++)
172 {
173 if ((ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_nd_status != ND_CACHE_STATE_INVALID) &&
174 (ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_interface_ptr))
175 {
176 _nx_nd_cache_delete_internal(ip_ptr, &ip_ptr -> nx_ipv6_nd_cache[i]);
177 }
178 }
179 }
180
181 /* Disable ND cache periodic update routine. */
182 ip_ptr -> nx_nd_cache_fast_periodic_update = NX_NULL;
183 ip_ptr -> nx_nd_cache_slow_periodic_update = NX_NULL;
184
185 /* Disable ICMPv6 services. */
186 ip_ptr -> nx_ip_icmpv6_packet_process = NX_NULL;
187
188 #ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY
189 ip_ptr -> nx_destination_table_periodic_update = NX_NULL;
190 #endif /* NX_ENABLE_IPV6_PATH_MTU_DISCOVERY */
191
192 /* Clean up the loop back address. */
193 #ifndef NX_DISABLE_LOOPBACK_INTERFACE
194 ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nxd_interface_ipv6_address_list_head = NX_NULL;
195 #endif /* NX_DISABLE_LOOPBACK_INTERFACE */
196
197 /* Release the IP protection. */
198 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
199
200 /* Return successful completion. */
201 return(NX_SUCCESS);
202
203 #else /* !FEATURE_NX_IPV6 */
204 NX_PARAMETER_NOT_USED(ip_ptr);
205
206 return(NX_NOT_SUPPORTED);
207
208 #endif /* FEATURE_NX_IPV6 */
209 }
210
211