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