http://www.whiteboard.ne.jp/~admin2/tuntap/

TAP driver for Solaris used for OpenVPN

This is a TAP driver for Solaris that can be used for OpenVPN
The code is base on Universal TUN/TAP driver. I made changes somewhat and added some code to it for supporting Ethernet tunneling feature, since Universal TUN/TAP driver for Solaris only supports IP tunneling known as TUN.

Since there has not been TAP driver for Solaris, OpenVPN does not have code for handling a TAP device for Solaris. So I also modified OpenVPN code somewhat, and made it work with this TAP driver.

Also, I wrote bridge moduel for Solaris, so that you can configure Solaris as bridge server.


TAP driver

  • tuntap.tar.gz (Last Update: 25th Jun 2007)
  • Source

    After extracting tuntap.tar.gz file, run './configure', 'make', and 'make install' as usual.
    Both 'tun' and 'tap' driver will be built and installed on your system. You can access these devices through /dev/tun and /dev/tap.


Difference file for OpenVPN

  • tun.c (Last Update: 5th Nov 2006)

    Put this file on the directory where you extracted source code of OpenVPN, and swap existing tun.c file for it.
    NOTE: This file is based on tun.c file included in OpenVPN version 2.0.7 and 2.0.9. so you might get error, if you try to build this code with the other source code of OpenVPN version than 2.0.7 or 2.0.9.


Bridge module

  • bridge.tar.gz (Last Update: 24th Sep 2007)
  • Source

    After extracting bridge.tar.gz file, run './configure', 'make', and 'make install'. 'brdg' and brdgadm will be built and installed on your system.
    Where 'brdg' is a STREAMS module which enables briging 2 interfaces. And where 'brdgadm' is a configuration command to add/delete bridge interfaces.

    Usage: brdgadm [ -a interface | -d interface]
    Options:
       -a interface   : Add interface as port
       -d interface   : Delete interface from port list
       -l             : List all interfaces in port list
        
    See following sample configuration.

    Network configuration


    HostB is a router which is connected to 2 networks. By installing TAP and OpenVPN on HostB and HostC, I try to join HostC to Network1 through OpenVPN.

    1. On HostB, install TAP driver and OpenVPN, and then configure it as bridging server using server-bridge option.
      -------------
      dev tap
      proto tcp-server
      server-bridge 10.0.0.90 255.0.0.0 10.0.0.10 10.0.0.30
      client-to-client
      ca /etc/openvpn/keys/ca.crt
      cert /etc/openvpn/keys/u1.crt
      key /etc/openvpn/keys/u1.key  # This file should be kept secret
      dh /etc/openvpn/keys/dh1024.pem
      --------------
              
      Then, run openvpn
    2. On HostB, make and install bridge module.
      1. Extrace bridge.tar.gz
           # gunzip -c bridge.tar.gz | tar xvf -
          
      2. Make bridge moduel(brdg) and control command(brdgadm)
           # ./configure
           # make
           # make install
          
    3. On HostB, setting up bridge.
         # /usr/local/bin/brdgadm -a tap0
         # /usr/local/bin/brdgadm -a hme1
        
      where hme1 is a network interface connected with Network1. As a result, tap0 and hme1 is bridged. At this time, ifconfig looks like as below.
        hme0: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 2
             inet 172.29.73.90 netmask ffffff00 broadcast 172.29.73.255
             ether 8:0:20:91:a6:90
        hme1: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 4
             inet 10.0.0.90 netmask ff000000 broadcast 10.255.255.255
              ether 8:0:20:91:a6:90
        tap0: flags=1000842<BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 5
             inet 0.0.0.0 netmask 0
             ether a:0:20:14:32:52
        
    4. On HostC, install TAP driver and openvpn, and configure it as a client.
      ------------
      remote HostB
      proto tcp-client
      dev tap
      client
      persist-tun
      ca /etc/openvpn/keys/ca.crt
      cert /etc/openvpn/keys/onnv01.crt
      key /etc/openvpn/keys/onnv01.key
      -----------
         
      Then, run openvpn. At this time, ifconfig on HostC looks like as below.
         hme0: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 2
              inet 172.29.73.55 netmask ffffff00 broadcast 172.29.73.255
              ether 8:0:20:c6:69:c7
         tap0: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 4
              inet 10.0.0.10 netmask ff000000 broadcast 10.255.255.255
              ether a:0:20:53:71:52
         
    Now, HostC joins Network1 via tap0 interface through openvpn.

    But, please note that there's some limitation.. HostC can't communicate with HostB using a bridged IP address on HostB. I mean, ping 10.0.0.90 on HostC won't work.

    1. Ethernet packet from OpenVPN headed to HostB is passed to TAP driver.
    2. TAP driver forwards packet to bridge module.
    3. Bridge module forwards packet to hme driver as RAW data.
    4. hme driver transfer the packet to the wire, but never forward it to IP module.

    Of course, HostC can communicate with all the other hosts on Network1, but.. it can't communicate with bridged IP address of bridge server.

    One more note. Once openvpn running on HostB is terminated, bridge setting will be invalidated. So, after executing 2nd openvpn on HostB, you need to re-setup the bridge again.

    First, you need to drop existing settings.

       # /usr/local/bin/brdgadm -d hme1
       # /usr/local/bin/brdgadm -d tap0
      
    Then, re-setup bridge.
       # /usr/local/bin/brdgadm -a hme1
       # /usr/local/bin/brdgadm -a tap0 
      

