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