ia64/xen-unstable

view stubdom/lwip.patch-cvs @ 19828:180ae4bca33e

VT-d: don't disable VT-d engine in suspend for security purpose

force_iommu option is used to force enabling and using IOMMU for
security purpose. So when force_iommu is set, it shouldn't disable
VT-d engines in suspend.

Signed-off-by: Weidong Han <weidong.han@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Jun 24 11:15:31 2009 +0100 (2009-06-24)
parents a8603b2fb786
children
line source
1 ? .ChangeLog.swp
2 ? ChangeLog
3 Index: CHANGELOG
4 ===================================================================
5 RCS file: /sources/lwip/lwip/CHANGELOG,v
6 retrieving revision 1.300
7 retrieving revision 1.318
8 diff -u -p -r1.300 -r1.318
9 --- CHANGELOG 23 Mar 2008 13:49:39 -0000 1.300
10 +++ CHANGELOG 14 Jul 2008 20:12:36 -0000 1.318
11 @@ -19,9 +19,77 @@ HISTORY
13 ++ New features:
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 +
41 ++ Bugfixes:
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 +
87 (STABLE-1.3.0)
89 Index: src/api/api_msg.c
90 ===================================================================
91 RCS file: /sources/lwip/lwip/src/api/api_msg.c,v
92 retrieving revision 1.102
93 retrieving revision 1.104
94 diff -u -p -r1.102 -r1.104
95 --- src/api/api_msg.c 21 Mar 2008 16:23:14 -0000 1.102
96 +++ 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));
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 */
142 Index: src/api/err.c
143 ===================================================================
144 RCS file: /sources/lwip/lwip/src/api/err.c,v
145 retrieving revision 1.11
146 retrieving revision 1.12
147 diff -u -p -r1.11 -r1.12
148 --- src/api/err.c 13 Dec 2007 23:06:50 -0000 1.11
149 +++ 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 };
179 Index: src/api/netdb.c
180 ===================================================================
181 RCS file: /sources/lwip/lwip/src/api/netdb.c,v
182 retrieving revision 1.4
183 retrieving revision 1.5
184 diff -u -p -r1.4 -r1.5
185 --- src/api/netdb.c 26 Jan 2008 16:11:39 -0000 1.4
186 +++ 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 }
197 Index: src/api/sockets.c
198 ===================================================================
199 RCS file: /sources/lwip/lwip/src/api/sockets.c,v
200 retrieving revision 1.116
201 retrieving revision 1.117
202 diff -u -p -r1.116 -r1.117
203 --- src/api/sockets.c 13 Mar 2008 20:03:57 -0000 1.116
204 +++ 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 };
234 Index: src/api/tcpip.c
235 ===================================================================
236 RCS file: /sources/lwip/lwip/src/api/tcpip.c,v
237 retrieving revision 1.70
238 retrieving revision 1.73
239 diff -u -p -r1.70 -r1.73
240 --- src/api/tcpip.c 12 Jan 2008 11:52:22 -0000 1.70
241 +++ 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 }
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 */
285 Index: src/core/dhcp.c
286 ===================================================================
287 RCS file: /sources/lwip/lwip/src/core/dhcp.c,v
288 retrieving revision 1.86
289 retrieving revision 1.87
290 diff -u -p -r1.86 -r1.87
291 --- src/core/dhcp.c 4 Mar 2008 14:25:58 -0000 1.86
292 +++ 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;
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;
317 LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | 3, ("dhcp_stop()\n"));
318 /* netif is DHCP configured? */
319 Index: src/core/mem.c
320 ===================================================================
321 RCS file: /sources/lwip/lwip/src/core/mem.c,v
322 retrieving revision 1.59
323 retrieving revision 1.62
324 diff -u -p -r1.59 -r1.62
325 --- src/core/mem.c 4 Mar 2008 16:31:32 -0000 1.59
326 +++ 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;
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;
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 }
374 /**
375 @@ -270,6 +295,7 @@ void
376 mem_free(void *rmem)
377 {
378 struct mem *mem;
379 + LWIP_MEM_FREE_DECL_PROTECT();
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);
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);
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 }
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));
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 }
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();
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);
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 }
464 /* protect the heap from concurrent access */
465 - sys_arch_sem_wait(mem_sem, 0);
466 + LWIP_MEM_FREE_PROTECT();
468 -#if MEM_STATS
469 - lwip_stats.mem.used -= (size - newsize);
470 -#endif /* MEM_STATS */
471 + MEM_STATS_DEC_USED(used, (size - newsize));
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 }
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();
496 if (size == 0) {
497 return NULL;
498 @@ -464,88 +505,101 @@ mem_malloc(mem_size_t size)
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 */
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 - }
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);
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 }
675 Index: src/core/memp.c
676 ===================================================================
677 RCS file: /sources/lwip/lwip/src/core/memp.c,v
678 retrieving revision 1.55
679 retrieving revision 1.56
680 diff -u -p -r1.55 -r1.56
681 --- src/core/memp.c 25 Nov 2007 10:43:28 -0000 1.55
682 +++ 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;
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 */
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 }
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 */
728 -#if MEMP_STATS
729 - lwip_stats.memp[type].used--;
730 -#endif /* MEMP_STATS */
731 + MEMP_STATS_DEC(used, type);
733 memp->next = memp_tab[type];
734 memp_tab[type] = memp;
735 Index: src/core/netif.c
736 ===================================================================
737 RCS file: /sources/lwip/lwip/src/core/netif.c,v
738 retrieving revision 1.65
739 retrieving revision 1.68
740 diff -u -p -r1.65 -r1.68
741 --- src/core/netif.c 9 Oct 2007 20:00:55 -0000 1.65
742 +++ 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 */
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 */
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 */
775 netif_set_addr(netif, ipaddr, netmask, gw);
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 */
938 Index: src/core/pbuf.c
939 ===================================================================
940 RCS file: /sources/lwip/lwip/src/core/pbuf.c,v
941 retrieving revision 1.127
942 retrieving revision 1.128
943 diff -u -p -r1.127 -r1.128
944 --- src/core/pbuf.c 4 Mar 2008 16:37:46 -0000 1.127
945 +++ 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
957 Index: src/core/stats.c
958 ===================================================================
959 RCS file: /sources/lwip/lwip/src/core/stats.c,v
960 retrieving revision 1.27
961 retrieving revision 1.28
962 diff -u -p -r1.27 -r1.28
963 --- src/core/stats.c 4 Mar 2008 16:31:32 -0000 1.27
964 +++ 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 }
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 */
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 }
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 */
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 */
1056 +void
1057 +stats_display(void)
1058 +{
1059 + s16_t i;
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);
1074 -#endif
1075 + SYS_STATS_DISPLAY();
1077 #endif /* LWIP_STATS_DISPLAY */
1079 Index: src/core/sys.c
1080 ===================================================================
1081 RCS file: /sources/lwip/lwip/src/core/sys.c,v
1082 retrieving revision 1.32
1083 retrieving revision 1.33
1084 diff -u -p -r1.32 -r1.33
1085 --- src/core/sys.c 25 Nov 2007 13:57:05 -0000 1.32
1086 +++ 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)
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
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;
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;
1130 @@ -125,7 +125,7 @@ sys_mbox_fetch(sys_mbox_t mbox, void **m
1131 void
1132 sys_sem_wait(sys_sem_t sem)
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;
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;
1166 Index: src/core/tcp.c
1167 ===================================================================
1168 RCS file: /sources/lwip/lwip/src/core/tcp.c,v
1169 retrieving revision 1.85
1170 retrieving revision 1.86
1171 diff -u -p -r1.85 -r1.86
1172 --- src/core/tcp.c 22 Jan 2008 21:15:15 -0000 1.85
1173 +++ 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;
1194 Index: src/core/tcp_in.c
1195 ===================================================================
1196 RCS file: /sources/lwip/lwip/src/core/tcp_in.c,v
1197 retrieving revision 1.97
1198 retrieving revision 1.100
1199 diff -u -p -r1.97 -r1.100
1200 --- src/core/tcp_in.c 22 Jan 2008 21:15:15 -0000 1.97
1201 +++ 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)
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;
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;
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 + }
1242 break;
1243 @@ -1282,10 +1282,7 @@ tcp_receive(struct tcp_pcb *pcb)
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);
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;
1263 /* And we are done processing options. */
1264 break;
1265 Index: src/core/ipv4/autoip.c
1266 ===================================================================
1267 RCS file: /sources/lwip/lwip/src/core/ipv4/autoip.c,v
1268 retrieving revision 1.16
1269 retrieving revision 1.17
1270 diff -u -p -r1.16 -r1.17
1271 --- src/core/ipv4/autoip.c 26 Jan 2008 16:11:40 -0000 1.16
1272 +++ 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));
1282 if ((netif->autoip->state == AUTOIP_STATE_PROBING) ||
1283 ((netif->autoip->state == AUTOIP_STATE_ANNOUNCING) &&
1284 Index: src/core/ipv4/inet_chksum.c
1285 ===================================================================
1286 RCS file: /sources/lwip/lwip/src/core/ipv4/inet_chksum.c,v
1287 retrieving revision 1.4
1288 retrieving revision 1.5
1289 diff -u -p -r1.4 -r1.5
1290 --- src/core/ipv4/inet_chksum.c 10 Mar 2008 16:12:31 -0000 1.4
1291 +++ 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"
1296 -#include <string.h>
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
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))
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;
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
1336 /* Consume left-over byte, if any */
1337 - if (len > 0)
1338 + if (len > 0) {
1339 ((u8_t *)&t)[0] = *(u8_t *)ps;;
1340 + }
1342 /* Add end bytes */
1343 sum += t;
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);
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 + }
1360 return sum;
1362 @@ -211,18 +215,20 @@ lwip_standard_chksum(void *dataptr, int
1364 while (len > 7) {
1365 tmp = sum + *pl++; /* ping */
1366 - if (tmp < sum)
1367 + if (tmp < sum) {
1368 tmp++; /* add back carry */
1369 + }
1371 sum = tmp + *pl++; /* pong */
1372 - if (sum < tmp)
1373 + if (sum < tmp) {
1374 sum++; /* add back carry */
1375 + }
1377 len -= 8;
1380 /* make room in upper bits */
1381 - sum = (sum >> 16) + (sum & 0xffff);
1382 + sum = FOLD_U32T(sum);
1384 ps = (u16_t *)pl;
1386 @@ -233,16 +239,20 @@ lwip_standard_chksum(void *dataptr, int
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 + }
1395 sum += t; /* add end bytes */
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);
1404 - if (odd)
1405 - sum = ((sum & 0xff) << 8) | ((sum & 0xff00) >> 8);
1406 + if (odd) {
1407 + sum = SWAP_BYTES_IN_WORD(sum);
1408 + }
1410 return sum;
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);
1427 /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
1430 if (swapped) {
1431 - acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);
1432 + acc = SWAP_BYTES_IN_WORD(acc);
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);
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);
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);
1464 /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
1467 if (swapped) {
1468 - acc = ((acc & 0xff) << 8) | ((acc & 0xff00UL) >> 8);
1469 + acc = SWAP_BYTES_IN_WORD(acc);
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);
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);
1487 @@ -380,13 +391,7 @@ inet_chksum_pseudo_partial(struct pbuf *
1488 u16_t
1489 inet_chksum(void *dataptr, u16_t len)
1491 - u32_t acc;
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);
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);
1517 if (swapped) {
1518 - acc = ((acc & 0x00ffUL) << 8) | ((acc & 0xff00UL) >> 8);
1519 + acc = SWAP_BYTES_IN_WORD(acc);
1521 return (u16_t)~(acc & 0xffffUL);
1523 Index: src/core/ipv4/ip.c
1524 ===================================================================
1525 RCS file: /sources/lwip/lwip/src/core/ipv4/ip.c,v
1526 retrieving revision 1.66
1527 retrieving revision 1.68
1528 diff -u -p -r1.66 -r1.68
1529 --- src/core/ipv4/ip.c 14 Jan 2008 20:53:23 -0000 1.66
1530 +++ 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);
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()"));
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()"));
1547 - return netif->output(netif, p, dest);
1548 + return netif->output(netif, p, dest);
1549 + }
1552 /**
1553 Index: src/include/lwip/debug.h
1554 ===================================================================
1555 RCS file: /sources/lwip/lwip/src/include/lwip/debug.h,v
1556 retrieving revision 1.37
1557 retrieving revision 1.39
1558 diff -u -p -r1.37 -r1.39
1559 --- src/include/lwip/debug.h 22 Sep 2007 11:16:07 -0000 1.37
1560 +++ 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
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 */
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 */
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)
1599 #else /* LWIP_DEBUG */
1600 -#define LWIP_DEBUGF(debug,x)
1601 +#define LWIP_DEBUGF(debug, message)
1602 #endif /* LWIP_DEBUG */
1604 #endif /* __LWIP_DEBUG_H__ */
1605 Index: src/include/lwip/err.h
1606 ===================================================================
1607 RCS file: /sources/lwip/lwip/src/include/lwip/err.h,v
1608 retrieving revision 1.13
1609 retrieving revision 1.15
1610 diff -u -p -r1.13 -r1.15
1611 --- src/include/lwip/err.h 13 Dec 2007 23:06:50 -0000 1.13
1612 +++ src/include/lwip/err.h 17 Jun 2008 20:27:32 -0000 1.15
1613 @@ -33,37 +33,43 @@
1614 #define __LWIP_ERR_H__
1616 #include "lwip/opt.h"
1617 +#include "lwip/arch.h"
1619 #ifdef __cplusplus
1620 extern "C" {
1621 #endif
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*/
1632 /* Definitions for error constants. */
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. */
1641 #define ERR_IS_FATAL(e) ((e) < ERR_RTE)
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. */
1652 -#define ERR_VAL -8 /* Illegal value. */
1653 +#define ERR_VAL -9 /* Illegal value. */
1655 -#define ERR_ARG -9 /* Illegal argument. */
1656 +#define ERR_ARG -10 /* Illegal argument. */
1658 -#define ERR_USE -10 /* Address in use. */
1659 +#define ERR_USE -11 /* Address in use. */
1661 -#define ERR_IF -11 /* Low-level netif error */
1662 -#define ERR_ISCONN -12 /* Already connected. */
1664 -#define ERR_TIMEOUT -13 /* Timeout. */
1665 +#define ERR_IF -12 /* Low-level netif error */
1666 +#define ERR_ISCONN -13 /* Already connected. */
1668 #define ERR_INPROGRESS -14 /* Operation in progress */
1670 Index: src/include/lwip/mem.h
1671 ===================================================================
1672 RCS file: /sources/lwip/lwip/src/include/lwip/mem.h,v
1673 retrieving revision 1.21
1674 retrieving revision 1.22
1675 diff -u -p -r1.21 -r1.22
1676 --- src/include/lwip/mem.h 4 Mar 2008 16:31:32 -0000 1.21
1677 +++ 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 */
1699 Index: src/include/lwip/netif.h
1700 ===================================================================
1701 RCS file: /sources/lwip/lwip/src/include/lwip/netif.h,v
1702 retrieving revision 1.43
1703 retrieving revision 1.46
1704 diff -u -p -r1.43 -r1.46
1705 --- src/include/lwip/netif.h 9 Oct 2007 19:59:59 -0000 1.43
1706 +++ src/include/lwip/netif.h 19 Jun 2008 16:27:23 -0000 1.46
1707 @@ -34,6 +34,8 @@
1709 #include "lwip/opt.h"
1711 +#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF)
1713 #include "lwip/err.h"
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 };
1730 #if LWIP_SNMP
1731 @@ -242,4 +252,12 @@ void netif_set_link_callback(struct neti
1733 #endif
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 */
1743 #endif /* __LWIP_NETIF_H__ */
1744 Index: src/include/lwip/opt.h
1745 ===================================================================
1746 RCS file: /sources/lwip/lwip/src/include/lwip/opt.h,v
1747 retrieving revision 1.116
1748 retrieving revision 1.122
1749 diff -u -p -r1.116 -r1.122
1750 --- src/include/lwip/opt.h 31 Jan 2008 18:19:29 -0000 1.116
1751 +++ 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
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
1778 /*
1779 ------------------------------------------------
1780 @@ -815,6 +836,39 @@
1781 #define LWIP_NETIF_HWADDRHINT 0
1782 #endif
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
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
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
1817 /*
1818 ------------------------------------
1819 ---------- LOOPIF options ----------
1820 @@ -827,20 +881,16 @@
1821 #define LWIP_HAVE_LOOPIF 0
1822 #endif
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
1848 /*
1849 Index: src/include/lwip/sio.h
1850 ===================================================================
1851 RCS file: /sources/lwip/lwip/src/include/lwip/sio.h,v
1852 retrieving revision 1.7
1853 retrieving revision 1.8
1854 diff -u -p -r1.7 -r1.8
1855 --- src/include/lwip/sio.h 6 Sep 2007 16:43:44 -0000 1.7
1856 +++ 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 */
1861 +#ifndef __SIO_H__
1862 +#define __SIO_H__
1864 #include "lwip/arch.h"
1866 #ifdef __cplusplus
1867 extern "C" {
1868 #endif
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
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. */
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
1885 #endif
1887 +#endif /* __SIO_H__ */
1888 Index: src/include/lwip/sockets.h
1889 ===================================================================
1890 RCS file: /sources/lwip/lwip/src/include/lwip/sockets.h,v
1891 retrieving revision 1.38
1892 retrieving revision 1.39
1893 diff -u -p -r1.38 -r1.39
1894 --- src/include/lwip/sockets.h 2 Dec 2007 15:24:02 -0000 1.38
1895 +++ 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 */
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
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)
1935 Index: src/include/lwip/stats.h
1936 ===================================================================
1937 RCS file: /sources/lwip/lwip/src/include/lwip/stats.h,v
1938 retrieving revision 1.19
1939 retrieving revision 1.23
1940 diff -u -p -r1.19 -r1.23
1941 --- src/include/lwip/stats.h 28 Nov 2007 21:25:07 -0000 1.19
1942 +++ src/include/lwip/stats.h 8 Jul 2008 09:15:57 -0000 1.23
1943 @@ -57,7 +57,6 @@ extern "C" {
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 };
1960 struct stats_syselem {
1961 @@ -142,64 +142,138 @@ extern struct stats_ lwip_stats;
1962 #define stats_init() /* Compatibility define, not init needed. */
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 */
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
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
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
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
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
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
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
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
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
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
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
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 */
2099 #ifdef __cplusplus
2100 Index: src/include/lwip/tcpip.h
2101 ===================================================================
2102 RCS file: /sources/lwip/lwip/src/include/lwip/tcpip.h,v
2103 retrieving revision 1.24
2104 retrieving revision 1.27
2105 diff -u -p -r1.24 -r1.27
2106 --- src/include/lwip/tcpip.h 12 Jan 2008 11:52:22 -0000 1.24
2107 +++ 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 */
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)
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);
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)
2121 Index: src/include/netif/loopif.h
2122 ===================================================================
2123 RCS file: /sources/lwip/lwip/src/include/netif/loopif.h,v
2124 retrieving revision 1.7
2125 retrieving revision 1.9
2126 diff -u -p -r1.7 -r1.9
2127 --- src/include/netif/loopif.h 10 May 2007 10:59:20 -0000 1.7
2128 +++ 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__
2133 +#include "lwip/opt.h"
2134 #include "lwip/netif.h"
2135 #include "lwip/err.h"
2137 @@ -39,9 +40,9 @@
2138 extern "C" {
2139 #endif
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 */
2148 err_t loopif_init(struct netif *netif);
2150 Index: src/netif/etharp.c
2151 ===================================================================
2152 RCS file: /sources/lwip/lwip/src/netif/etharp.c,v
2153 retrieving revision 1.145
2154 retrieving revision 1.148
2155 diff -u -p -r1.145 -r1.148
2156 --- src/netif/etharp.c 4 Mar 2008 13:41:24 -0000 1.145
2157 +++ 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
2165 * { ETHARP_TRY_HARD is set at this point }
2166 */
2167 @@ -1130,7 +1130,14 @@ ethernet_input(struct pbuf *p, struct ne
2169 /* points to packet payload, which starts with an Ethernet header */
2170 ethhdr = p->payload;
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)));
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 */
2186 default:
2187 + ETHARP_STATS_INC(etharp.proterr);
2188 + ETHARP_STATS_INC(etharp.drop);
2189 pbuf_free(p);
2190 p = NULL;
2191 break;
2192 Index: src/netif/loopif.c
2193 ===================================================================
2194 RCS file: /sources/lwip/lwip/src/netif/loopif.c,v
2195 retrieving revision 1.26
2196 retrieving revision 1.27
2197 diff -u -p -r1.26 -r1.27
2198 --- src/netif/loopif.c 31 Aug 2007 10:14:09 -0000 1.26
2199 +++ src/netif/loopif.c 12 Jun 2008 20:10:10 -0000 1.27
2200 @@ -40,149 +40,8 @@
2201 #if LWIP_HAVE_LOOPIF
2203 #include "netif/loopif.h"
2204 -#include "lwip/pbuf.h"
2205 #include "lwip/snmp.h"
2207 -#include <string.h>
2209 -#if !LWIP_LOOPIF_MULTITHREADING
2211 -#include "lwip/sys.h"
2212 -#include "lwip/mem.h"
2214 -/* helper struct for the linked list of pbufs */
2215 -struct loopif_private {
2216 - struct pbuf *first;
2217 - struct pbuf *last;
2218 -};
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;
2235 - LWIP_ERROR("priv != NULL", (priv != NULL), return;);
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);
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 */
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;
2302 - LWIP_UNUSED_ARG(ipaddr);
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 - }
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 - }
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;
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 */
2344 - return ERR_OK;
2345 -}
2347 /**
2348 * Initialize a lwip network interface structure for a loopback interface
2350 @@ -193,16 +52,6 @@ loopif_output(struct netif *netif, struc
2351 err_t
2352 loopif_init(struct netif *netif)
2354 -#if !LWIP_LOOPIF_MULTITHREADING
2355 - struct loopif_private *priv;
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 */
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)
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;
2376 Index: src/netif/slipif.c
2377 ===================================================================
2378 RCS file: /sources/lwip/lwip/src/netif/slipif.c,v
2379 retrieving revision 1.29
2380 retrieving revision 1.30
2381 diff -u -p -r1.29 -r1.30
2382 --- src/netif/slipif.c 30 Nov 2007 17:22:21 -0000 1.29
2383 +++ src/netif/slipif.c 17 Jun 2008 20:14:05 -0000 1.30
2384 @@ -44,6 +44,9 @@
2386 #include "netif/slipif.h"
2387 #include "lwip/opt.h"
2389 +#if LWIP_HAVE_SLIPIF
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;
2398 +#endif /* LWIP_HAVE_SLIPIF */