tunctl command for Solaris

  • tunctl.tar.gz (Last Update: 24th Sep 2007)
  • Source

    This is a Solaris version of tunctl command which was originally written by Jeff Dike.
    The tunctl command enables administrator to preconfigure a TUN/TAP device. This command would be useful for testing, or for those who wants to use tun/tap interface just as a virtual interface.

    After extracting tuncntl.tar.gz file, run './configure', 'make', and 'make install'.
    By default, tunctl command is installed in /usr/local/bin

    NOTE:
    This Solaris version of tunctl command doesn't support the -u option, which enables administrator to specify an user who can use the interface.

    Example)
    Create tap0 interface

       # /usr/local/bin/tunctl -t tap0
       Set 'tap0' persistent
       #
        
    Delete tap0 interface
       # /usr/local/bin/tunctl -d tap0
       #
        

Tested Solaris versioin

I've tested on following Solaris version and platform.
  • 32 bit Solaris 9 on x86.
  • 32 bit Solaris 9 on sparc.
  • 64 bit Solaris 9 on sparc.
  • 32 bit Solaris 10 on x86.
  • 64 bit Solaris 10 on sparc.
  • 64 bit Solaris 10 on x64 (*).
(*) I've not done test, but some guys reported me that bridge module and tun/tap driver was able to be built and worked on x64 Solaris.

Change log

  • 05/08/2006
    • Modified tun_unitdata_req() to work on x86 Solaris 9
  • 05/12/2006
    • Added tun_generate_mac_addr() to generate MAC address for tap device.
  • 10/09/2006
    • Confirmed that the driver was able to work with OpenVPN 2.0.9.
      And also confirmed that tun.c file included in OpenVPN 2.0.9 has not been changed.
      So the above tun.c file can be compiled with OpenVPN 2.0.9 as well.
  • 11/05/2006
    • In tun_ioctl() of tap driver, reverted to original TUN/TAP driver's code which retrieves ppa from user program.
    • In open_tun() of openvpn, changed it to use I_STR ioctl command to pass ppa to tap driver.
      This will allow openvpn to specify instance number using 'dev' option, like "dev tap7".
  • 01/03/2007
    • Added comments about bridge module.
  • 02/21/2007
    • Modified brdgadm.c file to make it to be able to handle e1000g.
    • Modified brdgadm.c file to make it to be able to handle instance number
    • Modified configure script of both bridge module and tun/tap driver to be able to build modules on x64 Solaris.
  • 03/22/2007
    • Removed unnecessary debug code from brdgadm.c.
  • 06/25/2007
    • Added "-mno-red-zone" compile option for amd64.
  • 09/24/2007
    • Modified Makefile.in for brdgadm command, so that it allows to specify installation directory by --prefix option of configure script.


I wrote this just for fun. Since this has not been tested well, please DON'T install this on production system. Use this at your own risk.
But your advice or comment would be appreciated.

---
Kazuyoshi <[EMAIL PROTECTED]>
28th Apr 2006





Reply via email to