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