summaryrefslogtreecommitdiffstats
path: root/recipes-extended/xen/files/lwip.patch-cvs
diff options
context:
space:
mode:
authorChristopher Clark <christopher.w.clark@gmail.com>2019-04-16 13:35:36 -0700
committerBruce Ashfield <bruce.ashfield@gmail.com>2019-04-18 09:32:40 -0400
commit15caed2f436afd6ab07a0865b161c54f51bab6a4 (patch)
tree130ef8d75252d6e4aba6ef9ad50e4298eabcad62 /recipes-extended/xen/files/lwip.patch-cvs
parentabcdb5841dfffc1ff4410f6c149dc304d4ac5e42 (diff)
downloadmeta-virtualization-15caed2f436afd6ab07a0865b161c54f51bab6a4.tar.gz
xen: remove recipes for stubdoms and dependent components
Retiring these as the components are not in use and work on updating the recipes to build with the OE native tools rather than host tools has been discontinued. Signed-off-by: Christopher Clark <christopher.clark6@baesystems.com> Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
Diffstat (limited to 'recipes-extended/xen/files/lwip.patch-cvs')
-rw-r--r--recipes-extended/xen/files/lwip.patch-cvs2398
1 files changed, 0 insertions, 2398 deletions
diff --git a/recipes-extended/xen/files/lwip.patch-cvs b/recipes-extended/xen/files/lwip.patch-cvs
deleted file mode 100644
index b2718778..00000000
--- a/recipes-extended/xen/files/lwip.patch-cvs
+++ /dev/null
@@ -1,2398 +0,0 @@
1? .ChangeLog.swp
2? ChangeLog
3Index: CHANGELOG
4===================================================================
5RCS file: /sources/lwip/lwip/CHANGELOG,v
6retrieving revision 1.300
7retrieving revision 1.318
8diff -u -p -r1.300 -r1.318
9--- a/CHANGELOG 23 Mar 2008 13:49:39 -0000 1.300
10+++ b/CHANGELOG 14 Jul 2008 20:12:36 -0000 1.318
11@@ -19,9 +19,77 @@ HISTORY
12
13 ++ New features:
14
15+ 2008-06-30 Simon Goldschmidt
16+ * mem.c, opt.h, stats.h: fixed bug #21433: Calling mem_free/pbuf_free from
17+ interrupt context isn't safe: LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT allows
18+ mem_free to run between mem_malloc iterations. Added illegal counter for
19+ mem stats.
20+
21+ 2008-06-27 Simon Goldschmidt
22+ * stats.h/.c, some other files: patch #6483: stats module improvement:
23+ Added defines to display each module's statistic individually, added stats
24+ defines for MEM, MEMP and SYS modules, removed (unused) rexmit counter.
25+
26+ 2008-06-17 Simon Goldschmidt
27+ * err.h: patch #6459: Made err_t overridable to use a more efficient type
28+ (define LWIP_ERR_T in cc.h)
29+
30+ 2008-06-17 Simon Goldschmidt
31+ * slipif.c: patch #6480: Added a configuration option for slipif for symmetry
32+ to loopif
33+
34+ 2008-06-17 Simon Goldschmidt (patch by Luca Ceresoli)
35+ * netif.c, loopif.c, ip.c, netif.h, loopif.h, opt.h: Checked in slightly
36+ modified version of patch # 6370: Moved loopif code to netif.c so that
37+ loopback traffic is supported on all netifs (all local IPs).
38+ Added option to limit loopback packets for each netifs.
39+
40
41 ++ Bugfixes:
42
43+ 2008-08-14 Simon Goldschmidt
44+ * api_msg.c: fixed bug #23847: do_close_internal references freed memory (when
45+ tcp_close returns != ERR_OK)
46+
47+ 2008-07-08 Frédéric Bernon
48+ * stats.h: Fix some build bugs introduced with patch #6483 (missing some parameters
49+ in macros, mainly if MEM_STATS=0 and MEMP_STATS=0).
50+
51+ 2008-06-24 Jonathan Larmour
52+ * tcp_in.c: Fix for bug #23693 as suggested by Art R. Ensure cseg is unused
53+ if tcp_seg_copy fails.
54+
55+ 2008-06-17 Simon Goldschmidt
56+ * inet_chksum.c: Checked in some ideas of patch #6460 (loop optimizations)
57+ and created defines for swapping bytes and folding u32 to u16.
58+
59+ 2008-05-30 Kieran Mansley
60+ * tcp_in.c Remove redundant "if" statement, and use real rcv_wnd
61+ rather than rcv_ann_wnd when deciding if packets are in-window.
62+ Contributed by <arasmussen@consultant.datasys.swri.edu>
63+
64+ 2008-05-30 Kieran Mansley
65+ * mem.h: Fix BUG#23254. Change macro definition of mem_* to allow
66+ passing as function pointers when MEM_LIBC_MALLOC is defined.
67+
68+ 2008-05-09 Jonathan Larmour
69+ * err.h, err.c, sockets.c: Fix bug #23119: Reorder timeout error code to
70+ stop it being treated as a fatal error.
71+
72+ 2008-04-15 Simon Goldschmidt
73+ * dhcp.c: fixed bug #22804: dhcp_stop doesn't clear NETIF_FLAG_DHCP
74+ (flag now cleared)
75+
76+ 2008-03-27 Simon Goldschmidt
77+ * mem.c, tcpip.c, tcpip.h, opt.h: fixed bug #21433 (Calling mem_free/pbuf_free
78+ from interrupt context isn't safe): set LWIP_USE_HEAP_FROM_INTERRUPT to 1
79+ in lwipopts.h or use pbuf_free_callback(p)/mem_free_callback(m) to free pbufs
80+ or heap memory from interrupt context
81+
82+ 2008-03-26 Simon Goldschmidt
83+ * tcp_in.c, tcp.c: fixed bug #22249: division by zero could occur if a remote
84+ host sent a zero mss as TCP option.
85+
86
87 (STABLE-1.3.0)
88
89Index: src/api/api_msg.c
90===================================================================
91RCS file: /sources/lwip/lwip/src/api/api_msg.c,v
92retrieving revision 1.102
93retrieving revision 1.104
94diff -u -p -r1.102 -r1.104
95--- a/src/api/api_msg.c 21 Mar 2008 16:23:14 -0000 1.102
96+++ b/src/api/api_msg.c 15 Jul 2008 11:18:58 -0000 1.104
97@@ -598,11 +598,16 @@ do_close_internal(struct netconn *conn)
98 LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL));
99
100 /* Set back some callback pointers */
101+ tcp_arg(conn->pcb.tcp, NULL);
102 if (conn->pcb.tcp->state == LISTEN) {
103- tcp_arg(conn->pcb.tcp, NULL);
104 tcp_accept(conn->pcb.tcp, NULL);
105 } else {
106 tcp_recv(conn->pcb.tcp, NULL);
107+ tcp_accept(conn->pcb.tcp, NULL);
108+ /* some callbacks have to be reset if tcp_close is not successful */
109+ tcp_sent(conn->pcb.tcp, NULL);
110+ tcp_poll(conn->pcb.tcp, NULL, 4);
111+ tcp_err(conn->pcb.tcp, NULL);
112 }
113 /* Try to close the connection */
114 err = tcp_close(conn->pcb.tcp);
115@@ -610,11 +615,6 @@ do_close_internal(struct netconn *conn)
116 /* Closing succeeded */
117 conn->state = NETCONN_NONE;
118 /* Set back some callback pointers as conn is going away */
119- tcp_err(conn->pcb.tcp, NULL);
120- tcp_poll(conn->pcb.tcp, NULL, 4);
121- tcp_sent(conn->pcb.tcp, NULL);
122- tcp_recv(conn->pcb.tcp, NULL);
123- tcp_arg(conn->pcb.tcp, NULL);
124 conn->pcb.tcp = NULL;
125 conn->err = ERR_OK;
126 /* Trigger select() in socket layer. This send should something else so the
127@@ -623,6 +623,14 @@ do_close_internal(struct netconn *conn)
128 API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
129 /* wake up the application task */
130 sys_sem_signal(conn->op_completed);
131+ } else {
132+ /* Closing failed, restore some of the callbacks */
133+ /* Closing of listen pcb will never fail! */
134+ LWIP_ASSERT("Closing a listen pcb may not fail!", (conn->pcb.tcp->state != LISTEN));
135+ tcp_sent(conn->pcb.tcp, sent_tcp);
136+ tcp_poll(conn->pcb.tcp, poll_tcp, 4);
137+ tcp_err(conn->pcb.tcp, err_tcp);
138+ tcp_arg(conn->pcb.tcp, conn);
139 }
140 /* If closing didn't succeed, we get called again either
141 from poll_tcp or from sent_tcp */
142Index: src/api/err.c
143===================================================================
144RCS file: /sources/lwip/lwip/src/api/err.c,v
145retrieving revision 1.11
146retrieving revision 1.12
147diff -u -p -r1.11 -r1.12
148--- a/src/api/err.c 13 Dec 2007 23:06:50 -0000 1.11
149+++ b/src/api/err.c 9 May 2008 12:14:23 -0000 1.12
150@@ -44,17 +44,17 @@ static const char *err_strerr[] = {
151 "Ok.", /* ERR_OK 0 */
152 "Out of memory error.", /* ERR_MEM -1 */
153 "Buffer error.", /* ERR_BUF -2 */
154- "Routing problem.", /* ERR_RTE -3 */
155- "Connection aborted.", /* ERR_ABRT -4 */
156- "Connection reset.", /* ERR_RST -5 */
157- "Connection closed.", /* ERR_CLSD -6 */
158- "Not connected.", /* ERR_CONN -7 */
159- "Illegal value.", /* ERR_VAL -8 */
160- "Illegal argument.", /* ERR_ARG -9 */
161- "Address in use.", /* ERR_USE -10 */
162- "Low-level netif error.", /* ERR_IF -11 */
163- "Already connected.", /* ERR_ISCONN -12 */
164- "Timeout.", /* ERR_TIMEOUT -13 */
165+ "Timeout.", /* ERR_TIMEOUT -3 */
166+ "Routing problem.", /* ERR_RTE -4 */
167+ "Connection aborted.", /* ERR_ABRT -5 */
168+ "Connection reset.", /* ERR_RST -6 */
169+ "Connection closed.", /* ERR_CLSD -7 */
170+ "Not connected.", /* ERR_CONN -8 */
171+ "Illegal value.", /* ERR_VAL -9 */
172+ "Illegal argument.", /* ERR_ARG -10 */
173+ "Address in use.", /* ERR_USE -11 */
174+ "Low-level netif error.", /* ERR_IF -12 */
175+ "Already connected.", /* ERR_ISCONN -13 */
176 "Operation in progress." /* ERR_INPROGRESS -14 */
177 };
178
179Index: src/api/netdb.c
180===================================================================
181RCS file: /sources/lwip/lwip/src/api/netdb.c,v
182retrieving revision 1.4
183retrieving revision 1.5
184diff -u -p -r1.4 -r1.5
185--- a/src/api/netdb.c 26 Jan 2008 16:11:39 -0000 1.4
186+++ b/src/api/netdb.c 16 Jul 2008 20:36:12 -0000 1.5
187@@ -326,7 +326,8 @@ lwip_getaddrinfo(const char *nodename, c
188 if (nodename != NULL) {
189 /* copy nodename to canonname if specified */
190 size_t namelen = strlen(nodename);
191- ai->ai_canonname = mem_malloc(namelen + 1);
192+ LWIP_ASSERT("namelen is too long", (namelen + 1) <= (mem_size_t)-1);
193+ ai->ai_canonname = mem_malloc((mem_size_t)(namelen + 1));
194 if (ai->ai_canonname == NULL) {
195 goto memerr;
196 }
197Index: src/api/sockets.c
198===================================================================
199RCS file: /sources/lwip/lwip/src/api/sockets.c,v
200retrieving revision 1.116
201retrieving revision 1.117
202diff -u -p -r1.116 -r1.117
203--- a/src/api/sockets.c 13 Mar 2008 20:03:57 -0000 1.116
204+++ b/src/api/sockets.c 9 May 2008 12:14:24 -0000 1.117
205@@ -128,17 +128,17 @@ static const int err_to_errno_table[] =
206 0, /* ERR_OK 0 No error, everything OK. */
207 ENOMEM, /* ERR_MEM -1 Out of memory error. */
208 ENOBUFS, /* ERR_BUF -2 Buffer error. */
209- EHOSTUNREACH, /* ERR_RTE -3 Routing problem. */
210- ECONNABORTED, /* ERR_ABRT -4 Connection aborted. */
211- ECONNRESET, /* ERR_RST -5 Connection reset. */
212- ESHUTDOWN, /* ERR_CLSD -6 Connection closed. */
213- ENOTCONN, /* ERR_CONN -7 Not connected. */
214- EINVAL, /* ERR_VAL -8 Illegal value. */
215- EIO, /* ERR_ARG -9 Illegal argument. */
216- EADDRINUSE, /* ERR_USE -10 Address in use. */
217- -1, /* ERR_IF -11 Low-level netif error */
218- -1, /* ERR_ISCONN -12 Already connected. */
219- ETIMEDOUT, /* ERR_TIMEOUT -13 Timeout */
220+ ETIMEDOUT, /* ERR_TIMEOUT -3 Timeout */
221+ EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */
222+ ECONNABORTED, /* ERR_ABRT -5 Connection aborted. */
223+ ECONNRESET, /* ERR_RST -6 Connection reset. */
224+ ESHUTDOWN, /* ERR_CLSD -7 Connection closed. */
225+ ENOTCONN, /* ERR_CONN -8 Not connected. */
226+ EINVAL, /* ERR_VAL -9 Illegal value. */
227+ EIO, /* ERR_ARG -10 Illegal argument. */
228+ EADDRINUSE, /* ERR_USE -11 Address in use. */
229+ -1, /* ERR_IF -12 Low-level netif error */
230+ -1, /* ERR_ISCONN -13 Already connected. */
231 EINPROGRESS /* ERR_INPROGRESS -14 Operation in progress */
232 };
233
234Index: src/api/tcpip.c
235===================================================================
236RCS file: /sources/lwip/lwip/src/api/tcpip.c,v
237retrieving revision 1.70
238retrieving revision 1.73
239diff -u -p -r1.70 -r1.73
240--- a/src/api/tcpip.c 12 Jan 2008 11:52:22 -0000 1.70
241+++ b/src/api/tcpip.c 27 Jun 2008 20:34:51 -0000 1.73
242@@ -518,4 +518,42 @@ tcpip_init(void (* initfunc)(void *), vo
243 sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
244 }
245
246+/**
247+ * Simple callback function used with tcpip_callback to free a pbuf
248+ * (pbuf_free has a wrong signature for tcpip_callback)
249+ *
250+ * @param p The pbuf (chain) to be dereferenced.
251+ */
252+static void
253+pbuf_free_int(void *p)
254+{
255+ struct pbuf *q = p;
256+ pbuf_free(q);
257+}
258+
259+/**
260+ * A simple wrapper function that allows you to free a pbuf from interrupt context.
261+ *
262+ * @param p The pbuf (chain) to be dereferenced.
263+ * @return ERR_OK if callback could be enqueued, an err_t if not
264+ */
265+err_t
266+pbuf_free_callback(struct pbuf *p)
267+{
268+ return tcpip_callback_with_block(pbuf_free_int, p, 0);
269+}
270+
271+/**
272+ * A simple wrapper function that allows you to free heap memory from
273+ * interrupt context.
274+ *
275+ * @param m the heap memory to free
276+ * @return ERR_OK if callback could be enqueued, an err_t if not
277+ */
278+err_t
279+mem_free_callback(void *m)
280+{
281+ return tcpip_callback_with_block(mem_free, m, 0);
282+}
283+
284 #endif /* !NO_SYS */
285Index: src/core/dhcp.c
286===================================================================
287RCS file: /sources/lwip/lwip/src/core/dhcp.c,v
288retrieving revision 1.86
289retrieving revision 1.87
290diff -u -p -r1.86 -r1.87
291--- a/src/core/dhcp.c 4 Mar 2008 14:25:58 -0000 1.86
292+++ b/src/core/dhcp.c 15 Apr 2008 17:24:55 -0000 1.87
293@@ -568,6 +568,8 @@ dhcp_start(struct netif *netif)
294 LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;);
295 dhcp = netif->dhcp;
296 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
297+ /* Remove the flag that says this netif is handled by DHCP,
298+ it is set when we succeeded starting. */
299 netif->flags &= ~NETIF_FLAG_DHCP;
300
301 /* no DHCP client attached yet? */
302@@ -609,6 +611,7 @@ dhcp_start(struct netif *netif)
303 dhcp_stop(netif);
304 return ERR_MEM;
305 }
306+ /* Set the flag that says this netif is handled by DHCP. */
307 netif->flags |= NETIF_FLAG_DHCP;
308 return result;
309 }
310@@ -1063,6 +1066,8 @@ dhcp_stop(struct netif *netif)
311 {
312 struct dhcp *dhcp = netif->dhcp;
313 LWIP_ERROR("dhcp_stop: netif != NULL", (netif != NULL), return;);
314+ /* Remove the flag that says this netif is handled by DHCP. */
315+ netif->flags &= ~NETIF_FLAG_DHCP;
316
317 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | 3, ("dhcp_stop()\n"));
318 /* netif is DHCP configured? */
319Index: src/core/mem.c
320===================================================================
321RCS file: /sources/lwip/lwip/src/core/mem.c,v
322retrieving revision 1.59
323retrieving revision 1.62
324diff -u -p -r1.59 -r1.62
325--- a/src/core/mem.c 4 Mar 2008 16:31:32 -0000 1.59
326+++ b/src/core/mem.c 30 Jun 2008 18:16:51 -0000 1.62
327@@ -177,9 +177,36 @@ static u8_t *ram;
328 static struct mem *ram_end;
329 /** pointer to the lowest free block, this is used for faster search */
330 static struct mem *lfree;
331+
332 /** concurrent access protection */
333 static sys_sem_t mem_sem;
334
335+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
336+
337+static volatile u8_t mem_free_count;
338+
339+/* Allow mem_free from other (e.g. interrupt) context */
340+#define LWIP_MEM_FREE_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_free)
341+#define LWIP_MEM_FREE_PROTECT() SYS_ARCH_PROTECT(lev_free)
342+#define LWIP_MEM_FREE_UNPROTECT() SYS_ARCH_UNPROTECT(lev_free)
343+#define LWIP_MEM_ALLOC_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_alloc)
344+#define LWIP_MEM_ALLOC_PROTECT() SYS_ARCH_PROTECT(lev_alloc)
345+#define LWIP_MEM_ALLOC_UNPROTECT() SYS_ARCH_UNPROTECT(lev_alloc)
346+
347+#else /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
348+
349+/* Protect the heap only by using a semaphore */
350+#define LWIP_MEM_FREE_DECL_PROTECT()
351+#define LWIP_MEM_FREE_PROTECT() sys_arch_sem_wait(mem_sem, 0)
352+#define LWIP_MEM_FREE_UNPROTECT() sys_sem_signal(mem_sem)
353+/* mem_malloc is protected using semaphore AND LWIP_MEM_ALLOC_PROTECT */
354+#define LWIP_MEM_ALLOC_DECL_PROTECT()
355+#define LWIP_MEM_ALLOC_PROTECT()
356+#define LWIP_MEM_ALLOC_UNPROTECT()
357+
358+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
359+
360+
361 /**
362 * "Plug holes" by combining adjacent empty struct mems.
363 * After this function is through, there should not exist
364@@ -255,9 +282,7 @@ mem_init(void)
365 /* initialize the lowest-free pointer to the start of the heap */
366 lfree = (struct mem *)ram;
367
368-#if MEM_STATS
369- lwip_stats.mem.avail = MEM_SIZE_ALIGNED;
370-#endif /* MEM_STATS */
371+ MEM_STATS_AVAIL(avail, MEM_SIZE_ALIGNED);
372 }
373
374 /**
375@@ -270,6 +295,7 @@ void
376 mem_free(void *rmem)
377 {
378 struct mem *mem;
379+ LWIP_MEM_FREE_DECL_PROTECT();
380
381 if (rmem == NULL) {
382 LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_TRACE | 2, ("mem_free(p == NULL) was called.\n"));
383@@ -277,20 +303,20 @@ mem_free(void *rmem)
384 }
385 LWIP_ASSERT("mem_free: sanity check alignment", (((mem_ptr_t)rmem) & (MEM_ALIGNMENT-1)) == 0);
386
387- /* protect the heap from concurrent access */
388- sys_arch_sem_wait(mem_sem, 0);
389-
390 LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram &&
391 (u8_t *)rmem < (u8_t *)ram_end);
392
393 if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
394+ SYS_ARCH_DECL_PROTECT(lev);
395 LWIP_DEBUGF(MEM_DEBUG | 3, ("mem_free: illegal memory\n"));
396-#if MEM_STATS
397- ++lwip_stats.mem.err;
398-#endif /* MEM_STATS */
399- sys_sem_signal(mem_sem);
400+ /* protect mem stats from concurrent access */
401+ SYS_ARCH_PROTECT(lev);
402+ MEM_STATS_INC(illegal);
403+ SYS_ARCH_UNPROTECT(lev);
404 return;
405 }
406+ /* protect the heap from concurrent access */
407+ LWIP_MEM_FREE_PROTECT();
408 /* Get the corresponding struct mem ... */
409 mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM);
410 /* ... which has to be in a used state ... */
411@@ -303,13 +329,14 @@ mem_free(void *rmem)
412 lfree = mem;
413 }
414
415-#if MEM_STATS
416- lwip_stats.mem.used -= mem->next - ((u8_t *)mem - ram);
417-#endif /* MEM_STATS */
418+ MEM_STATS_DEC_USED(used, mem->next - ((u8_t *)mem - ram));
419
420 /* finally, see if prev or next are free also */
421 plug_holes(mem);
422- sys_sem_signal(mem_sem);
423+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
424+ mem_free_count = 1;
425+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
426+ LWIP_MEM_FREE_UNPROTECT();
427 }
428
429 /**
430@@ -321,6 +348,8 @@ mem_free(void *rmem)
431 * @param newsize required size after shrinking (needs to be smaller than or
432 * equal to the previous size)
433 * @return for compatibility reasons: is always == rmem, at the moment
434+ * or NULL if newsize is > old size, in which case rmem is NOT touched
435+ * or freed!
436 */
437 void *
438 mem_realloc(void *rmem, mem_size_t newsize)
439@@ -328,6 +357,8 @@ mem_realloc(void *rmem, mem_size_t newsi
440 mem_size_t size;
441 mem_size_t ptr, ptr2;
442 struct mem *mem, *mem2;
443+ /* use the FREE_PROTECT here: it protects with sem OR SYS_ARCH_PROTECT */
444+ LWIP_MEM_FREE_DECL_PROTECT();
445
446 /* Expand the size of the allocated memory region so that we can
447 adjust for alignment. */
448@@ -346,7 +377,12 @@ mem_realloc(void *rmem, mem_size_t newsi
449 (u8_t *)rmem < (u8_t *)ram_end);
450
451 if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
452+ SYS_ARCH_DECL_PROTECT(lev);
453 LWIP_DEBUGF(MEM_DEBUG | 3, ("mem_realloc: illegal memory\n"));
454+ /* protect mem stats from concurrent access */
455+ SYS_ARCH_PROTECT(lev);
456+ MEM_STATS_INC(illegal);
457+ SYS_ARCH_UNPROTECT(lev);
458 return rmem;
459 }
460 /* Get the corresponding struct mem ... */
461@@ -366,11 +402,9 @@ mem_realloc(void *rmem, mem_size_t newsi
462 }
463
464 /* protect the heap from concurrent access */
465- sys_arch_sem_wait(mem_sem, 0);
466+ LWIP_MEM_FREE_PROTECT();
467
468-#if MEM_STATS
469- lwip_stats.mem.used -= (size - newsize);
470-#endif /* MEM_STATS */
471+ MEM_STATS_DEC_USED(used, (size - newsize));
472
473 mem2 = (struct mem *)&ram[mem->next];
474 if(mem2->used == 0) {
475@@ -426,7 +460,10 @@ mem_realloc(void *rmem, mem_size_t newsi
476 -> don't do anyhting.
477 -> the remaining space stays unused since it is too small
478 } */
479- sys_sem_signal(mem_sem);
480+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
481+ mem_free_count = 1;
482+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
483+ LWIP_MEM_FREE_UNPROTECT();
484 return rmem;
485 }
486
487@@ -444,6 +481,10 @@ mem_malloc(mem_size_t size)
488 {
489 mem_size_t ptr, ptr2;
490 struct mem *mem, *mem2;
491+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
492+ u8_t local_mem_free_count = 0;
493+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
494+ LWIP_MEM_ALLOC_DECL_PROTECT();
495
496 if (size == 0) {
497 return NULL;
498@@ -464,88 +505,101 @@ mem_malloc(mem_size_t size)
499
500 /* protect the heap from concurrent access */
501 sys_arch_sem_wait(mem_sem, 0);
502+ LWIP_MEM_ALLOC_PROTECT();
503+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
504+ /* run as long as a mem_free disturbed mem_malloc */
505+ do {
506+ local_mem_free_count = 0;
507+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
508+
509+ /* Scan through the heap searching for a free block that is big enough,
510+ * beginning with the lowest free block.
511+ */
512+ for (ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE_ALIGNED - size;
513+ ptr = ((struct mem *)&ram[ptr])->next) {
514+ mem = (struct mem *)&ram[ptr];
515+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
516+ mem_free_count = 0;
517+ LWIP_MEM_ALLOC_UNPROTECT();
518+ /* allow mem_free to run */
519+ LWIP_MEM_ALLOC_PROTECT();
520+ if (mem_free_count != 0) {
521+ local_mem_free_count = mem_free_count;
522+ }
523+ mem_free_count = 0;
524+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
525
526- /* Scan through the heap searching for a free block that is big enough,
527- * beginning with the lowest free block.
528- */
529- for (ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE_ALIGNED - size;
530- ptr = ((struct mem *)&ram[ptr])->next) {
531- mem = (struct mem *)&ram[ptr];
532-
533- if ((!mem->used) &&
534- (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) {
535- /* mem is not used and at least perfect fit is possible:
536- * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */
537-
538- if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) {
539- /* (in addition to the above, we test if another struct mem (SIZEOF_STRUCT_MEM) containing
540- * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem')
541- * -> split large block, create empty remainder,
542- * remainder must be large enough to contain MIN_SIZE_ALIGNED data: if
543- * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size,
544- * struct mem would fit in but no data between mem2 and mem2->next
545- * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty
546- * region that couldn't hold data, but when mem->next gets freed,
547- * the 2 regions would be combined, resulting in more free memory
548- */
549- ptr2 = ptr + SIZEOF_STRUCT_MEM + size;
550- /* create mem2 struct */
551- mem2 = (struct mem *)&ram[ptr2];
552- mem2->used = 0;
553- mem2->next = mem->next;
554- mem2->prev = ptr;
555- /* and insert it between mem and mem->next */
556- mem->next = ptr2;
557- mem->used = 1;
558-
559- if (mem2->next != MEM_SIZE_ALIGNED) {
560- ((struct mem *)&ram[mem2->next])->prev = ptr2;
561- }
562-#if MEM_STATS
563- lwip_stats.mem.used += (size + SIZEOF_STRUCT_MEM);
564- if (lwip_stats.mem.max < lwip_stats.mem.used) {
565- lwip_stats.mem.max = lwip_stats.mem.used;
566+ if ((!mem->used) &&
567+ (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) {
568+ /* mem is not used and at least perfect fit is possible:
569+ * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */
570+
571+ if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) {
572+ /* (in addition to the above, we test if another struct mem (SIZEOF_STRUCT_MEM) containing
573+ * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem')
574+ * -> split large block, create empty remainder,
575+ * remainder must be large enough to contain MIN_SIZE_ALIGNED data: if
576+ * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size,
577+ * struct mem would fit in but no data between mem2 and mem2->next
578+ * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty
579+ * region that couldn't hold data, but when mem->next gets freed,
580+ * the 2 regions would be combined, resulting in more free memory
581+ */
582+ ptr2 = ptr + SIZEOF_STRUCT_MEM + size;
583+ /* create mem2 struct */
584+ mem2 = (struct mem *)&ram[ptr2];
585+ mem2->used = 0;
586+ mem2->next = mem->next;
587+ mem2->prev = ptr;
588+ /* and insert it between mem and mem->next */
589+ mem->next = ptr2;
590+ mem->used = 1;
591+
592+ if (mem2->next != MEM_SIZE_ALIGNED) {
593+ ((struct mem *)&ram[mem2->next])->prev = ptr2;
594+ }
595+ MEM_STATS_INC_USED(used, (size + SIZEOF_STRUCT_MEM));
596+ } else {
597+ /* (a mem2 struct does no fit into the user data space of mem and mem->next will always
598+ * be used at this point: if not we have 2 unused structs in a row, plug_holes should have
599+ * take care of this).
600+ * -> near fit or excact fit: do not split, no mem2 creation
601+ * also can't move mem->next directly behind mem, since mem->next
602+ * will always be used at this point!
603+ */
604+ mem->used = 1;
605+ MEM_STATS_INC_USED(used, mem->next - ((u8_t *)mem - ram));
606 }
607-#endif /* MEM_STATS */
608- } else {
609- /* (a mem2 struct does no fit into the user data space of mem and mem->next will always
610- * be used at this point: if not we have 2 unused structs in a row, plug_holes should have
611- * take care of this).
612- * -> near fit or excact fit: do not split, no mem2 creation
613- * also can't move mem->next directly behind mem, since mem->next
614- * will always be used at this point!
615- */
616- mem->used = 1;
617-#if MEM_STATS
618- lwip_stats.mem.used += mem->next - ((u8_t *)mem - ram);
619- if (lwip_stats.mem.max < lwip_stats.mem.used) {
620- lwip_stats.mem.max = lwip_stats.mem.used;
621- }
622-#endif /* MEM_STATS */
623- }
624
625- if (mem == lfree) {
626- /* Find next free block after mem and update lowest free pointer */
627- while (lfree->used && lfree != ram_end) {
628- lfree = (struct mem *)&ram[lfree->next];
629+ if (mem == lfree) {
630+ /* Find next free block after mem and update lowest free pointer */
631+ while (lfree->used && lfree != ram_end) {
632+ LWIP_MEM_ALLOC_UNPROTECT();
633+ /* prevent high interrupt latency... */
634+ LWIP_MEM_ALLOC_PROTECT();
635+ lfree = (struct mem *)&ram[lfree->next];
636+ }
637+ LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used)));
638 }
639- LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used)));
640- }
641- sys_sem_signal(mem_sem);
642- LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",
643- (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end);
644- LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",
645- (unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
646- LWIP_ASSERT("mem_malloc: sanity check alignment",
647- (((mem_ptr_t)mem) & (MEM_ALIGNMENT-1)) == 0);
648+ LWIP_MEM_ALLOC_UNPROTECT();
649+ sys_sem_signal(mem_sem);
650+ LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",
651+ (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end);
652+ LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",
653+ (unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
654+ LWIP_ASSERT("mem_malloc: sanity check alignment",
655+ (((mem_ptr_t)mem) & (MEM_ALIGNMENT-1)) == 0);
656
657- return (u8_t *)mem + SIZEOF_STRUCT_MEM;
658+ return (u8_t *)mem + SIZEOF_STRUCT_MEM;
659+ }
660 }
661- }
662+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
663+ /* if we got interrupted by a mem_free, try again */
664+ } while(local_mem_free_count != 0);
665+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
666 LWIP_DEBUGF(MEM_DEBUG | 2, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size));
667-#if MEM_STATS
668- ++lwip_stats.mem.err;
669-#endif /* MEM_STATS */
670+ MEM_STATS_INC(err);
671+ LWIP_MEM_ALLOC_UNPROTECT();
672 sys_sem_signal(mem_sem);
673 return NULL;
674 }
675Index: src/core/memp.c
676===================================================================
677RCS file: /sources/lwip/lwip/src/core/memp.c,v
678retrieving revision 1.55
679retrieving revision 1.56
680diff -u -p -r1.55 -r1.56
681--- a/src/core/memp.c 25 Nov 2007 10:43:28 -0000 1.55
682+++ b/src/core/memp.c 27 Jun 2008 18:37:54 -0000 1.56
683@@ -252,13 +252,12 @@ memp_init(void)
684 struct memp *memp;
685 u16_t i, j;
686
687-#if MEMP_STATS
688 for (i = 0; i < MEMP_MAX; ++i) {
689- lwip_stats.memp[i].used = lwip_stats.memp[i].max =
690- lwip_stats.memp[i].err = 0;
691- lwip_stats.memp[i].avail = memp_num[i];
692+ MEMP_STATS_AVAIL(used, i, 0);
693+ MEMP_STATS_AVAIL(max, i, 0);
694+ MEMP_STATS_AVAIL(err, i, 0);
695+ MEMP_STATS_AVAIL(avail, i, memp_num[i]);
696 }
697-#endif /* MEMP_STATS */
698
699 memp = LWIP_MEM_ALIGN(memp_memory);
700 /* for every pool: */
701@@ -315,20 +314,13 @@ memp_malloc_fn(memp_t type, const char*
702 memp->file = file;
703 memp->line = line;
704 #endif /* MEMP_OVERFLOW_CHECK */
705-#if MEMP_STATS
706- ++lwip_stats.memp[type].used;
707- if (lwip_stats.memp[type].used > lwip_stats.memp[type].max) {
708- lwip_stats.memp[type].max = lwip_stats.memp[type].used;
709- }
710-#endif /* MEMP_STATS */
711+ MEMP_STATS_INC_USED(used, type);
712 LWIP_ASSERT("memp_malloc: memp properly aligned",
713 ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0);
714 memp = (struct memp*)((u8_t*)memp + MEMP_SIZE);
715 } else {
716 LWIP_DEBUGF(MEMP_DEBUG | 2, ("memp_malloc: out of memory in pool %s\n", memp_desc[type]));
717-#if MEMP_STATS
718- ++lwip_stats.memp[type].err;
719-#endif /* MEMP_STATS */
720+ MEMP_STATS_INC(err, type);
721 }
722
723 SYS_ARCH_UNPROTECT(old_level);
724@@ -365,9 +357,7 @@ memp_free(memp_t type, void *mem)
725 #endif /* MEMP_OVERFLOW_CHECK >= 2 */
726 #endif /* MEMP_OVERFLOW_CHECK */
727
728-#if MEMP_STATS
729- lwip_stats.memp[type].used--;
730-#endif /* MEMP_STATS */
731+ MEMP_STATS_DEC(used, type);
732
733 memp->next = memp_tab[type];
734 memp_tab[type] = memp;
735Index: src/core/netif.c
736===================================================================
737RCS file: /sources/lwip/lwip/src/core/netif.c,v
738retrieving revision 1.65
739retrieving revision 1.68
740diff -u -p -r1.65 -r1.68
741--- a/src/core/netif.c 9 Oct 2007 20:00:55 -0000 1.65
742+++ b/src/core/netif.c 19 Jun 2008 16:27:18 -0000 1.68
743@@ -45,6 +45,12 @@
744 #include "lwip/snmp.h"
745 #include "lwip/igmp.h"
746 #include "netif/etharp.h"
747+#if ENABLE_LOOPBACK
748+#include "lwip/sys.h"
749+#if LWIP_NETIF_LOOPBACK_MULTITHREADING
750+#include "lwip/tcpip.h"
751+#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
752+#endif /* ENABLE_LOOPBACK */
753
754 #if LWIP_NETIF_STATUS_CALLBACK
755 #define NETIF_STATUS_CALLBACK(n) { if (n->status_callback) (n->status_callback)(n); }
756@@ -106,6 +112,10 @@ netif_add(struct netif *netif, struct ip
757 #if LWIP_IGMP
758 netif->igmp_mac_filter = NULL;
759 #endif /* LWIP_IGMP */
760+#if ENABLE_LOOPBACK
761+ netif->loop_first = NULL;
762+ netif->loop_last = NULL;
763+#endif /* ENABLE_LOOPBACK */
764
765 /* remember netif specific state information data */
766 netif->state = state;
767@@ -114,6 +124,9 @@ netif_add(struct netif *netif, struct ip
768 #if LWIP_NETIF_HWADDRHINT
769 netif->addr_hint = NULL;
770 #endif /* LWIP_NETIF_HWADDRHINT*/
771+#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS
772+ netif->loop_cnt_current = 0;
773+#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */
774
775 netif_set_addr(netif, ipaddr, netmask, gw);
776
777@@ -493,7 +506,158 @@ u8_t netif_is_link_up(struct netif *neti
778 */
779 void netif_set_link_callback(struct netif *netif, void (* link_callback)(struct netif *netif ))
780 {
781- if ( netif )
782- netif->link_callback = link_callback;
783+ if (netif) {
784+ netif->link_callback = link_callback;
785+ }
786 }
787 #endif /* LWIP_NETIF_LINK_CALLBACK */
788+
789+#if ENABLE_LOOPBACK
790+/**
791+ * Send an IP packet to be received on the same netif (loopif-like).
792+ * The pbuf is simply copied and handed back to netif->input.
793+ * In multithreaded mode, this is done directly since netif->input must put
794+ * the packet on a queue.
795+ * In callback mode, the packet is put on an internal queue and is fed to
796+ * netif->input by netif_poll().
797+ *
798+ * @param netif the lwip network interface structure
799+ * @param p the (IP) packet to 'send'
800+ * @param ipaddr the ip address to send the packet to (not used)
801+ * @return ERR_OK if the packet has been sent
802+ * ERR_MEM if the pbuf used to copy the packet couldn't be allocated
803+ */
804+err_t
805+netif_loop_output(struct netif *netif, struct pbuf *p,
806+ struct ip_addr *ipaddr)
807+{
808+ struct pbuf *r;
809+ err_t err;
810+ struct pbuf *last;
811+#if LWIP_LOOPBACK_MAX_PBUFS
812+ u8_t clen = 0;
813+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
814+ SYS_ARCH_DECL_PROTECT(lev);
815+ LWIP_UNUSED_ARG(ipaddr);
816+
817+ /* Allocate a new pbuf */
818+ r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM);
819+ if (r == NULL) {
820+ return ERR_MEM;
821+ }
822+#if LWIP_LOOPBACK_MAX_PBUFS
823+ clen = pbuf_clen(r);
824+ /* check for overflow or too many pbuf on queue */
825+ if(((netif->loop_cnt_current + clen) < netif->loop_cnt_current) ||
826+ ((netif->loop_cnt_current + clen) > LWIP_LOOPBACK_MAX_PBUFS)) {
827+ pbuf_free(r);
828+ r = NULL;
829+ return ERR_MEM;
830+ }
831+ netif->loop_cnt_current += clen;
832+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
833+
834+ /* Copy the whole pbuf queue p into the single pbuf r */
835+ if ((err = pbuf_copy(r, p)) != ERR_OK) {
836+ pbuf_free(r);
837+ r = NULL;
838+ return err;
839+ }
840+
841+ /* Put the packet on a linked list which gets emptied through calling
842+ netif_poll(). */
843+
844+ /* let last point to the last pbuf in chain r */
845+ for (last = r; last->next != NULL; last = last->next);
846+
847+ SYS_ARCH_PROTECT(lev);
848+ if(netif->loop_first != NULL) {
849+ LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL);
850+ netif->loop_last->next = r;
851+ netif->loop_last = last;
852+ } else {
853+ netif->loop_first = r;
854+ netif->loop_last = last;
855+ }
856+ SYS_ARCH_UNPROTECT(lev);
857+
858+#if LWIP_NETIF_LOOPBACK_MULTITHREADING
859+ /* For multithreading environment, schedule a call to netif_poll */
860+ tcpip_callback(netif_poll, netif);
861+#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
862+
863+ return ERR_OK;
864+}
865+
866+/**
867+ * Call netif_poll() in the main loop of your application. This is to prevent
868+ * reentering non-reentrant functions like tcp_input(). Packets passed to
869+ * netif_loop_output() are put on a list that is passed to netif->input() by
870+ * netif_poll().
871+ */
872+void
873+netif_poll(struct netif *netif)
874+{
875+ struct pbuf *in;
876+ SYS_ARCH_DECL_PROTECT(lev);
877+
878+ do {
879+ /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */
880+ SYS_ARCH_PROTECT(lev);
881+ in = netif->loop_first;
882+ if(in != NULL) {
883+ struct pbuf *in_end = in;
884+#if LWIP_LOOPBACK_MAX_PBUFS
885+ u8_t clen = pbuf_clen(in);
886+ /* adjust the number of pbufs on queue */
887+ LWIP_ASSERT("netif->loop_cnt_current underflow",
888+ ((netif->loop_cnt_current - clen) < netif->loop_cnt_current));
889+ netif->loop_cnt_current -= clen;
890+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
891+ while(in_end->len != in_end->tot_len) {
892+ LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL);
893+ in_end = in_end->next;
894+ }
895+ /* 'in_end' now points to the last pbuf from 'in' */
896+ if(in_end == netif->loop_last) {
897+ /* this was the last pbuf in the list */
898+ netif->loop_first = netif->loop_last = NULL;
899+ } else {
900+ /* pop the pbuf off the list */
901+ netif->loop_first = in_end->next;
902+ LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL);
903+ }
904+ /* De-queue the pbuf from its successors on the 'loop_' list. */
905+ in_end->next = NULL;
906+ }
907+ SYS_ARCH_UNPROTECT(lev);
908+
909+ if(in != NULL) {
910+ /* loopback packets are always IP packets! */
911+ if(ip_input(in, netif) != ERR_OK) {
912+ pbuf_free(in);
913+ }
914+ /* Don't reference the packet any more! */
915+ in = NULL;
916+ }
917+ /* go on while there is a packet on the list */
918+ } while(netif->loop_first != NULL);
919+}
920+
921+#if !LWIP_NETIF_LOOPBACK_MULTITHREADING
922+/**
923+ * Calls netif_poll() for every netif on the netif_list.
924+ */
925+void
926+netif_poll_all(void)
927+{
928+ struct netif *netif = netif_list;
929+ /* loop through netifs */
930+ while (netif != NULL) {
931+ netif_poll(netif);
932+ /* proceed to next network interface */
933+ netif = netif->next;
934+ }
935+}
936+#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */
937+#endif /* ENABLE_LOOPBACK */
938Index: src/core/pbuf.c
939===================================================================
940RCS file: /sources/lwip/lwip/src/core/pbuf.c,v
941retrieving revision 1.127
942retrieving revision 1.128
943diff -u -p -r1.127 -r1.128
944--- a/src/core/pbuf.c 4 Mar 2008 16:37:46 -0000 1.127
945+++ b/src/core/pbuf.c 1 Apr 2008 19:05:40 -0000 1.128
946@@ -667,8 +667,8 @@ pbuf_dechain(struct pbuf *p)
947 *
948 * @note Only one packet is copied, no packet queue!
949 *
950- * @param p_to pbuf source of the copy
951- * @param p_from pbuf destination of the copy
952+ * @param p_to pbuf destination of the copy
953+ * @param p_from pbuf source of the copy
954 *
955 * @return ERR_OK if pbuf was copied
956 * ERR_ARG if one of the pbufs is NULL or p_to is not big
957Index: src/core/stats.c
958===================================================================
959RCS file: /sources/lwip/lwip/src/core/stats.c,v
960retrieving revision 1.27
961retrieving revision 1.28
962diff -u -p -r1.27 -r1.28
963--- a/src/core/stats.c 4 Mar 2008 16:31:32 -0000 1.27
964+++ b/src/core/stats.c 27 Jun 2008 18:37:54 -0000 1.28
965@@ -54,7 +54,6 @@ stats_display_proto(struct stats_proto *
966 {
967 LWIP_PLATFORM_DIAG(("\n%s\n\t", name));
968 LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", proto->xmit));
969- LWIP_PLATFORM_DIAG(("rexmit: %"STAT_COUNTER_F"\n\t", proto->rexmit));
970 LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", proto->recv));
971 LWIP_PLATFORM_DIAG(("fw: %"STAT_COUNTER_F"\n\t", proto->fw));
972 LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", proto->drop));
973@@ -68,6 +67,7 @@ stats_display_proto(struct stats_proto *
974 LWIP_PLATFORM_DIAG(("cachehit: %"STAT_COUNTER_F"\n", proto->cachehit));
975 }
976
977+#if IGMP_STATS
978 void
979 stats_display_igmp(struct stats_igmp *igmp)
980 {
981@@ -82,7 +82,9 @@ stats_display_igmp(struct stats_igmp *ig
982 LWIP_PLATFORM_DIAG(("report_rxed: %"STAT_COUNTER_F"\n\t", igmp->report_rxed));
983 LWIP_PLATFORM_DIAG(("group_query_rxed: %"STAT_COUNTER_F"\n", igmp->group_query_rxed));
984 }
985+#endif /* IGMP_STATS */
986
987+#if MEM_STATS || MEMP_STATS
988 void
989 stats_display_mem(struct stats_mem *mem, char *name)
990 {
991@@ -93,48 +95,53 @@ stats_display_mem(struct stats_mem *mem,
992 LWIP_PLATFORM_DIAG(("err: %"U32_F"\n", (u32_t)mem->err));
993 }
994
995+#if MEMP_STATS
996 void
997-stats_display(void)
998+stats_display_memp(struct stats_mem *mem, int index)
999 {
1000-#if MEMP_STATS
1001- s16_t i;
1002 char * memp_names[] = {
1003 #define LWIP_MEMPOOL(name,num,size,desc) desc,
1004 #include "lwip/memp_std.h"
1005 };
1006-#endif
1007-#if LINK_STATS
1008- stats_display_proto(&lwip_stats.link, "LINK");
1009-#endif
1010-#if ETHARP_STATS
1011- stats_display_proto(&lwip_stats.etharp, "ETHARP");
1012-#endif
1013-#if IPFRAG_STATS
1014- stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG");
1015-#endif
1016-#if IP_STATS
1017- stats_display_proto(&lwip_stats.ip, "IP");
1018-#endif
1019-#if ICMP_STATS
1020- stats_display_proto(&lwip_stats.icmp, "ICMP");
1021-#endif
1022-#if IGMP_STATS
1023- stats_display_igmp(&lwip_stats.igmp);
1024-#endif
1025-#if UDP_STATS
1026- stats_display_proto(&lwip_stats.udp, "UDP");
1027-#endif
1028-#if TCP_STATS
1029- stats_display_proto(&lwip_stats.tcp, "TCP");
1030-#endif
1031-#if MEM_STATS
1032- stats_display_mem(&lwip_stats.mem, "HEAP");
1033-#endif
1034-#if MEMP_STATS
1035+ if(index < MEMP_MAX) {
1036+ stats_display_mem(mem, memp_names[index]);
1037+ }
1038+}
1039+#endif /* MEMP_STATS */
1040+#endif /* MEM_STATS || MEMP_STATS */
1041+
1042+#if SYS_STATS
1043+void
1044+stats_display_sys(struct stats_sys *sys)
1045+{
1046+ LWIP_PLATFORM_DIAG(("\nSYS\n\t"));
1047+ LWIP_PLATFORM_DIAG(("sem.used: %"U32_F"\n\t", (u32_t)sys->sem.used));
1048+ LWIP_PLATFORM_DIAG(("sem.max: %"U32_F"\n\t", (u32_t)sys->sem.max));
1049+ LWIP_PLATFORM_DIAG(("sem.err: %"U32_F"\n\t", (u32_t)sys->sem.err));
1050+ LWIP_PLATFORM_DIAG(("mbox.used: %"U32_F"\n\t", (u32_t)sys->mbox.used));
1051+ LWIP_PLATFORM_DIAG(("mbox.max: %"U32_F"\n\t", (u32_t)sys->mbox.max));
1052+ LWIP_PLATFORM_DIAG(("mbox.err: %"U32_F"\n\t", (u32_t)sys->mbox.err));
1053+}
1054+#endif /* SYS_STATS */
1055+
1056+void
1057+stats_display(void)
1058+{
1059+ s16_t i;
1060+
1061+ LINK_STATS_DISPLAY();
1062+ ETHARP_STATS_DISPLAY();
1063+ IPFRAG_STATS_DISPLAY();
1064+ IP_STATS_DISPLAY();
1065+ IGMP_STATS_DISPLAY();
1066+ ICMP_STATS_DISPLAY();
1067+ UDP_STATS_DISPLAY();
1068+ TCP_STATS_DISPLAY();
1069+ MEM_STATS_DISPLAY();
1070 for (i = 0; i < MEMP_MAX; i++) {
1071- stats_display_mem(&lwip_stats.memp[i], memp_names[i]);
1072+ MEMP_STATS_DISPLAY(i);
1073 }
1074-#endif
1075+ SYS_STATS_DISPLAY();
1076 }
1077 #endif /* LWIP_STATS_DISPLAY */
1078
1079Index: src/core/sys.c
1080===================================================================
1081RCS file: /sources/lwip/lwip/src/core/sys.c,v
1082retrieving revision 1.32
1083retrieving revision 1.33
1084diff -u -p -r1.32 -r1.33
1085--- a/src/core/sys.c 25 Nov 2007 13:57:05 -0000 1.32
1086+++ b/src/core/sys.c 16 Jul 2008 20:36:12 -0000 1.33
1087@@ -65,7 +65,7 @@ struct sswt_cb
1088 void
1089 sys_mbox_fetch(sys_mbox_t mbox, void **msg)
1090 {
1091- u32_t time;
1092+ u32_t time_needed;
1093 struct sys_timeouts *timeouts;
1094 struct sys_timeo *tmptimeout;
1095 sys_timeout_handler h;
1096@@ -76,18 +76,18 @@ sys_mbox_fetch(sys_mbox_t mbox, void **m
1097
1098 if (!timeouts || !timeouts->next) {
1099 UNLOCK_TCPIP_CORE();
1100- time = sys_arch_mbox_fetch(mbox, msg, 0);
1101+ time_needed = sys_arch_mbox_fetch(mbox, msg, 0);
1102 LOCK_TCPIP_CORE();
1103 } else {
1104 if (timeouts->next->time > 0) {
1105 UNLOCK_TCPIP_CORE();
1106- time = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time);
1107+ time_needed = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time);
1108 LOCK_TCPIP_CORE();
1109 } else {
1110- time = SYS_ARCH_TIMEOUT;
1111+ time_needed = SYS_ARCH_TIMEOUT;
1112 }
1113
1114- if (time == SYS_ARCH_TIMEOUT) {
1115+ if (time_needed == SYS_ARCH_TIMEOUT) {
1116 /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
1117 could be fetched. We should now call the timeout handler and
1118 deallocate the memory allocated for the timeout. */
1119@@ -107,8 +107,8 @@ sys_mbox_fetch(sys_mbox_t mbox, void **m
1120 /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
1121 occured. The time variable is set to the number of
1122 milliseconds we waited for the message. */
1123- if (time < timeouts->next->time) {
1124- timeouts->next->time -= time;
1125+ if (time_needed < timeouts->next->time) {
1126+ timeouts->next->time -= time_needed;
1127 } else {
1128 timeouts->next->time = 0;
1129 }
1130@@ -125,7 +125,7 @@ sys_mbox_fetch(sys_mbox_t mbox, void **m
1131 void
1132 sys_sem_wait(sys_sem_t sem)
1133 {
1134- u32_t time;
1135+ u32_t time_needed;
1136 struct sys_timeouts *timeouts;
1137 struct sys_timeo *tmptimeout;
1138 sys_timeout_handler h;
1139@@ -139,12 +139,12 @@ sys_sem_wait(sys_sem_t sem)
1140 sys_arch_sem_wait(sem, 0);
1141 } else {
1142 if (timeouts->next->time > 0) {
1143- time = sys_arch_sem_wait(sem, timeouts->next->time);
1144+ time_needed = sys_arch_sem_wait(sem, timeouts->next->time);
1145 } else {
1146- time = SYS_ARCH_TIMEOUT;
1147+ time_needed = SYS_ARCH_TIMEOUT;
1148 }
1149
1150- if (time == SYS_ARCH_TIMEOUT) {
1151+ if (time_needed == SYS_ARCH_TIMEOUT) {
1152 /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message
1153 could be fetched. We should now call the timeout handler and
1154 deallocate the memory allocated for the timeout. */
1155@@ -164,8 +164,8 @@ sys_sem_wait(sys_sem_t sem)
1156 /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout
1157 occured. The time variable is set to the number of
1158 milliseconds we waited for the message. */
1159- if (time < timeouts->next->time) {
1160- timeouts->next->time -= time;
1161+ if (time_needed < timeouts->next->time) {
1162+ timeouts->next->time -= time_needed;
1163 } else {
1164 timeouts->next->time = 0;
1165 }
1166Index: src/core/tcp.c
1167===================================================================
1168RCS file: /sources/lwip/lwip/src/core/tcp.c,v
1169retrieving revision 1.85
1170retrieving revision 1.86
1171diff -u -p -r1.85 -r1.86
1172--- a/src/core/tcp.c 22 Jan 2008 21:15:15 -0000 1.85
1173+++ b/src/core/tcp.c 26 Mar 2008 11:57:13 -0000 1.86
1174@@ -509,7 +509,8 @@ tcp_connect(struct tcp_pcb *pcb, struct
1175 pcb->rcv_wnd = TCP_WND;
1176 pcb->rcv_ann_wnd = TCP_WND;
1177 pcb->snd_wnd = TCP_WND;
1178- /* The send MSS is updated when an MSS option is received. */
1179+ /* As initial send MSS, we use TCP_MSS but limit it to 536.
1180+ The send MSS is updated when an MSS option is received. */
1181 pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
1182 #if TCP_CALCULATE_EFF_SEND_MSS
1183 pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr);
1184@@ -991,7 +992,8 @@ tcp_alloc(u8_t prio)
1185 pcb->rcv_ann_wnd = TCP_WND;
1186 pcb->tos = 0;
1187 pcb->ttl = TCP_TTL;
1188- /* The send MSS is updated when an MSS option is received. */
1189+ /* As initial send MSS, we use TCP_MSS but limit it to 536.
1190+ The send MSS is updated when an MSS option is received. */
1191 pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
1192 pcb->rto = 3000 / TCP_SLOW_INTERVAL;
1193 pcb->sa = 0;
1194Index: src/core/tcp_in.c
1195===================================================================
1196RCS file: /sources/lwip/lwip/src/core/tcp_in.c,v
1197retrieving revision 1.97
1198retrieving revision 1.100
1199diff -u -p -r1.97 -r1.100
1200--- a/src/core/tcp_in.c 22 Jan 2008 21:15:15 -0000 1.97
1201+++ b/src/core/tcp_in.c 24 Jun 2008 15:46:39 -0000 1.100
1202@@ -511,7 +511,7 @@ tcp_process(struct tcp_pcb *pcb)
1203 }
1204 } else {
1205 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
1206- pcb->rcv_nxt+pcb->rcv_ann_wnd)) {
1207+ pcb->rcv_nxt+pcb->rcv_wnd)) {
1208 acceptable = 1;
1209 }
1210 }
1211@@ -1038,7 +1038,7 @@ tcp_receive(struct tcp_pcb *pcb)
1212 and below rcv_nxt + rcv_wnd) in order to be further
1213 processed. */
1214 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
1215- pcb->rcv_nxt + pcb->rcv_ann_wnd - 1)){
1216+ pcb->rcv_nxt + pcb->rcv_wnd - 1)){
1217 if (pcb->rcv_nxt == seqno) {
1218 accepted_inseq = 1;
1219 /* The incoming segment is the next in sequence. We check if
1220@@ -1195,14 +1195,14 @@ tcp_receive(struct tcp_pcb *pcb)
1221 } else {
1222 pcb->ooseq = cseg;
1223 }
1224- }
1225- tcp_seg_free(next);
1226- if (cseg->next != NULL) {
1227- next = cseg->next;
1228- if (TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) {
1229- /* We need to trim the incoming segment. */
1230- cseg->len = (u16_t)(next->tcphdr->seqno - seqno);
1231- pbuf_realloc(cseg->p, cseg->len);
1232+ tcp_seg_free(next);
1233+ if (cseg->next != NULL) {
1234+ next = cseg->next;
1235+ if (TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) {
1236+ /* We need to trim the incoming segment. */
1237+ cseg->len = (u16_t)(next->tcphdr->seqno - seqno);
1238+ pbuf_realloc(cseg->p, cseg->len);
1239+ }
1240 }
1241 }
1242 break;
1243@@ -1282,10 +1282,7 @@ tcp_receive(struct tcp_pcb *pcb)
1244
1245 }
1246 } else {
1247- if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
1248- pcb->rcv_nxt + pcb->rcv_ann_wnd-1)){
1249- tcp_ack_now(pcb);
1250- }
1251+ tcp_ack_now(pcb);
1252 }
1253 } else {
1254 /* Segments with length 0 is taken care of here. Segments that
1255@@ -1331,7 +1328,8 @@ tcp_parseopt(struct tcp_pcb *pcb)
1256 opts[c + 1] == 0x04) {
1257 /* An MSS option with the right option length. */
1258 mss = (opts[c + 2] << 8) | opts[c + 3];
1259- pcb->mss = mss > TCP_MSS? TCP_MSS: mss;
1260+ /* Limit the mss to the configured TCP_MSS and prevent division by zero */
1261+ pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss;
1262
1263 /* And we are done processing options. */
1264 break;
1265Index: src/core/ipv4/autoip.c
1266===================================================================
1267RCS file: /sources/lwip/lwip/src/core/ipv4/autoip.c,v
1268retrieving revision 1.16
1269retrieving revision 1.17
1270diff -u -p -r1.16 -r1.17
1271--- a/src/core/ipv4/autoip.c 26 Jan 2008 16:11:40 -0000 1.16
1272+++ b/src/core/ipv4/autoip.c 17 Jun 2008 20:16:23 -0000 1.17
1273@@ -395,8 +395,8 @@ autoip_arp_reply(struct netif *netif, st
1274 /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without
1275 * structure packing (not using structure copy which breaks strict-aliasing rules).
1276 */
1277- MEMCPY(&sipaddr, &hdr->sipaddr, sizeof(sipaddr));
1278- MEMCPY(&dipaddr, &hdr->dipaddr, sizeof(dipaddr));
1279+ SMEMCPY(&sipaddr, &hdr->sipaddr, sizeof(sipaddr));
1280+ SMEMCPY(&dipaddr, &hdr->dipaddr, sizeof(dipaddr));
1281
1282 if ((netif->autoip->state == AUTOIP_STATE_PROBING) ||
1283 ((netif->autoip->state == AUTOIP_STATE_ANNOUNCING) &&
1284Index: src/core/ipv4/inet_chksum.c
1285===================================================================
1286RCS file: /sources/lwip/lwip/src/core/ipv4/inet_chksum.c,v
1287retrieving revision 1.4
1288retrieving revision 1.5
1289diff -u -p -r1.4 -r1.5
1290--- a/src/core/ipv4/inet_chksum.c 10 Mar 2008 16:12:31 -0000 1.4
1291+++ b/src/core/ipv4/inet_chksum.c 17 Jun 2008 20:06:25 -0000 1.5
1292@@ -41,8 +41,6 @@
1293 #include "lwip/inet_chksum.h"
1294 #include "lwip/inet.h"
1295
1296-#include <string.h>
1297-
1298 /* These are some reference implementations of the checksum algorithm, with the
1299 * aim of being simple, correct and fully portable. Checksumming is the
1300 * first thing you would want to optimize for your platform. If you create
1301@@ -65,6 +63,11 @@
1302 # define LWIP_CHKSUM_ALGORITHM 0
1303 #endif
1304
1305+/** Like the name says... */
1306+#define SWAP_BYTES_IN_WORD(w) ((w & 0xff) << 8) | ((w & 0xff00) >> 8)
1307+/** Split an u32_t in two u16_ts and add them up */
1308+#define FOLD_U32T(u) ((u >> 16) + (u & 0x0000ffffUL))
1309+
1310 #if (LWIP_CHKSUM_ALGORITHM == 1) /* Version #1 */
1311 /**
1312 * lwip checksum
1313@@ -86,8 +89,7 @@ lwip_standard_chksum(void *dataptr, u16_
1314 acc = 0;
1315 /* dataptr may be at odd or even addresses */
1316 octetptr = (u8_t*)dataptr;
1317- while (len > 1)
1318- {
1319+ while (len > 1) {
1320 /* declare first octet as most significant
1321 thus assume network order, ignoring host order */
1322 src = (*octetptr) << 8;
1323@@ -98,8 +100,7 @@ lwip_standard_chksum(void *dataptr, u16_
1324 acc += src;
1325 len -= 2;
1326 }
1327- if (len > 0)
1328- {
1329+ if (len > 0) {
1330 /* accumulate remaining octet */
1331 src = (*octetptr) << 8;
1332 acc += src;
1333@@ -154,19 +155,22 @@ lwip_standard_chksum(void *dataptr, int
1334 }
1335
1336 /* Consume left-over byte, if any */
1337- if (len > 0)
1338+ if (len > 0) {
1339 ((u8_t *)&t)[0] = *(u8_t *)ps;;
1340+ }
1341
1342 /* Add end bytes */
1343 sum += t;
1344
1345- /* Fold 32-bit sum to 16 bits */
1346- while ((sum >> 16) != 0)
1347- sum = (sum & 0xffff) + (sum >> 16);
1348+ /* Fold 32-bit sum to 16 bits
1349+ calling this twice is propably faster than if statements... */
1350+ sum = FOLD_U32T(sum);
1351+ sum = FOLD_U32T(sum);
1352
1353 /* Swap if alignment was odd */
1354- if (odd)
1355- sum = ((sum & 0xff) << 8) | ((sum & 0xff00) >> 8);
1356+ if (odd) {
1357+ sum = SWAP_BYTES_IN_WORD(sum);
1358+ }
1359
1360 return sum;
1361 }
1362@@ -211,18 +215,20 @@ lwip_standard_chksum(void *dataptr, int
1363
1364 while (len > 7) {
1365 tmp = sum + *pl++; /* ping */
1366- if (tmp < sum)
1367+ if (tmp < sum) {
1368 tmp++; /* add back carry */
1369+ }
1370
1371 sum = tmp + *pl++; /* pong */
1372- if (sum < tmp)
1373+ if (sum < tmp) {
1374 sum++; /* add back carry */
1375+ }
1376
1377 len -= 8;
1378 }
1379
1380 /* make room in upper bits */
1381- sum = (sum >> 16) + (sum & 0xffff);
1382+ sum = FOLD_U32T(sum);
1383
1384 ps = (u16_t *)pl;
1385
1386@@ -233,16 +239,20 @@ lwip_standard_chksum(void *dataptr, int
1387 }
1388
1389 /* dangling tail byte remaining? */
1390- if (len > 0) /* include odd byte */
1391+ if (len > 0) { /* include odd byte */
1392 ((u8_t *)&t)[0] = *(u8_t *)ps;
1393+ }
1394
1395 sum += t; /* add end bytes */
1396
1397- while ((sum >> 16) != 0) /* combine halves */
1398- sum = (sum >> 16) + (sum & 0xffff);
1399+ /* Fold 32-bit sum to 16 bits
1400+ calling this twice is propably faster than if statements... */
1401+ sum = FOLD_U32T(sum);
1402+ sum = FOLD_U32T(sum);
1403
1404- if (odd)
1405- sum = ((sum & 0xff) << 8) | ((sum & 0xff00) >> 8);
1406+ if (odd) {
1407+ sum = SWAP_BYTES_IN_WORD(sum);
1408+ }
1409
1410 return sum;
1411 }
1412@@ -277,18 +287,18 @@ inet_chksum_pseudo(struct pbuf *p,
1413 (void *)q, (void *)q->next));
1414 acc += LWIP_CHKSUM(q->payload, q->len);
1415 /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/
1416- while ((acc >> 16) != 0) {
1417- acc = (acc & 0xffffUL) + (acc >> 16);
1418- }
1419+ /* just executing this next line is probably faster that the if statement needed
1420+ to check whether we really need to execute it, and does no harm */
1421+ acc = FOLD_U32T(acc);
1422 if (q->len % 2 != 0) {
1423 swapped = 1 - swapped;
1424- acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);
1425+ acc = SWAP_BYTES_IN_WORD(acc);
1426 }
1427 /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
1428 }
1429
1430 if (swapped) {
1431- acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);
1432+ acc = SWAP_BYTES_IN_WORD(acc);
1433 }
1434 acc += (src->addr & 0xffffUL);
1435 acc += ((src->addr >> 16) & 0xffffUL);
1436@@ -297,9 +307,10 @@ inet_chksum_pseudo(struct pbuf *p,
1437 acc += (u32_t)htons((u16_t)proto);
1438 acc += (u32_t)htons(proto_len);
1439
1440- while ((acc >> 16) != 0) {
1441- acc = (acc & 0xffffUL) + (acc >> 16);
1442- }
1443+ /* Fold 32-bit sum to 16 bits
1444+ calling this twice is propably faster than if statements... */
1445+ acc = FOLD_U32T(acc);
1446+ acc = FOLD_U32T(acc);
1447 LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));
1448 return (u16_t)~(acc & 0xffffUL);
1449 }
1450@@ -340,18 +351,17 @@ inet_chksum_pseudo_partial(struct pbuf *
1451 chksum_len -= chklen;
1452 LWIP_ASSERT("delete me", chksum_len < 0x7fff);
1453 /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/
1454- while ((acc >> 16) != 0) {
1455- acc = (acc & 0xffffUL) + (acc >> 16);
1456- }
1457+ /* fold the upper bit down */
1458+ acc = FOLD_U32T(acc);
1459 if (q->len % 2 != 0) {
1460 swapped = 1 - swapped;
1461- acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);
1462+ acc = SWAP_BYTES_IN_WORD(acc);
1463 }
1464 /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
1465 }
1466
1467 if (swapped) {
1468- acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);
1469+ acc = SWAP_BYTES_IN_WORD(acc);
1470 }
1471 acc += (src->addr & 0xffffUL);
1472 acc += ((src->addr >> 16) & 0xffffUL);
1473@@ -360,9 +370,10 @@ inet_chksum_pseudo_partial(struct pbuf *
1474 acc += (u32_t)htons((u16_t)proto);
1475 acc += (u32_t)htons(proto_len);
1476
1477- while ((acc >> 16) != 0) {
1478- acc = (acc & 0xffffUL) + (acc >> 16);
1479- }
1480+ /* Fold 32-bit sum to 16 bits
1481+ calling this twice is propably faster than if statements... */
1482+ acc = FOLD_U32T(acc);
1483+ acc = FOLD_U32T(acc);
1484 LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));
1485 return (u16_t)~(acc & 0xffffUL);
1486 }
1487@@ -380,13 +391,7 @@ inet_chksum_pseudo_partial(struct pbuf *
1488 u16_t
1489 inet_chksum(void *dataptr, u16_t len)
1490 {
1491- u32_t acc;
1492-
1493- acc = LWIP_CHKSUM(dataptr, len);
1494- while ((acc >> 16) != 0) {
1495- acc = (acc & 0xffff) + (acc >> 16);
1496- }
1497- return (u16_t)~(acc & 0xffff);
1498+ return ~LWIP_CHKSUM(dataptr, len);
1499 }
1500
1501 /**
1502@@ -407,17 +412,15 @@ inet_chksum_pbuf(struct pbuf *p)
1503 swapped = 0;
1504 for(q = p; q != NULL; q = q->next) {
1505 acc += LWIP_CHKSUM(q->payload, q->len);
1506- while ((acc >> 16) != 0) {
1507- acc = (acc & 0xffffUL) + (acc >> 16);
1508- }
1509+ acc = FOLD_U32T(acc);
1510 if (q->len % 2 != 0) {
1511 swapped = 1 - swapped;
1512- acc = (acc & 0x00ffUL << 8) | (acc & 0xff00UL >> 8);
1513+ acc = SWAP_BYTES_IN_WORD(acc);
1514 }
1515 }
1516
1517 if (swapped) {
1518- acc = ((acc & 0x00ffUL) << 8) | ((acc & 0xff00UL) >> 8);
1519+ acc = SWAP_BYTES_IN_WORD(acc);
1520 }
1521 return (u16_t)~(acc & 0xffffUL);
1522 }
1523Index: src/core/ipv4/ip.c
1524===================================================================
1525RCS file: /sources/lwip/lwip/src/core/ipv4/ip.c,v
1526retrieving revision 1.66
1527retrieving revision 1.68
1528diff -u -p -r1.66 -r1.68
1529--- a/src/core/ipv4/ip.c 14 Jan 2008 20:53:23 -0000 1.66
1530+++ b/src/core/ipv4/ip.c 17 Jun 2008 19:39:22 -0000 1.68
1531@@ -531,9 +531,19 @@ ip_output_if(struct pbuf *p, struct ip_a
1532 LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num));
1533 ip_debug_print(p);
1534
1535- LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
1536+#if (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF)
1537+ if (ip_addr_cmp(dest, &netif->ip_addr)) {
1538+ /* Packet to self, enqueue it for loopback */
1539+ LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));
1540+
1541+ return netif_loop_output(netif, p, dest);
1542+ } else
1543+#endif /* (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) */
1544+ {
1545+ LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
1546
1547- return netif->output(netif, p, dest);
1548+ return netif->output(netif, p, dest);
1549+ }
1550 }
1551
1552 /**
1553Index: src/include/lwip/debug.h
1554===================================================================
1555RCS file: /sources/lwip/lwip/src/include/lwip/debug.h,v
1556retrieving revision 1.37
1557retrieving revision 1.39
1558diff -u -p -r1.37 -r1.39
1559--- a/src/include/lwip/debug.h 22 Sep 2007 11:16:07 -0000 1.37
1560+++ b/src/include/lwip/debug.h 16 Jul 2008 20:36:22 -0000 1.39
1561@@ -61,26 +61,28 @@
1562 #define LWIP_DBG_HALT 0x08U
1563
1564 #ifndef LWIP_NOASSERT
1565-#define LWIP_ASSERT(x,y) do { if(!(y)) LWIP_PLATFORM_ASSERT(x); } while(0)
1566+#define LWIP_ASSERT(message, assertion) do { if(!(assertion)) \
1567+ LWIP_PLATFORM_ASSERT(message); } while(0)
1568 #else /* LWIP_NOASSERT */
1569-#define LWIP_ASSERT(x,y)
1570+#define LWIP_ASSERT(message, assertion)
1571 #endif /* LWIP_NOASSERT */
1572
1573-/** print "m" message only if "e" is true, and execute "h" expression */
1574+/** if "expression" isn't true, then print "message" and execute "handler" expression */
1575 #ifndef LWIP_ERROR
1576-#define LWIP_ERROR(m,e,h) do { if (!(e)) { LWIP_PLATFORM_ASSERT(m); h;}} while(0)
1577+#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \
1578+ LWIP_PLATFORM_ASSERT(message); handler;}} while(0)
1579 #endif /* LWIP_ERROR */
1580
1581 #ifdef LWIP_DEBUG
1582 /** print debug message only if debug message type is enabled...
1583 * AND is of correct type AND is at least LWIP_DBG_LEVEL
1584 */
1585-#define LWIP_DEBUGF(debug,x) do { \
1586+#define LWIP_DEBUGF(debug, message) do { \
1587 if ( \
1588 ((debug) & LWIP_DBG_ON) && \
1589 ((debug) & LWIP_DBG_TYPES_ON) && \
1590 ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \
1591- LWIP_PLATFORM_DIAG(x); \
1592+ LWIP_PLATFORM_DIAG(message); \
1593 if ((debug) & LWIP_DBG_HALT) { \
1594 while(1); \
1595 } \
1596@@ -88,7 +90,7 @@
1597 } while(0)
1598
1599 #else /* LWIP_DEBUG */
1600-#define LWIP_DEBUGF(debug,x)
1601+#define LWIP_DEBUGF(debug, message)
1602 #endif /* LWIP_DEBUG */
1603
1604 #endif /* __LWIP_DEBUG_H__ */
1605Index: src/include/lwip/err.h
1606===================================================================
1607RCS file: /sources/lwip/lwip/src/include/lwip/err.h,v
1608retrieving revision 1.13
1609retrieving revision 1.15
1610diff -u -p -r1.13 -r1.15
1611--- a/src/include/lwip/err.h 13 Dec 2007 23:06:50 -0000 1.13
1612+++ b/src/include/lwip/err.h 17 Jun 2008 20:27:32 -0000 1.15
1613@@ -33,37 +33,43 @@
1614 #define __LWIP_ERR_H__
1615
1616 #include "lwip/opt.h"
1617+#include "lwip/arch.h"
1618
1619 #ifdef __cplusplus
1620 extern "C" {
1621 #endif
1622
1623-typedef s8_t err_t;
1624+/** Define LWIP_ERR_T in cc.h if you want to use
1625+ * a different type for your platform (must be signed). */
1626+#ifdef LWIP_ERR_T
1627+typedef LWIP_ERR_T err_t;
1628+#else /* LWIP_ERR_T */
1629+ typedef s8_t err_t;
1630+#endif /* LWIP_ERR_T*/
1631
1632 /* Definitions for error constants. */
1633
1634 #define ERR_OK 0 /* No error, everything OK. */
1635 #define ERR_MEM -1 /* Out of memory error. */
1636 #define ERR_BUF -2 /* Buffer error. */
1637-#define ERR_RTE -3 /* Routing problem. */
1638+#define ERR_TIMEOUT -3 /* Timeout. */
1639+#define ERR_RTE -4 /* Routing problem. */
1640
1641 #define ERR_IS_FATAL(e) ((e) < ERR_RTE)
1642
1643-#define ERR_ABRT -4 /* Connection aborted. */
1644-#define ERR_RST -5 /* Connection reset. */
1645-#define ERR_CLSD -6 /* Connection closed. */
1646-#define ERR_CONN -7 /* Not connected. */
1647+#define ERR_ABRT -5 /* Connection aborted. */
1648+#define ERR_RST -6 /* Connection reset. */
1649+#define ERR_CLSD -7 /* Connection closed. */
1650+#define ERR_CONN -8 /* Not connected. */
1651
1652-#define ERR_VAL -8 /* Illegal value. */
1653+#define ERR_VAL -9 /* Illegal value. */
1654
1655-#define ERR_ARG -9 /* Illegal argument. */
1656+#define ERR_ARG -10 /* Illegal argument. */
1657
1658-#define ERR_USE -10 /* Address in use. */
1659+#define ERR_USE -11 /* Address in use. */
1660
1661-#define ERR_IF -11 /* Low-level netif error */
1662-#define ERR_ISCONN -12 /* Already connected. */
1663-
1664-#define ERR_TIMEOUT -13 /* Timeout. */
1665+#define ERR_IF -12 /* Low-level netif error */
1666+#define ERR_ISCONN -13 /* Already connected. */
1667
1668 #define ERR_INPROGRESS -14 /* Operation in progress */
1669
1670Index: src/include/lwip/mem.h
1671===================================================================
1672RCS file: /sources/lwip/lwip/src/include/lwip/mem.h,v
1673retrieving revision 1.21
1674retrieving revision 1.22
1675diff -u -p -r1.21 -r1.22
1676--- a/src/include/lwip/mem.h 4 Mar 2008 16:31:32 -0000 1.21
1677+++ b/src/include/lwip/mem.h 30 May 2008 11:37:15 -0000 1.22
1678@@ -50,16 +50,16 @@ typedef size_t mem_size_t;
1679 * allow these defines to be overridden.
1680 */
1681 #ifndef mem_free
1682-#define mem_free(x) free(x)
1683+#define mem_free free
1684 #endif
1685 #ifndef mem_malloc
1686-#define mem_malloc(x) malloc(x)
1687+#define mem_malloc malloc
1688 #endif
1689 #ifndef mem_calloc
1690-#define mem_calloc(x, y) calloc(x, y)
1691+#define mem_calloc calloc
1692 #endif
1693 #ifndef mem_realloc
1694-#define mem_realloc(x, size) (x)
1695+#define mem_realloc realloc
1696 #endif
1697 #else /* MEM_LIBC_MALLOC */
1698
1699Index: src/include/lwip/netif.h
1700===================================================================
1701RCS file: /sources/lwip/lwip/src/include/lwip/netif.h,v
1702retrieving revision 1.43
1703retrieving revision 1.46
1704diff -u -p -r1.43 -r1.46
1705--- a/src/include/lwip/netif.h 9 Oct 2007 19:59:59 -0000 1.43
1706+++ b/src/include/lwip/netif.h 19 Jun 2008 16:27:23 -0000 1.46
1707@@ -34,6 +34,8 @@
1708
1709 #include "lwip/opt.h"
1710
1711+#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF)
1712+
1713 #include "lwip/err.h"
1714
1715 #include "lwip/ip_addr.h"
1716@@ -165,6 +167,14 @@ struct netif {
1717 #if LWIP_NETIF_HWADDRHINT
1718 u8_t *addr_hint;
1719 #endif /* LWIP_NETIF_HWADDRHINT */
1720+#if ENABLE_LOOPBACK
1721+ /* List of packets to be queued for ourselves. */
1722+ struct pbuf *loop_first;
1723+ struct pbuf *loop_last;
1724+#if LWIP_LOOPBACK_MAX_PBUFS
1725+ u16_t loop_cnt_current;
1726+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
1727+#endif /* ENABLE_LOOPBACK */
1728 };
1729
1730 #if LWIP_SNMP
1731@@ -242,4 +252,12 @@ void netif_set_link_callback(struct neti
1732 }
1733 #endif
1734
1735+#if ENABLE_LOOPBACK
1736+err_t netif_loop_output(struct netif *netif, struct pbuf *p, struct ip_addr *dest_ip);
1737+void netif_poll(struct netif *netif);
1738+#if !LWIP_NETIF_LOOPBACK_MULTITHREADING
1739+void netif_poll_all(void);
1740+#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */
1741+#endif /* ENABLE_LOOPBACK */
1742+
1743 #endif /* __LWIP_NETIF_H__ */
1744Index: src/include/lwip/opt.h
1745===================================================================
1746RCS file: /sources/lwip/lwip/src/include/lwip/opt.h,v
1747retrieving revision 1.116
1748retrieving revision 1.122
1749diff -u -p -r1.116 -r1.122
1750--- a/src/include/lwip/opt.h 31 Jan 2008 18:19:29 -0000 1.116
1751+++ b/src/include/lwip/opt.h 30 Jun 2008 18:16:52 -0000 1.122
1752@@ -155,6 +155,27 @@
1753 #define MEMP_USE_CUSTOM_POOLS 0
1754 #endif
1755
1756+/**
1757+ * Set this to 1 if you want to free PBUF_RAM pbufs (or call mem_free()) from
1758+ * interrupt context (or another context that doesn't allow waiting for a
1759+ * semaphore).
1760+ * If set to 1, mem_malloc will be protected by a semaphore and SYS_ARCH_PROTECT,
1761+ * while mem_free will only use SYS_ARCH_PROTECT. mem_malloc SYS_ARCH_UNPROTECTs
1762+ * with each loop so that mem_free can run.
1763+ *
1764+ * ATTENTION: As you can see from the above description, this leads to dis-/
1765+ * enabling interrupts often, which can be slow! Also, on low memory, mem_malloc
1766+ * can need longer.
1767+ *
1768+ * If you don't want that, at least for NO_SYS=0, you can still use the following
1769+ * functions to enqueue a deallocation call which then runs in the tcpip_thread
1770+ * context:
1771+ * - pbuf_free_callback(p);
1772+ * - mem_free_callback(m);
1773+ */
1774+#ifndef LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
1775+#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0
1776+#endif
1777
1778 /*
1779 ------------------------------------------------
1780@@ -815,6 +836,39 @@
1781 #define LWIP_NETIF_HWADDRHINT 0
1782 #endif
1783
1784+/**
1785+ * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP
1786+ * address equal to the netif IP address, looping them back up the stack.
1787+ */
1788+#ifndef LWIP_NETIF_LOOPBACK
1789+#define LWIP_NETIF_LOOPBACK 0
1790+#endif
1791+
1792+/**
1793+ * LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback
1794+ * sending for each netif (0 = disabled)
1795+ */
1796+#ifndef LWIP_LOOPBACK_MAX_PBUFS
1797+#define LWIP_LOOPBACK_MAX_PBUFS 0
1798+#endif
1799+
1800+/**
1801+ * LWIP_NETIF_LOOPBACK_MULTITHREADING: Indicates whether threading is enabled in
1802+ * the system, as netifs must change how they behave depending on this setting
1803+ * for the LWIP_NETIF_LOOPBACK option to work.
1804+ * Setting this is needed to avoid reentering non-reentrant functions like
1805+ * tcp_input().
1806+ * LWIP_NETIF_LOOPBACK_MULTITHREADING==1: Indicates that the user is using a
1807+ * multithreaded environment like tcpip.c. In this case, netif->input()
1808+ * is called directly.
1809+ * LWIP_NETIF_LOOPBACK_MULTITHREADING==0: Indicates a polling (or NO_SYS) setup.
1810+ * The packets are put on a list and netif_poll() must be called in
1811+ * the main application loop.
1812+ */
1813+#ifndef LWIP_NETIF_LOOPBACK_MULTITHREADING
1814+#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS)
1815+#endif
1816+
1817 /*
1818 ------------------------------------
1819 ---------- LOOPIF options ----------
1820@@ -827,20 +881,16 @@
1821 #define LWIP_HAVE_LOOPIF 0
1822 #endif
1823
1824+/*
1825+ ------------------------------------
1826+ ---------- SLIPIF options ----------
1827+ ------------------------------------
1828+*/
1829 /**
1830- * LWIP_LOOPIF_MULTITHREADING: Indicates whether threading is enabled in
1831- * the system, as LOOPIF must change how it behaves depending on this setting.
1832- * Setting this is needed to avoid reentering non-reentrant functions like
1833- * tcp_input().
1834- * LWIP_LOOPIF_MULTITHREADING==1: Indicates that the user is using a
1835- * multithreaded environment like tcpip.c. In this case, netif->input()
1836- * is called directly.
1837- * LWIP_LOOPIF_MULTITHREADING==0: Indicates a polling (or NO_SYS) setup.
1838- * The packets are put on a list and loopif_poll() must be called in
1839- * the main application loop.
1840+ * LWIP_HAVE_SLIPIF==1: Support slip interface and slipif.c
1841 */
1842-#ifndef LWIP_LOOPIF_MULTITHREADING
1843-#define LWIP_LOOPIF_MULTITHREADING 1
1844+#ifndef LWIP_HAVE_SLIPIF
1845+#define LWIP_HAVE_SLIPIF 0
1846 #endif
1847
1848 /*
1849Index: src/include/lwip/sio.h
1850===================================================================
1851RCS file: /sources/lwip/lwip/src/include/lwip/sio.h,v
1852retrieving revision 1.7
1853retrieving revision 1.8
1854diff -u -p -r1.7 -r1.8
1855--- a/src/include/lwip/sio.h 6 Sep 2007 16:43:44 -0000 1.7
1856+++ b/src/include/lwip/sio.h 27 Mar 2008 18:06:02 -0000 1.8
1857@@ -32,16 +32,24 @@
1858 * It needs to be implemented by those platforms which need SLIP or PPP
1859 */
1860
1861+#ifndef __SIO_H__
1862+#define __SIO_H__
1863+
1864 #include "lwip/arch.h"
1865
1866 #ifdef __cplusplus
1867 extern "C" {
1868 #endif
1869
1870+/* If you want to define sio_fd_t elsewhere or differently,
1871+ define this in your cc.h file. */
1872 #ifndef __sio_fd_t_defined
1873 typedef void * sio_fd_t;
1874 #endif
1875
1876+/* The following functions can be defined to something else in your cc.h file
1877+ or be implemented in your custom sio.c file. */
1878+
1879 #ifndef sio_open
1880 sio_fd_t sio_open(u8_t);
1881 #endif
1882@@ -69,3 +77,5 @@ void sio_read_abort(sio_fd_t);
1883 #ifdef __cplusplus
1884 }
1885 #endif
1886+
1887+#endif /* __SIO_H__ */
1888Index: src/include/lwip/sockets.h
1889===================================================================
1890RCS file: /sources/lwip/lwip/src/include/lwip/sockets.h,v
1891retrieving revision 1.38
1892retrieving revision 1.39
1893diff -u -p -r1.38 -r1.39
1894--- a/src/include/lwip/sockets.h 2 Dec 2007 15:24:02 -0000 1.38
1895+++ b/src/include/lwip/sockets.h 26 Apr 2008 10:46:23 -0000 1.39
1896@@ -177,7 +177,22 @@ typedef struct ip_mreq {
1897 } ip_mreq;
1898 #endif /* LWIP_IGMP */
1899
1900-/* Unimplemented for now... */
1901+/*
1902+ * The Type of Service provides an indication of the abstract
1903+ * parameters of the quality of service desired. These parameters are
1904+ * to be used to guide the selection of the actual service parameters
1905+ * when transmitting a datagram through a particular network. Several
1906+ * networks offer service precedence, which somehow treats high
1907+ * precedence traffic as more important than other traffic (generally
1908+ * by accepting only traffic above a certain precedence at time of high
1909+ * load). The major choice is a three way tradeoff between low-delay,
1910+ * high-reliability, and high-throughput.
1911+ * The use of the Delay, Throughput, and Reliability indications may
1912+ * increase the cost (in some sense) of the service. In many networks
1913+ * better performance for one of these parameters is coupled with worse
1914+ * performance on another. Except for very unusual cases at most two
1915+ * of these three indications should be set.
1916+ */
1917 #define IPTOS_TOS_MASK 0x1E
1918 #define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK)
1919 #define IPTOS_LOWDELAY 0x10
1920@@ -187,7 +202,13 @@ typedef struct ip_mreq {
1921 #define IPTOS_MINCOST IPTOS_LOWCOST
1922
1923 /*
1924- * Definitions for IP precedence (also in ip_tos) (Unimplemented)
1925+ * The Network Control precedence designation is intended to be used
1926+ * within a network only. The actual use and control of that
1927+ * designation is up to each network. The Internetwork Control
1928+ * designation is intended for use by gateway control originators only.
1929+ * If the actual use of these precedence designations is of concern to
1930+ * a particular network, it is the responsibility of that network to
1931+ * control the access to, and use of, those precedence designations.
1932 */
1933 #define IPTOS_PREC_MASK 0xe0
1934 #define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK)
1935Index: src/include/lwip/stats.h
1936===================================================================
1937RCS file: /sources/lwip/lwip/src/include/lwip/stats.h,v
1938retrieving revision 1.19
1939retrieving revision 1.23
1940diff -u -p -r1.19 -r1.23
1941--- a/src/include/lwip/stats.h 28 Nov 2007 21:25:07 -0000 1.19
1942+++ b/src/include/lwip/stats.h 8 Jul 2008 09:15:57 -0000 1.23
1943@@ -57,7 +57,6 @@ extern "C" {
1944
1945 struct stats_proto {
1946 STAT_COUNTER xmit; /* Transmitted packets. */
1947- STAT_COUNTER rexmit; /* Retransmitted packets. */
1948 STAT_COUNTER recv; /* Received packets. */
1949 STAT_COUNTER fw; /* Forwarded packets. */
1950 STAT_COUNTER drop; /* Dropped packets. */
1951@@ -87,7 +86,8 @@ struct stats_mem {
1952 mem_size_t avail;
1953 mem_size_t used;
1954 mem_size_t max;
1955- mem_size_t err;
1956+ STAT_COUNTER err;
1957+ STAT_COUNTER illegal;
1958 };
1959
1960 struct stats_syselem {
1961@@ -142,64 +142,138 @@ extern struct stats_ lwip_stats;
1962 #define stats_init() /* Compatibility define, not init needed. */
1963
1964 #define STATS_INC(x) ++lwip_stats.x
1965+#define STATS_DEC(x) --lwip_stats.x
1966 #else
1967 #define stats_init()
1968 #define STATS_INC(x)
1969+#define STATS_DEC(x)
1970 #endif /* LWIP_STATS */
1971
1972 #if TCP_STATS
1973 #define TCP_STATS_INC(x) STATS_INC(x)
1974+#define TCP_STATS_DISPLAY() stats_display_proto(&lwip_stats.tcp, "TCP")
1975 #else
1976 #define TCP_STATS_INC(x)
1977+#define TCP_STATS_DISPLAY()
1978 #endif
1979
1980 #if UDP_STATS
1981 #define UDP_STATS_INC(x) STATS_INC(x)
1982+#define UDP_STATS_DISPLAY() stats_display_proto(&lwip_stats.udp, "UDP")
1983 #else
1984 #define UDP_STATS_INC(x)
1985+#define UDP_STATS_DISPLAY()
1986 #endif
1987
1988 #if ICMP_STATS
1989 #define ICMP_STATS_INC(x) STATS_INC(x)
1990+#define ICMP_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp, "ICMP")
1991 #else
1992 #define ICMP_STATS_INC(x)
1993+#define ICMP_STATS_DISPLAY()
1994 #endif
1995
1996 #if IGMP_STATS
1997 #define IGMP_STATS_INC(x) STATS_INC(x)
1998+#define IGMP_STATS_DISPLAY() stats_display_igmp(&lwip_stats.igmp)
1999 #else
2000 #define IGMP_STATS_INC(x)
2001+#define IGMP_STATS_DISPLAY()
2002 #endif
2003
2004 #if IP_STATS
2005 #define IP_STATS_INC(x) STATS_INC(x)
2006+#define IP_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip, "IP")
2007 #else
2008 #define IP_STATS_INC(x)
2009+#define IP_STATS_DISPLAY()
2010 #endif
2011
2012 #if IPFRAG_STATS
2013 #define IPFRAG_STATS_INC(x) STATS_INC(x)
2014+#define IPFRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG")
2015 #else
2016 #define IPFRAG_STATS_INC(x)
2017+#define IPFRAG_STATS_DISPLAY()
2018 #endif
2019
2020 #if ETHARP_STATS
2021 #define ETHARP_STATS_INC(x) STATS_INC(x)
2022+#define ETHARP_STATS_DISPLAY() stats_display_proto(&lwip_stats.etharp, "ETHARP")
2023 #else
2024 #define ETHARP_STATS_INC(x)
2025+#define ETHARP_STATS_DISPLAY()
2026 #endif
2027
2028 #if LINK_STATS
2029 #define LINK_STATS_INC(x) STATS_INC(x)
2030+#define LINK_STATS_DISPLAY() stats_display_proto(&lwip_stats.link, "LINK")
2031 #else
2032 #define LINK_STATS_INC(x)
2033+#define LINK_STATS_DISPLAY()
2034+#endif
2035+
2036+#if MEM_STATS
2037+#define MEM_STATS_AVAIL(x, y) lwip_stats.mem.x = y
2038+#define MEM_STATS_INC(x) STATS_INC(mem.x)
2039+#define MEM_STATS_INC_USED(x, y) do { lwip_stats.mem.used += y; \
2040+ if (lwip_stats.mem.max < lwip_stats.mem.used) { \
2041+ lwip_stats.mem.max = lwip_stats.mem.used; \
2042+ } \
2043+ } while(0)
2044+#define MEM_STATS_DEC_USED(x, y) lwip_stats.mem.x -= y
2045+#define MEM_STATS_DISPLAY() stats_display_mem(&lwip_stats.mem, "HEAP")
2046+#else
2047+#define MEM_STATS_AVAIL(x, y)
2048+#define MEM_STATS_INC(x)
2049+#define MEM_STATS_INC_USED(x, y)
2050+#define MEM_STATS_DEC_USED(x, y)
2051+#define MEM_STATS_DISPLAY()
2052+#endif
2053+
2054+#if MEMP_STATS
2055+#define MEMP_STATS_AVAIL(x, i, y) lwip_stats.memp[i].x = y
2056+#define MEMP_STATS_INC(x, i) STATS_INC(memp[i].x)
2057+#define MEMP_STATS_DEC(x, i) STATS_DEC(memp[i].x)
2058+#define MEMP_STATS_INC_USED(x, i) do { ++lwip_stats.memp[i].used; \
2059+ if (lwip_stats.memp[i].max < lwip_stats.memp[i].used) { \
2060+ lwip_stats.memp[i].max = lwip_stats.memp[i].used; \
2061+ } \
2062+ } while(0)
2063+#define MEMP_STATS_DISPLAY(i) stats_display_memp(&lwip_stats.memp[i], i)
2064+#else
2065+#define MEMP_STATS_AVAIL(x, i, y)
2066+#define MEMP_STATS_INC(x, i)
2067+#define MEMP_STATS_DEC(x, i)
2068+#define MEMP_STATS_INC_USED(x, i)
2069+#define MEMP_STATS_DISPLAY(i)
2070+#endif
2071+
2072+#if SYS_STATS
2073+#define SYS_STATS_INC(x) STATS_INC(sys.x)
2074+#define SYS_STATS_DEC(x) STATS_DEC(sys.x)
2075+#define SYS_STATS_DISPLAY() stats_display_sys(&lwip_stats.sys)
2076+#else
2077+#define SYS_STATS_INC(x)
2078+#define SYS_STATS_DEC(x)
2079+#define SYS_STATS_DISPLAY()
2080 #endif
2081
2082 /* Display of statistics */
2083 #if LWIP_STATS_DISPLAY
2084 void stats_display(void);
2085+void stats_display_proto(struct stats_proto *proto, char *name);
2086+void stats_display_igmp(struct stats_igmp *igmp);
2087+void stats_display_mem(struct stats_mem *mem, char *name);
2088+void stats_display_memp(struct stats_mem *mem, int index);
2089+void stats_display_sys(struct stats_sys *sys);
2090 #else
2091 #define stats_display()
2092+#define stats_display_proto(proto, name)
2093+#define stats_display_igmp(igmp)
2094+#define stats_display_mem(mem, name)
2095+#define stats_display_memp(mem, index)
2096+#define stats_display_sys(sys)
2097 #endif /* LWIP_STATS_DISPLAY */
2098
2099 #ifdef __cplusplus
2100Index: src/include/lwip/tcpip.h
2101===================================================================
2102RCS file: /sources/lwip/lwip/src/include/lwip/tcpip.h,v
2103retrieving revision 1.24
2104retrieving revision 1.27
2105diff -u -p -r1.24 -r1.27
2106--- a/src/include/lwip/tcpip.h 12 Jan 2008 11:52:22 -0000 1.24
2107+++ b/src/include/lwip/tcpip.h 27 Jun 2008 20:34:55 -0000 1.27
2108@@ -83,7 +83,11 @@ err_t tcpip_netifapi_lock(struct netifap
2109 #endif /* LWIP_NETIF_API */
2110
2111 err_t tcpip_callback_with_block(void (*f)(void *ctx), void *ctx, u8_t block);
2112-#define tcpip_callback(f,ctx) tcpip_callback_with_block(f,ctx,1)
2113+#define tcpip_callback(f, ctx) tcpip_callback_with_block(f, ctx, 1)
2114+
2115+/* free pbufs or heap memory from another context without blocking */
2116+err_t pbuf_free_callback(struct pbuf *p);
2117+err_t mem_free_callback(void *m);
2118
2119 err_t tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg);
2120 #define tcpip_untimeout(h, arg) tcpip_timeout(0xffffffff, h, arg)
2121Index: src/include/netif/loopif.h
2122===================================================================
2123RCS file: /sources/lwip/lwip/src/include/netif/loopif.h,v
2124retrieving revision 1.7
2125retrieving revision 1.9
2126diff -u -p -r1.7 -r1.9
2127--- a/src/include/netif/loopif.h 10 May 2007 10:59:20 -0000 1.7
2128+++ b/src/include/netif/loopif.h 17 Jun 2008 20:12:22 -0000 1.9
2129@@ -32,6 +32,7 @@
2130 #ifndef __NETIF_LOOPIF_H__
2131 #define __NETIF_LOOPIF_H__
2132
2133+#include "lwip/opt.h"
2134 #include "lwip/netif.h"
2135 #include "lwip/err.h"
2136
2137@@ -39,9 +40,9 @@
2138 extern "C" {
2139 #endif
2140
2141-#if !LWIP_LOOPIF_MULTITHREADING
2142-void loopif_poll(struct netif *netif);
2143-#endif
2144+#if !LWIP_NETIF_LOOPBACK_MULTITHREADING
2145+#define loopif_poll netif_poll
2146+#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */
2147
2148 err_t loopif_init(struct netif *netif);
2149
2150Index: src/netif/etharp.c
2151===================================================================
2152RCS file: /sources/lwip/lwip/src/netif/etharp.c,v
2153retrieving revision 1.145
2154retrieving revision 1.148
2155diff -u -p -r1.145 -r1.148
2156--- a/src/netif/etharp.c 4 Mar 2008 13:41:24 -0000 1.145
2157+++ b/src/netif/etharp.c 19 Jun 2008 16:40:59 -0000 1.148
2158@@ -353,7 +353,7 @@ find_entry(struct ip_addr *ipaddr, u8_t
2159 * 1) empty entry
2160 * 2) oldest stable entry
2161 * 3) oldest pending entry without queued packets
2162- * 4) oldest pending entry without queued packets
2163+ * 4) oldest pending entry with queued packets
2164 *
2165 * { ETHARP_TRY_HARD is set at this point }
2166 */
2167@@ -1130,7 +1130,14 @@ ethernet_input(struct pbuf *p, struct ne
2168
2169 /* points to packet payload, which starts with an Ethernet header */
2170 ethhdr = p->payload;
2171-
2172+ LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
2173+ ("ethernet_input: dest:%02x:%02x:%02x:%02x:%02x:%02x, src:%02x:%02x:%02x:%02x:%02x:%02x, type:%2hx\n",
2174+ (unsigned)ethhdr->dest.addr[0], (unsigned)ethhdr->dest.addr[1], (unsigned)ethhdr->dest.addr[2],
2175+ (unsigned)ethhdr->dest.addr[3], (unsigned)ethhdr->dest.addr[4], (unsigned)ethhdr->dest.addr[5],
2176+ (unsigned)ethhdr->src.addr[0], (unsigned)ethhdr->src.addr[1], (unsigned)ethhdr->src.addr[2],
2177+ (unsigned)ethhdr->src.addr[3], (unsigned)ethhdr->src.addr[4], (unsigned)ethhdr->src.addr[5],
2178+ (unsigned)htons(ethhdr->type)));
2179+
2180 switch (htons(ethhdr->type)) {
2181 /* IP packet? */
2182 case ETHTYPE_IP:
2183@@ -1165,6 +1172,8 @@ ethernet_input(struct pbuf *p, struct ne
2184 #endif /* PPPOE_SUPPORT */
2185
2186 default:
2187+ ETHARP_STATS_INC(etharp.proterr);
2188+ ETHARP_STATS_INC(etharp.drop);
2189 pbuf_free(p);
2190 p = NULL;
2191 break;
2192Index: src/netif/loopif.c
2193===================================================================
2194RCS file: /sources/lwip/lwip/src/netif/loopif.c,v
2195retrieving revision 1.26
2196retrieving revision 1.27
2197diff -u -p -r1.26 -r1.27
2198--- a/src/netif/loopif.c 31 Aug 2007 10:14:09 -0000 1.26
2199+++ b/src/netif/loopif.c 12 Jun 2008 20:10:10 -0000 1.27
2200@@ -40,149 +40,8 @@
2201 #if LWIP_HAVE_LOOPIF
2202
2203 #include "netif/loopif.h"
2204-#include "lwip/pbuf.h"
2205 #include "lwip/snmp.h"
2206
2207-#include <string.h>
2208-
2209-#if !LWIP_LOOPIF_MULTITHREADING
2210-
2211-#include "lwip/sys.h"
2212-#include "lwip/mem.h"
2213-
2214-/* helper struct for the linked list of pbufs */
2215-struct loopif_private {
2216- struct pbuf *first;
2217- struct pbuf *last;
2218-};
2219-
2220-/**
2221- * Call loopif_poll() in the main loop of your application. This is to prevent
2222- * reentering non-reentrant functions like tcp_input(). Packets passed to
2223- * loopif_output() are put on a list that is passed to netif->input() by
2224- * loopif_poll().
2225- *
2226- * @param netif the lwip network interface structure for this loopif
2227- */
2228-void
2229-loopif_poll(struct netif *netif)
2230-{
2231- SYS_ARCH_DECL_PROTECT(lev);
2232- struct pbuf *in, *in_end;
2233- struct loopif_private *priv = (struct loopif_private*)netif->state;
2234-
2235- LWIP_ERROR("priv != NULL", (priv != NULL), return;);
2236-
2237- do {
2238- /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */
2239- SYS_ARCH_PROTECT(lev);
2240- in = priv->first;
2241- if(in) {
2242- in_end = in;
2243- while(in_end->len != in_end->tot_len) {
2244- LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL);
2245- in_end = in_end->next;
2246- }
2247- /* 'in_end' now points to the last pbuf from 'in' */
2248- if(in_end == priv->last) {
2249- /* this was the last pbuf in the list */
2250- priv->first = priv->last = NULL;
2251- } else {
2252- /* pop the pbuf off the list */
2253- priv->first = in_end->next;
2254- LWIP_ASSERT("should not be null since first != last!", priv->first != NULL);
2255- }
2256- }
2257- SYS_ARCH_UNPROTECT(lev);
2258-
2259- if(in != NULL) {
2260- if(in_end->next != NULL) {
2261- /* De-queue the pbuf from its successors on the 'priv' list. */
2262- in_end->next = NULL;
2263- }
2264- if(netif->input(in, netif) != ERR_OK) {
2265- pbuf_free(in);
2266- }
2267- /* Don't reference the packet any more! */
2268- in = NULL;
2269- in_end = NULL;
2270- }
2271- /* go on while there is a packet on the list */
2272- } while(priv->first != NULL);
2273-}
2274-#endif /* LWIP_LOOPIF_MULTITHREADING */
2275-
2276-/**
2277- * Send an IP packet over the loopback interface.
2278- * The pbuf is simply copied and handed back to netif->input.
2279- * In multithreaded mode, this is done directly since netif->input must put
2280- * the packet on a queue.
2281- * In callback mode, the packet is put on an internal queue and is fed to
2282- * netif->input by loopif_poll().
2283- *
2284- * @param netif the lwip network interface structure for this loopif
2285- * @param p the (IP) packet to 'send'
2286- * @param ipaddr the ip address to send the packet to (not used for loopif)
2287- * @return ERR_OK if the packet has been sent
2288- * ERR_MEM if the pbuf used to copy the packet couldn't be allocated
2289- */
2290-static err_t
2291-loopif_output(struct netif *netif, struct pbuf *p,
2292- struct ip_addr *ipaddr)
2293-{
2294-#if !LWIP_LOOPIF_MULTITHREADING
2295- SYS_ARCH_DECL_PROTECT(lev);
2296- struct loopif_private *priv;
2297- struct pbuf *last;
2298-#endif /* LWIP_LOOPIF_MULTITHREADING */
2299- struct pbuf *r;
2300- err_t err;
2301-
2302- LWIP_UNUSED_ARG(ipaddr);
2303-
2304- /* Allocate a new pbuf */
2305- r = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
2306- if (r == NULL) {
2307- return ERR_MEM;
2308- }
2309-
2310- /* Copy the whole pbuf queue p into the single pbuf r */
2311- if ((err = pbuf_copy(r, p)) != ERR_OK) {
2312- pbuf_free(r);
2313- r = NULL;
2314- return err;
2315- }
2316-
2317-#if LWIP_LOOPIF_MULTITHREADING
2318- /* Multithreading environment, netif->input() is supposed to put the packet
2319- into a mailbox, so we can safely call it here without risking to re-enter
2320- functions that are not reentrant (TCP!!!) */
2321- if(netif->input(r, netif) != ERR_OK) {
2322- pbuf_free(r);
2323- r = NULL;
2324- }
2325-#else /* LWIP_LOOPIF_MULTITHREADING */
2326- /* Raw API without threads: put the packet on a linked list which gets emptied
2327- through calling loopif_poll(). */
2328- priv = (struct loopif_private*)netif->state;
2329-
2330- /* let last point to the last pbuf in chain r */
2331- for (last = r; last->next != NULL; last = last->next);
2332- SYS_ARCH_PROTECT(lev);
2333- if(priv->first != NULL) {
2334- LWIP_ASSERT("if first != NULL, last must also be != NULL", priv->last != NULL);
2335- priv->last->next = r;
2336- priv->last = last;
2337- } else {
2338- priv->first = r;
2339- priv->last = last;
2340- }
2341- SYS_ARCH_UNPROTECT(lev);
2342-#endif /* LWIP_LOOPIF_MULTITHREADING */
2343-
2344- return ERR_OK;
2345-}
2346-
2347 /**
2348 * Initialize a lwip network interface structure for a loopback interface
2349 *
2350@@ -193,16 +52,6 @@ loopif_output(struct netif *netif, struc
2351 err_t
2352 loopif_init(struct netif *netif)
2353 {
2354-#if !LWIP_LOOPIF_MULTITHREADING
2355- struct loopif_private *priv;
2356-
2357- priv = (struct loopif_private*)mem_malloc(sizeof(struct loopif_private));
2358- if(priv == NULL)
2359- return ERR_MEM;
2360- priv->first = priv->last = NULL;
2361- netif->state = priv;
2362-#endif /* LWIP_LOOPIF_MULTITHREADING */
2363-
2364 /* initialize the snmp variables and counters inside the struct netif
2365 * ifSpeed: no assumption can be made!
2366 */
2367@@ -210,7 +59,7 @@ loopif_init(struct netif *netif)
2368
2369 netif->name[0] = 'l';
2370 netif->name[1] = 'o';
2371- netif->output = loopif_output;
2372+ netif->output = netif_loop_output;
2373 return ERR_OK;
2374 }
2375
2376Index: src/netif/slipif.c
2377===================================================================
2378RCS file: /sources/lwip/lwip/src/netif/slipif.c,v
2379retrieving revision 1.29
2380retrieving revision 1.30
2381diff -u -p -r1.29 -r1.30
2382--- a/src/netif/slipif.c 30 Nov 2007 17:22:21 -0000 1.29
2383+++ b/src/netif/slipif.c 17 Jun 2008 20:14:05 -0000 1.30
2384@@ -44,6 +44,9 @@
2385
2386 #include "netif/slipif.h"
2387 #include "lwip/opt.h"
2388+
2389+#if LWIP_HAVE_SLIPIF
2390+
2391 #include "lwip/def.h"
2392 #include "lwip/pbuf.h"
2393 #include "lwip/sys.h"
2394@@ -273,3 +276,4 @@ slipif_init(struct netif *netif)
2395 sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop, netif, SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO);
2396 return ERR_OK;
2397 }
2398+#endif /* LWIP_HAVE_SLIPIF */