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 /**   Neighbor Discovery Cache                                            */
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 #include "nx_nd_cache.h"
30 #include "nx_icmpv6.h"
31 
32 #ifdef FEATURE_NX_IPV6
33 
34 
35 /**************************************************************************/
36 /*                                                                        */
37 /*  FUNCTION                                               RELEASE        */
38 /*                                                                        */
39 /*    _nx_nd_cache_fast_periodic_update                   PORTABLE C      */
40 /*                                                           6.1          */
41 /*  AUTHOR                                                                */
42 /*                                                                        */
43 /*    Yuxin Zhou, Microsoft Corporation                                   */
44 /*                                                                        */
45 /*  DESCRIPTION                                                           */
46 /*                                                                        */
47 /*    This function handles the ND entries in PROBE or INCOMPLETE state.  */
48 /*    It decrements the timer tick.  If the ticker reaches zero           */
49 /*    a NS is sent.  If MAX NS has been sent, this entry times out        */
50 /*    and is marked as INVALID.                                           */
51 /*                                                                        */
52 /*  INPUT                                                                 */
53 /*                                                                        */
54 /*    ip_ptr                                Pointer to the IP instance    */
55 /*                                                                        */
56 /*  OUTPUT                                                                */
57 /*                                                                        */
58 /*    NONE                                                                */
59 /*                                                                        */
60 /*  CALLS                                                                 */
61 /*                                                                        */
62 /*    tx_mutex_get                          Obtain protection mutex       */
63 /*    tx_mutex_put                          Release protection mutex      */
64 /*    _nx_icmpv6_send_ns                    Transmit a new NS message.    */
65 /*                                                                        */
66 /*  CALLED BY                                                             */
67 /*                                                                        */
68 /*    _nx_nd_cache_delete_internal                                        */
69 /*    _nx_ip_thread_entry                                                 */
70 /*    tx_mutex_get                                                        */
71 /*    tx_mutex_put                                                        */
72 /*                                                                        */
73 /*  Note:                                                                 */
74 /*                                                                        */
75 /*    This routine acquires the nx_nd_cache_protection mutex.             */
76 /*    Caller shall not hold this mutex before calling this function.      */
77 /*                                                                        */
78 /*                                                                        */
79 /*  RELEASE HISTORY                                                       */
80 /*                                                                        */
81 /*    DATE              NAME                      DESCRIPTION             */
82 /*                                                                        */
83 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
84 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
85 /*                                            resulting in version 6.1    */
86 /*                                                                        */
87 /**************************************************************************/
_nx_nd_cache_fast_periodic_update(NX_IP * ip_ptr)88 VOID _nx_nd_cache_fast_periodic_update(NX_IP *ip_ptr)
89 {
90 
91 INT i;
92 
93     /* Loop through all entries, and invalidate the ones that are timed out. */
94     for (i = 0; i < NX_IPV6_NEIGHBOR_CACHE_SIZE; i++)
95     {
96 
97         /* Check the entry is valid. */
98         if (ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_nd_status == ND_CACHE_STATE_INVALID)
99         {
100             continue;
101         }
102 
103         /* Is this entry being checked for neighbor discovery? */
104         if ((ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_nd_status != ND_CACHE_STATE_PROBE) &&
105             (ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_nd_status != ND_CACHE_STATE_INCOMPLETE))
106         {
107 
108             /* No, so skip over. */
109             continue;
110         }
111 
112 
113 
114         /* Has this entry timed out? */
115         if (ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_timer_tick == 0)
116         {
117 
118             /* Yes, is the max number of solicitations used up? */
119             if (ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_num_solicit == 0)
120             {
121 
122                 /* Yes; We already sent #num_solicit packets. So the destination
123                    is unreachable.  Clean up router, destination and cache table entries and crosslinks. */
124                 _nx_nd_cache_delete_internal(ip_ptr, &ip_ptr -> nx_ipv6_nd_cache[i]);
125             }
126             else
127             {
128             /*  Send another solicitation (NS) packet. */
129             INT uniCastNS;
130 
131                 uniCastNS = (ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_nd_status == ND_CACHE_STATE_PROBE);
132 
133                 /* Send out another mcast ns.*/
134                 _nx_icmpv6_send_ns(ip_ptr, ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_dest_ip,
135                                    1, ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_outgoing_address, uniCastNS, &ip_ptr -> nx_ipv6_nd_cache[i]);
136 
137                 /* Keep track of how many we have sent. */
138                 ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_num_solicit--;
139 
140                 /* Reset the expiration timer for sending the next NS.  */
141                 ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_timer_tick = ip_ptr -> nx_ipv6_retrans_timer_ticks;
142             }
143         }
144         else
145         {
146 
147             /* Note that the only cache entries whose timer ticks are being decremented in this
148                function are states whose timer tick was set in actual timer ticks (as compared
149                with the slow periodic update where cache entry'timer ticks' are updated in
150                seconds.  This is intentional and correct behavior. */
151             ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_timer_tick--;
152         }
153     }
154 }
155 
156 #endif /* FEATURE_NX_IPV6 */
157 
158