As already mentioned, lwIP does not seek to provide a complete implementation of a TCP/IP stack providing the same level of functionality provided in large OSes such as Linux, Windows, *BSD, etc. While some aspects are controlled by configuration, in other cases functionality is intentionally limited to fit the design requirements of a compact footprint.
While a complete list of the limitations would be too numerous to enumerate, here are some of the most relevant ones to be aware of:
Retransmission and windowing algorithms are implemented simply, at the expense of some performance.
Routing is simplified - one gateway per interface. IP forwarding follows the same rules as the host itself.
No support for IGMP, NAT, nor packet filtering.
The TCP, DHCP and IP protocols can contain options in their packets. Relatively few of these options are supported by lwIP.
Path MTU discovery (from RFC1191) is not supported. Ordinarily it is used to avoid fragmentation of packets resulting from the maximum MTU of an intermediate link between source and destination being smaller than the packet sizes actually transmitted. lwIP does however allow the TCP Maximum Segment Size (MSS) to be configured.
No complex data structures, caches and search trees to optimise speed. Generally simple lists are used.
Thread safety (for the sequential and BSD compatibility API) is implemented in a very simple form. Individual connections should not be operated on by multiple threads simultaneously. The mutual exclusion that is provided is at a very coarse grain - the network processing operations themselves are not multi-threaded.
Selective Acknowledgements (SACKs) (from RFC2018) are not provided in the TCP implementation. SACKs are a commonly implemented approach to increasing performance on links subject to packet loss, packet errors or congestion.
Most ICMP packet types are ignored.
If IP fragmentation and reassembly support is enabled, no more than one sequence of IP fragments received at one point on any connection can be reassembled at one time. Even for each connection, overlapping fragments from different packets are not handled. In such cases, the packet is simply dropped. It is hoped, that a retransmission may be successful. Received IP fragments are allowed to be reassembled out of order however.
The BSD sockets compatibility API does not implement all socket options (including SO_REUSEADDR/SO_REUSEPORT), API functions, nor API semantics.
Error handling for application errors is frequently only handled with asserts - used only during debug builds during development, allowing for smaller production code in release builds.
The TCP persist timer is not implemented. If a remote peer has filled its receive window and as a result lwIP stops sending, then when the remote peer processes more data it sends an ACK to update the window. However if that ACK is lost, then if data is entirely unidirectional (lwIP to remote host), the connection could stall. In practice, this has not been something people have experienced really.
TCP data is not split in the unsent queue, resulting in somewhat inefficient use of receiver windows.