Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of OmniWheels by
neighbor_cache.c
00001 /* 00002 * Copyright (c) 2014-2017, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 #include "nsconfig.h" 00018 #include "ns_types.h" 00019 #include "common_functions.h" 00020 #include "ns_trace.h" 00021 #include "string.h" 00022 #include "nsdynmemLIB.h" 00023 #include "Service_Libs/Neighbor_cache/neighbor_table_definition.h" 00024 00025 #ifdef HAVE_NEIGHBOR_CACHE 00026 00027 static void entry_delete(neigh_cache_s *neigh_cache, neigh_cache_entry_s *entry); 00028 00029 /** 00030 * \brief A function to initialize a neighbor cache before use 00031 * 00032 * \param neigh_cache pointer to neighbor cache. 00033 */ 00034 void neighbor_cache_init(neigh_cache_s *neigh_cache) 00035 { 00036 ns_list_init(&neigh_cache->head); 00037 } 00038 00039 /** 00040 * \brief A function to flush an entire neighbour cache 00041 * 00042 * \param neigh_cache pointer to neighbor cache. 00043 * 00044 * \return <n> The number of entries removed 00045 */ 00046 int neighbor_cache_flush(neigh_cache_s *neigh_cache) 00047 { 00048 int count = 0; 00049 00050 ns_list_foreach_safe(neigh_cache_entry_s, entry, &neigh_cache->head) { 00051 entry_delete(neigh_cache, entry); 00052 count++; 00053 } 00054 00055 return count; 00056 } 00057 00058 /** 00059 * \brief Extended internal implementation of neighbor_cache_entry_get 00060 * 00061 * \param neigh_cache pointer to neighbor cache. 00062 * \param address_type type for 16-bit or 64-bit address 00063 * \param address_ptr pointer to address of specified type 00064 * \param reorder true if permitted to reorder the list 00065 * 00066 * \return pointer to found entry 00067 * \return NULL if not found 00068 */ 00069 static neigh_cache_entry_s *entry_get(neigh_cache_s *neigh_cache, neighbor_address_type_e address_type, const void *address_ptr, bool reorder) 00070 { 00071 uint16_t mac16 = 0; 00072 neigh_cache_entry_s *entry = NULL; 00073 00074 if (address_type == NEIGH_16_BIT_ADDRESS) { 00075 mac16 = common_read_16_bit(address_ptr); 00076 } 00077 00078 ns_list_foreach(neigh_cache_entry_s, e, &neigh_cache->head) { 00079 bool match = false; 00080 switch (address_type) { 00081 case NEIGH_64_BIT_ADDRESS: 00082 match = memcmp(address_ptr, e->mac64, sizeof(entry->mac64)) == 0; 00083 break; 00084 case NEIGH_16_BIT_ADDRESS: 00085 match = e->mac16 == mac16; 00086 break; 00087 case NEIGH__TIMED_OUT: 00088 match = e->ttl == 0; 00089 break; 00090 } 00091 if (match) { 00092 entry = e; 00093 break; 00094 } 00095 } 00096 00097 if (!entry) { 00098 return NULL; 00099 } 00100 00101 /* 00102 * If permitted, move this entry to head of list, so frequently-used entries 00103 * stay near the top. 00104 */ 00105 if (entry != ns_list_get_first(&neigh_cache->head) && reorder) { 00106 ns_list_remove(&neigh_cache->head, entry); 00107 ns_list_add_to_start(&neigh_cache->head, entry); 00108 } 00109 00110 return entry; 00111 } 00112 00113 /** 00114 * \brief A function to locate a specific entry by address 00115 * 00116 * Note that this can re-order the cache, so could upset iteration using macros. 00117 * 00118 * \param neigh_cache pointer to neighbor cache. 00119 * \param address_type type for 16-bit or 64-bit address 00120 * \param address_ptr pointer to address of specified type 00121 * 00122 * \return pointer to cache entry 00123 * \return NULL if not found 00124 */ 00125 neigh_cache_entry_s *neighbor_cache_entry_get(neigh_cache_s *neigh_cache, neighbor_address_type_e address_type, const void *address_ptr) 00126 { 00127 return entry_get(neigh_cache, address_type, address_ptr, true); 00128 } 00129 00130 /** 00131 * \brief A function to create or return an existing neighbor cache entry. 00132 * 00133 * \param neigh_cache pointer to neighbor cache. 00134 * \param address_ptr pointer to EUI-64 address (64-bit) 00135 * 00136 * \return pointer to cache entry, possibly newly created. 00137 * \return NULL if entry not found an unable to allocate memory for new entry 00138 */ 00139 neigh_cache_entry_s *neighbor_cache_entry_create(neigh_cache_s *neigh_cache, const uint8_t address_ptr[8]) 00140 { 00141 neigh_cache_entry_s *entry; 00142 00143 entry = neighbor_cache_entry_get(neigh_cache, NEIGH_64_BIT_ADDRESS, address_ptr); 00144 if (entry) { 00145 return entry; 00146 } 00147 00148 entry = ns_dyn_mem_alloc(sizeof * entry); 00149 if (!entry) { 00150 return NULL; 00151 } 00152 00153 memset(entry, 0, sizeof * entry); 00154 memcpy(entry->mac64, address_ptr, sizeof entry->mac64); 00155 entry->mac16 = 0xFFFF; 00156 entry->neighbor_keypair_info = NULL; 00157 ns_list_add_to_start(&neigh_cache->head, entry); 00158 00159 return entry; 00160 } 00161 00162 /** 00163 * \brief Delete an entry from the list, including housekeeping 00164 * 00165 * \param neigh_cache pointer to neighbor cache. 00166 * \param entry pointer to entry 00167 */ 00168 static void entry_delete(neigh_cache_s *neigh_cache, neigh_cache_entry_s *entry) 00169 { 00170 ns_list_remove(&neigh_cache->head, entry); 00171 if (entry->neighbor_keypair_info) { 00172 ns_dyn_mem_free(entry->neighbor_keypair_info); 00173 } 00174 ns_dyn_mem_free(entry); 00175 } 00176 00177 /** 00178 * \brief A function to delete an entry by address. 00179 * 00180 * \param neigh_cache pointer to neighbor cache. 00181 * \param address_type type for 16-bit or 64-bit address 00182 * \param address_ptr pointer to address of specified type 00183 * 00184 * \return 0 Removed OK 00185 * \return -1 Entry not found 00186 */ 00187 int8_t neighbor_cache_entry_delete(neigh_cache_s *neigh_cache, neighbor_address_type_e address_type, const void *address_ptr) 00188 { 00189 neigh_cache_entry_s *entry; 00190 00191 entry = entry_get(neigh_cache, address_type, address_ptr, false); 00192 if (!entry) { 00193 return -1; 00194 } 00195 00196 entry_delete(neigh_cache, entry); 00197 00198 return 0; 00199 } 00200 00201 /** 00202 * \brief A function to delete an entry by entry pointer. 00203 * 00204 * \param neigh_cache pointer to neighbor cache. 00205 * \param entry pointer to entry 00206 * 00207 * \return pointer to the next entry, to allow deletion during iteration 00208 * \return NULL if no more entries 00209 * \return NEIGH_ENTRY_PTR_ERR if entry pointer not found (no longer checked) 00210 */ 00211 neigh_cache_entry_s *neighbor_cache_entry_delete_by_entry_pointer(neigh_cache_s *neigh_cache, neigh_cache_entry_s *entry) 00212 { 00213 neigh_cache_entry_s *next = ns_list_get_next(&neigh_cache->head, entry); 00214 00215 entry_delete(neigh_cache, entry); 00216 00217 return next; 00218 } 00219 00220 /** 00221 * \brief A function to update Neighbor cache Time-To-Live values. 00222 * 00223 * This decrements the TTL for all entries in the cache. TTL values are 00224 * are clamped to not wrap past zero. When an entry's TTL value becomes zero, 00225 * link_req_counter is set to NEIGH_LINK_REQUEST_COUNTER. (Note that 00226 * newly-created entries have ttl and link_req_counter both zero - they will 00227 * need initialising before use). 00228 * 00229 * \param neigh_cache pointer to neighbor cache. 00230 * \param tick amount to decrement TTL 00231 * 00232 * \return total number of entries in the cache whose TTL is 0 after the update 00233 */ 00234 int neighbor_cache_ttl_update(neigh_cache_s *neigh_cache, uint16_t ticks) 00235 { 00236 int count = 0; 00237 00238 ns_list_foreach(neigh_cache_entry_s, entry, &neigh_cache->head) { 00239 if (entry->ttl > ticks) { 00240 entry->ttl -= ticks; 00241 } else { 00242 if (entry->ttl > 0) { 00243 entry->link_req_counter = NEIGH_LINK_REQUEST_COUNTER; 00244 entry->ttl = 0; 00245 } 00246 count++; 00247 } 00248 } 00249 00250 return count; 00251 } 00252 00253 /** 00254 * \brief A function to get a timed-out neighbor entry. 00255 * 00256 * Returns an entry whose TTL field is set to zero. 00257 * 00258 * \param neigh_cache pointer to neighbor cache. 00259 * 00260 * \return pointer to a timed-out entry 00261 * \return NULL if no timed-out entries 00262 */ 00263 neigh_cache_entry_s *neighbor_cache_entry_get_timed_out(neigh_cache_s *neigh_cache) 00264 { 00265 return neighbor_cache_entry_get(neigh_cache, NEIGH__TIMED_OUT, NULL); 00266 } 00267 00268 #else // HAVE_NEIGHBOR_CACHE 00269 00270 void neighbor_cache_init(neigh_cache_s *neigh_cache) { 00271 (void)neigh_cache; 00272 } 00273 int neighbor_cache_flush(neigh_cache_s *neigh_cache){ 00274 (void)neigh_cache; 00275 return 0; 00276 } 00277 00278 #endif // HAVE_NEIGHBOR_CACHE
Generated on Fri Jul 22 2022 04:53:57 by
1.7.2
