Changed loopback code (less difference between NO_SYS = 0 / 1), added setting LWIP_LOOPBACK_MAX_PBUFS to limit loopback-queued pbufs

This commit is contained in:
goldsimon 2008-06-17 19:39:22 +00:00
parent a8141c53a8
commit eba83ab740
5 changed files with 75 additions and 40 deletions

View File

@ -23,6 +23,7 @@ HISTORY
* netif.c, loopif.c, ip.c, netif.h, loopif.h, opt.h: Checked in slightly * netif.c, loopif.c, ip.c, netif.h, loopif.h, opt.h: Checked in slightly
modified version of patch # 6370: Moved loopif code to netif.c so that modified version of patch # 6370: Moved loopif code to netif.c so that
loopback traffic is supported on all netifs (all local IPs). loopback traffic is supported on all netifs (all local IPs).
Added option to limit loopback packets for each netifs.
++ Bugfixes: ++ Bugfixes:

View File

@ -531,14 +531,14 @@ ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num)); LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num));
ip_debug_print(p); ip_debug_print(p);
#if (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) && !LWIP_NETIF_LOOPBACK_MULTITHREADING #if (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF)
if (ip_addr_cmp(dest, &netif->ip_addr)) { if (ip_addr_cmp(dest, &netif->ip_addr)) {
/* Packet to self, enqueue it for loopback */ /* Packet to self, enqueue it for loopback */
LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()")); LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));
return netif_loop_output(netif, p, dest); return netif_loop_output(netif, p, dest);
} else } else
#endif /* (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) && !LWIP_NETIF_LOOPBACK_MULTITHREADING */ #endif /* (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) */
{ {
LWIP_DEBUGF(IP_DEBUG, ("netif->output()")); LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));

View File

