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
30 #ifdef FEATURE_NX_IPV6
31 #include "nx_ip.h"
32 #include "nx_nd_cache.h"
33 #include "nx_icmpv6.h"
34 #endif /* FEATURE_NX_IPV6 */
35
36 /**************************************************************************/
37 /* */
38 /* FUNCTION RELEASE */
39 /* */
40 /* _nxd_ipv6_enable PORTABLE C */
41 /* 6.1 */
42 /* AUTHOR */
43 /* */
44 /* Yuxin Zhou, Microsoft Corporation */
45 /* */
46 /* DESCRIPTION */
47 /* */
48 /* This function enables the IPv6 for the specified IP instance. */
49 /* */
50 /* INPUT */
51 /* */
52 /* ip_ptr IP instance pointer */
53 /* */
54 /* OUTPUT */
55 /* */
56 /* status Completion status */
57 /* */
58 /* CALLS */
59 /* */
60 /* _nx_ipv6_multicast_join Join the multicast group */
61 /* _nxd_ipv6_default_router_table_init Initialize IPv6 routing table */
62 /* _nx_ip_fast_periodic_timer_create Create timer for IPv6 events */
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_enable(NX_IP * ip_ptr)79 UINT _nxd_ipv6_enable(NX_IP *ip_ptr)
80 {
81
82
83 #ifdef FEATURE_NX_IPV6
84
85 TX_INTERRUPT_SAVE_AREA
86 UINT i;
87 #ifndef NX_DISABLE_ICMPV6_ROUTER_SOLICITATION
88 ULONG address[4];
89 #endif /* NX_DISABLE_ICMPV6_ROUTER_SOLICITATION */
90
91
92 /* Make sure IPv6 is not already enabled. */
93 if (ip_ptr -> nx_ipv6_packet_receive)
94 {
95 return(NX_ALREADY_ENABLED);
96 }
97
98 /* If trace is enabled, insert this event into the trace buffer. */
99 NX_TRACE_IN_LINE_INSERT(NX_TRACE_IPV6_ENABLE, 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_ipv6_packet_receive;
110
111 /* Enable Interrupt */
112 TX_RESTORE
113
114 /* Initialize IPv6 default router table */
115 _nxd_ipv6_default_router_table_init(ip_ptr);
116
117 /* Set the default reachable timer. */
118 ip_ptr -> nx_ipv6_reachable_timer = NX_REACHABLE_TIME;
119
120 /*
121 Set the default retrans timer. The retrans timer value is
122 expressed in millisecond. To compute the timer ticks, first
123 covert the retrans timer to second and then multiply
124 the system_ticks_per_second value, or multiply system_ticks_per_second
125 before doing division.
126 If the retrans_timer is smaller than tick resolution, set it to 1.
127 */
128 #if ((NX_RETRANS_TIMER * NX_IP_FAST_TIMER_RATE) > 1000)
129 ip_ptr -> nx_ipv6_retrans_timer_ticks = (NX_RETRANS_TIMER * NX_IP_FAST_TIMER_RATE) / 1000;
130 #else
131 ip_ptr -> nx_ipv6_retrans_timer_ticks = 1;
132 #endif
133
134 /* Set the default hop limit. */
135 ip_ptr -> nx_ipv6_hop_limit = 0xFF;
136
137 /* Set index of each address. */
138 for (i = 0; i < (NX_MAX_IPV6_ADDRESSES + NX_LOOPBACK_IPV6_ENABLED); i++)
139 {
140 ip_ptr -> nx_ipv6_address[i].nxd_ipv6_address_index = (UCHAR)i;
141 }
142
143 /* Check if router solicitation is not disabled. */
144 #ifndef NX_DISABLE_ICMPV6_ROUTER_SOLICITATION
145
146 /* Create the all-node multicast group address, */
147 address[0] = 0xFF020000;
148 address[1] = 0;
149 address[2] = 0;
150 address[3] = 1;
151
152 /* Initializes the router solicitation values . */
153 for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
154 {
155 if (ip_ptr -> nx_ip_interface[i].nx_interface_valid == NX_TRUE)
156 {
157 ip_ptr -> nx_ip_interface[i].nx_ipv6_rtr_solicitation_max = NX_ICMPV6_MAX_RTR_SOLICITATIONS;
158 ip_ptr -> nx_ip_interface[i].nx_ipv6_rtr_solicitation_count = ip_ptr -> nx_ip_interface[i].nx_ipv6_rtr_solicitation_max;
159 ip_ptr -> nx_ip_interface[i].nx_ipv6_rtr_solicitation_interval = NX_ICMPV6_RTR_SOLICITATION_INTERVAL;
160 ip_ptr -> nx_ip_interface[i].nx_ipv6_rtr_solicitation_timer = NX_ICMPV6_RTR_SOLICITATION_DELAY;
161
162 /* Join all-node multicast group. */
163 _nx_ipv6_multicast_join(ip_ptr, address, &ip_ptr -> nx_ip_interface[i]);
164 }
165 }
166 #endif /* NX_DISABLE_ICMPV6_ROUTER_SOLICITATION */
167
168 /* Start a faster periodic timer for IPv6 .*/
169 _nx_ip_fast_periodic_timer_create(ip_ptr);
170
171 #ifndef NX_DISABLE_LOOPBACK_INTERFACE
172
173 /* Setup loop back address. */
174 /* Page 9, section 2.5.3, RFC 4291. */
175 ip_ptr -> nx_ipv6_address[NX_LOOPBACK_IPV6_SOURCE_INDEX].nxd_ipv6_address[0] = 0x0;
176 ip_ptr -> nx_ipv6_address[NX_LOOPBACK_IPV6_SOURCE_INDEX].nxd_ipv6_address[1] = 0x0;
177 ip_ptr -> nx_ipv6_address[NX_LOOPBACK_IPV6_SOURCE_INDEX].nxd_ipv6_address[2] = 0x0;
178 ip_ptr -> nx_ipv6_address[NX_LOOPBACK_IPV6_SOURCE_INDEX].nxd_ipv6_address[3] = 0x1;
179
180 /* Config loop bcak address. */
181 ip_ptr -> nx_ipv6_address[NX_LOOPBACK_IPV6_SOURCE_INDEX].nxd_ipv6_address_valid = NX_TRUE;
182 ip_ptr -> nx_ipv6_address[NX_LOOPBACK_IPV6_SOURCE_INDEX].nxd_ipv6_address_type = NX_IP_VERSION_V6;
183 ip_ptr -> nx_ipv6_address[NX_LOOPBACK_IPV6_SOURCE_INDEX].nxd_ipv6_address_prefix_length = 128;
184 ip_ptr -> nx_ipv6_address[NX_LOOPBACK_IPV6_SOURCE_INDEX].nxd_ipv6_address_next = NX_NULL;
185 ip_ptr -> nx_ipv6_address[NX_LOOPBACK_IPV6_SOURCE_INDEX].nxd_ipv6_address_attached = &ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE];
186 ip_ptr -> nx_ipv6_address[NX_LOOPBACK_IPV6_SOURCE_INDEX].nxd_ipv6_address_ConfigurationMethod = NX_IPV6_ADDRESS_MANUAL_CONFIG;
187 ip_ptr -> nx_ipv6_address[NX_LOOPBACK_IPV6_SOURCE_INDEX].nxd_ipv6_address_state = NX_IPV6_ADDR_STATE_VALID;
188
189 ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nxd_interface_ipv6_address_list_head = &ip_ptr -> nx_ipv6_address[NX_LOOPBACK_IPV6_SOURCE_INDEX];
190 #endif /* NX_DISABLE_LOOPBACK_INTERFACE */
191
192 /* Release the IP protection. */
193 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
194
195 /* Return successful completion. */
196 return(NX_SUCCESS);
197
198 #else /* !FEATURE_NX_IPV6 */
199 NX_PARAMETER_NOT_USED(ip_ptr);
200
201 return(NX_NOT_SUPPORTED);
202
203 #endif /* FEATURE_NX_IPV6 */
204 }
205
206