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 /** Address Resolution Protocol (ARP) */ 18 /** */ 19 /**************************************************************************/ 20 /**************************************************************************/ 21 22 #define NX_SOURCE_CODE 23 24 /* Include necessary system files. */ 25 26 #include "nx_api.h" 27 #include "nx_arp.h" 28 29 #ifndef NX_DISABLE_IPV4 30 /**************************************************************************/ 31 /* */ 32 /* FUNCTION RELEASE */ 33 /* */ 34 /* _nx_arp_static_entry_delete_internal PORTABLE C */ 35 /* 6.1 */ 36 /* AUTHOR */ 37 /* */ 38 /* Yuxin Zhou, Microsoft Corporation */ 39 /* */ 40 /* DESCRIPTION */ 41 /* */ 42 /* This function deletes the ARP entry pointed to by the caller. Note */ 43 /* the caller should already have searched the ARP list to verify a */ 44 /* valid ARP entry to delete. Also, it is assumed the caller already */ 45 /* has obtained the IP protection mutex before invoking this service. */ 46 /* */ 47 /* INPUT */ 48 /* */ 49 /* ip_ptr IP instance owner of APR table*/ 50 /* arp_entry ARP entry to delete */ 51 /* */ 52 /* OUTPUT */ 53 /* */ 54 /* None */ 55 /* */ 56 /* CALLS */ 57 /* */ 58 /* None */ 59 /* */ 60 /* CALLED BY */ 61 /* */ 62 /* _nx_arp_interface_entries_delete Delete ARP entry associated */ 63 /* with the specified interface*/ 64 /* _nx_arp_static_entry_delete Delete static ARP entry */ 65 /* */ 66 /* RELEASE HISTORY */ 67 /* */ 68 /* DATE NAME DESCRIPTION */ 69 /* */ 70 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ 71 /* 09-30-2020 Yuxin Zhou Modified comment(s), */ 72 /* resulting in version 6.1 */ 73 /* */ 74 /**************************************************************************/ _nx_arp_static_entry_delete_internal(NX_IP * ip_ptr,NX_ARP * arp_entry)75VOID _nx_arp_static_entry_delete_internal(NX_IP *ip_ptr, NX_ARP *arp_entry) 76 { 77 78 TX_INTERRUPT_SAVE_AREA 79 80 81 #ifndef NX_DISABLE_ARP_INFO 82 /* Decrement the ARP static entry count. */ 83 ip_ptr -> nx_ip_arp_static_entries--; 84 #endif 85 86 /* Disable interrupts temporarily. */ 87 TX_DISABLE 88 89 /* Determine if this ARP entry is already active. */ 90 if (arp_entry -> nx_arp_active_list_head) 91 { 92 93 /* Remove this dynamic ARP entry from the associated list. */ 94 95 /* Determine if this is the only ARP entry on the list. */ 96 if (arp_entry == arp_entry -> nx_arp_active_next) 97 { 98 99 /* Remove the entry from the list. */ 100 *(arp_entry -> nx_arp_active_list_head) = NX_NULL; 101 } 102 else 103 { 104 105 /* Remove the entry from a list of more than one entry. */ 106 107 /* Update the list head pointer. */ 108 if (*(arp_entry -> nx_arp_active_list_head) == arp_entry) 109 { 110 *(arp_entry -> nx_arp_active_list_head) = arp_entry -> nx_arp_active_next; 111 } 112 113 /* Update the links of the adjacent ARP entries. */ 114 (arp_entry -> nx_arp_active_next) -> nx_arp_active_previous = 115 arp_entry -> nx_arp_active_previous; 116 (arp_entry -> nx_arp_active_previous) -> nx_arp_active_next = 117 arp_entry -> nx_arp_active_next; 118 } 119 } 120 121 /* Remove this entry from the static ARP list. */ 122 123 /* Determine if this is the only ARP entry on the static list. */ 124 if (arp_entry == arp_entry -> nx_arp_pool_next) 125 { 126 127 /* Remove the sole entry from the static list head. */ 128 ip_ptr -> nx_ip_arp_static_list = NX_NULL; 129 } 130 else 131 { 132 133 /* Remove the entry from a list of more than one entry. */ 134 135 /* Update the links of the adjacent ARP dynamic pool entries. */ 136 (arp_entry -> nx_arp_pool_next) -> nx_arp_pool_previous = 137 arp_entry -> nx_arp_pool_previous; 138 (arp_entry -> nx_arp_pool_previous) -> nx_arp_pool_next = 139 arp_entry -> nx_arp_pool_next; 140 141 /* Update the list head pointer. */ 142 if (ip_ptr -> nx_ip_arp_static_list == arp_entry) 143 { 144 ip_ptr -> nx_ip_arp_static_list = arp_entry -> nx_arp_pool_next; 145 } 146 } 147 148 /* Clear the fields that indicate the ARP entry is a static entry and make sure 149 it is viewed as inactive in preparation for returning it to the dynamic ARP 150 pool. */ 151 arp_entry -> nx_arp_route_static = NX_FALSE; 152 arp_entry -> nx_arp_active_list_head = NX_NULL; 153 154 /* Place the ARP entry at the end of the dynamic ARP pool, which is where new 155 ARP requests are allocated from. */ 156 157 /* Determine if the dynamic ARP pool is empty. */ 158 if (ip_ptr -> nx_ip_arp_dynamic_list) 159 { 160 161 /* Dynamic list is not empty, add former static ARP entry to the end of the list. */ 162 arp_entry -> nx_arp_pool_next = ip_ptr -> nx_ip_arp_dynamic_list; 163 arp_entry -> nx_arp_pool_previous = (ip_ptr -> nx_ip_arp_dynamic_list) -> nx_arp_pool_previous; 164 ((ip_ptr -> nx_ip_arp_dynamic_list) -> nx_arp_pool_previous) -> nx_arp_pool_next = arp_entry; 165 (ip_ptr -> nx_ip_arp_dynamic_list) -> nx_arp_pool_previous = arp_entry; 166 } 167 else 168 { 169 170 /* Dynamic list was empty, just place it at the head of the dynamic list. */ 171 ip_ptr -> nx_ip_arp_dynamic_list = arp_entry; 172 arp_entry -> nx_arp_pool_next = arp_entry; 173 arp_entry -> nx_arp_pool_previous = arp_entry; 174 } 175 176 /* Restore interrupts. */ 177 TX_RESTORE 178 } 179 #endif /* !NX_DISABLE_IPV4 */ 180 181