@ -47,6 +47,8 @@
#include "netif/etharp.h" #include "netif/etharp.h"
#if ENABLE_LOOPBACK && !LWIP_NETIF_LOOPBACK_MULTITHREADING #if ENABLE_LOOPBACK && !LWIP_NETIF_LOOPBACK_MULTITHREADING
#include "lwip/sys.h" #include "lwip/sys.h"
#else /* ENABLE_LOOPBACK && !LWIP_NETIF_LOOPBACK_MULTITHREADING */
#include "lwip/tcpip.h"
#endif /* ENABLE_LOOPBACK && !LWIP_NETIF_LOOPBACK_MULTITHREADING */ #endif /* ENABLE_LOOPBACK && !LWIP_NETIF_LOOPBACK_MULTITHREADING */
#if LWIP_NETIF_STATUS_CALLBACK #if LWIP_NETIF_STATUS_CALLBACK
@ -109,10 +111,10 @@ netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
#if LWIP_IGMP #if LWIP_IGMP
netif->igmp_mac_filter = NULL; netif->igmp_mac_filter = NULL;
#endif /* LWIP_IGMP */ #endif /* LWIP_IGMP */
#if ENABLE_LOOPBACK && !LWIP_NETIF_LOOPBACK_MULTITHREADING #if ENABLE_LOOPBACK
netif->loop_first = NULL; netif->loop_first = NULL;
netif->loop_last = NULL; netif->loop_last = NULL;
#endif /* ENABLE_LOOPBACK && !LWIP_NETIF_LOOPBACK_MULTITHREADING */ #endif /* ENABLE_LOOPBACK */
/* remember netif specific state information data */ /* remember netif specific state information data */
netif->state = state; netif->state = state;
@ -121,6 +123,10 @@ netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
#if LWIP_NETIF_HWADDRHINT #if LWIP_NETIF_HWADDRHINT
netif->addr_hint = NULL; netif->addr_hint = NULL;
#endif /* LWIP_NETIF_HWADDRHINT*/ #endif /* LWIP_NETIF_HWADDRHINT*/
#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS
netif->loop_cnt_max = LWIP_LOOPBACK_MAX_PBUFS;
netif->loop_cnt_current = 0;
#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */
netif_set_addr(netif, ipaddr, netmask, gw); netif_set_addr(netif, ipaddr, netmask, gw);
@ -500,8 +506,9 @@ u8_t netif_is_link_up(struct netif *netif)
*/ */
void netif_set_link_callback(struct netif *netif, void (* link_callback)(struct netif *netif )) void netif_set_link_callback(struct netif *netif, void (* link_callback)(struct netif *netif ))
{ {
if ( netif ) if (netif) {
netif->link_callback = link_callback; netif->link_callback = link_callback;
}
} }
#endif /* LWIP_NETIF_LINK_CALLBACK */ #endif /* LWIP_NETIF_LINK_CALLBACK */
@ -526,10 +533,11 @@ netif_loop_output(struct netif *netif, struct pbuf *p,
{ {
struct pbuf *r; struct pbuf *r;
err_t err; err_t err;
#if !LWIP_NETIF_LOOPBACK_MULTITHREADING
struct pbuf *last; struct pbuf *last;
#if LWIP_LOOPBACK_MAX_PBUFS
u8_t clen = 0;
#endif /* LWIP_LOOPBACK_MAX_PBUFS */
SYS_ARCH_DECL_PROTECT(lev); SYS_ARCH_DECL_PROTECT(lev);
#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
LWIP_UNUSED_ARG(ipaddr); LWIP_UNUSED_ARG(ipaddr);
/* Allocate a new pbuf */ /* Allocate a new pbuf */
@ -537,6 +545,17 @@ netif_loop_output(struct netif *netif, struct pbuf *p,
if (r == NULL) { if (r == NULL) {
return ERR_MEM; return ERR_MEM;
} }
#if LWIP_LOOPBACK_MAX_PBUFS
clen = pbuf_clen(r);
/* check for overflow or too many pbuf on queue */
if(((netif->loop_cnt_current + clen) < netif->loop_cnt_current) ||
((netif->loop_cnt_current + clen) > netif->loop_cnt_max)) {
pbuf_free(r);
r = NULL;
return ERR_MEM;
}
netif->loop_cnt_current += clen;
#endif /* LWIP_LOOPBACK_MAX_PBUFS */
/* Copy the whole pbuf queue p into the single pbuf r */ /* Copy the whole pbuf queue p into the single pbuf r */
if ((err = pbuf_copy(r, p)) != ERR_OK) { if ((err = pbuf_copy(r, p)) != ERR_OK) {
@ -545,21 +564,12 @@ netif_loop_output(struct netif *netif, struct pbuf *p,
return err; return err;
} }
#if LWIP_NETIF_LOOPBACK_MULTITHREADING /* Put the packet on a linked list which gets emptied through calling
/* Multithreading environment, netif->input() is supposed to put the packet netif_poll(). */
into a mailbox, so we can safely call it here without risking to re-enter
functions that are not reentrant (TCP!!!) */
LWIP_ASSERT(netif->input != ip_input, "Don't use ip_input as netif->input with LWIP_NETIF_LOOPBACK_MULTITHREADING = 1!");
if(netif->input(r, netif) != ERR_OK) {
pbuf_free(r);
r = NULL;
}
#else /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
/* Raw API without threads: put the packet on a linked list which gets emptied
through calling netif_poll(). */
/* let last point to the last pbuf in chain r */ /* let last point to the last pbuf in chain r */
for (last = r; last->next != NULL; last = last->next); for (last = r; last->next != NULL; last = last->next);
SYS_ARCH_PROTECT(lev); SYS_ARCH_PROTECT(lev);
if(netif->loop_first != NULL) { if(netif->loop_first != NULL) {
LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL); LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL);
@ -570,27 +580,15 @@ netif_loop_output(struct netif *netif, struct pbuf *p,
netif->loop_last = last; netif->loop_last = last;
} }
SYS_ARCH_UNPROTECT(lev); SYS_ARCH_UNPROTECT(lev);
#if LWIP_NETIF_LOOPBACK_MULTITHREADING
/* For multithreading environment, schedule a call to netif_poll */
tcpip_callback(netif_poll, netif);
#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ #endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
return ERR_OK; return ERR_OK;
} }
#if !LWIP_NETIF_LOOPBACK_MULTITHREADING
/**
* Calls netif_poll() for every netif on the netif_list.
*/
void
netif_poll_all(void)
{
struct netif *netif = netif_list;
/* loop through netifs */
while (netif != NULL) {
netif_poll(netif);
/* proceed to next network interface */
netif = netif->next;
}
}
/** /**
* Call netif_poll() in the main loop of your application. This is to prevent * Call netif_poll() in the main loop of your application. This is to prevent
* reentering non-reentrant functions like tcp_input(). Packets passed to * reentering non-reentrant functions like tcp_input(). Packets passed to
@ -609,6 +607,13 @@ netif_poll(struct netif *netif)
in = netif->loop_first; in = netif->loop_first;
if(in != NULL) { if(in != NULL) {
struct pbuf *in_end = in; struct pbuf *in_end = in;
#if LWIP_LOOPBACK_MAX_PBUFS
u8_t clen = pbuf_clen(in);
/* adjust the number of pbufs on queue */
LWIP_ASSERT("netif->loop_cnt_current underflow",
((netif->loop_cnt_current - clen) < netif->loop_cnt_current));
netif->loop_cnt_current -= clen;
#endif /* LWIP_LOOPBACK_MAX_PBUFS */
while(in_end->len != in_end->tot_len) { while(in_end->len != in_end->tot_len) {
LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL); LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL);
in_end = in_end->next; in_end = in_end->next;
@ -628,7 +633,8 @@ netif_poll(struct netif *netif)
SYS_ARCH_UNPROTECT(lev); SYS_ARCH_UNPROTECT(lev);
if(in != NULL) { if(in != NULL) {
if(netif->input(in, netif) != ERR_OK) { /* loopback packets are always IP packets! */
if(ip_input(in, netif) != ERR_OK) {
pbuf_free(in); pbuf_free(in);
} }
/* Don't reference the packet any more! */ /* Don't reference the packet any more! */
@ -637,5 +643,21 @@ netif_poll(struct netif *netif)
/* go on while there is a packet on the list */ /* go on while there is a packet on the list */
} while(netif->loop_first != NULL); } while(netif->loop_first != NULL);
} }
#if !LWIP_NETIF_LOOPBACK_MULTITHREADING
/**
* Calls netif_poll() for every netif on the netif_list.
*/
void
netif_poll_all(void)
{
struct netif *netif = netif_list;
/* loop through netifs */
while (netif != NULL) {
netif_poll(netif);
/* proceed to next network interface */
netif = netif->next;
}
}
#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ #endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */
#endif /* ENABLE_LOOPBACK */ #endif /* ENABLE_LOOPBACK */

