mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-12-25 00:14:02 +00:00
Fix bug #53667: ARP table max size is to small
arp table functions, nd6 destination cache and struct netif_hint can now be u16_t or u8_t depending on table size, so up to 32K entries can be used in these tables (s16_t) Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
This commit is contained in:
parent
0f165ff136
commit
0c2fdfcf42
@ -105,7 +105,7 @@ struct etharp_entry {
|
||||
static struct etharp_entry arp_table[ARP_TABLE_SIZE];
|
||||
|
||||
#if !LWIP_NETIF_HWADDRHINT
|
||||
static u8_t etharp_cached_entry;
|
||||
static netif_addr_idx_t etharp_cached_entry;
|
||||
#endif /* !LWIP_NETIF_HWADDRHINT */
|
||||
|
||||
/** Try hard to create a new entry - we want the IP address to appear in
|
||||
@ -196,7 +196,7 @@ etharp_free_entry(int i)
|
||||
void
|
||||
etharp_tmr(void)
|
||||
{
|
||||
u8_t i;
|
||||
int i;
|
||||
|
||||
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));
|
||||
/* remove expired entries from the ARP table */
|
||||
@ -212,8 +212,8 @@ etharp_tmr(void)
|
||||
((arp_table[i].state == ETHARP_STATE_PENDING) &&
|
||||
(arp_table[i].ctime >= ARP_MAXPENDING))) {
|
||||
/* pending or stable entry has become old! */
|
||||
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %"U16_F".\n",
|
||||
arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", (u16_t)i));
|
||||
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %d.\n",
|
||||
arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", i));
|
||||
/* clean up entries that have just been expired */
|
||||
etharp_free_entry(i);
|
||||
} else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_1) {
|
||||
@ -252,14 +252,14 @@ etharp_tmr(void)
|
||||
* @return The ARP entry index that matched or is created, ERR_MEM if no
|
||||
* entry is found or could be recycled.
|
||||
*/
|
||||
static s8_t
|
||||
static s16_t
|
||||
etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif)
|
||||
{
|
||||
s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE;
|
||||
s8_t empty = ARP_TABLE_SIZE;
|
||||
u8_t i = 0;
|
||||
s16_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE;
|
||||
s16_t empty = ARP_TABLE_SIZE;
|
||||
s16_t i = 0;
|
||||
/* oldest entry with packets on queue */
|
||||
s8_t old_queue = ARP_TABLE_SIZE;
|
||||
s16_t old_queue = ARP_TABLE_SIZE;
|
||||
/* its age */
|
||||
u16_t age_queue = 0, age_pending = 0, age_stable = 0;
|
||||
|
||||
@ -284,9 +284,9 @@ etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif)
|
||||
u8_t state = arp_table[i].state;
|
||||
/* no empty entry found yet and now we do find one? */
|
||||
if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) {
|
||||
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_find_entry: found empty entry %"U16_F"\n", (u16_t)i));
|
||||
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_find_entry: found empty entry %d\n", (int)i));
|
||||
/* remember first empty entry */
|
||||
empty = (s8_t)i;
|
||||
empty = i;
|
||||
} else if (state != ETHARP_STATE_EMPTY) {
|
||||
LWIP_ASSERT("state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE",
|
||||
state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE);
|
||||
@ -296,23 +296,23 @@ etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif)
|
||||
&& ((netif == NULL) || (netif == arp_table[i].netif))
|
||||
#endif /* ETHARP_TABLE_MATCH_NETIF */
|
||||
) {
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %"U16_F"\n", (u16_t)i));
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %d\n", (int)i));
|
||||
/* found exact IP address match, simply bail out */
|
||||
return (s8_t)i;
|
||||
return i;
|
||||
}
|
||||
/* pending entry? */
|
||||
if (state == ETHARP_STATE_PENDING) {
|
||||
/* pending with queued packets? */
|
||||
if (arp_table[i].q != NULL) {
|
||||
if (arp_table[i].ctime >= age_queue) {
|
||||
old_queue = (s8_t)i;
|
||||
old_queue = i;
|
||||
age_queue = arp_table[i].ctime;
|
||||
}
|
||||
} else
|
||||
/* pending without queued packets? */
|
||||
{
|
||||
if (arp_table[i].ctime >= age_pending) {
|
||||
old_pending = (s8_t)i;
|
||||
old_pending = i;
|
||||
age_pending = arp_table[i].ctime;
|
||||
}
|
||||
}
|
||||
@ -325,7 +325,7 @@ etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif)
|
||||
{
|
||||
/* remember entry with oldest stable entry in oldest, its age in maxtime */
|
||||
if (arp_table[i].ctime >= age_stable) {
|
||||
old_stable = (s8_t)i;
|
||||
old_stable = i;
|
||||
age_stable = arp_table[i].ctime;
|
||||
}
|
||||
}
|
||||
@ -339,7 +339,7 @@ etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif)
|
||||
/* or no empty entry found and not allowed to recycle? */
|
||||
((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) {
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty entry found and not allowed to recycle\n"));
|
||||
return (s8_t)ERR_MEM;
|
||||
return (s16_t)ERR_MEM;
|
||||
}
|
||||
|
||||
/* b) choose the least destructive entry to recycle:
|
||||
@ -353,30 +353,30 @@ etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif)
|
||||
|
||||
/* 1) empty entry available? */
|
||||
if (empty < ARP_TABLE_SIZE) {
|
||||
i = (u8_t)empty;
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting empty entry %"U16_F"\n", (u16_t)i));
|
||||
i = empty;
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting empty entry %d\n", (int)i));
|
||||
} else {
|
||||
/* 2) found recyclable stable entry? */
|
||||
if (old_stable < ARP_TABLE_SIZE) {
|
||||
/* recycle oldest stable*/
|
||||
i = (u8_t)old_stable;
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i));
|
||||
i = old_stable;
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest stable entry %d\n", (int)i));
|
||||
/* no queued packets should exist on stable entries */
|
||||
LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL);
|
||||
/* 3) found recyclable pending entry without queued packets? */
|
||||
} else if (old_pending < ARP_TABLE_SIZE) {
|
||||
/* recycle oldest pending */
|
||||
i = (u8_t)old_pending;
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i));
|
||||
i = old_pending;
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %d (without queue)\n", (int)i));
|
||||
/* 4) found recyclable pending entry with queued packets? */
|
||||
} else if (old_queue < ARP_TABLE_SIZE) {
|
||||
/* recycle oldest pending (queued packets are free in etharp_free_entry) */
|
||||
i = (u8_t)old_queue;
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F", freeing packet queue %p\n", (u16_t)i, (void *)(arp_table[i].q)));
|
||||
i = old_queue;
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %d, freeing packet queue %p\n", (int)i, (void *)(arp_table[i].q)));
|
||||
/* no empty or recyclable entries found */
|
||||
} else {
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty or recyclable entries found\n"));
|
||||
return (s8_t)ERR_MEM;
|
||||
return (s16_t)ERR_MEM;
|
||||
}
|
||||
|
||||
/* { empty or recyclable entry found } */
|
||||
@ -397,7 +397,7 @@ etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif)
|
||||
#if ETHARP_TABLE_MATCH_NETIF
|
||||
arp_table[i].netif = netif;
|
||||
#endif /* ETHARP_TABLE_MATCH_NETIF */
|
||||
return (s8_t)i;
|
||||
return (s16_t)i;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -421,7 +421,7 @@ etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif)
|
||||
static err_t
|
||||
etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags)
|
||||
{
|
||||
s8_t i;
|
||||
s16_t i;
|
||||
LWIP_ASSERT("netif->hwaddr_len == ETH_HWADDR_LEN", netif->hwaddr_len == ETH_HWADDR_LEN);
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
|
||||
ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
|
||||
@ -460,7 +460,7 @@ etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct et
|
||||
/* insert in SNMP ARP index tree */
|
||||
mib2_add_arp_entry(netif, &arp_table[i].ipaddr);
|
||||
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i));
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %"S16_F"\n", i));
|
||||
/* update address */
|
||||
SMEMCPY(&arp_table[i].ethaddr, ethaddr, ETH_HWADDR_LEN);
|
||||
/* reset time stamp */
|
||||
@ -528,7 +528,7 @@ etharp_add_static_entry(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr)
|
||||
err_t
|
||||
etharp_remove_static_entry(const ip4_addr_t *ipaddr)
|
||||
{
|
||||
s8_t i;
|
||||
s16_t i;
|
||||
LWIP_ASSERT_CORE_LOCKED();
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_remove_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
|
||||
ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
|
||||
@ -558,7 +558,7 @@ etharp_remove_static_entry(const ip4_addr_t *ipaddr)
|
||||
void
|
||||
etharp_cleanup_netif(struct netif *netif)
|
||||
{
|
||||
u8_t i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARP_TABLE_SIZE; ++i) {
|
||||
u8_t state = arp_table[i].state;
|
||||
@ -583,7 +583,7 @@ ssize_t
|
||||
etharp_find_addr(struct netif *netif, const ip4_addr_t *ipaddr,
|
||||
struct eth_addr **eth_ret, const ip4_addr_t **ip_ret)
|
||||
{
|
||||
s8_t i;
|
||||
s16_t i;
|
||||
|
||||
LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL",
|
||||
eth_ret != NULL && ip_ret != NULL);
|
||||
@ -745,7 +745,7 @@ etharp_input(struct pbuf *p, struct netif *netif)
|
||||
* in the arp_table specified by the index 'arp_idx'.
|
||||
*/
|
||||
static err_t
|
||||
etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, u8_t arp_idx)
|
||||
etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, netif_addr_idx_t arp_idx)
|
||||
{
|
||||
LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE",
|
||||
arp_table[arp_idx].state >= ETHARP_STATE_STABLE);
|
||||
@ -819,7 +819,7 @@ etharp_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr)
|
||||
dest = &mcastaddr;
|
||||
/* unicast destination IP address? */
|
||||
} else {
|
||||
u8_t i;
|
||||
u16_t i;
|
||||
/* outside local network? if so, this can neither be a global broadcast nor
|
||||
a subnet broadcast. */
|
||||
if (!ip4_addr_netcmp(ipaddr, netif_ip4_addr(netif), netif_ip4_netmask(netif)) &&
|
||||
@ -855,7 +855,7 @@ etharp_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr)
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
if (netif->hints != NULL) {
|
||||
/* per-pcb cached entry was given */
|
||||
u8_t etharp_cached_entry = netif->hints->addr_hint;
|
||||
netif_addr_idx_t etharp_cached_entry = netif->hints->addr_hint;
|
||||
if (etharp_cached_entry < ARP_TABLE_SIZE) {
|
||||
#endif /* LWIP_NETIF_HWADDRHINT */
|
||||
if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) &&
|
||||
@ -935,8 +935,8 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q)
|
||||
struct eth_addr *srcaddr = (struct eth_addr *)netif->hwaddr;
|
||||
err_t result = ERR_MEM;
|
||||
int is_new_entry = 0;
|
||||
s8_t i_err;
|
||||
u8_t i;
|
||||
s16_t i_err;
|
||||
u16_t i;
|
||||
|
||||
/* non-unicast address? */
|
||||
if (ip4_addr_isbroadcast(ipaddr, netif) ||
|
||||
@ -958,7 +958,7 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q)
|
||||
}
|
||||
return (err_t)i_err;
|
||||
}
|
||||
i = (u8_t)i_err;
|
||||
i = (u16_t)i_err;
|
||||
|
||||
/* mark a fresh entry as pending (we just sent a request) */
|
||||
if (arp_table[i].state == ETHARP_STATE_EMPTY) {
|
||||
@ -1054,7 +1054,7 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q)
|
||||
memp_free(MEMP_ARP_QUEUE, old);
|
||||
}
|
||||
#endif
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"U16_F"\n", (void *)q, i));
|
||||
result = ERR_OK;
|
||||
} else {
|
||||
/* the pool MEMP_ARP_QUEUE is empty */
|
||||
@ -1065,12 +1065,12 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q)
|
||||
#else /* ARP_QUEUEING */
|
||||
/* always queue one packet per ARP request only, freeing a previously queued packet */
|
||||
if (arp_table[i].q != NULL) {
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: dropped previously queued packet %p for ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: dropped previously queued packet %p for ARP entry %"U16_F"\n", (void *)q, i));
|
||||
pbuf_free(arp_table[i].q);
|
||||
}
|
||||
arp_table[i].q = p;
|
||||
result = ERR_OK;
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"U16_F"\n", (void *)q, i));
|
||||
#endif /* ARP_QUEUEING */
|
||||
} else {
|
||||
ETHARP_STATS_INC(etharp.memerr);
|
||||
|
@ -85,7 +85,7 @@ u32_t retrans_timer = LWIP_ND6_RETRANS_TIMER; /* @todo implement this value in t
|
||||
|
||||
/* Index for cache entries. */
|
||||
static u8_t nd6_cached_neighbor_index;
|
||||
static u8_t nd6_cached_destination_index;
|
||||
static netif_addr_idx_t nd6_cached_destination_index;
|
||||
|
||||
/* Multicast address holder. */
|
||||
static ip6_addr_t multicast_address;
|
||||
@ -105,9 +105,9 @@ static union ra_options nd6_ra_buffer;
|
||||
static s8_t nd6_find_neighbor_cache_entry(const ip6_addr_t *ip6addr);
|
||||
static s8_t nd6_new_neighbor_cache_entry(void);
|
||||
static void nd6_free_neighbor_cache_entry(s8_t i);
|
||||
static s8_t nd6_find_destination_cache_entry(const ip6_addr_t *ip6addr);
|
||||
static s8_t nd6_new_destination_cache_entry(void);
|
||||
static s8_t nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif);
|
||||
static s16_t nd6_find_destination_cache_entry(const ip6_addr_t *ip6addr);
|
||||
static s16_t nd6_new_destination_cache_entry(void);
|
||||
static int nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif);
|
||||
static s8_t nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif);
|
||||
static s8_t nd6_get_router(const ip6_addr_t *router_addr, struct netif *netif);
|
||||
static s8_t nd6_new_router(const ip6_addr_t *router_addr, struct netif *netif);
|
||||
@ -1561,7 +1561,7 @@ nd6_find_destination_cache_entry(const ip6_addr_t *ip6addr)
|
||||
* @return The destination cache entry index that was created, -1 if no
|
||||
* entry was created
|
||||
*/
|
||||
static s8_t
|
||||
static s16_t
|
||||
nd6_new_destination_cache_entry(void)
|
||||
{
|
||||
s8_t i, j;
|
||||
@ -1609,7 +1609,7 @@ nd6_clear_destination_cache(void)
|
||||
* @param ip6addr the IPv6 address to match
|
||||
* @return 1 if the address is on-link, 0 otherwise
|
||||
*/
|
||||
static s8_t
|
||||
static int
|
||||
nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif)
|
||||
{
|
||||
s8_t i;
|
||||
@ -1916,7 +1916,7 @@ nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif)
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
if (netif->hints != NULL) {
|
||||
/* per-pcb cached entry was given */
|
||||
u8_t addr_hint = netif->hints->addr_hint;
|
||||
netif_addr_idx_t addr_hint = netif->hints->addr_hint;
|
||||
if (addr_hint < LWIP_ND6_NUM_DESTINATIONS) {
|
||||
nd6_cached_destination_index = addr_hint;
|
||||
}
|
||||
|
@ -237,10 +237,16 @@ u8_t netif_alloc_client_data_id(void);
|
||||
#define netif_get_client_data(netif, id) (netif)->client_data[(id)]
|
||||
#endif
|
||||
|
||||
#if (LWIP_IPV4 && LWIP_ARP && (ARP_TABLE_SIZE > 0x7f)) || (LWIP_IPV6 && (LWIP_ND6_NUM_DESTINATIONS > 0x7f))
|
||||
typedef u16_t netif_addr_idx_t;
|
||||
#else
|
||||
typedef u8_t netif_addr_idx_t;
|
||||
#endif
|
||||
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
#define LWIP_NETIF_USE_HINTS 1
|
||||
struct netif_hint {
|
||||
u8_t addr_hint;
|
||||
netif_addr_idx_t addr_hint;
|
||||
};
|
||||
#else /* LWIP_NETIF_HWADDRHINT */
|
||||
#define LWIP_NETIF_USE_HINTS 0
|
||||
|
Loading…
Reference in New Issue
Block a user