mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-04 14:29:39 +00:00
Added option LWIP_NETIF_HWADDRHINT (default=off) to cache ARP table indices with each pcb instead of single-entry cache for the complete stack.
This commit is contained in:
parent
fa4b711495
commit
96e4ec4a15
@ -241,7 +241,13 @@ HISTORY
|
||||
|
||||
++ Bug fixes:
|
||||
|
||||
2007-06-28 Simon Goldschmidt
|
||||
2007-07-02 Simon Goldschmidt
|
||||
* ipv4/ip.h, ipv6/ip.h, opt.h, netif.h, etharp.h, ipv4/ip.c, netif.c, raw.c,
|
||||
tcp_out.c, udp.c, etharp.c: Added option LWIP_NETIF_HWADDRHINT (default=off)
|
||||
to cache ARP table indices with each pcb instead of single-entry cache for
|
||||
the complete stack.
|
||||
|
||||
2007-07-02 Simon Goldschmidt
|
||||
* tcp.h, tcp.c, tcp_in.c, tcp_out.c: Added some ASSERTS and casts to prevent
|
||||
warnings when assigning to smaller types.
|
||||
|
||||
|
@ -96,6 +96,11 @@ ip_route(struct ip_addr *dest)
|
||||
return netif;
|
||||
}
|
||||
}
|
||||
if (netif_default == NULL) {
|
||||
LWIP_DEBUGF(IP_DEBUG | 2, ("ip_route: No route to 0x%"X32_F"\n", dest->addr));
|
||||
IP_STATS_INC(ip.rterr);
|
||||
snmp_inc_ipoutnoroutes();
|
||||
}
|
||||
/* no matching netif found, use default netif */
|
||||
return netif_default;
|
||||
}
|
||||
@ -515,10 +520,6 @@ ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
||||
struct netif *netif;
|
||||
|
||||
if ((netif = ip_route(dest)) == NULL) {
|
||||
LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%"X32_F"\n", dest->addr));
|
||||
|
||||
IP_STATS_INC(ip.rterr);
|
||||
snmp_inc_ipoutnoroutes();
|
||||
return ERR_RTE;
|
||||
}
|
||||
|
||||
|
@ -105,6 +105,9 @@ netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
|
||||
netif->state = state;
|
||||
netif->num = netifnum++;
|
||||
netif->input = input;
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
netif->addr_hint = NULL;
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
|
||||
netif_set_addr(netif, ipaddr, netmask, gw);
|
||||
|
||||
|
@ -248,7 +248,13 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr)
|
||||
src_ip = &(pcb->local_ip);
|
||||
}
|
||||
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
netif->addr_hint = &(pcb->addr_hint);
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
err = ip_output_if (q, src_ip, ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif);
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
netif->addr_hint = NULL;
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
|
||||
/* did we chain a header earlier? */
|
||||
if (q != p) {
|
||||
|
@ -456,8 +456,21 @@ tcp_output(struct tcp_pcb *pcb)
|
||||
tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
|
||||
IP_PROTO_TCP, p->tot_len);
|
||||
#endif
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
{
|
||||
struct netif *netif;
|
||||
netif = ip_route(&pcb->remote_ip);
|
||||
if(netif != NULL){
|
||||
netif->addr_hint = &(pcb->addr_hint);
|
||||
ip_output_if(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl,
|
||||
pcb->tos, IP_PROTO_TCP, netif);
|
||||
netif->addr_hint = NULL;
|
||||
}
|
||||
}
|
||||
#else /* LWIP_NETIF_HWADDRHINT*/
|
||||
ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
|
||||
IP_PROTO_TCP);
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
pbuf_free(p);
|
||||
|
||||
return ERR_OK;
|
||||
@ -602,8 +615,21 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
|
||||
#endif
|
||||
TCP_STATS_INC(tcp.xmit);
|
||||
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
{
|
||||
struct netif *netif;
|
||||
netif = ip_route(&pcb->remote_ip);
|
||||
if(netif != NULL){
|
||||
netif->addr_hint = &(pcb->addr_hint);
|
||||
ip_output_if(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl,
|
||||
pcb->tos, IP_PROTO_TCP, netif);
|
||||
netif->addr_hint = NULL;
|
||||
}
|
||||
}
|
||||
#else /* LWIP_NETIF_HWADDRHINT*/
|
||||
ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
|
||||
IP_PROTO_TCP);
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
}
|
||||
|
||||
/**
|
||||
@ -776,7 +802,20 @@ tcp_keepalive(struct tcp_pcb *pcb)
|
||||
TCP_STATS_INC(tcp.xmit);
|
||||
|
||||
/* Send output to IP */
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
{
|
||||
struct netif *netif;
|
||||
netif = ip_route(&pcb->remote_ip);
|
||||
if(netif != NULL){
|
||||
netif->addr_hint = &(pcb->addr_hint);
|
||||
ip_output_if(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl,
|
||||
0, IP_PROTO_TCP, netif);
|
||||
netif->addr_hint = NULL;
|
||||
}
|
||||
}
|
||||
#else /* LWIP_NETIF_HWADDRHINT*/
|
||||
ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP);
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
|
||||
pbuf_free(p);
|
||||
|
||||
|
@ -439,7 +439,13 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
#endif /* CHECKSUM_CHECK_UDP */
|
||||
/* output to IP */
|
||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n"));
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
netif->addr_hint = &(pcb->addr_hint);
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
err = ip_output_if(q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
netif->addr_hint = NULL;
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
} else
|
||||
#endif /* LWIP_UDPLITE */
|
||||
{ /* UDP */
|
||||
@ -456,7 +462,13 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum));
|
||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));
|
||||
/* output to IP */
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
netif->addr_hint = &(pcb->addr_hint);
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
err = ip_output_if(q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
netif->addr_hint = NULL;
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
}
|
||||
/* TODO: must this be increased even if error occured? */
|
||||
snmp_inc_udpoutdatagrams();
|
||||
|
@ -83,7 +83,9 @@ err_t ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
||||
/* Type Of Service */ \
|
||||
u8_t tos; \
|
||||
/* Time To Live */ \
|
||||
u8_t ttl
|
||||
u8_t ttl; \
|
||||
/* link layer address resolution hint */ \
|
||||
u8_t addr_hint
|
||||
|
||||
/*
|
||||
* Option flags per-socket. These are the same like SO_XXX.
|
||||
|
@ -69,7 +69,9 @@ extern "C" {
|
||||
/* Type Of Service */ \
|
||||
u8_t tos; \
|
||||
/* Time To Live */ \
|
||||
u8_t ttl
|
||||
u8_t ttl; \
|
||||
/* link layer address resolution hint */ \
|
||||
u8_t addr_hint
|
||||
|
||||
|
||||
/* The IPv6 header. */
|
||||
|
@ -155,6 +155,9 @@ struct netif {
|
||||
/* This function could be called to add or delete a entry in the multicast filter table of the ethernet MAC.*/
|
||||
err_t (*igmp_mac_filter)( struct netif *netif, struct ip_addr *group, u8_t action);
|
||||
#endif /* LWIP_IGMP */
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
u8_t *addr_hint;
|
||||
#endif /* LWIP_NETIF_HWADDRHINT */
|
||||
};
|
||||
|
||||
#if LWIP_SNMP
|
||||
|
@ -481,6 +481,15 @@
|
||||
#define LWIP_NETIF_CALLBACK 0
|
||||
#endif
|
||||
|
||||
/** Cache link-layer-address hints (e.g. table indices) in struct netif.
|
||||
TCP and UDP can make use of this to prevent scanning the ARP table
|
||||
for every sent packet. While this is faster for big ARP tables or many
|
||||
concurrent connections, it might be contra-productive if having a tiny
|
||||
ARP table only or there never are concurrent connections. */
|
||||
#ifndef LWIP_NETIF_HWADDRHINT
|
||||
#define LWIP_NETIF_HWADDRHINT 0
|
||||
#endif
|
||||
|
||||
/* Support loop interface (127.0.0.1) */
|
||||
#ifndef LWIP_HAVE_LOOPIF
|
||||
#define LWIP_HAVE_LOOPIF 0
|
||||
|
@ -157,6 +157,11 @@ err_t etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
|
||||
|
||||
#define eth_addr_cmp(addr1, addr2) (memcmp((addr1)->addr, (addr2)->addr, ETHARP_HWADDR_LEN) == 0)
|
||||
|
||||
/* finally, check some defines */
|
||||
#if ARP_TABLE_SIZE > 0x7f
|
||||
#error ARP_TABLE_SIZE must fit in an s8_t
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -105,7 +105,9 @@ struct etharp_entry {
|
||||
static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
|
||||
static const struct eth_addr ethzero = {{0,0,0,0,0,0}};
|
||||
static struct etharp_entry arp_table[ARP_TABLE_SIZE];
|
||||
#if !LWIP_NETIF_HWADDRHINT
|
||||
static u8_t etharp_cached_entry = 0;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Try hard to create a new entry - we want the IP address to appear in
|
||||
@ -113,7 +115,14 @@ static u8_t etharp_cached_entry = 0;
|
||||
#define ETHARP_TRY_HARD 1
|
||||
#define ETHARP_FIND_ONLY 2
|
||||
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
#define NETIF_SET_HINT(netif, hint) (((netif) != NULL) && ((netif)->addr_hint != NULL)) ? \
|
||||
*((netif)->addr_hint) = (hint) : LWIP_UNUSED_ARG(hint) ;
|
||||
static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags, struct netif *netif);
|
||||
#else /* LWIP_NETIF_HWADDRHINT */
|
||||
static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags);
|
||||
#endif /* LWIP_NETIF_HWADDRHINT */
|
||||
|
||||
static err_t update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags);
|
||||
|
||||
/**
|
||||
@ -231,7 +240,11 @@ etharp_tmr(void)
|
||||
* entry is found or could be recycled.
|
||||
*/
|
||||
static s8_t
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
find_entry(struct ip_addr *ipaddr, u8_t flags, struct netif *netif)
|
||||
#else /* LWIP_NETIF_HWADDRHINT */
|
||||
find_entry(struct ip_addr *ipaddr, u8_t flags)
|
||||
#endif /* LWIP_NETIF_HWADDRHINT */
|
||||
{
|
||||
s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE;
|
||||
s8_t empty = ARP_TABLE_SIZE;
|
||||
@ -247,6 +260,19 @@ find_entry(struct ip_addr *ipaddr, u8_t flags)
|
||||
* same address. If so, we're really fast! */
|
||||
if (ipaddr) {
|
||||
/* ipaddr to search for was given */
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
if ((netif != NULL) && (netif->addr_hint != NULL)) {
|
||||
/* per-pcb cached entry was given */
|
||||
u8_t per_pcb_cache = *(netif->addr_hint);
|
||||
if ((per_pcb_cache < ARP_TABLE_SIZE) && arp_table[per_pcb_cache].state == ETHARP_STATE_STABLE) {
|
||||
/* the per-pcb-cached entry is stable */
|
||||
if (ip_addr_cmp(ipaddr, &arp_table[per_pcb_cache].ipaddr)) {
|
||||
/* per-pcb cached entry was the right one! */
|
||||
return per_pcb_cache;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else /* #if LWIP_NETIF_HWADDRHINT */
|
||||
if (arp_table[etharp_cached_entry].state == ETHARP_STATE_STABLE) {
|
||||
/* the cached entry is stable */
|
||||
if (ip_addr_cmp(ipaddr, &arp_table[etharp_cached_entry].ipaddr)) {
|
||||
@ -254,6 +280,7 @@ find_entry(struct ip_addr *ipaddr, u8_t flags)
|
||||
return etharp_cached_entry;
|
||||
}
|
||||
}
|
||||
#endif /* #if LWIP_NETIF_HWADDRHINT */
|
||||
}
|
||||
|
||||
/**
|
||||
@ -284,7 +311,11 @@ find_entry(struct ip_addr *ipaddr, u8_t flags)
|
||||
if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: found matching pending entry %"U16_F"\n", (u16_t)i));
|
||||
/* found exact IP address match, simply bail out */
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
NETIF_SET_HINT(netif, i);
|
||||
#else /* #if LWIP_NETIF_HWADDRHINT */
|
||||
etharp_cached_entry = i;
|
||||
#endif /* #if LWIP_NETIF_HWADDRHINT */
|
||||
return i;
|
||||
#if ARP_QUEUEING
|
||||
/* pending with queued packets? */
|
||||
@ -308,7 +339,11 @@ find_entry(struct ip_addr *ipaddr, u8_t flags)
|
||||
if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: found matching stable entry %"U16_F"\n", (u16_t)i));
|
||||
/* found exact IP address match, simply bail out */
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
NETIF_SET_HINT(netif, i);
|
||||
#else /* #if LWIP_NETIF_HWADDRHINT */
|
||||
etharp_cached_entry = i;
|
||||
#endif /* #if LWIP_NETIF_HWADDRHINT */
|
||||
return i;
|
||||
/* remember entry with oldest stable entry in oldest, its age in maxtime */
|
||||
} else if (arp_table[i].ctime >= age_stable) {
|
||||
@ -384,7 +419,11 @@ find_entry(struct ip_addr *ipaddr, u8_t flags)
|
||||
ip_addr_set(&arp_table[i].ipaddr, ipaddr);
|
||||
}
|
||||
arp_table[i].ctime = 0;
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
NETIF_SET_HINT(netif, i);
|
||||
#else /* #if LWIP_NETIF_HWADDRHINT */
|
||||
etharp_cached_entry = i;
|
||||
#endif /* #if LWIP_NETIF_HWADDRHINT */
|
||||
return (err_t)i;
|
||||
}
|
||||
|
||||
@ -456,7 +495,11 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e
|
||||
return ERR_ARG;
|
||||
}
|
||||
/* find or create ARP entry */
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
i = find_entry(ipaddr, flags, netif);
|
||||
#else /* LWIP_NETIF_HWADDRHINT */
|
||||
i = find_entry(ipaddr, flags);
|
||||
#endif /* LWIP_NETIF_HWADDRHINT */
|
||||
/* bail out if no entry could be found */
|
||||
if (i < 0)
|
||||
return (err_t)i;
|
||||
@ -516,7 +559,11 @@ etharp_find_addr(struct netif *netif, struct ip_addr *ipaddr,
|
||||
{
|
||||
s8_t i;
|
||||
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
i = find_entry(ipaddr, ETHARP_FIND_ONLY, NULL);
|
||||
#else /* LWIP_NETIF_HWADDRHINT */
|
||||
i = find_entry(ipaddr, ETHARP_FIND_ONLY);
|
||||
#endif /* LWIP_NETIF_HWADDRHINT */
|
||||
if((i >= 0) && arp_table[i].state == ETHARP_STATE_STABLE) {
|
||||
*eth_ret = &arp_table[i].ethaddr;
|
||||
*ip_ret = &arp_table[i].ipaddr;
|
||||
@ -833,7 +880,11 @@ etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
||||
}
|
||||
|
||||
/* find entry in ARP cache, ask to create entry if queueing packet */
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
i = find_entry(ipaddr, ETHARP_TRY_HARD, netif);
|
||||
#else /* LWIP_NETIF_HWADDRHINT */
|
||||
i = find_entry(ipaddr, ETHARP_TRY_HARD);
|
||||
#endif /* LWIP_NETIF_HWADDRHINT */
|
||||
|
||||
/* could not find or create entry? */
|
||||
if (i < 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user