View File

@ -167,11 +167,15 @@ struct netif {
#if LWIP_NETIF_HWADDRHINT #if LWIP_NETIF_HWADDRHINT
u8_t *addr_hint; u8_t *addr_hint;
#endif /* LWIP_NETIF_HWADDRHINT */ #endif /* LWIP_NETIF_HWADDRHINT */
#if ENABLE_LOOPBACK && !LWIP_NETIF_LOOPBACK_MULTITHREADING #if ENABLE_LOOPBACK
/* List of packets to be queued for ourselves. */ /* List of packets to be queued for ourselves. */
struct pbuf *loop_first; struct pbuf *loop_first;
struct pbuf *loop_last; struct pbuf *loop_last;
#endif /* ENABLE_LOOPBACK && !LWIP_NETIF_LOOPBACK_MULTITHREADING */ #if LWIP_LOOPBACK_MAX_PBUFS
u16_t loop_cnt_max;
u16_t loop_cnt_current;
#endif /* LWIP_LOOPBACK_MAX_PBUFS */
#endif /* ENABLE_LOOPBACK */
}; };
#if LWIP_SNMP #if LWIP_SNMP
@ -251,9 +255,9 @@ void netif_set_link_callback(struct netif *netif, void (* link_callback)(struct
#if ENABLE_LOOPBACK #if ENABLE_LOOPBACK
err_t netif_loop_output(struct netif *netif, struct pbuf *p, struct ip_addr *dest_ip); err_t netif_loop_output(struct netif *netif, struct pbuf *p, struct ip_addr *dest_ip);
void netif_poll(struct netif *netif);
#if !LWIP_NETIF_LOOPBACK_MULTITHREADING #if !LWIP_NETIF_LOOPBACK_MULTITHREADING
void netif_poll_all(void); void netif_poll_all(void);
void netif_poll(struct netif *netif);
#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ #endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */
#endif /* ENABLE_LOOPBACK */ #endif /* ENABLE_LOOPBACK */

View File

@ -840,6 +840,14 @@
#define LWIP_NETIF_LOOPBACK 0 #define LWIP_NETIF_LOOPBACK 0
#endif #endif
/**
* LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback
* sending for each netif (0 = disabled)
*/
#ifndef LWIP_LOOPBACK_MAX_PBUFS
#define LWIP_LOOPBACK_MAX_PBUFS 0
#endif
/** /**
* LWIP_NETIF_LOOPBACK_MULTITHREADING: Indicates whether threading is enabled in * LWIP_NETIF_LOOPBACK_MULTITHREADING: Indicates whether threading is enabled in
* the system, as netifs must change how they behave depending on this setting * the system, as netifs must change how they behave depending on this setting