Tun device: How to avoid routing dead loop when write a transparent proxy?

I am not quite sure what your LWIP network stack is supposed to do in this scenario, and how it is related to being a transparent proxy, so partial answer:

From a networking perspective, your TUN device just looks like another network interface. So the computer assumes there's a LAN segment attached to this device, there's other computers on this segment, etc.

Now LWIP (which I haven't used) seems to be a library in implement a network stack. Assuming you connect up the bottom layer of LWIP to a TUN interface (if that's not what you are doing, then please clarify), that means that the applications using LWIP would be the "other device" the main computer sees on the LAN segment behind the TUN.

Which means in this scenario, the main computer gets a private-only IP-address, say 192.168.0.1 on the TUN, your application gets 192.168.0.2 on LWIP, and they can communicate.

Now if the application you have in mind is transparent proxy (again, please add additional information to your question if that is not what you are doing), and this application wants to use the normal Linux networking stack to connect to the rest of the world, then the easiest way is to use networking namespace:

Set up a fresh namespace (google for tutorials). Move your computer's default network interface (say wlan0) into that namespace. Add a default route to that network interface in the namespace. Run your application + LWIP library in the namespace, but move the TUN interface to the main network namespace. In the main network namespace, have a default route to your application's IP (192.168.0.2) via the TUN interface.

That means all applications running in the main network namespace connect to the outside via your application using the default route in the main network namespace, and your application can forward those and connect to the outside via the "real" interface wlan0 and the second default route.

No route conflict, no returning packets.