etharp queueing functionality separated in queueing functions. Fixed couple of GCC 3.3.1 warnings in TCP.

This commit is contained in:
likewise 2003-11-15 00:41:47 +00:00
parent c13adc3616
commit eb84532b3a
3 changed files with 117 additions and 104 deletions

View File

@ -558,7 +558,7 @@ tcp_process(struct tcp_pcb *pcb)
tcp_parseopt(pcb); tcp_parseopt(pcb);
/* Call the user specified function to call when sucessfully /* Call the user specified function to call when sucessfully
connected. */ * connected. */
TCP_EVENT_CONNECTED(pcb, ERR_OK, err); TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
tcp_ack(pcb); tcp_ack(pcb);
} }
@ -570,17 +570,19 @@ tcp_process(struct tcp_pcb *pcb)
TCP_SEQ_LEQ(ackno, pcb->snd_nxt)) { TCP_SEQ_LEQ(ackno, pcb->snd_nxt)) {
pcb->state = ESTABLISHED; pcb->state = ESTABLISHED;
LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection established %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest)); LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection established %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
#if LWIP_CALLBACK_API
LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL); LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
#endif
/* Call the accept function. */ /* Call the accept function. */
TCP_EVENT_ACCEPT(pcb, ERR_OK, err); TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
if (err != ERR_OK) { if (err != ERR_OK) {
/* If the accept function returns with an error, we abort /* If the accept function returns with an error, we abort
the connection. */ * the connection. */
tcp_abort(pcb); tcp_abort(pcb);
return ERR_ABRT; return ERR_ABRT;
} }
/* If there was any data contained within this ACK, /* If there was any data contained within this ACK,
we'd better pass it on to the application as well. */ * we'd better pass it on to the application as well. */
tcp_receive(pcb); tcp_receive(pcb);
pcb->cwnd = pcb->mss; pcb->cwnd = pcb->mss;
} }

View File

@ -133,7 +133,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
pcb->unsent != NULL); pcb->unsent != NULL);
} }
seg = NULL; seg = useg = NULL;
seglen = 0; seglen = 0;
/* First, break up the data into segments and tuck them together in /* First, break up the data into segments and tuck them together in
@ -158,6 +158,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
} }
else { else {
/* Attach the segment to the end of the queued segments. */ /* Attach the segment to the end of the queued segments. */
LWIP_ASSERT("useg != NULL", useg != NULL);
useg->next = seg; useg->next = seg;
useg = seg; useg = seg;
} }

View File

