This page describes our Linux IPSEC implementation.
We are distributing our complete x-kernel environment (minus the export controlled protocols) at our site. To build the x-kernel you will also need Christopher Provenzano's pthreads package. You can find both of these packages below.
You may request the export controlled sections by sending email to mjk@cs.arizona.edu.
The following sections explain how this is accomplished.
Linux provides for kernel loadable modules. The most common use for these modules is to provide for a multitude of device drivers without polluting the kernel proper. The above diagram shows a NIC driver loaded into the kernel.
The ETHTAP module is used to intercept all network traffic both to and from the lower level NIC driver. This is accomplished by a combination of overriding a few kernel functions which are exported to the NIC driver module, and overriding a few device methods used in the NIC driver module. To allow user processes access to the intercepted Ethernet frames, the module provides two pseudo-devices.
The high tap attaches to the Kernel side of the network stack.
The low tap attaches to the Driver side of the network stack.
Each device has three states which are defined as follows:
Network flow is disturbed since only frames written to /dev/htap get to the Kernel, and only frames written the /dev/ltap get to the NIC.
Or, in pseudo-code from:
FILE *htap = open("/dev/htap") FILE *ltap = open("/dev/ltap") char hbuf[BUFSIZE] char lbuf[BUFSIZE] while !done { if read(htap, hbuf) write(ltap, hbuf) if read(ltap, lbuf) write(htap, lbuf) }
The above diagram shows an x-kernel IP forwarder graph attached to the /dev/htap and /dev/ltap devices. This graph interposes itself between the Kernel network stack and the NIC driver in the same manner explained in the previous section.
To illustrate the flow of data in this diagram consider the following scenario (numbers match points on the diagram).
There are a few things glossed over in the above scenario. First of all there are also forwarders for UDP and ICMP so TCP is not the only supported protocol. Second, the data flow from the NIC to the Kernel is exactly the reverse of the above procedure.
Lastly, there is a bit of IP and Ethernet address manipulation required to get traffic to flow from one side of the graph to the other. This manipulation takes place in the following protocols ETHKERN, ETHDEV, TCP_IPF, UDP_IPF, and ICMP_IPF. Additionally, the left hand side ARP must change to allow all IP addresses to resolve to the Ethernet address of the host machine. For more information see the source code for the mentioned protocols.
There is no diagram for this configuration since it would be too complex, but you can see the x-kernel graph.comp file used to implement this.
@; name=watchdog; name=ethkern; name=ethdev; name=eth/1 protocols=ethdev; name=arp/1 dir=arp files=arp.c,arp_rom.c,arp_table.c protocols=eth/1; name=eth/0 protocols=ethkern; name=arp/0 protocols=eth/0; name=vnet protocols=eth/0,arp/0,eth/1,arp/1; name=rfc1825 protocols=km/sauser,km/sauser,md5,md5, crypt,crypt3,tcrypt,md5,crypt3in; name=ip dir=ip files=ip.c,ip_frag.c,ip_hdr.c,ip_rom.c,iproute.c, ip_control.c,ip_gc.c,ip_input.c,ip_util.c protocols=vnet,rfc1825; name=km/sauser; name=km/b; name=km/md5; name=km/alg; name=km/crypt; name=km/tcrypt; name=km/crypt3; name=km/crypt3in; name=sink; name=md5 protocols=km/md5; name=tcrypt protocols=km/tcrypt; name=crypt protocols=km/crypt; name=crypt3 protocols=km/crypt3; name=crypt3in protocols=km/crypt3in; name=spiint protocols=ip,saidmgr; name=saidmgr protocols=sink,vnet,km/sauser,km/b,km/alg,km/md5,km/crypt; name=ipf_udp protocols=spiint; name=ipf_tcp protocols=spiint; name=ipf_icmp protocols=spiint; @; name=prottest trace=TR_MAJOR_EVENTS; name=init trace=TR_FULL_TRACE; name=watchdogp trace=TR_FULL_TRACE; prottbl=./prottbl; romopt md5 useipsec; romopt md5 leafmode; romopt md5 rfc1828; romopt crypt useipsec; romopt tcrypt useipsec; romopt km/sauser kmparams 8 0-100 100; romopt km/b kmparams 4 0-100 100; romopt km/md5 kmparams 8 16 16; romopt km/crypt kmparams 8 8 10; romopt km/tcrypt kmparams 8 8 10; romopt km/crypt3 kmparams 8 16 10; romopt km/crypt3in kmparams 8 16 10;