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 31 #ifdef FEATURE_NX_IPV6 32 33 34 /**************************************************************************/ 35 /* */ 36 /* FUNCTION RELEASE */ 37 /* */ 38 /* _nx_nd_cache_slow_periodic_update PORTABLE C */ 39 /* 6.1 */ 40 /* AUTHOR */ 41 /* */ 42 /* Yuxin Zhou, Microsoft Corporation */ 43 /* */ 44 /* DESCRIPTION */ 45 /* */ 46 /* This function handles the ND entries in REACHABLE, STALE, and */ 47 /* DELAY states. It decrements the timer tick. If the timer ticks */ 48 /* reach zero, the entry is moved to the next state. */ 49 /* */ 50 /* Note that the only cache entries whose timer ticks are being */ 51 /* decremented in this function are states whose timer tick was set in */ 52 /* effectively in seconds (as compared with the fast periodic update */ 53 /* where cache entry'timer ticks' are updated in as timer ticks. This */ 54 /* is intentional and correct behavior. */ 55 /* */ 56 /* INPUT */ 57 /* */ 58 /* ip_ptr Pointer to the IP instance */ 59 /* */ 60 /* OUTPUT */ 61 /* */ 62 /* NONE */ 63 /* */ 64 /* CALLS */ 65 /* */ 66 /* tx_mutex_get Obtain protection mutex */ 67 /* tx_mutex_put Release protection mutex */ 68 /* */ 69 /* CALLED BY */ 70 /* */ 71 /* _nx_ip_thread_entry */ 72 /* */ 73 /* RELEASE HISTORY */ 74 /* */ 75 /* DATE NAME DESCRIPTION */ 76 /* */ 77 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ 78 /* 09-30-2020 Yuxin Zhou Modified comment(s), */ 79 /* resulting in version 6.1 */ 80 /* */ 81 /**************************************************************************/ _nx_nd_cache_slow_periodic_update(NX_IP * ip_ptr)82VOID _nx_nd_cache_slow_periodic_update(NX_IP *ip_ptr) 83 { 84 85 INT i; 86 87 /* Check all entries in the ND cache for timer expiration. */ 88 for (i = 0; i < NX_IPV6_NEIGHBOR_CACHE_SIZE; i++) 89 { 90 /* Skip the invalid or empty ones. */ 91 if (ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_nd_status == ND_CACHE_STATE_INVALID) 92 { 93 continue; 94 } 95 96 /* No need to update the static entries! */ 97 if (ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_is_static) 98 { 99 continue; 100 } 101 102 /* If this is a reachable entry... */ 103 if (ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_nd_status == ND_CACHE_STATE_REACHABLE) 104 { 105 106 ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_timer_tick--; 107 108 /* And we have timed out... */ 109 if (ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_timer_tick == 0) 110 { 111 112 /* Time to move the state into the STALE state. */ 113 ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_nd_status = ND_CACHE_STATE_STALE; 114 } 115 } 116 /* Entries in the delay state are set to be 'probed'. */ 117 else if (ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_nd_status == ND_CACHE_STATE_DELAY) 118 { 119 120 ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_timer_tick--; 121 122 /* Has the timeout expired? */ 123 if (ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_timer_tick == 0) 124 { 125 126 /* Set to the probe state. We do not send out NS; 127 the nd_cache_fast_periodic_update will handle the 128 processing of this entry now. */ 129 ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_nd_status = ND_CACHE_STATE_PROBE; 130 ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_num_solicit = NX_MAX_UNICAST_SOLICIT; 131 } 132 } 133 else if (ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_nd_status == ND_CACHE_STATE_STALE) 134 { 135 136 /* When the entry is in stale mode, we actually increment the timer_tick. 137 The larger the timer_tick value, the longer then entry has been in 138 stale mode. This makes the entry a target for recycling (being replaced 139 by a newer reachable entry). */ 140 ip_ptr -> nx_ipv6_nd_cache[i].nx_nd_cache_timer_tick++; 141 } 142 } 143 } 144 145 146 #endif /* FEATURE_NX_IPV6 */ 147 148