@ -124,22 +124,27 @@ struct etharp_entry {
static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}}; static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
static struct etharp_entry arp_table[ARP_TABLE_SIZE]; static struct etharp_entry arp_table[ARP_TABLE_SIZE];
static struct pbuf *update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags); static s8_t find_arp_entry(void);
#define ARP_INSERT_FLAG 1 #define ARP_INSERT_FLAG 1
static struct pbuf *update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags);
#if ARP_QUEUEING
static struct pbuf *etharp_enqueue(s8_t i, struct pbuf *q);
static struct pbuf *etharp_dequeue(s8_t i);
#endif
/** /**
* Initializes ARP module. * Initializes ARP module.
*/ */
void void
etharp_init(void) etharp_init(void)
{ {
u8_t i; s8_t i;
/* clear ARP entries */ /* clear ARP entries */
for(i = 0; i < ARP_TABLE_SIZE; ++i) { for(i = 0; i < ARP_TABLE_SIZE; ++i) {
arp_table[i].state = ETHARP_STATE_EMPTY; arp_table[i].state = ETHARP_STATE_EMPTY;
#if ARP_QUEUEING #if ARP_QUEUEING
arp_table[i].p = NULL; arp_table[i].p = NULL;
#endif #endif
arp_table[i].ctime = 0;
} }
} }
@ -152,7 +157,7 @@ etharp_init(void)
void void
etharp_tmr(void) etharp_tmr(void)
{ {
u8_t i; s8_t i;
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n")); LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));
/* remove expired entries from the ARP table */ /* remove expired entries from the ARP table */
@ -186,53 +191,101 @@ etharp_tmr(void)
} }
/** /**
* Return an empty ARP entry or, if the table is full, ARP_TABLE_SIZE if all * Return an empty ARP entry (possibly recycling the oldest stable entry).
* entries are pending, otherwise the oldest entry.
* *
* @return The ARP entry index that is available, ARP_TABLE_SIZE if no usable * @return The ARP entry index that is available, ERR_MEM if no usable
* entry is found. * entry is found.
*/ */
static u8_t static s8_t
find_arp_entry(void) find_arp_entry(void)
{ {
u8_t i, j, maxtime; s8_t i, j;
u8_t maxtime = 0;
/* Try to find an unused entry in the ARP table. */
for (i = 0; i < ARP_TABLE_SIZE; ++i) {
if (arp_table[i].state == ETHARP_STATE_EMPTY) {
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found empty entry %u\n", i));
break;
}
}
/* If no unused entry is found, we try to find the oldest entry and
throw it away. If all entries are new and ctime drop one */
if (i == ARP_TABLE_SIZE) {
maxtime = 0;
j = ARP_TABLE_SIZE; j = ARP_TABLE_SIZE;
/* search ARP table for an unused or old entry */
for (i = 0; i < ARP_TABLE_SIZE; ++i) { for (i = 0; i < ARP_TABLE_SIZE; ++i) {
/* empty entry? */
if (arp_table[i].state == ETHARP_STATE_EMPTY) {
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: returning empty entry %u\n", i));
return i;
/* stable entry? */
} else if (arp_table[i].state == ETHARP_STATE_STABLE) {
/* remember entry with oldest stable entry in j */ /* remember entry with oldest stable entry in j */
if ((arp_table[i].state == ETHARP_STATE_STABLE) && if (arp_table[i].ctime >= maxtime) maxtime = arp_table[j = i].ctime;
#if ARP_QUEUEING /* do not want to re-use an entry with queued packets */
(arp_table[i].p == NULL) &&
#endif
(arp_table[i].ctime >= maxtime)) {
maxtime = arp_table[i].ctime;
j = i;
/* { j = oldest stable entry } */
} }
} }
if (j != ARP_TABLE_SIZE) { /* no empty entry found? */
if (i == ARP_TABLE_SIZE) {
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found oldest stable entry %u\n", j)); LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found oldest stable entry %u\n", j));
} else { /* fall-back to oldest stable */
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: no replacable entry could be found\n"));
}
i = j; i = j;
} }
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: returning %u, state %u\n", i, arp_table[i].state)); /* no available entry found? */
if (i == ARP_TABLE_SIZE) {
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: no replacable entry could be found\n"));
/* return failure */
return ERR_MEM;
}
/* clean up the recycled stable entry */
if (arp_table[i].state == ETHARP_STATE_STABLE) {
#if ARP_QUEUEING
struct pbuf *q;
/* free packets on queue */
q = etharp_dequeue(i);
if (q != NULL) pbuf_free(q);
#endif
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_arp_entry: recycling oldest stable entry %u\n", i));
arp_table[i].state = ETHARP_STATE_EMPTY;
arp_table[i].ctime = 0;
}
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: returning %u\n", i));
return i; return i;
} }
#if ARP_QUEUEING
static struct pbuf *
etharp_enqueue(s8_t i, struct pbuf *q)
{
/* any pbuf to queue? */
if (q != NULL) {
/* remove old packet on queue? */
#if ARP_QUEUE_FIRST == 0
struct pbuf *p;
p = etharp_dequeue(i);
if (p != NULL) pbuf_free(p);
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("etharp_query: dropped packet %p on ARP queue. Should not occur.\n", (void *)arp_table[i].p));
#endif
/* packet can be queued? */
if (arp_table[i].p == NULL) {
/* copy PBUF_REF referenced payloads into PBUF_RAM */
q = pbuf_take(q);
/* remember pbuf to queue, if any */
arp_table[i].p = q;
/* pbufs are queued, increase the reference count */
pbuf_ref(q);
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: queued packet %p on ARP entry %u.\n", (void *)q, i));
}
}
return arp_table[i].p;
}
static struct pbuf *
etharp_dequeue(s8_t i)
{
/* queued packets on a stable entry (work in progress) */
if (arp_table[i].p != NULL) {
/* send the queued IP packets */
netif->linkoutput(netif, arp_table[i].p);
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3,
("find_arp_entry: sent queued packet %p.\n", (void *)arp_table[i].p));
arp_table[i].p = NULL;
}
return arp_table[i].p;
}
#endif
/** /**
* Update (or insert) a IP/MAC address pair in the ARP cache. * Update (or insert) a IP/MAC address pair in the ARP cache.
* *
@ -250,7 +303,7 @@ find_arp_entry(void)
static struct pbuf * static struct pbuf *
update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags) update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags)
{ {
u8_t i, k; s8_t i, k;
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("update_arp_entry()\n")); LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("update_arp_entry()\n"));
LWIP_ASSERT("netif->hwaddr_len != 0", netif->hwaddr_len != 0); LWIP_ASSERT("netif->hwaddr_len != 0", netif->hwaddr_len != 0);
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: %u.%u.%u.%u - %02x:%02x:%02x:%02x:%02x:%02x\n", ip4_addr1(ipaddr), ip4_addr2(ipaddr), ip4_addr3(ipaddr), ip4_addr4(ipaddr), LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: %u.%u.%u.%u - %02x:%02x:%02x:%02x:%02x:%02x\n", ip4_addr1(ipaddr), ip4_addr2(ipaddr), ip4_addr3(ipaddr), ip4_addr4(ipaddr),
@ -322,21 +375,10 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: adding entry to table\n")); LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: adding entry to table\n"));
/* find an empty or old entry. */ /* find an empty or old entry. */
i = find_arp_entry(); i = find_arp_entry();
if (i == ARP_TABLE_SIZE) { if (i == ERR_MEM) {
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: no available entry found\n")); LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: no available entry found\n"));
return NULL; return NULL;
} }
/* see if find_arp_entry() gave us an old stable, or empty entry to re-use */
if (arp_table[i].state == ETHARP_STATE_STABLE) {
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: overwriting old stable entry %u\n", i));
/* stable entries should have no queued packets (TODO: allow later) */
#if ARP_QUEUEING
LWIP_ASSERT("update_arp_entry: arp_table[i].p == NULL", arp_table[i].p == NULL);
#endif
} else {
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("update_arp_entry: filling empty entry %u with state %u\n", i, arp_table[i].state));
LWIP_ASSERT("update_arp_entry: arp_table[i].state == ETHARP_STATE_EMPTY", arp_table[i].state == ETHARP_STATE_EMPTY);
}
/* set IP address */ /* set IP address */
ip_addr_set(&arp_table[i].ipaddr, ipaddr); ip_addr_set(&arp_table[i].ipaddr, ipaddr);
/* set Ethernet hardware address */ /* set Ethernet hardware address */
@ -538,7 +580,7 @@ etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
{ {
struct eth_addr *dest, *srcaddr, mcastaddr; struct eth_addr *dest, *srcaddr, mcastaddr;
struct eth_hdr *ethhdr; struct eth_hdr *ethhdr;
u8_t i; s8_t i;
/* make room for Ethernet header */ /* make room for Ethernet header */
if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) { if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
@ -667,7 +709,7 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
struct eth_addr *srcaddr; struct eth_addr *srcaddr;
struct etharp_hdr *hdr; struct etharp_hdr *hdr;
err_t result = ERR_OK; err_t result = ERR_OK;
u8_t i; s8_t i;
u8_t perform_arp_request = 1; u8_t perform_arp_request = 1;
/* prevent 'unused argument' warning if ARP_QUEUEING == 0 */ /* prevent 'unused argument' warning if ARP_QUEUEING == 0 */
(void)q; (void)q;
@ -677,7 +719,7 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
if (ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) { if (ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
if (arp_table[i].state == ETHARP_STATE_PENDING) { if (arp_table[i].state == ETHARP_STATE_PENDING) {
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already pending as entry %u\n", i)); LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already pending as entry %u\n", i));
/* break out of for-loop, user may wish to queue a packet on a stable entry */ /* break out of for-loop, user may wish to queue a packet on a pending entry */
/* TODO: we will issue a new ARP request, which should not occur too often */ /* TODO: we will issue a new ARP request, which should not occur too often */
/* we might want to run a faster timer on ARP to limit this */ /* we might want to run a faster timer on ARP to limit this */
break; break;
@ -697,51 +739,19 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
/* find an available (unused or old) entry */ /* find an available (unused or old) entry */
i = find_arp_entry(); i = find_arp_entry();
/* bail out if no ARP entries are available */ /* bail out if no ARP entries are available */
if (i == ARP_TABLE_SIZE) { if (i == ERR_MEM) {
LWIP_DEBUGF(ETHARP_DEBUG | 2, ("etharp_query: no more ARP entries available. Should seldom occur.\n")); LWIP_DEBUGF(ETHARP_DEBUG | 2, ("etharp_query: no more ARP entries available. Should seldom occur.\n"));
return ERR_MEM; return ERR_MEM;
} }
/* we will now recycle entry i */
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: created ARP table entry %u.\n", i));
/* i is available, create ARP entry */ /* i is available, create ARP entry */
ip_addr_set(&arp_table[i].ipaddr, ipaddr);
arp_table[i].ctime = 0;
arp_table[i].state = ETHARP_STATE_PENDING; arp_table[i].state = ETHARP_STATE_PENDING;
#if ARP_QUEUEING /* deal with queue of recycled entry */ ip_addr_set(&arp_table[i].ipaddr, ipaddr);
/* free queued packet, as entry is now invalidated and recycled */ /* queried address was already in ARP table */
if (arp_table[i].p != NULL) { } else {
pbuf_free(arp_table[i].p);
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3,
("etharp_query: dropped packet %p from recycled ARP entry queue. Should not occur.\n", (void *)arp_table[i].p));
arp_table[i].p = NULL;
}
#endif
}
#if ARP_QUEUEING #if ARP_QUEUEING
/* any pbuf to queue and queue is empty? */ etharp_enqueue(i, q);
if (q != NULL) {
/* yield later packets over older packets? */
#if ARP_QUEUE_FIRST == 0
/* earlier queued packet on this entry? */
if (arp_table[i].p != NULL) {
pbuf_free(arp_table[i].p);
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("etharp_query: dropped packet %p on ARP queue. Should not occur.\n", (void *)arp_table[i].p));
arp_table[i].p = NULL;
/* fall-through into next if */
}
#endif #endif
/* packet can be queued? */
if (arp_table[i].p == NULL) {
/* copy PBUF_REF referenced payloads into PBUF_RAM */
q = pbuf_take(q);
/* remember pbuf to queue, if any */
arp_table[i].p = q;
/* pbufs are queued, increase the reference count */
pbuf_ref(q);
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: queued packet %p on ARP entry %u.\n", (void *)q, i));
} }
}
#endif
/* ARP request? */ /* ARP request? */
if (perform_arp_request) if (perform_arp_request)
{ {