How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction How to port a TCP/IP stack in your kernel TCP/IP stacks without an Ethernet driver Focus on lw IP Conclusion Nassim Eddequiouaq July 20, 2014
Plan How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction TCP/IP stacks 1 Introduction Focus on lw IP Conclusion
Generic TCP/IP stack How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction TCP/IP stacks Focus on lw IP Conclusion
Plan How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction TCP/IP stacks 2 TCP/IP stacks Focus on lw IP Conclusion
Which free open source stacks ? How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction • uIP TCP/IP stacks • lw IP Focus on lw IP Conclusion • tinytcp, wattcp.. • fNET • Bentham’s TCP/IP stack • OpenBSD → not standalone
Focus on what you need How to port a TCP/IP stack in your kernel Nassim Eddequiouaq • embedded ? Introduction TCP/IP stacks • bare metal ? (no operating system) Focus on lw IP • Keep It Simple, Stupid ? Conclusion • fast ? • out of the box ? Your choice.
uIP How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction • world’s smallest TCP/IP Stack TCP/IP stacks • used mostly for 8/16 bits microcontrollers Focus on lw IP Conclusion • separates 32-bit arithmetic • useful for embedded systems • uses polling • handles TCP , UDP (poorly), IPv4
uIP simple example How to port a TCP/IP stack in your kernel #define UIP_ACTIVE_OPEN 1 Nassim Eddequiouaq void setup() { connect_test(); Introduction } TCP/IP stacks Focus on lw IP void loop() { uip_send("foo\n", 4); Conclusion } void connect_test(void) { uip_ipaddr_t ipaddr; uip_ipaddr(&ipaddr , 192, 168, 1, 100); uip_connect(&ipaddr, HTONS(8080)); } [...]
lw IP How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction • works with IRQs TCP/IP stacks Focus on lw IP • which makes it VERY fast Conclusion • DHCP , AUTO-IP , ARP , UDP , PPP. . . • works well even with few RAM • several layouts of API
fNET structure How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction TCP/IP stacks Focus on lw IP Conclusion
fNET How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction TCP/IP stacks • mostly for 32bits microcontrollers Focus on lw IP • supports ARM, Coldfire and Power Architecture Conclusion • TCP , UDP , IPv4, IPv6 • HTTP server, DHCP client, DNS. . .
Plan How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction Focus on lw IP 3 TCP/IP stacks Port lw IP Focus on lw IP Port lw IP Test and debug Test and debug Conclusion
Plan How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction Focus on lw IP 3 TCP/IP stacks Port lw IP Focus on lw IP Port lw IP Test and debug Test and debug Conclusion
lw IP structure How to port a TCP/IP stack in your kernel lw IP offers 3 APIs: Nassim Eddequiouaq • Raw API • Netconn API Introduction TCP/IP stacks • BSD Socket API Focus on lw IP Port lw IP Test and debug These APIs are layered in term of abstraction as follows: Conclusion Very useful!
lw IP structure How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction TCP/IP stacks Focus on lw IP Port lw IP Test and debug Conclusion
Raw API How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction TCP/IP stacks This is the core API of lw IP Focus on lw IP • best performances Port lw IP Test and debug • handles asynchronous events Conclusion • does not need an OS, bare metal works
Netconn API How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction This is the sequential API: TCP/IP stacks • allows multi-threading Focus on lw IP Port lw IP • needs an OS Test and debug Conclusion • lower performances than Raw API • easier to use • needs much more memory
BSD Socket API How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction TCP/IP stacks A Berkeley-like Socket implementation: Focus on lw IP Port lw IP • POSIX compliant Test and debug Conclusion • very portable
Initialize the lw IP stack How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction Two ways: TCP/IP stacks • single-threaded: Focus on lw IP Port lw IP lwip_init() Test and debug Conclusion • multi-threaded: tcpip_init(...) The second one calls implicitly the first one
Your network interface How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction First, setup the compiler abstraction layer. TCP/IP stacks In ‘cc.h’ , define macros describing your processor and Focus on lw IP your compiler for : Port lw IP Test and debug • types Conclusion • byte ordering • structure packing
Your network interface How to port a TCP/IP stack in your kernel Nassim Eddequiouaq lwIP is able to use higher-level mechanisms and Introduction structures. TCP/IP stacks Focus on lw IP In ‘sys_arch.c’ , you may define a set of wrappers in Port lw IP Test and debug order to make it access: Conclusion • semaphores • mailboxes • threads This file is optional
Start your network interface How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Add the interface: Introduction • struct *netif netif_add(...) TCP/IP stacks • specify IP address, netmask, gateway address Focus on lw IP Port lw IP Test and debug Conclusion Set the interface up: • static IP address: netif_set_{up,down} • DHCP: dhcp_{start,stop} • AUTO-IP: autoip_{start,stop}
Initialize your device driver How to port a TCP/IP stack in your kernel Nassim Eddequiouaq netif_add(...) takes (among other parameters) the init Introduction and input functions. TCP/IP stacks Focus on lw IP Port lw IP You must provide these two functions with defined Test and debug Conclusion prototypes: • err_t foo_init(struct netif *netif) • err_t foo_input(struct pbuf *p, struct netif *netif)
Set your net interface properly How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction Set your struct netif during initialization: TCP/IP stacks • state fields (i.e hardware address Focus on lw IP and length, MTU, name. . . ) Port lw IP Test and debug Conclusion • functions fields (output, link_output, input) • flag field: OR options you want to activate (broadcast, PPP , ARP. . . )
Your driver’s ouput functions How to port a TCP/IP stack in your kernel There are two function pointers that you need to set: Nassim Eddequiouaq • netif->linkoutput Introduction • netif->output TCP/IP stacks Focus on lw IP Implement the following functions: Port lw IP Test and debug • err_t foo_linkoutput(...) : called when a raw link Conclusion packet is ready to be send and does the actual transmission • err_t foo_output(...) : called when an IP packet is ready for transmission foo_output should call foo_linkoutput when the treated packet is ready.
Your driver’s input management How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction When you receive a packet, pass it to foo_netif->input . TCP/IP stacks Focus on lw IP Port lw IP Test and debug This field has been set by your netif_add call, the last Conclusion parameter being a function pointer: • err_t (*input)(struct pbuf *p, struct netif *netif)
Sum up How to port a TCP/IP stack in your kernel Nassim Call lwip_init() / tcpip_init(...) 1 Eddequiouaq Ethernet init function to pass to netif_add(...) 2 Introduction TCP/IP stacks Ethernet input function to pass to netif_add(...) 3 Focus on lw IP Port lw IP Setup struct netif to pass to netif_add(...) 4 Test and debug Conclusion Ethernet link_output function and add it to struct netif 5 Ethernet output function and add it to struct netif 6 Call netif_add(...) 7 Set default network interface with netif_set_default(...) 8 9 Set interface to ‘UP’ with netif_set_up(...)
Plan How to port a TCP/IP stack in your kernel Nassim Eddequiouaq Introduction Focus on lw IP 3 TCP/IP stacks Port lw IP Focus on lw IP Port lw IP Test and debug Test and debug Conclusion
How to test your network interface ? How to port a TCP/IP stack in your kernel Nassim Remember, we have no Ethernet driver yet! Eddequiouaq Introduction Several solutions: TCP/IP stacks • init another lw IP inside your kernel as a standalone Focus on lw IP module Port lw IP Test and debug • setup a protocol control block (PCB) and a TCP Conclusion connection associated to this PCB • activate the TCP connection • make it tcp_write(...) data to your network interface • create a TAP device before starting qemu and make it output/input data
Debugging your stack How to port a TCP/IP stack in your kernel Nassim Eddequiouaq There are some rough edges, you might want to tweak Introduction your stack: TCP/IP stacks Focus on lw IP • a debugger, a JTAG → what if you don’t have one ? Port lw IP Test and debug • printf / built-in debug → quite nice actually! Conclusion 1 #define LWIP_DEBUG 1 2 #define IP_DEBUG LWIP_DBG_ON configure debug messages in ‘opt.h’ and ‘lwipopts.h’ 3
Recommend
More recommend