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)75 VOID _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