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 /** NetX Component                                                        */
14 /**                                                                       */
15 /**   Internet Protocol version 6 Default Router Table (IPv6 router)      */
16 /**                                                                       */
17 /**************************************************************************/
18 /**************************************************************************/
19 #define NX_SOURCE_CODE
20 
21 
22 /* Include necessary system files.  */
23 
24 #include "nx_api.h"
25 #include "nx_ipv6.h"
26 #include "nx_nd_cache.h"
27 #include "nx_icmpv6.h"
28 
29 
30 #ifdef FEATURE_NX_IPV6
31 /**************************************************************************/
32 /*                                                                        */
33 /*  FUNCTION                                               RELEASE        */
34 /*                                                                        */
35 /*    _nxd_ipv6_prefix_router_timer_tick                   PORTABLE C     */
36 /*                                                           6.1          */
37 /*  AUTHOR                                                                */
38 /*                                                                        */
39 /*    Yuxin Zhou, Microsoft Corporation                                   */
40 /*                                                                        */
41 /*  DESCRIPTION                                                           */
42 /*                                                                        */
43 /*    At every time tick, this function checks for time out expiration on */
44 /*    both the default router list and the prefix list tables bound to the*/
45 /*    supplied IP instance.                                               */
46 /*                                                                        */
47 /*  INPUT                                                                 */
48 /*                                                                        */
49 /*    ip_ptr                                IP instance pointer           */
50 /*                                                                        */
51 /*  OUTPUT                                                                */
52 /*                                                                        */
53 /*    None                                                                */
54 /*                                                                        */
55 /*  CALLS                                                                 */
56 /*                                                                        */
57 /*    _nx_invalidate_destination_entry    Invalidate the entry in the     */
58 /*                                           destination                  */
59 /*                                                                        */
60 /*  CALLED BY                                                             */
61 /*                                                                        */
62 /*    _nx_ip_thread_entry                                                 */
63 /*                                                                        */
64 /*  NOTE                                                                  */
65 /*                                                                        */
66 /*    The nx_ip_protection mutex must be obtained before calling this     */
67 /*    function.                                                           */
68 /*                                                                        */
69 /*    This function cannot be called from ISR.                            */
70 /*                                                                        */
71 /*  RELEASE HISTORY                                                       */
72 /*                                                                        */
73 /*    DATE              NAME                      DESCRIPTION             */
74 /*                                                                        */
75 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
76 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
77 /*                                            resulting in version 6.1    */
78 /*                                                                        */
79 /**************************************************************************/
_nxd_ipv6_prefix_router_timer_tick(NX_IP * ip_ptr)80 VOID _nxd_ipv6_prefix_router_timer_tick(NX_IP *ip_ptr)
81 {
82 
83 UINT                          i, table_size;
84 NX_IPV6_PREFIX_ENTRY         *tmp, *prefix_entry;
85 NX_IPV6_DEFAULT_ROUTER_ENTRY *rt_entry;
86 
87 
88     /* Set a local variable for convenience. */
89     table_size = ip_ptr -> nx_ipv6_default_router_table_size;
90 
91     /* Check each entry in the default router table. */
92     for (i = 0; table_size && (i < NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE); i++)
93     {
94 
95         /* Set a local variable for convenience. */
96         rt_entry = &ip_ptr -> nx_ipv6_default_router_table[i];
97 
98         /* Skip invalid or empty slots. */
99         if ((rt_entry -> nx_ipv6_default_router_entry_flag & NX_IPV6_ROUTE_TYPE_VALID) == 0)
100         {
101             continue;
102         }
103 
104         /* Keep track of valid entries we've checked. */
105         table_size--;
106 
107         /* Has the entry on the current table entry expired? */
108         if (rt_entry -> nx_ipv6_default_router_entry_life_time == 0)
109         {
110 
111             /* Yes, the router has timed out. */
112             /* Does this router have an entry in the ND cache table? */
113             if (rt_entry -> nx_ipv6_default_router_entry_neighbor_cache_ptr)
114             {
115 
116                 /* Yes, clear out that entry, we are invalidating this entry. */
117                 rt_entry -> nx_ipv6_default_router_entry_neighbor_cache_ptr -> nx_nd_cache_is_router = NX_NULL;
118             }
119 
120             /* Clean any entries in the destination table for this router.  */
121             _nx_invalidate_destination_entry(ip_ptr, rt_entry -> nx_ipv6_default_router_entry_router_address);
122 
123             /* Invalidate the entry in the router table. */
124             rt_entry -> nx_ipv6_default_router_entry_flag = 0;
125 
126             /* Clear the interface pointer .*/
127             rt_entry -> nx_ipv6_default_router_entry_interface_ptr = NX_NULL;
128 
129             /* Decrease the IP instance default router count. */
130             ip_ptr -> nx_ipv6_default_router_table_size--;
131         }
132         else
133         {
134             /* Is this a static router (infinite timeout)? */
135             if (rt_entry -> nx_ipv6_default_router_entry_life_time != 0xFFFF)
136             {
137 
138                 /* No, so decrement the lifetime by one tick.*/
139                 rt_entry -> nx_ipv6_default_router_entry_life_time--;
140             }
141         }
142     }
143 
144     /* Set a pointer to the first prefix entry in the IP prefix list. */
145     prefix_entry = ip_ptr -> nx_ipv6_prefix_list_ptr;
146 
147     /* Loop through the entire list. */
148     while (prefix_entry)
149     {
150 
151         /* Set a placemarker at the current prefix. */
152         tmp = prefix_entry;
153 
154         /* Get a pointer to the next prefix. */
155         prefix_entry = prefix_entry -> nx_ipv6_prefix_entry_next;
156 
157         /* Skip the static entries. */
158         if (tmp -> nx_ipv6_prefix_entry_valid_lifetime != (UINT)0xFFFFFFFF)
159         {
160 
161             /* Has the prefix entry timeout expired? */
162             if (tmp -> nx_ipv6_prefix_entry_valid_lifetime == 0)
163             {
164 
165                 /* Yes, so delete it from the list. */
166                 _nx_ipv6_prefix_list_delete_entry(ip_ptr, tmp);
167             }
168             else
169             {
170 
171                 /* Just decrement the time remaining. */
172                 tmp -> nx_ipv6_prefix_entry_valid_lifetime--;
173             }
174         }
175     }
176 
177     return;
178 }
179 
180 #endif /* FEATURE_NX_IPV6 */
181 
182