/[lwip]/lwip/src/netif/etharp.c
ViewVC logotype

Diff of /lwip/src/netif/etharp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.85 by likewise, Sun Nov 28 18:00:20 2004 UTC revision 1.86 by likewise, Mon Nov 29 11:01:20 2004 UTC
# Line 178  etharp_tmr(void) Line 178  etharp_tmr(void)
178  }  }
179    
180  /**  /**
181   * Search the ARP table for a specific entry.   * Search the ARP table for a matching or new entry.
182   *   *
183   * If an IP address is given, return a pending or stable ARP entry that matches   * If an IP address is given, return a pending or stable ARP entry that matches
184   * the address. If no match is found, create a new entry with this address set,   * the address. If no match is found, create a new entry with this address set,
# Line 193  etharp_tmr(void) Line 193  etharp_tmr(void)
193   *   *
194   * @param ipaddr IP address to find in ARP cache, or to add if not found.   * @param ipaddr IP address to find in ARP cache, or to add if not found.
195   * @param flags   * @param flags
196   * - ETHARP_TRY_HARD: Try hard to create a entry by allowing recycling.   * - ETHARP_TRY_HARD: Try hard to create a entry by allowing recycling of
197     * active (stable or pending) entries.
198   *     *  
199   * @return The ARP entry index that matched or is created, ERR_MEM if no   * @return The ARP entry index that matched or is created, ERR_MEM if no
200   * entry is found or could be recycled.   * entry is found or could be recycled.
201   */   */
202  static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags)  static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags)
203  {  {
204    s8_t old_pending, old_stable, empty, i;    s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE, empty = ARP_TABLE_SIZE, i;
205    u8_t age_pending, age_stable;    u8_t age_pending = 0, age_stable = 0;
206  #if ARP_QUEUEING  #if ARP_QUEUEING
207      /* oldest entry with packets on queue */
208    s8_t old_queue = ARP_TABLE_SIZE;    s8_t old_queue = ARP_TABLE_SIZE;
209      /* its age */
210    u8_t age_queue = 0;    u8_t age_queue = 0;
211  #endif  #endif
212    
   old_pending = old_stable = empty = ARP_TABLE_SIZE;  
   age_pending = age_stable = 0;  
   
213    /**    /**
214     * a) do a search through the cache, remember candidates     * a) do a search through the cache, remember candidates
215     * b) select candidate entry     * b) select candidate entry
# Line 237  static s8_t find_entry(struct ip_addr *i Line 237  static s8_t find_entry(struct ip_addr *i
237        /* if given, does IP address match IP address in ARP entry? */        /* if given, does IP address match IP address in ARP entry? */
238        if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {        if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
239          LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: found matching pending entry %d\n", i));          LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: found matching pending entry %d\n", i));
240          /* found match, simply bail out */          /* found exact IP address match, simply bail out */
241          return i;          return i;
242  #if ARP_QUEUEING  #if ARP_QUEUEING
243        /* pending with queued packets? */        /* pending with queued packets? */
# Line 260  static s8_t find_entry(struct ip_addr *i Line 260  static s8_t find_entry(struct ip_addr *i
260        /* if given, does IP address match IP address in ARP entry? */        /* if given, does IP address match IP address in ARP entry? */
261        if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {        if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
262          LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: found matching stable entry %d\n", i));          LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: found matching stable entry %d\n", i));
263          /* found match, simply bail out */          /* found exact IP address match, simply bail out */
264          return i;          return i;
265        /* remember entry with oldest stable entry in oldest, its age in maxtime */        /* remember entry with oldest stable entry in oldest, its age in maxtime */
266        } else if (arp_table[i].ctime >= age_stable) {        } else if (arp_table[i].ctime >= age_stable) {
# Line 269  static s8_t find_entry(struct ip_addr *i Line 269  static s8_t find_entry(struct ip_addr *i
269        }        }
270      }      }
271    }    }
272      /* { we have no match } => try to create a new entry */
273      
274      /* no empty entry found and not allowed to recycle? */
275      if ((i == ARP_TABLE_SIZE) && ((flags & ETHARP_TRY_HARD) == 0))
276      {
277            return (s8_t)ERR_MEM;
278      }
279        
280    /* b) choose the least destructive entry to recycle:    /* b) choose the least destructive entry to recycle:
281     * 1) empty entry     * 1) empty entry
282     * 2) oldest stable entry     * 2) oldest stable entry
283     * 3) oldest pending entry without queued packets     * 3) oldest pending entry without queued packets
284     * 4) oldest pending entry without queued packets     * 4) oldest pending entry without queued packets
285       *
286       * { ETHARP_TRY_HARD is set at this point }
287     */     */
288    
289    /* 1) empty entry available? */    /* 1) empty entry available? */
# Line 305  static s8_t find_entry(struct ip_addr *i Line 314  static s8_t find_entry(struct ip_addr *i
314      /* no empty or recyclable entries found */      /* no empty or recyclable entries found */
315  #endif  #endif
316    } else {    } else {
317      return ERR_MEM;      return (s8_t)ERR_MEM;
318    }    }
319    
320    /* { empty or recyclable entry found } */    /* { empty or recyclable entry found } */
321    LWIP_ASSERT("i >= 0", i >= 0);    LWIP_ASSERT("i >= 0", i >= 0);
322    LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);    LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
323    
324    /* allowed to recycle a entry? */    /* recycle entry (no-op for an already empty entry) */
325    if (flags & ETHARP_TRY_HARD) {    arp_table[i].state = ETHARP_STATE_EMPTY;
326      /* recycle (no-op for an already empty entry) */    /* IP address given? */
327      arp_table[i].state = ETHARP_STATE_EMPTY;    if (ipaddr != NULL) {
328        /* set IP address */
329        ip_addr_set(&arp_table[i].ipaddr, ipaddr);
330    }    }
331      arp_table[i].ctime = 0;
   /* empty entry found or created? */  
   if (arp_table[i].state == ETHARP_STATE_EMPTY) {  
     /* IP address given? */  
     if (ipaddr != NULL) {  
       /* set IP address */  
       ip_addr_set(&arp_table[i].ipaddr, ipaddr);  
     }  
     arp_table[i].ctime = 0;  
332  #if ARP_QUEUEING  #if ARP_QUEUEING
333      /* remove any queued packets */    /* remove any queued packets */
334      if (arp_table[i].p != NULL) pbuf_free(arp_table[i].p);    if (arp_table[i].p != NULL) pbuf_free(arp_table[i].p);
335      arp_table[i].p = NULL;    arp_table[i].p = NULL;
336  #endif  #endif
   /* no entry available */  
   } else {  
     /* return failure */  
     i = (s8_t)ERR_MEM;  
   }  
           
337    return (err_t)i;    return (err_t)i;
338  }  }
339    

Legend:
Removed from v.1.85  
changed lines
  Added in v.1.86

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26